bool PLOT_CONTROLLER::OpenPlotfile( const wxString &aSuffix, PlotFormat aFormat, const wxString &aSheetDesc ) { LOCALE_IO toggle; /* Save the current format: sadly some plot routines depends on this but the main reason is that the StartPlot method uses it to dispatch the plotter creation */ m_plotOpts.SetFormat( aFormat ); // Ensure that the previous plot is closed ClosePlot(); // Now compute the full filename for the output and start the plot // (after ensuring the output directory is OK) wxString outputDirName = m_plotOpts.GetOutputDirectory() ; wxFileName outputDir = wxFileName::DirName( outputDirName ); wxString boardFilename = m_board->GetFileName(); if( EnsureOutputDirectory( &outputDir, boardFilename ) ) { wxFileName fn( boardFilename ); BuildPlotFileName( &fn, outputDirName, aSuffix, GetDefaultPlotExtension( aFormat ) ); m_plotter = StartPlotBoard( m_board, &m_plotOpts, fn.GetFullPath(), aSheetDesc ); } return( m_plotter != NULL ); }
void GENDRILL_WRITER_BASE::CreateMapFilesSet( const wxString& aPlotDirectory, REPORTER * aReporter ) { wxFileName fn; wxString msg; std::vector<DRILL_LAYER_PAIR> hole_sets = getUniqueLayerPairs(); // append a pair representing the NPTH set of holes, for separate drill files. if( !m_merge_PTH_NPTH ) hole_sets.push_back( DRILL_LAYER_PAIR( F_Cu, B_Cu ) ); for( std::vector<DRILL_LAYER_PAIR>::const_iterator it = hole_sets.begin(); it != hole_sets.end(); ++it ) { DRILL_LAYER_PAIR pair = *it; // For separate drill files, the last layer pair is the NPTH drill file. bool doing_npth = m_merge_PTH_NPTH ? false : ( it == hole_sets.end() - 1 ); buildHolesList( pair, doing_npth ); // The file is created if it has holes, or if it is the non plated drill file // to be sure the NPTH file is up to date in separate files mode. if( getHolesCount() > 0 || doing_npth ) { fn = getDrillFileName( pair, doing_npth, m_merge_PTH_NPTH ); fn.SetPath( aPlotDirectory ); fn.SetExt( wxEmptyString ); // Will be added by GenDrillMap wxString fullfilename = fn.GetFullPath() + wxT( "-drl_map" ); fullfilename << wxT(".") << GetDefaultPlotExtension( m_mapFileFmt ); bool success = genDrillMapFile( fullfilename, m_mapFileFmt ); if( ! success ) { if( aReporter ) { msg.Printf( _( "** Unable to create %s **\n" ), GetChars( fullfilename ) ); aReporter->Report( msg ); } return; } else { if( aReporter ) { msg.Printf( _( "Create file %s\n" ), GetChars( fullfilename ) ); aReporter->Report( msg ); } } } } }
bool PLOT_CONTROLLER::OpenPlotfile( const wxString &aSuffix, PlotFormat aFormat, const wxString &aSheetDesc ) { LOCALE_IO toggle; /* Save the current format: sadly some plot routines depends on this but the main reason is that the StartPlot method uses it to dispatch the plotter creation */ GetPlotOptions().SetFormat( aFormat ); // Ensure that the previous plot is closed ClosePlot(); // Now compute the full filename for the output and start the plot // (after ensuring the output directory is OK) wxString outputDirName = GetPlotOptions().GetOutputDirectory() ; wxFileName outputDir = wxFileName::DirName( outputDirName ); wxString boardFilename = m_board->GetFileName(); if( EnsureFileDirectoryExists( &outputDir, boardFilename ) ) { // outputDir contains now the full path of plot files m_plotFile = boardFilename; m_plotFile.SetPath( outputDir.GetPath() ); wxString fileExt = GetDefaultPlotExtension( aFormat ); // Gerber format can use specific file ext, depending on layers // (now not a good practice, because the official file ext is .gbr) if( GetPlotOptions().GetFormat() == PLOT_FORMAT_GERBER && GetPlotOptions().GetUseGerberProtelExtensions() ) fileExt = GetGerberProtelExtension( GetLayer() ); // Build plot filenames from the board name and layer names: BuildPlotFileName( &m_plotFile, outputDir.GetPath(), aSuffix, fileExt ); m_plotter = StartPlotBoard( m_board, &GetPlotOptions(), ToLAYER_ID( GetLayer() ), m_plotFile.GetFullPath(), aSheetDesc ); } return( m_plotter != NULL ); }
void EXCELLON_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory, bool aGenDrill, bool aGenMap, REPORTER * aReporter ) { wxFileName fn; wxString msg; wxString layername_extend; // added to the board filefame to create a full filename //(board fileName + layer pair names) // If some buried/blind vias are found, drill files are created // layer pair by layer pair for buried vias bool hasBuriedVias = false; for( TRACK* track = m_pcb->m_Track; track != NULL; track = track->Next() ) { if( track->Type() == PCB_VIA_T ) { const VIA *via = static_cast<const VIA*>( track ); if( via->GetViaType() == VIA_MICROVIA || via->GetViaType() == VIA_BLIND_BURIED ) { hasBuriedVias = true; break; } } } int layer1 = F_Cu; int layer2 = B_Cu; bool gen_through_holes = true; bool gen_NPTH_holes = false; for( ; ; ) { BuildHolesList( layer1, layer2, gen_through_holes ? false : true, gen_NPTH_holes, m_merge_PTH_NPTH ); if( GetHolesCount() > 0 ) // has holes? { fn = m_pcb->GetFileName(); layername_extend.Empty(); if( gen_NPTH_holes ) { layername_extend << wxT( "-NPTH" ); } else if( !gen_through_holes ) { if( layer1 == F_Cu ) layername_extend << wxT( "-front" ); else layername_extend << wxT( "-inner" ) << layer1; if( layer2 == B_Cu ) layername_extend << wxT( "-back" ); else layername_extend << wxT( "-inner" ) << layer2; } fn.SetName( fn.GetName() + layername_extend ); fn.SetPath( aPlotDirectory ); if( aGenDrill ) { fn.SetExt( DrillFileExtension ); wxString fullFilename = fn.GetFullPath(); FILE* file = wxFopen( fullFilename, wxT( "w" ) ); if( file == NULL ) { if( aReporter ) { msg.Printf( _( "** Unable to create %s **\n" ), GetChars( fullFilename ) ); aReporter->Report( msg ); } break; } else { if( aReporter ) { msg.Printf( _( "Create file %s\n" ), GetChars( fullFilename ) ); aReporter->Report( msg ); } } CreateDrillFile( file ); } if( aGenMap ) { fn.SetExt( wxEmptyString ); // Will be added by GenDrillMap wxString fullfilename = fn.GetFullPath() + wxT( "-drl_map" ); fullfilename << wxT(".") << GetDefaultPlotExtension( m_mapFileFmt ); bool success = GenDrillMapFile( fullfilename, m_mapFileFmt ); if( ! success ) { if( aReporter ) { msg.Printf( _( "** Unable to create %s **\n" ), GetChars( fullfilename ) ); aReporter->Report( msg ); } return; } else { if( aReporter ) { msg.Printf( _( "Create file %s\n" ), GetChars( fullfilename ) ); aReporter->Report( msg ); } } } } if( gen_NPTH_holes ) // The last drill file was created break; if( !hasBuriedVias ) gen_NPTH_holes = true; else { if( gen_through_holes ) layer2 = layer1 + 1; // done with through-board holes, prepare generation of first layer pair else { if( layer2 >= B_Cu ) // no more layer pair to consider { layer1 = F_Cu; layer2 = B_Cu; gen_NPTH_holes = true; continue; } layer1++; layer2++; // use next layer pair if( layer2 == m_pcb->GetCopperLayerCount() - 1 ) layer2 = B_Cu; // the last layer is always the back layer } gen_through_holes = false; } } }
void DIALOG_PLOT::Plot( wxCommandEvent& event ) { applyPlotSettings(); // If no layer selected, we have nothing plotted. // Prompt user if it happens because he could think there is a bug in Pcbnew. if( !m_plotOpts.GetLayerSelection().any() ) { DisplayError( this, _( "No layer selected, Nothing to plot" ) ); return; } // Create output directory if it does not exist (also transform it in // absolute form). Bail if it fails wxFileName outputDir = wxFileName::DirName( m_plotOpts.GetOutputDirectory() ); wxString boardFilename = m_parent->GetBoard()->GetFileName(); REPORTER& reporter = m_messagesPanel->Reporter(); if( !EnsureFileDirectoryExists( &outputDir, boardFilename, &reporter ) ) { wxString msg; msg.Printf( _( "Could not write plot files to folder \"%s\"." ), GetChars( outputDir.GetPath() ) ); DisplayError( this, msg ); return; } m_plotOpts.SetAutoScale( false ); m_plotOpts.SetScale( 1 ); switch( m_plotOpts.GetScaleSelection() ) { default: break; case 0: // Autoscale option m_plotOpts.SetAutoScale( true ); break; case 2: // 3:2 option m_plotOpts.SetScale( 1.5 ); break; case 3: // 2:1 option m_plotOpts.SetScale( 2 ); break; case 4: // 3:1 option m_plotOpts.SetScale( 3 ); break; } /* If the scale factor edit controls are disabled or the scale value * is 0, don't adjust the base scale factor. This fixes a bug when * the default scale adjust is initialized to 0 and saved in program * settings resulting in a divide by zero fault. */ if( m_fineAdjustXscaleOpt->IsEnabled() && m_XScaleAdjust != 0.0 ) m_plotOpts.SetFineScaleAdjustX( m_XScaleAdjust ); if( m_fineAdjustYscaleOpt->IsEnabled() && m_YScaleAdjust != 0.0 ) m_plotOpts.SetFineScaleAdjustY( m_YScaleAdjust ); if( m_PSFineAdjustWidthOpt->IsEnabled() ) m_plotOpts.SetWidthAdjust( m_PSWidthAdjust ); wxString file_ext( GetDefaultPlotExtension( m_plotOpts.GetFormat() ) ); // Test for a reasonable scale value // XXX could this actually happen? isn't it constrained in the apply // function? if( m_plotOpts.GetScale() < PLOT_MIN_SCALE ) DisplayInfoMessage( this, _( "Warning: Scale option set to a very small value" ) ); if( m_plotOpts.GetScale() > PLOT_MAX_SCALE ) DisplayInfoMessage( this, _( "Warning: Scale option set to a very large value" ) ); GERBER_JOBFILE_WRITER jobfile_writer( m_board, &reporter ); // Save the current plot options in the board m_parent->SetPlotSettings( m_plotOpts ); wxBusyCursor dummy; for( LSEQ seq = m_plotOpts.GetLayerSelection().UIOrder(); seq; ++seq ) { PCB_LAYER_ID layer = *seq; // All copper layers that are disabled are actually selected // This is due to wonkyness in automatically selecting copper layers // for plotting when adding more than two layers to a board. // If plot options become accessible to the layers setup dialog // please move this functionality there! // This skips a copper layer if it is actually disabled on the board. if( ( LSET::AllCuMask() & ~m_board->GetEnabledLayers() )[layer] ) continue; // Pick the basename from the board file wxFileName fn( boardFilename ); // Use Gerber Extensions based on layer number // (See http://en.wikipedia.org/wiki/Gerber_File) if( m_plotOpts.GetFormat() == PLOT_FORMAT_GERBER && m_useGerberExtensions->GetValue() ) file_ext = GetGerberProtelExtension( layer ); BuildPlotFileName( &fn, outputDir.GetPath(), m_board->GetLayerName( layer ), file_ext ); wxString fullname = fn.GetFullName(); jobfile_writer.AddGbrFile( layer, fullname ); LOCALE_IO toggle; BOARD* board = m_parent->GetBoard(); PLOTTER* plotter = StartPlotBoard( board, &m_plotOpts, layer, fn.GetFullPath(), wxEmptyString ); // Print diags in messages box: wxString msg; if( plotter ) { PlotOneBoardLayer( board, plotter, layer, m_plotOpts ); plotter->EndPlot(); delete plotter; msg.Printf( _( "Plot file \"%s\" created." ), GetChars( fn.GetFullPath() ) ); reporter.Report( msg, REPORTER::RPT_ACTION ); } else { msg.Printf( _( "Unable to create file \"%s\"." ), GetChars( fn.GetFullPath() ) ); reporter.Report( msg, REPORTER::RPT_ERROR ); } } if( m_plotOpts.GetFormat() == PLOT_FORMAT_GERBER && m_plotOpts.GetCreateGerberJobFile() ) { // Pick the basename from the board file wxFileName fn( boardFilename ); // Build gerber job file from basename BuildPlotFileName( &fn, outputDir.GetPath(), "job", GerberJobFileExtension ); jobfile_writer.CreateJobFile( fn.GetFullPath() ); } }