KiCad PCB EDA Suite
pcbplot.h File Reference

Board plot function definition file. More...

#include <wx/filename.h>
#include <pad_shapes.h>
#include <pcb_plot_params.h>
#include <layers_id_colors_and_visibility.h>

Go to the source code of this file.

Classes

class  BRDITEMS_PLOTTER
 

Macros

#define PLOT_MIN_SCALE   0.01
 
#define PLOT_MAX_SCALE   100.0
 
#define SMALL_DRILL   KiROUND( 0.35 * IU_PER_MM )
 
#define OPTKEY_LAYERBASE   wxT( "PlotLayer_%d" )
 
#define OPTKEY_PRINT_X_FINESCALE_ADJ   wxT( "PrintXFineScaleAdj" )
 
#define OPTKEY_PRINT_Y_FINESCALE_ADJ   wxT( "PrintYFineScaleAdj" )
 
#define OPTKEY_PRINT_SCALE   wxT( "PrintScale" )
 
#define OPTKEY_PRINT_MODULE_SCALE   wxT( "PrintModuleScale" )
 
#define OPTKEY_PRINT_PAGE_FRAME   wxT( "PrintPageFrame" )
 
#define OPTKEY_PRINT_MONOCHROME_MODE   wxT( "PrintMonochrome" )
 
#define OPTKEY_PRINT_PAGE_PER_LAYER   wxT( "PrintSinglePage" )
 
#define OPTKEY_PRINT_PADS_DRILL   wxT( "PrintPadsDrillOpt" )
 
#define OPTKEY_PLOT_X_FINESCALE_ADJ   wxT( "PlotXFineScaleAdj" )
 
#define OPTKEY_PLOT_Y_FINESCALE_ADJ   wxT( "PlotYFineScaleAdj" )
 
#define CONFIG_PS_FINEWIDTH_ADJ   wxT( "PSPlotFineWidthAdj" )
 

Functions

PLOTTERStartPlotBoard (BOARD *aBoard, PCB_PLOT_PARAMS *aPlotOpts, int aLayer, const wxString &aFullFileName, const wxString &aSheetDesc)
 Open a new plotfile using the options (and especially the format) specified in the options and prepare the page for plotting. More...
 
void PlotOneBoardLayer (BOARD *aBoard, PLOTTER *aPlotter, PCB_LAYER_ID aLayer, const PCB_PLOT_PARAMS &aPlotOpt)
 Function PlotOneBoardLayer main function to plot one copper or technical layer. More...
 
void PlotStandardLayer (BOARD *aBoard, PLOTTER *aPlotter, LSET aLayerMask, const PCB_PLOT_PARAMS &aPlotOpt)
 Function PlotStandardLayer plot copper or technical layers. More...
 
void PlotLayerOutlines (BOARD *aBoard, PLOTTER *aPlotter, LSET aLayerMask, const PCB_PLOT_PARAMS &aPlotOpt)
 Function PlotLayerOutlines plot copper outline of a copper layer. More...
 
void PlotSilkScreen (BOARD *aBoard, PLOTTER *aPlotter, LSET aLayerMask, const PCB_PLOT_PARAMS &aPlotOpt)
 Function PlotSilkScreen plot silkscreen layers which have specific requirements, mainly for pads. More...
 
void BuildPlotFileName (wxFileName *aFilename, const wxString &aOutputDir, const wxString &aSuffix, const wxString &aExtension)
 Function BuildPlotFileName (helper function) Complete a plot filename: forces the output directory, add a suffix to the name and sets the specified extension the suffix is usually the layer name replaces not allowed chars in suffix by '_'. More...
 
const wxString GetGerberProtelExtension (LAYER_NUM aLayer)
 Function GetGerberProtelExtension. More...
 
const wxString GetGerberFileFunctionAttribute (const BOARD *aBoard, LAYER_NUM aLayer)
 Function GetGerberFileFunctionAttribute Returns the "file function" attribute for aLayer, as defined in the Gerber file format specification J1 (chapter 5). More...
 
void AddGerberX2Header (PLOTTER *aPlotter, const BOARD *aBoard, bool aUseX1CompatibilityMode=false)
 Calculates some X2 attributes, as defined in the Gerber file format specification J4 (chapter 5) and add them the to the gerber file header: TF.GenerationSoftware TF.CreationDate TF.ProjectId file format attribute is not added. More...
 
void AddGerberX2Attribute (PLOTTER *aPlotter, const BOARD *aBoard, LAYER_NUM aLayer, bool aUseX1CompatibilityMode)
 Calculates some X2 attributes, as defined in the Gerber file format specification and add them to the gerber file header: TF.GenerationSoftware TF.CreationDate TF.ProjectId TF.FileFunction TF.FilePolarity. More...
 

Detailed Description

Board plot function definition file.

Definition in file pcbplot.h.

Macro Definition Documentation

#define PLOT_MAX_SCALE   100.0
#define PLOT_MIN_SCALE   0.01
#define SMALL_DRILL   KiROUND( 0.35 * IU_PER_MM )

Function Documentation

void AddGerberX2Attribute ( PLOTTER aPlotter,
const BOARD aBoard,
LAYER_NUM  aLayer,
bool  aUseX1CompatibilityMode 
)

Calculates some X2 attributes, as defined in the Gerber file format specification and add them to the gerber file header: TF.GenerationSoftware TF.CreationDate TF.ProjectId TF.FileFunction TF.FilePolarity.

Parameters
aPlotter= the current plotter.
aBoard= the board, needed to extract some info
aLayer= the layer number to create the attribute for
aUseX1CompatibilityMode= false to generate X2 attributes, true to use X1 compatibility (X2 attributes added as structured comments, starting by "G04 #@! " followed by the X2 attribute

Definition at line 466 of file pcbplot.cpp.

References AddGerberX2Header(), PLOTTER::AddLineToHeader(), GetGerberFileFunctionAttribute(), GetGerberFilePolarityAttribute(), and makeStringCompatX1().

Referenced by StartPlotBoard().

468 {
469  AddGerberX2Header( aPlotter, aBoard, aUseX1CompatibilityMode );
470 
471  wxString text;
472 
473  // Add the TF.FileFunction
474  text = GetGerberFileFunctionAttribute( aBoard, aLayer );
475  aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );
476 
477  // Add the TF.FilePolarity (for layers which support that)
478  text = GetGerberFilePolarityAttribute( aLayer );
479 
480  if( !text.IsEmpty() )
481  aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );
482 }
void AddGerberX2Header(PLOTTER *aPlotter, const BOARD *aBoard, bool aUseX1CompatibilityMode)
Calculates some X2 attributes, as defined in the Gerber file format specification J4 (chapter 5) and ...
Definition: pcbplot.cpp:369
void AddLineToHeader(const wxString &aExtraString)
Function AddLineToHeader Add a line to the list of free lines to print at the beginning of the file...
Definition: plot_common.h:166
static const wxString GetGerberFilePolarityAttribute(LAYER_NUM aLayer)
Definition: pcbplot.cpp:202
static wxString & makeStringCompatX1(wxString &aText, bool aUseX1CompatibilityMode)
Definition: pcbplot.cpp:261
const wxString GetGerberFileFunctionAttribute(const BOARD *aBoard, LAYER_NUM aLayer)
Function GetGerberFileFunctionAttribute Returns the "file function" attribute for aLayer...
Definition: pcbplot.cpp:89
void AddGerberX2Header ( PLOTTER aPlotter,
const BOARD aBoard,
bool  aUseX1CompatibilityMode = false 
)

Calculates some X2 attributes, as defined in the Gerber file format specification J4 (chapter 5) and add them the to the gerber file header: TF.GenerationSoftware TF.CreationDate TF.ProjectId file format attribute is not added.

Parameters
aPlotter= the current plotter.
aBoard= the board, needed to extract some info
aUseX1CompatibilityMode= false to generate X2 attributes, true to use X1 compatibility (X2 attributes added as structured comments, starting by "G04 #@! " followed by the X2 attribute

Definition at line 369 of file pcbplot.cpp.

References PLOTTER::AddLineToHeader(), Format(), BOARD::GetAuxOrigin(), GetBuildVersion(), GetChars(), BOARD::GetFileName(), BOARD::GetPlotOptions(), PCB_PLOT_PARAMS::GetUseAuxOrigin(), makeStringCompatX1(), wxPoint::x, and wxPoint::y.

Referenced by AddGerberX2Attribute(), and GERBER_WRITER::createDrillFile().

371 {
372  wxString text;
373 
374  // Creates the TF,.GenerationSoftware. Format is:
375  // %TF,.GenerationSoftware,<vendor>,<application name>[,<application version>]*%
376  text.Printf( wxT( "%%TF.GenerationSoftware,KiCad,Pcbnew,%s*%%" ), GetBuildVersion() );
377  aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );
378 
379  // creates the TF.CreationDate ext:
380  // The attribute value must conform to the full version of the ISO 8601
381  // date and time format, including time and time zone. Note that this is
382  // the date the Gerber file was effectively created,
383  // not the time the project of PCB was started
384  wxDateTime date( wxDateTime::GetTimeNow() );
385  // Date format: see http://www.cplusplus.com/reference/ctime/strftime
386  wxString msg = date.Format( wxT( "%z" ) ); // Extract the time zone offset
387  // The time zone offset format is + (or -) mm or hhmm (mm = number of minutes, hh = number of hours)
388  // we want +(or -) hh:mm
389  if( msg.Len() > 3 )
390  msg.insert( 3, ":", 1 ),
391  text.Printf( wxT( "%%TF.CreationDate,%s%s*%%" ), GetChars( date.FormatISOCombined() ), GetChars( msg ) );
392  aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );
393 
394  // Creates the TF,.ProjectId. Format is (from Gerber file format doc):
395  // %TF.ProjectId,<project id>,<project GUID>,<revision id>*%
396  // <project id> is the name of the project, restricted to basic ASCII symbols only,
397  // and comma not accepted
398  // All illegal chars will be replaced by underscore
399  // <project GUID> is a 32 hexadecimal digits string which is an unique id of a project.
400  // This is a random 128-bit number expressed in 32 hexadecimal digits.
401  // See en.wikipedia.org/wiki/GUID for more information
402  // However Kicad does not handle such a project GUID, so it is built from the board name
403  // Rem: <project id> accepts only ASCII 7 code (only basic ASCII codes are allowed in gerber files).
404  wxFileName fn = aBoard->GetFileName();
405  msg = fn.GetFullName();
406  wxString guid;
407 
408  // Build a 32 digits GUID from the board name:
409  for( unsigned ii = 0; ii < msg.Len(); ii++ )
410  {
411  int cc1 = int( msg[ii] ) & 0x0F;
412  int cc2 = ( int( msg[ii] ) >> 4) & 0x0F;
413  guid << wxString::Format( wxT( "%X%X" ), cc2, cc1 );
414 
415  if( guid.Len() >= 32 )
416  break;
417  }
418 
419  // guid has 32 digits, so add missing digits
420  int cnt = 32 - guid.Len();
421 
422  if( cnt > 0 )
423  guid.Append( '0', cnt );
424 
425  // build the <project id> string: this is the board short filename (without ext)
426  // and all non ASCII chars and comma are replaced by '_'
427  msg = fn.GetName();
428  msg.Replace( wxT( "," ), wxT( "_" ) );
429 
430  // build the <rec> string. All non ASCII chars and comma are replaced by '_'
431  wxString rev = ((BOARD*)aBoard)->GetTitleBlock().GetRevision();
432  rev.Replace( wxT( "," ), wxT( "_" ) );
433 
434  if( rev.IsEmpty() )
435  rev = wxT( "rev?" );
436 
437  text.Printf( wxT( "%%TF.ProjectId,%s,%s,%s*%%" ), msg.ToAscii(), GetChars( guid ), rev.ToAscii() );
438  aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );
439 
440  // Add the TF.SameCoordinates, that specify all gerber files uses the same
441  // origin and orientation, and the registration between files is OK.
442  // The parameter of TF.SameCoordinates is a string that is common
443  // to all files using the same registration and has no special meaning:
444  // this is just a key
445  // Because there is no mirroring/rotation in Kicad, only the plot offset origin
446  // can create incorrect registration.
447  // So we create a key from plot offset options.
448  // and therefore for a given board, all Gerber files having the same key have the same
449  // plot origin and use the same registration
450  //
451  // Currently the key is "Original" when using absolute Pcbnew coordinates,
452  // and te PY ans PY position od auxiliary axis, when using it.
453  // Please, if absolute Pcbnew coordinates, one day, are set by user, change the way
454  // the key is built to ensure file only using the *same* axis have the same key.
455  wxString registration_id = "Original";
456  wxPoint auxOrigin = aBoard->GetAuxOrigin();
457 
458  if( aBoard->GetPlotOptions().GetUseAuxOrigin() && auxOrigin.x && auxOrigin.y )
459  registration_id.Printf( "PX%xPY%x", auxOrigin.x, auxOrigin.y );
460 
461  text.Printf( "%%TF.SameCoordinates,%s*%%", registration_id.GetData() );
462  aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );
463 }
bool GetUseAuxOrigin() const
void AddLineToHeader(const wxString &aExtraString)
Function AddLineToHeader Add a line to the list of free lines to print at the beginning of the file...
Definition: plot_common.h:166
wxString GetBuildVersion()
Function GetBuildVersion Return the build version string.
const wxString & GetFileName() const
Definition: class_board.h:234
const PCB_PLOT_PARAMS & GetPlotOptions() const
Definition: class_board.h:550
const wxPoint & GetAuxOrigin() const
Definition: class_board.h:343
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
static wxString & makeStringCompatX1(wxString &aText, bool aUseX1CompatibilityMode)
Definition: pcbplot.cpp:261
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:169
void BuildPlotFileName ( wxFileName *  aFilename,
const wxString &  aOutputDir,
const wxString &  aSuffix,
const wxString &  aExtension 
)

Function BuildPlotFileName (helper function) Complete a plot filename: forces the output directory, add a suffix to the name and sets the specified extension the suffix is usually the layer name replaces not allowed chars in suffix by '_'.

Parameters
aFilename= the wxFileName to initialize Contains the base filename
aOutputDir= the path
aSuffix= the suffix to add to the base filename
aExtension= the file extension

Definition at line 485 of file pcbplot.cpp.

Referenced by DIALOG_SVG_PRINT::ExportSVGFile(), PLOT_CONTROLLER::OpenPlotfile(), and DIALOG_PLOT::Plot().

487 {
488  // aFilename contains the base filename only (without path and extension)
489  // when calling this function.
490  // It is expected to be a valid filename (this is usually the board filename)
491  aFilename->SetPath( aOutputDir );
492 
493  // Set the file extension
494  aFilename->SetExt( aExtension );
495 
496  // remove leading and trailing spaces if any from the suffix, if
497  // something survives add it to the name;
498  // also the suffix can contain some not allowed chars in filename (/ \ . :),
499  // so change them to underscore
500  // Remember it can be called from a python script, so the illegal chars
501  // have to be filtered here.
502  wxString suffix = aSuffix;
503  suffix.Trim( true );
504  suffix.Trim( false );
505 
506  wxString badchars = wxFileName::GetForbiddenChars(wxPATH_DOS);
507  badchars.Append( '%' );
508 
509  for( unsigned ii = 0; ii < badchars.Len(); ii++ )
510  suffix.Replace( badchars[ii], wxT("_") );
511 
512  if( !suffix.IsEmpty() )
513  aFilename->SetName( aFilename->GetName() + wxT( "-" ) + suffix );
514 }
const wxString GetGerberFileFunctionAttribute ( const BOARD aBoard,
LAYER_NUM  aLayer 
)

Function GetGerberFileFunctionAttribute Returns the "file function" attribute for aLayer, as defined in the Gerber file format specification J1 (chapter 5).

The returned string includes the "%TF.FileFunction" attribute prefix and the "*%" suffix.

Parameters
aBoard= the board, needed to get the total count of copper layers
aLayer= the layer number to create the attribute for
Returns
The attribute, as a text string

Definition at line 89 of file pcbplot.cpp.

References B_Adhes, B_Cu, B_Fab, B_Mask, B_Paste, B_SilkS, Cmts_User, Dwgs_User, Eco1_User, Eco2_User, Edge_Cuts, F_Adhes, F_Cu, F_Fab, F_Mask, F_Paste, F_SilkS, GetChars(), BOARD::GetCopperLayerCount(), BOARD::GetLayerType(), IsCopperLayer(), LT_MIXED, LT_POWER, LT_SIGNAL, and ToLAYER_ID().

Referenced by AddGerberX2Attribute().

90 {
91  wxString attrib;
92 
93  switch( aLayer )
94  {
95  case F_Adhes:
96  attrib = "Glue,Top";
97  break;
98 
99  case B_Adhes:
100  attrib = "Glue,Bot";
101  break;
102 
103  case F_SilkS:
104  attrib = "Legend,Top";
105  break;
106 
107  case B_SilkS:
108  attrib = "Legend,Bot";
109  break;
110 
111  case F_Mask:
112  attrib = "Soldermask,Top";
113  break;
114 
115  case B_Mask:
116  attrib = "Soldermask,Bot";
117  break;
118 
119  case F_Paste:
120  attrib = "Paste,Top";
121  break;
122 
123  case B_Paste:
124  attrib = "Paste,Bot";
125  break;
126 
127  case Edge_Cuts:
128  // Board outline.
129  // Can be "Profile,NP" (Not Plated: usual) or "Profile,P"
130  // This last is the exception (Plated)
131  attrib = "Profile,NP";
132  break;
133 
134  case Dwgs_User:
135  attrib = "Drawing";
136  break;
137 
138  case Cmts_User:
139  attrib = "Other,Comment";
140  break;
141 
142  case Eco1_User:
143  attrib = "Other,ECO1";
144  break;
145 
146  case Eco2_User:
147  attrib = "Other,ECO2";
148  break;
149 
150  case B_Fab:
151  attrib = "Other,Fab,Bot";
152  break;
153 
154  case F_Fab:
155  attrib = "Other,Fab,Top";
156  break;
157 
158  case B_Cu:
159  attrib.Printf( wxT( "Copper,L%d,Bot" ), aBoard->GetCopperLayerCount() );
160  break;
161 
162  case F_Cu:
163  attrib = "Copper,L1,Top";
164  break;
165 
166  default:
167  if( IsCopperLayer( aLayer ) )
168  attrib.Printf( wxT( "Copper,L%d,Inr" ), aLayer+1 );
169  else
170  attrib.Printf( wxT( "Other,User" ), aLayer+1 );
171  break;
172  }
173 
174  // Add the signal type of the layer, if relevant
175  if( IsCopperLayer( aLayer ) )
176  {
177  LAYER_T type = aBoard->GetLayerType( ToLAYER_ID( aLayer ) );
178 
179  switch( type )
180  {
181  case LT_SIGNAL:
182  attrib += ",Signal";
183  break;
184  case LT_POWER:
185  attrib += ",Plane";
186  break;
187  case LT_MIXED:
188  attrib += ",Mixed";
189  break;
190  default:
191  break; // do nothing (but avoid a warning for unhandled LAYER_T values from GCC)
192  }
193  }
194 
195  wxString fileFct;
196  fileFct.Printf( "%%TF.FileFunction,%s*%%", GetChars( attrib ) );
197 
198  return fileFct;
199 }
int GetCopperLayerCount() const
Function GetCopperLayerCount.
LAYER_T
Enum LAYER_T gives the allowed types of layers, same as Specctra DSN spec.
Definition: class_board.h:71
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
LAYER_T GetLayerType(PCB_LAYER_ID aLayer) const
Function GetLayerType returns the type of the copper layer given by aLayer.
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:774
const wxString GetGerberProtelExtension ( LAYER_NUM  aLayer)

Function GetGerberProtelExtension.

Returns
the appropriate Gerber file extension for aLayer used by Protel, and still sometimes in use (although the official Gerber Ext is now .gbr)

Definition at line 48 of file pcbplot.cpp.

References B_Adhes, B_Cu, B_Mask, B_Paste, B_SilkS, Cmts_User, Dwgs_User, Eco1_User, Eco2_User, Edge_Cuts, F_Adhes, F_Cu, F_Mask, F_Paste, F_SilkS, Format(), and IsCopperLayer().

Referenced by PLOT_CONTROLLER::OpenPlotfile(), and DIALOG_PLOT::Plot().

49 {
50  if( IsCopperLayer( aLayer ) )
51  {
52  if( aLayer == F_Cu )
53  return wxT( "gtl" );
54  else if( aLayer == B_Cu )
55  return wxT( "gbl" );
56  else
57  {
58  return wxString::Format( wxT( "g%d" ), aLayer+1 );
59  }
60  }
61  else
62  {
63  switch( aLayer )
64  {
65  case B_Adhes: return wxT( "gba" );
66  case F_Adhes: return wxT( "gta" );
67 
68  case B_Paste: return wxT( "gbp" );
69  case F_Paste: return wxT( "gtp" );
70 
71  case B_SilkS: return wxT( "gbo" );
72  case F_SilkS: return wxT( "gto" );
73 
74  case B_Mask: return wxT( "gbs" );
75  case F_Mask: return wxT( "gts" );
76 
77  case Edge_Cuts: return wxT( "gm1" );
78 
79  case Dwgs_User:
80  case Cmts_User:
81  case Eco1_User:
82  case Eco2_User:
83  default: return wxT( "gbr" );
84  }
85  }
86 }
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
void PlotLayerOutlines ( BOARD aBoard,
PLOTTER aPlotter,
LSET  aLayerMask,
const PCB_PLOT_PARAMS aPlotOpt 
)

Function PlotLayerOutlines plot copper outline of a copper layer.

Parameters
aBoard= the board to plot
aPlotter= the plotter to use
aLayerMask= the mask to define the layers to plot
aPlotOpt= the plot options. Has meaning for some formats only

Definition at line 639 of file plot_board_layers.cpp.

References SHAPE_POLY_SET::CHole(), PLOTTER::Circle(), BOARD::ConvertBrdLayerToPolygonalContours(), SHAPE_POLY_SET::COutline(), SHAPE_LINE_CHAIN::CPoint(), DIM, dyn_cast(), PCB_PLOT_PARAMS::GetDrillMarksType(), VIA::GetDrillValue(), VIA::GetPosition(), SHAPE_POLY_SET::HoleCount(), VIA::IsOnLayer(), BOARD::m_Modules, BOARD::m_Track, TRACK::Next(), MODULE::Next(), D_PAD::Next(), PCB_PLOT_PARAMS::NO_DRILL_SHAPE, NO_FILL, SHAPE_POLY_SET::OutlineCount(), plot_seq, PLOTTER::PlotPoly(), SHAPE_POLY_SET::PM_FAST, SHAPE_LINE_CHAIN::PointCount(), SHAPE_POLY_SET::RemoveAllContours(), LSET::Seq(), BRDITEMS_PLOTTER::SetLayerSet(), SHAPE_POLY_SET::Simplify(), SKETCH, PLOTTER::ThickSegment(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by PlotOneBoardLayer().

641 {
642 
643  BRDITEMS_PLOTTER itemplotter( aPlotter, aBoard, aPlotOpt );
644  itemplotter.SetLayerSet( aLayerMask );
645 
646  SHAPE_POLY_SET outlines;
647 
648  for( LSEQ seq = aLayerMask.Seq( plot_seq, DIM( plot_seq ) ); seq; ++seq )
649  {
650  PCB_LAYER_ID layer = *seq;
651 
652  outlines.RemoveAllContours();
653  aBoard->ConvertBrdLayerToPolygonalContours( layer, outlines );
654 
655  outlines.Simplify( SHAPE_POLY_SET::PM_FAST );
656 
657  // Plot outlines
658  std::vector< wxPoint > cornerList;
659 
660  // Now we have one or more basic polygons: plot each polygon
661  for( int ii = 0; ii < outlines.OutlineCount(); ii++ )
662  {
663  for(int kk = 0; kk <= outlines.HoleCount (ii); kk++ )
664  {
665  cornerList.clear();
666  const SHAPE_LINE_CHAIN& path = (kk == 0) ? outlines.COutline( ii ) : outlines.CHole( ii, kk - 1 );
667 
668  for( int jj = 0; jj < path.PointCount(); jj++ )
669  cornerList.push_back( wxPoint( path.CPoint( jj ).x , path.CPoint( jj ).y ) );
670 
671 
672  // Ensure the polygon is closed
673  if( cornerList[0] != cornerList[cornerList.size() - 1] )
674  cornerList.push_back( cornerList[0] );
675 
676  aPlotter->PlotPoly( cornerList, NO_FILL );
677  }
678  }
679 
680  // Plot pad holes
682  {
683  for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
684  {
685  for( D_PAD* pad = module->PadsList(); pad; pad = pad->Next() )
686  {
687  wxSize hole = pad->GetDrillSize();
688 
689  if( hole.x == 0 || hole.y == 0 )
690  continue;
691 
692  if( hole.x == hole.y )
693  aPlotter->Circle( pad->GetPosition(), hole.x, NO_FILL );
694  else
695  {
696  wxPoint drl_start, drl_end;
697  int width;
698  pad->GetOblongDrillGeometry( drl_start, drl_end, width );
699  aPlotter->ThickSegment( pad->GetPosition() + drl_start,
700  pad->GetPosition() + drl_end, width, SKETCH, NULL );
701  }
702  }
703  }
704  }
705 
706  // Plot vias holes
707  for( TRACK* track = aBoard->m_Track; track; track = track->Next() )
708  {
709  const VIA* via = dyn_cast<const VIA*>( track );
710 
711  if( via && via->IsOnLayer( layer ) ) // via holes can be not through holes
712  {
713  aPlotter->Circle( via->GetPosition(), via->GetDrillValue(), NO_FILL );
714  }
715  }
716  }
717 }
#define DIM(x)
of elements in an array
Definition: macros.h:98
int PointCount() const
Function PointCount()
static const PCB_LAYER_ID plot_seq[]
MODULE * Next() const
Definition: class_module.h:100
int HoleCount(int aOutline) const
Returns the number of holes in a given outline
const SHAPE_LINE_CHAIN & CHole(int aOutline, int aHole) const
int OutlineCount() const
Returns the number of outlines in the set
virtual void PlotPoly(const std::vector< wxPoint > &aCornerList, FILL_T aFill, int aWidth=USE_DEFAULT_LINE_WIDTH, void *aData=NULL)=0
Function PlotPoly.
Casted dyn_cast(From aObject)
Function dyn_cast()
Definition: typeinfo.h:73
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Function Seq returns an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:337
DrillMarksType GetDrillMarksType() const
PCB_LAYER_ID
A quick note on layer IDs:
Class SHAPE_POLY_SET.
D_PAD * Next() const
Definition: class_pad.h:160
void ConvertBrdLayerToPolygonalContours(PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aOutlines)
Function ConvertBrdLayerToPolygonalContours Build a set of polygons which are the outlines of copper ...
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
void Simplify(POLYGON_MODE aFastMode)
Simplifies the polyset (merges overlapping polys, eliminates degeneracy/self-intersections) For aFast...
Class LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
TRACK * Next() const
Definition: class_track.h:98
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
DLIST< MODULE > m_Modules
Definition: class_board.h:245
Class SHAPE_LINE_CHAIN.
virtual void ThickSegment(const wxPoint &start, const wxPoint &end, int width, EDA_DRAW_MODE_T tracemode, void *aData)
void RemoveAllContours()
Removes all outlines & holes (clears) the polygon set.
const wxPoint & GetPosition() const override
Definition: class_track.h:411
DLIST< TRACK > m_Track
Definition: class_board.h:246
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Function IsOnLayer tests to see if this object is on the given layer.
const VECTOR2I & CPoint(int aIndex) const
Function CPoint()
virtual void Circle(const wxPoint &pos, int diametre, FILL_T fill, int width=USE_DEFAULT_LINE_WIDTH)=0
void PlotOneBoardLayer ( BOARD aBoard,
PLOTTER aPlotter,
PCB_LAYER_ID  aLayer,
const PCB_PLOT_PARAMS aPlotOpt 
)

Function PlotOneBoardLayer main function to plot one copper or technical layer.

It prepare options and calls the specialized plot function, according to the layer type

Parameters
aBoard= the board to plot
aPlotter= the plotter to use
aLayer= the layer id to plot
aPlotOpt= the plot options (files, sketch). Has meaning for some formats only

Definition at line 153 of file plot_board_layers.cpp.

References B_Adhes, B_CrtYd, B_Fab, B_Mask, B_Paste, B_SilkS, Cmts_User, Dwgs_User, Eco1_User, Eco2_User, Edge_Cuts, F_Adhes, F_CrtYd, F_Fab, F_Mask, F_Paste, F_SilkS, PCB_PLOT_PARAMS::GetColor(), BOARD::GetDesignSettings(), PCB_PLOT_PARAMS::GetDXFPlotPolygonMode(), PCB_PLOT_PARAMS::GetExcludeEdgeLayer(), PCB_PLOT_PARAMS::GetFormat(), PLOTTER::GetPlotterType(), PCB_PLOT_PARAMS::GetSubtractMaskFromSilk(), PCB_PLOT_PARAMS::GetTextMode(), IsCopperLayer(), BOARD_DESIGN_SETTINGS::m_SolderMaskMinWidth, Margin, PCB_PLOT_PARAMS::NO_DRILL_SHAPE, PLOT_FORMAT_DXF, PLOT_FORMAT_GERBER, PlotLayerOutlines(), PlotSilkScreen(), PlotSolderMaskLayer(), PlotStandardLayer(), PLOTTER::SetColor(), PCB_PLOT_PARAMS::SetDrillMarksType(), PLOTTER::SetLayerPolarity(), PCB_PLOT_PARAMS::SetSkipPlotNPTH_Pads(), and PLOTTER::SetTextMode().

Referenced by DIALOG_SVG_PRINT::CreateSVGFile(), DIALOG_PLOT::Plot(), and PLOT_CONTROLLER::PlotLayer().

155 {
156  PCB_PLOT_PARAMS plotOpt = aPlotOpt;
157  int soldermask_min_thickness = aBoard->GetDesignSettings().m_SolderMaskMinWidth;
158 
159  // Set a default color and the text mode for this layer
160  aPlotter->SetColor( aPlotOpt.GetColor() );
161  aPlotter->SetTextMode( aPlotOpt.GetTextMode() );
162 
163  // Specify that the contents of the "Edges Pcb" layer are to be plotted
164  // in addition to the contents of the currently specified layer.
165  LSET layer_mask( aLayer );
166 
167  if( !aPlotOpt.GetExcludeEdgeLayer() )
168  layer_mask.set( Edge_Cuts );
169 
170  if( IsCopperLayer( aLayer ) )
171  {
172  // Skip NPTH pads on copper layers ( only if hole size == pad size ):
173  // Drill mark will be plotted,
174  // if drill mark is SMALL_DRILL_SHAPE or FULL_DRILL_SHAPE
175  if( plotOpt.GetFormat() == PLOT_FORMAT_DXF )
176  {
177  plotOpt.SetSkipPlotNPTH_Pads( false );
178  PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
179  }
180  else
181  {
182  plotOpt.SetSkipPlotNPTH_Pads( true );
183  PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
184  }
185  }
186  else
187  {
188  switch( aLayer )
189  {
190  case B_Mask:
191  case F_Mask:
192  plotOpt.SetSkipPlotNPTH_Pads( false );
193  // Disable plot pad holes
195 
196  // Plot solder mask:
197  if( soldermask_min_thickness == 0 )
198  {
199  if( plotOpt.GetFormat() == PLOT_FORMAT_DXF )
200  PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
201  else
202  PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
203  }
204  else
205  PlotSolderMaskLayer( aBoard, aPlotter, layer_mask, plotOpt,
206  soldermask_min_thickness );
207 
208  break;
209 
210  case B_Adhes:
211  case F_Adhes:
212  case B_Paste:
213  case F_Paste:
214  plotOpt.SetSkipPlotNPTH_Pads( false );
215  // Disable plot pad holes
217 
218  if( plotOpt.GetFormat() == PLOT_FORMAT_DXF )
219  PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
220  else
221  PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
222  break;
223 
224  case F_SilkS:
225  case B_SilkS:
226  if( plotOpt.GetFormat() == PLOT_FORMAT_DXF && plotOpt.GetDXFPlotPolygonMode() )
227  // PlotLayerOutlines() is designed only for DXF plotters.
228  // and must not be used for other plot formats
229  PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
230  else
231  PlotSilkScreen( aBoard, aPlotter, layer_mask, plotOpt );
232 
233  // Gerber: Subtract soldermask from silkscreen if enabled
234  if( aPlotter->GetPlotterType() == PLOT_FORMAT_GERBER
235  && plotOpt.GetSubtractMaskFromSilk() )
236  {
237  if( aLayer == F_SilkS )
238  layer_mask = LSET( F_Mask );
239  else
240  layer_mask = LSET( B_Mask );
241 
242  // Create the mask to subtract by creating a negative layer polarity
243  aPlotter->SetLayerPolarity( false );
244 
245  // Disable plot pad holes
247 
248  // Plot the mask
249  PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
250  }
251  break;
252 
253  // These layers are plotted like silk screen layers.
254  // Mainly, pads on these layers are not filled.
255  // This is not necessary the best choice.
256  case Dwgs_User:
257  case Cmts_User:
258  case Eco1_User:
259  case Eco2_User:
260  case Edge_Cuts:
261  case Margin:
262  case F_CrtYd:
263  case B_CrtYd:
264  case F_Fab:
265  case B_Fab:
266  plotOpt.SetSkipPlotNPTH_Pads( false );
268 
269  if( plotOpt.GetFormat() == PLOT_FORMAT_DXF && plotOpt.GetDXFPlotPolygonMode() )
270  // PlotLayerOutlines() is designed only for DXF plotters.
271  // and must not be used for other plot formats
272  PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
273  else
274  PlotSilkScreen( aBoard, aPlotter, layer_mask, plotOpt );
275  break;
276 
277  default:
278  plotOpt.SetSkipPlotNPTH_Pads( false );
280 
281  if( plotOpt.GetFormat() == PLOT_FORMAT_DXF && plotOpt.GetDXFPlotPolygonMode() )
282  // PlotLayerOutlines() is designed only for DXF plotters.
283  // and must not be used for other plot formats
284  PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
285  else
286  PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
287  break;
288  }
289  }
290 }
bool GetSubtractMaskFromSilk() const
virtual void SetColor(COLOR4D color)=0
virtual void SetLayerPolarity(bool aPositive)
Function SetLayerPolarity sets current Gerber layer polarity to positive or negative by writing %LPD*...
Definition: plot_common.h:398
void PlotStandardLayer(BOARD *aBoard, PLOTTER *aPlotter, LSET aLayerMask, const PCB_PLOT_PARAMS &aPlotOpt)
Function PlotStandardLayer plot copper or technical layers.
void PlotSilkScreen(BOARD *aBoard, PLOTTER *aPlotter, LSET aLayerMask, const PCB_PLOT_PARAMS &aPlotOpt)
Function PlotSilkScreen plot silkscreen layers which have specific requirements, mainly for pads...
void SetDrillMarksType(DrillMarksType aVal)
bool GetExcludeEdgeLayer() const
static void PlotSolderMaskLayer(BOARD *aBoard, PLOTTER *aPlotter, LSET aLayerMask, const PCB_PLOT_PARAMS &aPlotOpt, int aMinThickness)
void PlotLayerOutlines(BOARD *aBoard, PLOTTER *aPlotter, LSET aLayerMask, const PCB_PLOT_PARAMS &aPlotOpt)
Function PlotLayerOutlines plot copper outline of a copper layer.
Class LSET is a set of PCB_LAYER_IDs.
PlotTextMode GetTextMode() const
virtual void SetTextMode(PlotTextMode mode)
Change the current text mode.
Definition: plot_common.h:407
void SetSkipPlotNPTH_Pads(bool aSkip)
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:532
PlotFormat GetFormat() const
Class PCB_PLOT_PARAMS handles plot parameters and options when plotting/printing a board...
COLOR4D GetColor() const
bool GetDXFPlotPolygonMode() const
virtual PlotFormat GetPlotterType() const =0
Returns the effective plot engine in use.
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
int m_SolderMaskMinWidth
Solder mask min width.
void PlotSilkScreen ( BOARD aBoard,
PLOTTER aPlotter,
LSET  aLayerMask,
const PCB_PLOT_PARAMS aPlotOpt 
)

Function PlotSilkScreen plot silkscreen layers which have specific requirements, mainly for pads.

Should not be used for other layers

Parameters
aBoard= the board to plot
aPlotter= the plotter to use
aLayerMask= the mask to define the layers to plot (silkscreen Front and/or Back)
aPlotOpt= the plot options (files, sketch). Has meaning for some formats only

Definition at line 68 of file plot_board_layers.cpp.

References B_SilkS, BLACK, color, BOARD::Colors(), PLOTTER::EndBlock(), F_SilkS, BOARD::GetArea(), BOARD::GetAreaCount(), GetChars(), ZONE_CONTAINER::GetLayer(), COLORS_DESIGN_SETTINGS::GetLayerColor(), PCB_PLOT_PARAMS::GetPlotMode(), PCB_PLOT_PARAMS::GetPlotPadsOnSilkLayer(), BOARD::m_Modules, BOARD::m_Zone, MODULE::Next(), D_PAD::Next(), SEGZONE::Next(), BRDITEMS_PLOTTER::Plot_Edges_Modules(), BRDITEMS_PLOTTER::PlotAllTextsModule(), BRDITEMS_PLOTTER::PlotBoardGraphicItems(), BRDITEMS_PLOTTER::PlotFilledAreas(), BRDITEMS_PLOTTER::PlotPad(), BRDITEMS_PLOTTER::SetLayerSet(), SKETCH, PLOTTER::StartBlock(), and PLOTTER::ThickSegment().

Referenced by PlotOneBoardLayer().

70 {
71  BRDITEMS_PLOTTER itemplotter( aPlotter, aBoard, aPlotOpt );
72  itemplotter.SetLayerSet( aLayerMask );
73 
74  // Plot edge layer and graphic items
75  itemplotter.PlotBoardGraphicItems();
76 
77  // Plot footprint outlines :
78  itemplotter.Plot_Edges_Modules();
79 
80  // Plot pads (creates pads outlines, for pads on silkscreen layers)
81  LSET layersmask_plotpads = aLayerMask;
82 
83  // Calculate the mask layers of allowed layers for pads
84 
85  if( !aPlotOpt.GetPlotPadsOnSilkLayer() ) // Do not plot pads on silk screen layers
86  layersmask_plotpads.set( B_SilkS, false ).set( F_SilkS, false );
87 
88  if( layersmask_plotpads.any() )
89  {
90  for( MODULE* Module = aBoard->m_Modules; Module; Module = Module->Next() )
91  {
92  aPlotter->StartBlock( NULL );
93 
94  for( D_PAD* pad = Module->PadsList(); pad; pad = pad->Next() )
95  {
96  // See if the pad is on this layer
97  LSET masklayer = pad->GetLayerSet();
98  if( !( masklayer & layersmask_plotpads ).any() )
99  continue;
100 
102 
103  if( layersmask_plotpads[B_SilkS] )
104  color = aBoard->Colors().GetLayerColor( B_SilkS );
105 
106  if( layersmask_plotpads[F_SilkS] )
107  color = ( color == COLOR4D::BLACK) ? aBoard->Colors().GetLayerColor( F_SilkS ) : color;
108 
109  itemplotter.PlotPad( pad, color, SKETCH );
110  }
111 
112  aPlotter->EndBlock( NULL );
113  }
114  }
115 
116  // Plot footprints fields (ref, value ...)
117  for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
118  {
119  if( ! itemplotter.PlotAllTextsModule( module ) )
120  {
121  wxLogMessage( _( "Your BOARD has a bad layer number for footprint %s" ),
122  GetChars( module->GetReference() ) );
123  }
124  }
125 
126  // Plot filled areas
127  aPlotter->StartBlock( NULL );
128 
129  for( int ii = 0; ii < aBoard->GetAreaCount(); ii++ )
130  {
131  ZONE_CONTAINER* edge_zone = aBoard->GetArea( ii );
132 
133  if( !aLayerMask[ edge_zone->GetLayer() ] )
134  continue;
135 
136  itemplotter.PlotFilledAreas( edge_zone );
137  }
138 
139  aPlotter->EndBlock( NULL );
140 
141  // Plot segments used to fill zone areas (outdated, but here for old boards
142  // compatibility):
143  for( SEGZONE* seg = aBoard->m_Zone; seg; seg = seg->Next() )
144  {
145  if( !aLayerMask[ seg->GetLayer() ] )
146  continue;
147 
148  aPlotter->ThickSegment( seg->GetStart(), seg->GetEnd(), seg->GetWidth(),
149  itemplotter.GetPlotMode(), NULL );
150  }
151 }
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:78
virtual void EndBlock(void *aData)
calling this function allows to define the end of a group of drawing items for instance in SVG or Ger...
Definition: plot_common.h:433
MODULE * Next() const
Definition: class_module.h:100
virtual PCB_LAYER_ID GetLayer() const override
Function GetLayer returns the primary layer this item is on.
Definition: class_zone.cpp:182
virtual void StartBlock(void *aData)
calling this function allows to define the beginning of a group of drawing items, for instance in SVG...
Definition: plot_common.h:424
DLIST< SEGZONE > m_Zone
Definition: class_board.h:247
SEGZONE * Next() const
Definition: class_track.h:358
Class LSET is a set of PCB_LAYER_IDs.
const COLORS_DESIGN_SETTINGS & Colors() const
Function GetColorSettings.
Definition: class_board.h:563
D_PAD * Next() const
Definition: class_pad.h:160
int GetAreaCount() const
Function GetAreaCount.
Definition: class_board.h:1011
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
ZONE_CONTAINER * GetArea(int index) const
Function GetArea returns the Area (Zone Container) at a given index.
Definition: class_board.h:982
DLIST< MODULE > m_Modules
Definition: class_board.h:245
virtual void ThickSegment(const wxPoint &start, const wxPoint &end, int width, EDA_DRAW_MODE_T tracemode, void *aData)
bool GetPlotPadsOnSilkLayer() const
COLOR4D GetLayerColor(LAYER_NUM aLayer) const
Function GetLayerColor.
Definition: colors.h:45
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
void PlotStandardLayer ( BOARD aBoard,
PLOTTER aPlotter,
LSET  aLayerMask,
const PCB_PLOT_PARAMS aPlotOpt 
)

Function PlotStandardLayer plot copper or technical layers.

not used for silk screen layers, because these layers have specific requirements, mainly for pads

Parameters
aBoard= the board to plot
aPlotter= the plotter to use
aLayerMask= the mask to define the layers to plot
aPlotOpt= the plot options (files, sketch). Has meaning for some formats only

aPlotOpt has 3 important options to control this plot, which are set, depending on the layer type to plot SetEnablePlotVia( bool aEnable ) aEnable = true to plot vias, false to skip vias (has meaning only for solder mask layers). SetSkipPlotNPTH_Pads( bool aSkip ) aSkip = true to skip NPTH Pads, when the pad size and the pad hole have the same size. Used in GERBER format only. SetDrillMarksType( DrillMarksType aVal ) controle the actual hole: no hole, small hole, actual hole

Definition at line 296 of file plot_board_layers.cpp.

References LSET::AllCuMask(), B_Cu, B_Mask, B_Paste, BLACK, color, BOARD::Colors(), delta, dyn_cast(), PLOTTER::EndBlock(), F_Cu, F_Mask, F_Paste, PLOTTER::FlashPadCircle(), GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CONDUCTOR, GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_VIAPAD, GBR_NETLIST_METADATA::GBR_NETINFO_NET, BOARD::GetArea(), BOARD::GetAreaCount(), GetChars(), BRDITEMS_PLOTTER::getColor(), BOARD::GetDesignSettings(), PCB_PLOT_PARAMS::GetDrillMarksType(), BRDITEMS_PLOTTER::getFineWidthAdj(), COLORS_DESIGN_SETTINGS::GetItemColor(), ZONE_CONTAINER::GetLayer(), VIA::GetLayerSet(), BOARD_CONNECTED_ITEM::GetNetname(), PCB_PLOT_PARAMS::GetPlotMode(), PCB_PLOT_PARAMS::GetPlotViaOnMaskLayer(), PCB_PLOT_PARAMS::GetSkipPlotNPTH_Pads(), TRACK::GetStart(), VIA::GetViaType(), TRACK::GetWidth(), LAYER_PAD_BK, LAYER_PAD_FR, LAYER_VIAS, LIGHTGRAY, BOARD::m_Modules, GBR_METADATA::m_NetlistMetadata, GBR_NETLIST_METADATA::m_NotInNet, BOARD_DESIGN_SETTINGS::m_SolderMaskMargin, BOARD::m_Track, BOARD::m_Zone, TRACK::Next(), MODULE::Next(), BOARD_ITEM::Next(), D_PAD::Next(), SEGZONE::Next(), PCB_PLOT_PARAMS::NO_DRILL_SHAPE, PAD_ATTRIB_HOLE_NOT_PLATED, PAD_SHAPE_CIRCLE, PAD_SHAPE_OVAL, PAD_SHAPE_RECT, PAD_SHAPE_ROUNDRECT, PAD_SHAPE_TRAPEZOID, PCB_MODULE_EDGE_T, PCB_VIA_T, BRDITEMS_PLOTTER::Plot_1_EdgeModule(), BRDITEMS_PLOTTER::PlotAllTextsModule(), BRDITEMS_PLOTTER::PlotBoardGraphicItems(), BRDITEMS_PLOTTER::PlotDrillMarks(), BRDITEMS_PLOTTER::PlotFilledAreas(), BRDITEMS_PLOTTER::PlotPad(), GBR_METADATA::SetApertureAttrib(), PLOTTER::SetColor(), BRDITEMS_PLOTTER::SetLayerSet(), GBR_METADATA::SetNetAttribType(), GBR_METADATA::SetNetName(), PLOTTER::StartBlock(), PLOTTER::ThickSegment(), WHITE, wxPoint::x, and wxPoint::y.

Referenced by DIALOG_SVG_PRINT::CreateSVGFile(), and PlotOneBoardLayer().

298 {
299  BRDITEMS_PLOTTER itemplotter( aPlotter, aBoard, aPlotOpt );
300 
301  itemplotter.SetLayerSet( aLayerMask );
302 
303  EDA_DRAW_MODE_T plotMode = aPlotOpt.GetPlotMode();
304 
305  // Plot edge layer and graphic items
306  itemplotter.PlotBoardGraphicItems();
307 
308  // Draw footprint shapes without pads (pads will plotted later)
309  // We plot here module texts, but they are usually on silkscreen layer,
310  // so they are not plot here but plot by PlotSilkScreen()
311  // Plot footprints fields (ref, value ...)
312  for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
313  {
314  if( ! itemplotter.PlotAllTextsModule( module ) )
315  {
316  wxLogMessage( _( "Your BOARD has a bad layer number for footprint %s" ),
317  GetChars( module->GetReference() ) );
318  }
319  }
320 
321  for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
322  {
323  for( BOARD_ITEM* item = module->GraphicalItemsList(); item; item = item->Next() )
324  {
325  if( !aLayerMask[ item->GetLayer() ] )
326  continue;
327 
328  switch( item->Type() )
329  {
330  case PCB_MODULE_EDGE_T:
331  itemplotter.Plot_1_EdgeModule( (EDGE_MODULE*) item );
332  break;
333 
334  default:
335  break;
336  }
337  }
338  }
339 
340  // Plot footprint pads
341  for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
342  {
343  aPlotter->StartBlock( NULL );
344 
345  for( D_PAD* pad = module->PadsList(); pad; pad = pad->Next() )
346  {
347  if( (pad->GetLayerSet() & aLayerMask) == 0 )
348  continue;
349 
350  wxSize margin;
351  double width_adj = 0;
352 
353  if( ( aLayerMask & LSET::AllCuMask() ).any() )
354  width_adj = itemplotter.getFineWidthAdj();
355 
356  static const LSET speed( 4, B_Mask, F_Mask, B_Paste, F_Paste );
357 
358  LSET anded = ( speed & aLayerMask );
359 
360  if( anded == LSET( F_Mask ) || anded == LSET( B_Mask ) )
361  {
362  margin.x = margin.y = pad->GetSolderMaskMargin();
363  }
364  else if( anded == LSET( F_Paste ) || anded == LSET( B_Paste ) )
365  {
366  margin = pad->GetSolderPasteMargin();
367  }
368 
369  // Now offset the pad size by margin + width_adj
370  // this is easy for most shapes, but not for a trapezoid
371  wxSize padPlotsSize;
372  wxSize extraSize = margin * 2;
373  extraSize.x += width_adj;
374  extraSize.y += width_adj;
375  wxSize deltaSize = pad->GetDelta(); // has meaning only for trapezoidal pads
376 
377  if( pad->GetShape() == PAD_SHAPE_TRAPEZOID )
378  { // The easy way is to use BuildPadPolygon to calculate
379  // size and delta of the trapezoidal pad after offseting:
380  wxPoint coord[4];
381  pad->BuildPadPolygon( coord, extraSize/2, 0.0 );
382  // Calculate the size and delta from polygon corners coordinates:
383  // coord[0] is the lower left
384  // coord[1] is the upper left
385  // coord[2] is the upper right
386  // coord[3] is the lower right
387 
388  // the size is the distance between middle of segments
389  // (left/right or top/bottom)
390  // size X is the dist between left and right middle points:
391  padPlotsSize.x = ( ( -coord[0].x + coord[3].x ) // the lower segment X length
392  + ( -coord[1].x + coord[2].x ) ) // the upper segment X length
393  / 2; // the Y size is the half sum
394  // size Y is the dist between top and bottom middle points:
395  padPlotsSize.y = ( ( coord[0].y - coord[1].y ) // the left segment Y lenght
396  + ( coord[3].y - coord[2].y ) ) // the right segment Y lenght
397  / 2; // the Y size is the half sum
398 
399  // calculate the delta ( difference of lenght between 2 opposite edges )
400  // The delta.x is the delta along the X axis, therefore the delta of Y lenghts
401  wxSize delta;
402 
403  if( coord[0].y != coord[3].y )
404  delta.x = coord[0].y - coord[3].y;
405  else
406  delta.y = coord[1].x - coord[0].x;
407 
408  pad->SetDelta( delta );
409  }
410  else
411  padPlotsSize = pad->GetSize() + extraSize;
412 
413  // Don't draw a null size item :
414  if( padPlotsSize.x <= 0 || padPlotsSize.y <= 0 )
415  continue;
416 
418 
419  if( pad->GetLayerSet()[B_Cu] )
420  color = aBoard->Colors().GetItemColor( LAYER_PAD_BK );
421 
422  if( pad->GetLayerSet()[F_Cu] )
423  color = color.LegacyMix( aBoard->Colors().GetItemColor( LAYER_PAD_FR ) );
424 
425  // Temporary set the pad size to the required plot size:
426  wxSize tmppadsize = pad->GetSize();
427  pad->SetSize( padPlotsSize );
428 
429  switch( pad->GetShape() )
430  {
431  case PAD_SHAPE_CIRCLE:
432  case PAD_SHAPE_OVAL:
433  if( aPlotOpt.GetSkipPlotNPTH_Pads() &&
434  (pad->GetSize() == pad->GetDrillSize()) &&
435  (pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED) )
436  break;
437 
438  // Fall through:
439  case PAD_SHAPE_TRAPEZOID:
440  case PAD_SHAPE_RECT:
441  case PAD_SHAPE_ROUNDRECT:
442  default:
443  itemplotter.PlotPad( pad, color, plotMode );
444  break;
445  }
446 
447  pad->SetSize( tmppadsize ); // Restore the pad size
448  pad->SetDelta( deltaSize );
449  }
450 
451  aPlotter->EndBlock( NULL );
452  }
453 
454  // Plot vias on copper layers, and if aPlotOpt.GetPlotViaOnMaskLayer() is true,
455  // plot them on solder mask
456 
457  GBR_METADATA gbr_metadata;
458 
459  bool isOnCopperLayer = ( aLayerMask & LSET::AllCuMask() ).any();
460 
461  if( isOnCopperLayer )
462  {
465  }
466 
467  aPlotter->StartBlock( NULL );
468 
469  for( TRACK* track = aBoard->m_Track; track; track = track->Next() )
470  {
471  const VIA* Via = dyn_cast<const VIA*>( track );
472 
473  if( !Via )
474  continue;
475 
476  // vias are not plotted if not on selected layer, but if layer
477  // is SOLDERMASK_LAYER_BACK or SOLDERMASK_LAYER_FRONT,vias are drawn,
478  // only if they are on the corresponding external copper layer
479  LSET via_mask_layer = Via->GetLayerSet();
480 
481  if( aPlotOpt.GetPlotViaOnMaskLayer() )
482  {
483  if( via_mask_layer[B_Cu] )
484  via_mask_layer.set( B_Mask );
485 
486  if( via_mask_layer[F_Cu] )
487  via_mask_layer.set( F_Mask );
488  }
489 
490  if( !( via_mask_layer & aLayerMask ).any() )
491  continue;
492 
493  int via_margin = 0;
494  double width_adj = 0;
495 
496  // If the current layer is a solder mask, use the global mask
497  // clearance for vias
498  if( aLayerMask[B_Mask] || aLayerMask[F_Mask] )
499  via_margin = aBoard->GetDesignSettings().m_SolderMaskMargin;
500 
501  if( ( aLayerMask & LSET::AllCuMask() ).any() )
502  width_adj = itemplotter.getFineWidthAdj();
503 
504  int diameter = Via->GetWidth() + 2 * via_margin + width_adj;
505 
506  // Don't draw a null size item :
507  if( diameter <= 0 )
508  continue;
509 
510  // Some vias can be not connected (no net).
511  // Set the m_NotInNet for these vias to force a empty net name in gerber file
512  gbr_metadata.m_NetlistMetadata.m_NotInNet = Via->GetNetname().IsEmpty();
513 
514  gbr_metadata.SetNetName( Via->GetNetname() );
515 
516  COLOR4D color = aBoard->Colors().GetItemColor( LAYER_VIAS + Via->GetViaType() );
517  // Set plot color (change WHITE to LIGHTGRAY because
518  // the white items are not seen on a white paper or screen
519  aPlotter->SetColor( color != WHITE ? color : LIGHTGRAY);
520  aPlotter->FlashPadCircle( Via->GetStart(), diameter, plotMode, &gbr_metadata );
521  }
522 
523  aPlotter->EndBlock( NULL );
524  aPlotter->StartBlock( NULL );
526 
527  // Plot tracks (not vias) :
528  for( TRACK* track = aBoard->m_Track; track; track = track->Next() )
529  {
530  if( track->Type() == PCB_VIA_T )
531  continue;
532 
533  if( !aLayerMask[track->GetLayer()] )
534  continue;
535 
536  // Some track segments can be not connected (no net).
537  // Set the m_NotInNet for these segments to force a empty net name in gerber file
538  gbr_metadata.m_NetlistMetadata.m_NotInNet = track->GetNetname().IsEmpty();
539 
540  gbr_metadata.SetNetName( track->GetNetname() );
541  int width = track->GetWidth() + itemplotter.getFineWidthAdj();
542  aPlotter->SetColor( itemplotter.getColor( track->GetLayer() ) );
543  aPlotter->ThickSegment( track->GetStart(), track->GetEnd(), width, plotMode, &gbr_metadata );
544  }
545 
546  aPlotter->EndBlock( NULL );
547 
548  // Plot zones (outdated, for old boards compatibility):
549  for( TRACK* track = aBoard->m_Zone; track; track = track->Next() )
550  {
551  if( !aLayerMask[track->GetLayer()] )
552  continue;
553 
554  int width = track->GetWidth() + itemplotter.getFineWidthAdj();
555  aPlotter->SetColor( itemplotter.getColor( track->GetLayer() ) );
556  aPlotter->ThickSegment( track->GetStart(), track->GetEnd(), width, plotMode, NULL );
557  }
558 
559  // Plot filled ares
560  aPlotter->StartBlock( NULL );
561  for( int ii = 0; ii < aBoard->GetAreaCount(); ii++ )
562  {
563  ZONE_CONTAINER* zone = aBoard->GetArea( ii );
564 
565  if( !aLayerMask[zone->GetLayer()] )
566  continue;
567 
568  itemplotter.PlotFilledAreas( zone );
569  }
570  aPlotter->EndBlock( NULL );
571 
572  // Adding drill marks, if required and if the plotter is able to plot them:
574  itemplotter.PlotDrillMarks();
575 }
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:646
int m_SolderMaskMargin
Solder mask margin.
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:78
virtual void EndBlock(void *aData)
calling this function allows to define the end of a group of drawing items for instance in SVG or Ger...
Definition: plot_common.h:433
virtual LSET GetLayerSet() const override
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:65
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class...
virtual void SetColor(COLOR4D color)=0
void SetNetAttribType(int aNetAttribType)
MODULE * Next() const
Definition: class_module.h:100
virtual PCB_LAYER_ID GetLayer() const override
Function GetLayer returns the primary layer this item is on.
Definition: class_zone.cpp:182
virtual void StartBlock(void *aData)
calling this function allows to define the beginning of a group of drawing items, for instance in SVG...
Definition: plot_common.h:424
DLIST< SEGZONE > m_Zone
Definition: class_board.h:247
smd pads, back layer
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:106
static const int delta[8][2]
Definition: solve.cpp:112
Casted dyn_cast(From aObject)
Function dyn_cast()
Definition: typeinfo.h:73
SEGZONE * Next() const
Definition: class_track.h:358
BOARD_ITEM * Next() const
COLOR4D GetItemColor(int aItemIdx) const
Function GetItemColor.
virtual void FlashPadCircle(const wxPoint &aPadPos, int aDiameter, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadCircle
DrillMarksType GetDrillMarksType() const
Class LSET is a set of PCB_LAYER_IDs.
VIATYPE_T GetViaType() const
Definition: class_track.h:439
EDA_DRAW_MODE_T
Definition: eda_text.h:62
const COLORS_DESIGN_SETTINGS & Colors() const
Function GetColorSettings.
Definition: class_board.h:563
const wxPoint & GetStart() const
Definition: class_track.h:121
D_PAD * Next() const
Definition: class_pad.h:160
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:532
bool GetPlotViaOnMaskLayer() const
int GetAreaCount() const
Function GetAreaCount.
Definition: class_board.h:1011
aperture used for connected items like tracks (not vias)
void SetNetName(const wxString &aNetname)
bool GetSkipPlotNPTH_Pads() const
TRACK * Next() const
Definition: class_track.h:98
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
smd pads, front layer
const wxString & GetNetname() const
Function GetNetname.
ZONE_CONTAINER * GetArea(int index) const
Function GetArea returns the Area (Zone Container) at a given index.
Definition: class_board.h:982
DLIST< MODULE > m_Modules
Definition: class_board.h:245
int GetWidth() const
Definition: class_track.h:115
virtual void ThickSegment(const wxPoint &start, const wxPoint &end, int width, EDA_DRAW_MODE_T tracemode, void *aData)
EDA_DRAW_MODE_T GetPlotMode() const
Definition: colors.h:49
void SetApertureAttrib(GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB aApertAttribute)
bool m_NotInNet
true if a pad of a footprint cannot be connected (for instance a mechanical NPTH, ot a not named pad)...
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:108
DLIST< TRACK > m_Track
Definition: class_board.h:246
GBR_NETLIST_METADATA m_NetlistMetadata
a item to handle object attribute:
Definition: colors.h:45
print info associated to a net (TO.N attribute)
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
PLOTTER* StartPlotBoard ( BOARD aBoard,
PCB_PLOT_PARAMS aPlotOpts,
int  aLayer,
const wxString &  aFullFileName,
const wxString &  aSheetDesc 
)

Open a new plotfile using the options (and especially the format) specified in the options and prepare the page for plotting.

Return the plotter object if OK, NULL if the file is not created (or has a problem)

Definition at line 1010 of file plot_board_layers.cpp.

References AddGerberX2Attribute(), PLOTTER::ClearHeaderLinesList(), BOARD::ComputeBoundingBox(), ConfigureHPGLPenSizes(), FillNegativeKnockout(), BOARD::GetFileName(), PCB_PLOT_PARAMS::GetFineScaleAdjustX(), PCB_PLOT_PARAMS::GetFineScaleAdjustY(), PCB_PLOT_PARAMS::GetFormat(), PCB_PLOT_PARAMS::GetIncludeGerberNetlistInfo(), PCB_PLOT_PARAMS::GetMirror(), PCB_PLOT_PARAMS::GetNegative(), BOARD::GetPageSettings(), PCB_PLOT_PARAMS::GetPlotFrameRef(), PLOTTER::GetPlotterType(), BOARD::GetTitleBlock(), PCB_PLOT_PARAMS::GetUseGerberAttributes(), initializePlotter(), PLOTTER::OpenFile(), PLOT_FORMAT_DXF, PLOT_FORMAT_GERBER, PLOT_FORMAT_HPGL, PLOT_FORMAT_PDF, PLOT_FORMAT_POST, PLOT_FORMAT_SVG, PlotWorkSheet(), PCB_PLOT_PARAMS::SetMirror(), PSLIKE_PLOTTER::SetScaleAdjust(), PLOTTER::StartPlot(), GERBER_PLOTTER::UseX2Attributes(), and GERBER_PLOTTER::UseX2NetAttributes().

Referenced by DIALOG_SVG_PRINT::CreateSVGFile(), PLOT_CONTROLLER::OpenPlotfile(), and DIALOG_PLOT::Plot().

1014 {
1015  // Create the plotter driver and set the few plotter specific
1016  // options
1017  PLOTTER* plotter = NULL;
1018 
1019  switch( aPlotOpts->GetFormat() )
1020  {
1021  case PLOT_FORMAT_DXF:
1022  plotter = new DXF_PLOTTER();
1023  break;
1024 
1025  case PLOT_FORMAT_POST:
1026  PS_PLOTTER* PS_plotter;
1027  PS_plotter = new PS_PLOTTER();
1028  PS_plotter->SetScaleAdjust( aPlotOpts->GetFineScaleAdjustX(),
1029  aPlotOpts->GetFineScaleAdjustY() );
1030  plotter = PS_plotter;
1031  break;
1032 
1033  case PLOT_FORMAT_PDF:
1034  plotter = new PDF_PLOTTER();
1035  break;
1036 
1037  case PLOT_FORMAT_HPGL:
1038  HPGL_PLOTTER* HPGL_plotter;
1039  HPGL_plotter = new HPGL_PLOTTER();
1040 
1041  /* HPGL options are a little more convoluted to compute, so
1042  they're split in an other function */
1043  ConfigureHPGLPenSizes( HPGL_plotter, aPlotOpts );
1044  plotter = HPGL_plotter;
1045  break;
1046 
1047  case PLOT_FORMAT_GERBER:
1048  plotter = new GERBER_PLOTTER();
1049  break;
1050 
1051  case PLOT_FORMAT_SVG:
1052  plotter = new SVG_PLOTTER();
1053  break;
1054 
1055  default:
1056  wxASSERT( false );
1057  return NULL;
1058  }
1059 
1060  // Compute the viewport and set the other options
1061 
1062  // page layout is not mirrored, so temporary change mirror option
1063  // just to plot the page layout
1064  PCB_PLOT_PARAMS plotOpts = *aPlotOpts;
1065 
1066  if( plotOpts.GetPlotFrameRef() && plotOpts.GetMirror() )
1067  plotOpts.SetMirror( false );
1068 
1069  initializePlotter( plotter, aBoard, &plotOpts );
1070 
1071  if( plotter->OpenFile( aFullFileName ) )
1072  {
1073  plotter->ClearHeaderLinesList();
1074 
1075  // For the Gerber "file function" attribute, set the layer number
1076  if( plotter->GetPlotterType() == PLOT_FORMAT_GERBER )
1077  {
1078  bool useX2mode = plotOpts.GetUseGerberAttributes();
1079 
1080  if( useX2mode )
1081  {
1082  AddGerberX2Attribute( plotter, aBoard, aLayer, false );
1083  GERBER_PLOTTER* gbrplotter = static_cast <GERBER_PLOTTER*> ( plotter );
1084  gbrplotter->UseX2Attributes( true );
1085  gbrplotter->UseX2NetAttributes( plotOpts.GetIncludeGerberNetlistInfo() );
1086  }
1087  else
1088  {
1089  AddGerberX2Attribute( plotter, aBoard, aLayer, true );
1090  }
1091  }
1092 
1093  plotter->StartPlot();
1094 
1095  // Plot the frame reference if requested
1096  if( aPlotOpts->GetPlotFrameRef() )
1097  {
1098  PlotWorkSheet( plotter, aBoard->GetTitleBlock(),
1099  aBoard->GetPageSettings(),
1100  1, 1, // Only one page
1101  aSheetDesc, aBoard->GetFileName() );
1102 
1103  if( aPlotOpts->GetMirror() )
1104  initializePlotter( plotter, aBoard, aPlotOpts );
1105  }
1106 
1107  /* When plotting a negative board: draw a black rectangle
1108  * (background for plot board in white) and switch the current
1109  * color to WHITE; note the color inversion is actually done
1110  * in the driver (if supported) */
1111  if( aPlotOpts->GetNegative() )
1112  {
1113  EDA_RECT bbox = aBoard->ComputeBoundingBox();
1114  FillNegativeKnockout( plotter, bbox );
1115  }
1116 
1117  return plotter;
1118  }
1119 
1120  delete plotter;
1121  return NULL;
1122 }
bool GetMirror() const
void UseX2NetAttributes(bool aEnable)
Definition: plot_common.h:1112
static void initializePlotter(PLOTTER *aPlotter, BOARD *aBoard, PCB_PLOT_PARAMS *aPlotOpts)
Set up most plot options for plotting a board (especially the viewport) Important thing: page size is...
virtual bool StartPlot()=0
static void FillNegativeKnockout(PLOTTER *aPlotter, const EDA_RECT &aBbbox)
Prefill in black an area a little bigger than the board to prepare for the negative plot...
bool GetUseGerberAttributes() const
EDA_RECT ComputeBoundingBox(bool aBoardEdgesOnly=false) const
Function ComputeBoundingBox calculates the bounding box containing all board items (or board edge seg...
virtual bool OpenFile(const wxString &aFullFilename)
Open or create the plot file aFullFilename.
void SetScaleAdjust(double scaleX, double scaleY)
Set the 'fine' scaling for the postscript engine.
Definition: plot_common.h:661
void SetMirror(bool aFlag)
void AddGerberX2Attribute(PLOTTER *aPlotter, const BOARD *aBoard, LAYER_NUM aLayer, bool aUseX1CompatibilityMode)
Calculates some X2 attributes, as defined in the Gerber file format specification and add them to the...
Definition: pcbplot.cpp:466
double GetFineScaleAdjustX() const
void PlotWorkSheet(PLOTTER *plotter, const TITLE_BLOCK &aTitleBlock, const PAGE_INFO &aPageInfo, int aSheetNumber, int aNumberOfSheets, const wxString &aSheetDesc, const wxString &aFilename)
bool GetIncludeGerberNetlistInfo() const
const wxString & GetFileName() const
Definition: class_board.h:234
static void ConfigureHPGLPenSizes(HPGL_PLOTTER *aPlotter, PCB_PLOT_PARAMS *aPlotOpts)
Calculate the effective size of HPGL pens and set them in the plotter object.
PlotFormat GetFormat() const
Class PCB_PLOT_PARAMS handles plot parameters and options when plotting/printing a board...
const PAGE_INFO & GetPageSettings() const
Definition: class_board.h:547
Base plotter engine class.
Definition: plot_common.h:86
TITLE_BLOCK & GetTitleBlock()
Definition: class_board.h:553
bool GetNegative() const
virtual PlotFormat GetPlotterType() const =0
Returns the effective plot engine in use.
bool GetPlotFrameRef() const
Class EDA_RECT handles the component boundary box.
void ClearHeaderLinesList()
Function ClearHeaderLinesList remove all lines from the list of free lines to print at the beginning ...
Definition: plot_common.h:175
void UseX2Attributes(bool aEnable)
Definition: plot_common.h:1111
double GetFineScaleAdjustY() const