KiCad PCB EDA Suite
pcbplot.h File Reference

Board plot function definition file. More...

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
 

Functions

PLOTTERStartPlotBoard (BOARD *aBoard, const 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)
 Plot one copper or technical layer. More...
 
void PlotStandardLayer (BOARD *aBoard, PLOTTER *aPlotter, LSET aLayerMask, const PCB_PLOT_PARAMS &aPlotOpt)
 Plot copper or technical layers. More...
 
void PlotLayerOutlines (BOARD *aBoard, PLOTTER *aPlotter, LSET aLayerMask, const PCB_PLOT_PARAMS &aPlotOpt)
 Plot copper outline of a copper layer. More...
 
void BuildPlotFileName (wxFileName *aFilename, const wxString &aOutputDir, const wxString &aSuffix, const wxString &aExtension)
 Complete a plot filename. More...
 
const wxString GetGerberProtelExtension (LAYER_NUM aLayer)
 
const wxString GetGerberFileFunctionAttribute (const BOARD *aBoard, LAYER_NUM aLayer)
 Return 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)
 Calculate some X2 attributes as defined in the Gerber file format specification J4 (chapter 5) and add them the to the gerber file header. More...
 
void AddGerberX2Attribute (PLOTTER *aPlotter, const BOARD *aBoard, LAYER_NUM aLayer, bool aUseX1CompatibilityMode)
 Calculate some X2 attributes as defined in the Gerber file format specification and add them to the gerber file header. More...
 

Detailed Description

Board plot function definition file.

Definition in file pcbplot.h.

Macro Definition Documentation

◆ PLOT_MAX_SCALE

#define PLOT_MAX_SCALE   100.0

Definition at line 55 of file pcbplot.h.

◆ PLOT_MIN_SCALE

#define PLOT_MIN_SCALE   0.01

Definition at line 54 of file pcbplot.h.

Function Documentation

◆ AddGerberX2Attribute()

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

Calculate 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
aPlotteris the current plotter.
aBoardis the board, needed to extract some info.
aLayeris the layer number to create the attribute for.
aUseX1CompatibilityModeset to 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 353 of file pcbplot.cpp.

355 {
356  AddGerberX2Header( aPlotter, aBoard, aUseX1CompatibilityMode );
357 
358  wxString text;
359 
360  // Add the TF.FileFunction
361  text = GetGerberFileFunctionAttribute( aBoard, aLayer );
362  aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );
363 
364  // Add the TF.FilePolarity (for layers which support that)
366 
367  if( !text.IsEmpty() )
368  aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );
369 }
void AddGerberX2Header(PLOTTER *aPlotter, const BOARD *aBoard, bool aUseX1CompatibilityMode)
Calculate some X2 attributes as defined in the Gerber file format specification J4 (chapter 5) and ad...
Definition: pcbplot.cpp:282
void AddLineToHeader(const wxString &aExtraString)
Add a line to the list of free lines to print at the beginning of the file.
Definition: plotter.h:183
static const wxString GetGerberFilePolarityAttribute(LAYER_NUM aLayer)
Definition: pcbplot.cpp:209
static wxString & makeStringCompatX1(wxString &aText, bool aUseX1CompatibilityMode)
Definition: pcbplot.cpp:270
const wxString GetGerberFileFunctionAttribute(const BOARD *aBoard, LAYER_NUM aLayer)
Return the "file function" attribute for aLayer, as defined in the Gerber file format specification J...
Definition: pcbplot.cpp:87

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

Referenced by StartPlotBoard().

◆ AddGerberX2Header()

void AddGerberX2Header ( PLOTTER aPlotter,
const BOARD aBoard,
bool  aUseX1CompatibilityMode = false 
)

Calculate 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
aPlotteris the current plotter.
aBoardis the board, needed to extract some info.
aUseX1CompatibilityModeset to 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 282 of file pcbplot.cpp.

283 {
284  wxString text;
285 
286  // Creates the TF,.GenerationSoftware. Format is:
287  // %TF,.GenerationSoftware,<vendor>,<application name>[,<application version>]*%
288  text.Printf( wxT( "%%TF.GenerationSoftware,KiCad,Pcbnew,%s*%%" ), GetBuildVersion() );
289  aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );
290 
291  // creates the TF.CreationDate attribute:
292  text = GbrMakeCreationDateAttributeString( aUseX1CompatibilityMode ?
295  aPlotter->AddLineToHeader( text );
296 
297  // Creates the TF,.ProjectId. Format is (from Gerber file format doc):
298  // %TF.ProjectId,<project id>,<project GUID>,<revision id>*%
299  // <project id> is the name of the project, restricted to basic ASCII symbols only,
300  // Rem: <project id> accepts only ASCII 7 code (only basic ASCII codes are allowed in
301  // gerber files) and comma not accepted.
302  // All illegal chars will be replaced by underscore.
303  //
304  // <project GUID> is a string which is an unique id of a project.
305  // However Kicad does not handle such a project GUID, so it is built from the board name
306  wxFileName fn = aBoard->GetFileName();
307  wxString msg = fn.GetFullName();
308 
309  // Build a <project GUID>, from the board name
310  wxString guid = GbrMakeProjectGUIDfromString( msg );
311 
312  // build the <project id> string: this is the board short filename (without ext)
313  // and all non ASCII chars and comma are replaced by '_'
314  msg = fn.GetName();
315  msg.Replace( wxT( "," ), wxT( "_" ) );
316 
317  // build the <revision id> string. All non ASCII chars and comma are replaced by '_'
318  wxString rev = ExpandTextVars( aBoard->GetTitleBlock().GetRevision(), aBoard->GetProject() );
319  rev.Replace( wxT( "," ), wxT( "_" ) );
320 
321  if( rev.IsEmpty() )
322  rev = wxT( "rev?" );
323 
324  text.Printf( wxT( "%%TF.ProjectId,%s,%s,%s*%%" ), msg.ToAscii(), guid, rev.ToAscii() );
325  aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );
326 
327  // Add the TF.SameCoordinates, that specify all gerber files uses the same
328  // origin and orientation, and the registration between files is OK.
329  // The parameter of TF.SameCoordinates is a string that is common
330  // to all files using the same registration and has no special meaning:
331  // this is just a key
332  // Because there is no mirroring/rotation in Kicad, only the plot offset origin
333  // can create incorrect registration.
334  // So we create a key from plot offset options.
335  // and therefore for a given board, all Gerber files having the same key have the same
336  // plot origin and use the same registration
337  //
338  // Currently the key is "Original" when using absolute Pcbnew coordinates,
339  // and the PY and PY position of auxiliary axis, when using it.
340  // Please, if absolute Pcbnew coordinates, one day, are set by user, change the way
341  // the key is built to ensure file only using the *same* axis have the same key.
342  wxString registration_id = "Original";
343  wxPoint auxOrigin = aBoard->GetDesignSettings().m_AuxOrigin;
344 
345  if( aBoard->GetPlotOptions().GetUseAuxOrigin() && auxOrigin.x && auxOrigin.y )
346  registration_id.Printf( "PX%xPY%x", auxOrigin.x, auxOrigin.y );
347 
348  text.Printf( "%%TF.SameCoordinates,%s*%%", registration_id.GetData() );
349  aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );
350 }
const PCB_PLOT_PARAMS & GetPlotOptions() const
Definition: board.h:538
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject)
Definition: common.cpp:64
PROJECT * GetProject() const
Definition: board.h:360
wxString GbrMakeCreationDateAttributeString(GBR_NC_STRING_FORMAT aFormat)
void AddLineToHeader(const wxString &aExtraString)
Add a line to the list of free lines to print at the beginning of the file.
Definition: plotter.h:183
const wxString & GetFileName() const
Definition: board.h:228
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:588
wxString GetBuildVersion()
Get the full KiCad version string.
const wxString & GetRevision() const
Definition: title_block.h:86
wxString GbrMakeProjectGUIDfromString(const wxString &aText)
Build a project GUID using format RFC4122 Version 1 or 4 from the project name, because a KiCad proje...
TITLE_BLOCK & GetTitleBlock()
Definition: board.h:541
static wxString & makeStringCompatX1(wxString &aText, bool aUseX1CompatibilityMode)
Definition: pcbplot.cpp:270
bool GetUseAuxOrigin() const
wxPoint m_AuxOrigin
origin for plot exports

References PLOTTER::AddLineToHeader(), ExpandTextVars(), GBR_NC_STRING_FORMAT_X1, GBR_NC_STRING_FORMAT_X2, GbrMakeCreationDateAttributeString(), GbrMakeProjectGUIDfromString(), GetBuildVersion(), BOARD::GetDesignSettings(), BOARD::GetFileName(), BOARD::GetPlotOptions(), BOARD::GetProject(), TITLE_BLOCK::GetRevision(), BOARD::GetTitleBlock(), PCB_PLOT_PARAMS::GetUseAuxOrigin(), BOARD_DESIGN_SETTINGS::m_AuxOrigin, makeStringCompatX1(), and text.

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

◆ BuildPlotFileName()

void BuildPlotFileName ( wxFileName *  aFilename,
const wxString &  aOutputDir,
const wxString &  aSuffix,
const wxString &  aExtension 
)

Complete a plot filename.

It forces the output directory, adds a suffix to the name, and sets the specified extension. The suffix is usually the layer name and replaces illegal file name character in the suffix with an underscore character.

Parameters
aFilenameis the file name to initialize that contains the base filename.
aOutputDiris the path.
aSuffixis the suffix to add to the base filename.
aExtensionis the file extension.

Definition at line 372 of file pcbplot.cpp.

374 {
375  // aFilename contains the base filename only (without path and extension)
376  // when calling this function.
377  // It is expected to be a valid filename (this is usually the board filename)
378  aFilename->SetPath( aOutputDir );
379 
380  // Set the file extension
381  aFilename->SetExt( aExtension );
382 
383  // remove leading and trailing spaces if any from the suffix, if
384  // something survives add it to the name;
385  // also the suffix can contain some not allowed chars in filename (/ \ . : and some others),
386  // so change them to underscore
387  // Remember it can be called from a python script, so the illegal chars
388  // have to be filtered here.
389  wxString suffix = aSuffix;
390  suffix.Trim( true );
391  suffix.Trim( false );
392 
393  wxString badchars = wxFileName::GetForbiddenChars(wxPATH_DOS);
394  badchars.Append( "%." );
395 
396  for( unsigned ii = 0; ii < badchars.Len(); ii++ )
397  suffix.Replace( badchars[ii], wxT("_") );
398 
399  if( !suffix.IsEmpty() )
400  aFilename->SetName( aFilename->GetName() + wxT( "-" ) + suffix );
401 }

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

◆ GetGerberFileFunctionAttribute()

const wxString GetGerberFileFunctionAttribute ( const BOARD aBoard,
LAYER_NUM  aLayer 
)

Return 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
aBoardis the board, needed to get the total count of copper layers.
aLayeris the layer number to create the attribute for.
Returns
The attribute, as a text string

Definition at line 87 of file pcbplot.cpp.

88 {
89  wxString attrib;
90 
91  switch( aLayer )
92  {
93  case F_Adhes:
94  attrib = "Glue,Top";
95  break;
96 
97  case B_Adhes:
98  attrib = "Glue,Bot";
99  break;
100 
101  case F_SilkS:
102  attrib = "Legend,Top";
103  break;
104 
105  case B_SilkS:
106  attrib = "Legend,Bot";
107  break;
108 
109  case F_Mask:
110  attrib = "Soldermask,Top";
111  break;
112 
113  case B_Mask:
114  attrib = "Soldermask,Bot";
115  break;
116 
117  case F_Paste:
118  attrib = "Paste,Top";
119  break;
120 
121  case B_Paste:
122  attrib = "Paste,Bot";
123  break;
124 
125  case Edge_Cuts:
126  // Board outline.
127  // Can be "Profile,NP" (Not Plated: usual) or "Profile,P"
128  // This last is the exception (Plated)
129  attrib = "Profile,NP";
130  break;
131 
132  case Dwgs_User:
133  attrib = "OtherDrawing,Comment";
134  break;
135 
136  case Cmts_User:
137  attrib = "Other,Comment";
138  break;
139 
140  case Eco1_User:
141  attrib = "Other,ECO1";
142  break;
143 
144  case Eco2_User:
145  attrib = "Other,ECO2";
146  break;
147 
148  case B_Fab:
149  // This is actually a assembly layer
150  attrib = "AssemblyDrawing,Bot";
151  break;
152 
153  case F_Fab:
154  // This is actually a assembly layer
155  attrib = "AssemblyDrawing,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  // This code adds a optional parameter: the type of copper layers.
175  // Because it is not used by Pcbnew (it can be used only by external autorouters)
176  // user do not really set this parameter.
177  // Therefore do not add it.
178  // However, this code is left here, for perhaps a future usage.
179 #if 0
180  // Add the signal type of the layer, if relevant
181  if( IsCopperLayer( aLayer ) )
182  {
183  LAYER_T type = aBoard->GetLayerType( ToLAYER_ID( aLayer ) );
184 
185  switch( type )
186  {
187  case LT_SIGNAL:
188  attrib += ",Signal";
189  break;
190  case LT_POWER:
191  attrib += ",Plane";
192  break;
193  case LT_MIXED:
194  attrib += ",Mixed";
195  break;
196  default:
197  break; // do nothing (but avoid a warning for unhandled LAYER_T values from GCC)
198  }
199  }
200 #endif
201 
202  wxString fileFct;
203  fileFct.Printf( "%%TF.FileFunction,%s*%%", attrib );
204 
205  return fileFct;
206 }
Definition: board.h:72
Definition: board.h:73
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:787
LAYER_T GetLayerType(PCB_LAYER_ID aLayer) const
Return the type of the copper layer given by aLayer.
Definition: board.cpp:394
Definition: layer_ids.h:70
int GetCopperLayerCount() const
Definition: board.cpp:453
LAYER_T
The allowed types of layers, same as Specctra DSN spec.
Definition: board.h:68
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:905

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, BOARD::GetCopperLayerCount(), BOARD::GetLayerType(), IsCopperLayer(), LT_MIXED, LT_POWER, LT_SIGNAL, and ToLAYER_ID().

Referenced by AddGerberX2Attribute().

◆ GetGerberProtelExtension()

const wxString GetGerberProtelExtension ( LAYER_NUM  aLayer)
Returns
the appropriate Gerber file extension for aLayer

Definition at line 46 of file pcbplot.cpp.

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

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().

◆ PlotLayerOutlines()

void PlotLayerOutlines ( BOARD aBoard,
PLOTTER aPlotter,
LSET  aLayerMask,
const PCB_PLOT_PARAMS aPlotOpt 
)

Plot copper outline of a copper layer.

Parameters
aBoardis the board to plot.
aPlotteris the plotter to use.
aLayerMaskis the mask to define the layers to plot.
aPlotOptis the plot options. Has meaning for some formats only.

Plot copper outline of a copper layer.

Definition at line 700 of file plot_board_layers.cpp.

702 {
703  BRDITEMS_PLOTTER itemplotter( aPlotter, aBoard, aPlotOpt );
704  itemplotter.SetLayerSet( aLayerMask );
705 
706  SHAPE_POLY_SET outlines;
707 
708  for( LSEQ seq = aLayerMask.Seq( plot_seq, arrayDim( plot_seq ) ); seq; ++seq )
709  {
710  PCB_LAYER_ID layer = *seq;
711 
712  outlines.RemoveAllContours();
713  aBoard->ConvertBrdLayerToPolygonalContours( layer, outlines );
714 
715  outlines.Simplify( SHAPE_POLY_SET::PM_FAST );
716 
717  // Plot outlines
718  std::vector<wxPoint> cornerList;
719 
720  // Now we have one or more basic polygons: plot each polygon
721  for( int ii = 0; ii < outlines.OutlineCount(); ii++ )
722  {
723  for( int kk = 0; kk <= outlines.HoleCount(ii); kk++ )
724  {
725  cornerList.clear();
726  const SHAPE_LINE_CHAIN& path =
727  ( kk == 0 ) ? outlines.COutline( ii ) : outlines.CHole( ii, kk - 1 );
728 
729  aPlotter->PlotPoly( path, FILL_TYPE::NO_FILL );
730  }
731  }
732 
733  // Plot pad holes
735  {
736  int smallDrill = (aPlotOpt.GetDrillMarksType() == PCB_PLOT_PARAMS::SMALL_DRILL_SHAPE)
738 
739  for( FOOTPRINT* footprint : aBoard->Footprints() )
740  {
741  for( PAD* pad : footprint->Pads() )
742  {
743  wxSize hole = pad->GetDrillSize();
744 
745  if( hole.x == 0 || hole.y == 0 )
746  continue;
747 
748  if( hole.x == hole.y )
749  {
750  hole.x = std::min( smallDrill, hole.x );
751  aPlotter->Circle( pad->GetPosition(), hole.x, FILL_TYPE::NO_FILL );
752  }
753  else
754  {
755  // Note: small drill marks have no significance when applied to slots
756  const SHAPE_SEGMENT* seg = pad->GetEffectiveHoleShape();
757  aPlotter->ThickSegment( (wxPoint) seg->GetSeg().A,
758  (wxPoint) seg->GetSeg().B,
759  seg->GetWidth(), SKETCH, nullptr );
760  }
761  }
762  }
763  }
764 
765  // Plot vias holes
766  for( PCB_TRACK* track : aBoard->Tracks() )
767  {
768  const PCB_VIA* via = dyn_cast<const PCB_VIA*>( track );
769 
770  if( via && via->IsOnLayer( layer ) ) // via holes can be not through holes
771  {
772  aPlotter->Circle( via->GetPosition(), via->GetDrillValue(), FILL_TYPE::NO_FILL );
773  }
774  }
775  }
776 }
virtual void PlotPoly(const std::vector< wxPoint > &aCornerList, FILL_TYPE aFill, int aWidth=USE_DEFAULT_LINE_WIDTH, void *aData=nullptr)=0
Draw a polygon ( filled or not ).
int OutlineCount() const
Return the number of vertices in a given outline/hole.
void ConvertBrdLayerToPolygonalContours(PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aOutlines) const
Build a set of polygons which are the outlines of copper items (pads, tracks, vias,...
static const PCB_LAYER_ID plot_seq[]
const SHAPE_LINE_CHAIN & CHole(int aOutline, int aHole) const
double m_SmallDrillMarkSize
The diameter of the drill marks on print and plot outputs (in mm), when the "Drill marks" option is s...
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:411
virtual void ThickSegment(const wxPoint &start, const wxPoint &end, int width, OUTLINE_MODE tracemode, void *aData)
Definition: plotter.cpp:522
const SEG & GetSeg() const
Represent a set of closed polygons.
FOOTPRINTS & Footprints()
Definition: board.h:233
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
Definition: arraydim.h:31
void Simplify(POLYGON_MODE aFastMode)
virtual void Circle(const wxPoint &pos, int diametre, FILL_TYPE fill, int width=USE_DEFAULT_LINE_WIDTH)=0
int HoleCount(int aOutline) const
Return the reference to aIndex-th outline in the set.
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
Definition: layer_ids.h:463
Represent a polyline (an zero-thickness chain of connected line segments).
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:64
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
VECTOR2I A
Definition: seg.h:48
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
Definition: pad.h:57
DrillMarksType GetDrillMarksType() const
int GetWidth() const
TRACKS & Tracks()
Definition: board.h:230
VECTOR2I B
Definition: seg.h:49

References SEG::A, arrayDim(), SEG::B, SHAPE_POLY_SET::CHole(), PLOTTER::Circle(), BOARD::ConvertBrdLayerToPolygonalContours(), SHAPE_POLY_SET::COutline(), BOARD::Footprints(), ADVANCED_CFG::GetCfg(), PCB_PLOT_PARAMS::GetDrillMarksType(), SHAPE_SEGMENT::GetSeg(), SHAPE_SEGMENT::GetWidth(), SHAPE_POLY_SET::HoleCount(), ADVANCED_CFG::m_SmallDrillMarkSize, PCB_PLOT_PARAMS::NO_DRILL_SHAPE, NO_FILL, SHAPE_POLY_SET::OutlineCount(), pad, path, plot_seq, PLOTTER::PlotPoly(), SHAPE_POLY_SET::PM_FAST, SHAPE_POLY_SET::RemoveAllContours(), LSET::Seq(), BRDITEMS_PLOTTER::SetLayerSet(), SHAPE_POLY_SET::Simplify(), SKETCH, PCB_PLOT_PARAMS::SMALL_DRILL_SHAPE, PLOTTER::ThickSegment(), BOARD::Tracks(), and via.

Referenced by PlotOneBoardLayer().

◆ PlotOneBoardLayer()

void PlotOneBoardLayer ( BOARD aBoard,
PLOTTER aPlotter,
PCB_LAYER_ID  aLayer,
const PCB_PLOT_PARAMS aPlotOpt 
)

Plot one copper or technical layer.

It prepares options and calls the specialized plot function according to the layer type.

Parameters
aBoardis the board to plot.
aPlotteris the plotter to use.
aLayeris the layer id to plot.
aPlotOptis the plot options (files, sketch). Has meaning for some formats only.

Definition at line 65 of file plot_board_layers.cpp.

67 {
68  PCB_PLOT_PARAMS plotOpt = aPlotOpt;
69  int soldermask_min_thickness = aBoard->GetDesignSettings().m_SolderMaskMinWidth;
70 
71  // Set a default color and the text mode for this layer
72  aPlotter->SetColor( BLACK );
73  aPlotter->SetTextMode( aPlotOpt.GetTextMode() );
74 
75  // Specify that the contents of the "Edges Pcb" layer are to be plotted in addition to the
76  // contents of the currently specified layer.
77  LSET layer_mask( aLayer );
78 
79  if( !aPlotOpt.GetExcludeEdgeLayer() )
80  layer_mask.set( Edge_Cuts );
81 
82  if( IsCopperLayer( aLayer ) )
83  {
84  // Skip NPTH pads on copper layers ( only if hole size == pad size ):
85  // Drill mark will be plotted if drill mark is SMALL_DRILL_SHAPE or FULL_DRILL_SHAPE
86  if( plotOpt.GetFormat() == PLOT_FORMAT::DXF )
87  {
88  plotOpt.SetSkipPlotNPTH_Pads( false );
89  PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
90  }
91  else
92  {
93  plotOpt.SetSkipPlotNPTH_Pads( true );
94  PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
95  }
96  }
97  else
98  {
99  switch( aLayer )
100  {
101  case B_Mask:
102  case F_Mask:
103  plotOpt.SetSkipPlotNPTH_Pads( false );
104  // Disable plot pad holes
106 
107  // Plot solder mask:
108  if( soldermask_min_thickness == 0 )
109  {
110  if( plotOpt.GetFormat() == PLOT_FORMAT::DXF )
111  PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
112  else
113  PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
114  }
115  else
116  {
117  PlotSolderMaskLayer( aBoard, aPlotter, layer_mask, plotOpt,
118  soldermask_min_thickness );
119  }
120 
121  break;
122 
123  case B_Adhes:
124  case F_Adhes:
125  case B_Paste:
126  case F_Paste:
127  plotOpt.SetSkipPlotNPTH_Pads( false );
128  // Disable plot pad holes
130 
131  if( plotOpt.GetFormat() == PLOT_FORMAT::DXF )
132  PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
133  else
134  PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
135 
136  break;
137 
138  case F_SilkS:
139  case B_SilkS:
140  if( plotOpt.GetFormat() == PLOT_FORMAT::DXF && plotOpt.GetDXFPlotPolygonMode() )
141  // PlotLayerOutlines() is designed only for DXF plotters.
142  // and must not be used for other plot formats
143  PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
144  else
145  PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
146 
147  // Gerber: Subtract soldermask from silkscreen if enabled
148  if( aPlotter->GetPlotterType() == PLOT_FORMAT::GERBER
149  && plotOpt.GetSubtractMaskFromSilk() )
150  {
151  if( aLayer == F_SilkS )
152  layer_mask = LSET( F_Mask );
153  else
154  layer_mask = LSET( B_Mask );
155 
156  // Create the mask to subtract by creating a negative layer polarity
157  aPlotter->SetLayerPolarity( false );
158 
159  // Disable plot pad holes
161 
162  // Plot the mask
163  PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
164  }
165 
166  break;
167 
168  // These layers are plotted like silk screen layers.
169  // Mainly, pads on these layers are not filled.
170  // This is not necessary the best choice.
171  case Dwgs_User:
172  case Cmts_User:
173  case Eco1_User:
174  case Eco2_User:
175  case Edge_Cuts:
176  case Margin:
177  case F_CrtYd:
178  case B_CrtYd:
179  case F_Fab:
180  case B_Fab:
181  plotOpt.SetSkipPlotNPTH_Pads( false );
183 
184  if( plotOpt.GetFormat() == PLOT_FORMAT::DXF && plotOpt.GetDXFPlotPolygonMode() )
185  // PlotLayerOutlines() is designed only for DXF plotters.
186  // and must not be used for other plot formats
187  PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
188  else
189  PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
190 
191  break;
192 
193  default:
194  plotOpt.SetSkipPlotNPTH_Pads( false );
196 
197  if( plotOpt.GetFormat() == PLOT_FORMAT::DXF && plotOpt.GetDXFPlotPolygonMode() )
198  // PlotLayerOutlines() is designed only for DXF plotters.
199  // and must not be used for other plot formats
200  PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
201  else
202  PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
203 
204  break;
205  }
206  }
207 }
bool GetDXFPlotPolygonMode() const
virtual void SetLayerPolarity(bool aPositive)
Set the current Gerber layer polarity to positive or negative by writing %LPD*% or %LPC*% to the Gerb...
Definition: plotter.h:456
void PlotStandardLayer(BOARD *aBoard, PLOTTER *aPlotter, LSET aLayerMask, const PCB_PLOT_PARAMS &aPlotOpt)
Plot a copper layer or mask.
Definition: color4d.h:44
void SetDrillMarksType(DrillMarksType aVal)
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:588
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)
Plot outlines of copper layer.
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:502
PLOT_FORMAT GetFormat() const
virtual PLOT_FORMAT GetPlotterType() const =0
Returns the effective plot engine in use.
virtual void SetTextMode(PLOT_TEXT_MODE mode)
Change the current text mode.
Definition: plotter.h:465
void SetSkipPlotNPTH_Pads(bool aSkip)
PLOT_TEXT_MODE GetTextMode() const
Parameters and options when plotting/printing a board.
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:787
virtual void SetColor(const COLOR4D &color)=0
bool GetSubtractMaskFromSilk() const
bool GetExcludeEdgeLayer() const

References B_Adhes, B_CrtYd, B_Fab, B_Mask, B_Paste, B_SilkS, BLACK, Cmts_User, Dwgs_User, DXF, Eco1_User, Eco2_User, Edge_Cuts, F_Adhes, F_CrtYd, F_Fab, F_Mask, F_Paste, F_SilkS, GERBER, 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, PlotLayerOutlines(), PlotSolderMaskLayer(), PlotStandardLayer(), PLOTTER::SetColor(), PCB_PLOT_PARAMS::SetDrillMarksType(), PLOTTER::SetLayerPolarity(), PCB_PLOT_PARAMS::SetSkipPlotNPTH_Pads(), and PLOTTER::SetTextMode().

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

◆ PlotStandardLayer()

void PlotStandardLayer ( BOARD aBoard,
PLOTTER aPlotter,
LSET  aLayerMask,
const PCB_PLOT_PARAMS aPlotOpt 
)

Plot copper or technical layers.

This is not used for silk screen layers because these layers have specific requirements. This is mainly for pads.

Parameters
aBoardis the board to plot.
aPlotteris the plotter to use.
aLayerMaskis the mask to define the layers to plot.
aPlotOptis 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 ) control the actual hole: no hole, small hole, actual hole

Plot copper or technical layers.

Silk screen layers are not plotted here.

pads not connected to copper are optionally not drawn

Vias not connected to copper are optionally not drawn

Definition at line 215 of file plot_board_layers.cpp.

217 {
218  BRDITEMS_PLOTTER itemplotter( aPlotter, aBoard, aPlotOpt );
219 
220  itemplotter.SetLayerSet( aLayerMask );
221 
222  OUTLINE_MODE plotMode = aPlotOpt.GetPlotMode();
223  bool onCopperLayer = ( LSET::AllCuMask() & aLayerMask ).any();
224  bool onSolderMaskLayer = ( LSET( 2, F_Mask, B_Mask ) & aLayerMask ).any();
225  bool onSolderPasteLayer = ( LSET( 2, F_Paste, B_Paste ) & aLayerMask ).any();
226  bool onFrontFab = ( LSET( F_Fab ) & aLayerMask ).any();
227  bool onBackFab = ( LSET( B_Fab ) & aLayerMask ).any();
228  bool sketchPads = ( onFrontFab || onBackFab ) && aPlotOpt.GetSketchPadsOnFabLayers();
229 
230  // Plot edge layer and graphic items
231  itemplotter.PlotBoardGraphicItems();
232 
233  // Draw footprint texts:
234  for( const FOOTPRINT* footprint : aBoard->Footprints() )
235  itemplotter.PlotFootprintTextItems( footprint );
236 
237  // Draw footprint other graphic items:
238  for( const FOOTPRINT* footprint : aBoard->Footprints() )
239  itemplotter.PlotFootprintGraphicItems( footprint );
240 
241  // Plot footprint pads
242  for( FOOTPRINT* footprint : aBoard->Footprints() )
243  {
244  aPlotter->StartBlock( nullptr );
245 
246  for( PAD* pad : footprint->Pads() )
247  {
248  OUTLINE_MODE padPlotMode = plotMode;
249 
250  if( !( pad->GetLayerSet() & aLayerMask ).any() )
251  {
252  if( sketchPads &&
253  ( ( onFrontFab && pad->GetLayerSet().Contains( F_Cu ) ) ||
254  ( onBackFab && pad->GetLayerSet().Contains( B_Cu ) ) ) )
255  {
256  padPlotMode = SKETCH;
257  }
258  else
259  {
260  continue;
261  }
262  }
263 
265  if( onCopperLayer && !pad->FlashLayer( aLayerMask ) )
266  continue;
267 
269 
270  if( pad->GetLayerSet()[B_Cu] )
271  color = aPlotOpt.ColorSettings()->GetColor( LAYER_PAD_BK );
272 
273  if( pad->GetLayerSet()[F_Cu] )
274  color = color.LegacyMix( aPlotOpt.ColorSettings()->GetColor( LAYER_PAD_FR ) );
275 
276  if( sketchPads && aLayerMask[F_Fab] )
277  color = aPlotOpt.ColorSettings()->GetColor( F_Fab );
278  else if( sketchPads && aLayerMask[B_Fab] )
279  color = aPlotOpt.ColorSettings()->GetColor( B_Fab );
280 
281  wxSize margin;
282  int width_adj = 0;
283 
284  if( onCopperLayer )
285  width_adj = itemplotter.getFineWidthAdj();
286 
287  if( onSolderMaskLayer )
288  margin.x = margin.y = pad->GetSolderMaskMargin();
289 
290  if( onSolderPasteLayer )
291  margin = pad->GetSolderPasteMargin();
292 
293  // not all shapes can have a different margin for x and y axis
294  // in fact only oval and rect shapes can have different values.
295  // Round shape have always the same x,y margin
296  // so define a unique value for other shapes that do not support different values
297  int mask_clearance = margin.x;
298 
299  // Now offset the pad size by margin + width_adj
300  wxSize padPlotsSize = pad->GetSize() + margin * 2 + wxSize( width_adj, width_adj );
301 
302  // Store these parameters that can be modified to plot inflated/deflated pads shape
303  PAD_SHAPE padShape = pad->GetShape();
304  wxSize padSize = pad->GetSize();
305  wxSize padDelta = pad->GetDelta(); // has meaning only for trapezoidal pads
306  double padCornerRadius = pad->GetRoundRectCornerRadius();
307 
308  // Don't draw a null size item :
309  if( padPlotsSize.x <= 0 || padPlotsSize.y <= 0 )
310  continue;
311 
312  switch( pad->GetShape() )
313  {
314  case PAD_SHAPE::CIRCLE:
315  case PAD_SHAPE::OVAL:
316  pad->SetSize( padPlotsSize );
317 
318  if( aPlotOpt.GetSkipPlotNPTH_Pads() &&
320  ( pad->GetSize() == pad->GetDrillSize() ) &&
321  ( pad->GetAttribute() == PAD_ATTRIB::NPTH ) )
322  {
323  break;
324  }
325 
326  itemplotter.PlotPad( pad, color, padPlotMode );
327  break;
328 
329  case PAD_SHAPE::RECT:
330  pad->SetSize( padPlotsSize );
331 
332  if( mask_clearance > 0 )
333  {
334  pad->SetShape( PAD_SHAPE::ROUNDRECT );
335  pad->SetRoundRectCornerRadius( mask_clearance );
336  }
337 
338  itemplotter.PlotPad( pad, color, padPlotMode );
339  break;
340 
342  // inflate/deflate a trapezoid is a bit complex.
343  // so if the margin is not null, build a similar polygonal pad shape,
344  // and inflate/deflate the polygonal shape
345  // because inflating/deflating using different values for y and y
346  // we are using only margin.x as inflate/deflate value
347  if( mask_clearance == 0 )
348  {
349  itemplotter.PlotPad( pad, color, padPlotMode );
350  }
351  else
352  {
353  PAD dummy( *pad );
354  dummy.SetAnchorPadShape( PAD_SHAPE::CIRCLE );
355  dummy.SetShape( PAD_SHAPE::CUSTOM );
356  SHAPE_POLY_SET outline;
357  outline.NewOutline();
358  int dx = padSize.x / 2;
359  int dy = padSize.y / 2;
360  int ddx = padDelta.x / 2;
361  int ddy = padDelta.y / 2;
362 
363  outline.Append( -dx - ddy, dy + ddx );
364  outline.Append( dx + ddy, dy - ddx );
365  outline.Append( dx - ddy, -dy + ddx );
366  outline.Append( -dx + ddy, -dy - ddx );
367 
368  // Shape polygon can have holes so use InflateWithLinkedHoles(), not Inflate()
369  // which can create bad shapes if margin.x is < 0
370  int maxError = aBoard->GetDesignSettings().m_MaxError;
371  int numSegs = GetArcToSegmentCount( mask_clearance, maxError, 360.0 );
372  outline.InflateWithLinkedHoles( mask_clearance, numSegs,
374  dummy.DeletePrimitivesList();
375  dummy.AddPrimitivePoly( outline, 0, true );
376 
377  // Be sure the anchor pad is not bigger than the deflated shape because this
378  // anchor will be added to the pad shape when plotting the pad. So now the
379  // polygonal shape is built, we can clamp the anchor size
380  dummy.SetSize( wxSize( 0,0 ) );
381 
382  itemplotter.PlotPad( &dummy, color, padPlotMode );
383  }
384 
385  break;
386 
388  {
389  // rounding is stored as a percent, but we have to change the new radius
390  // to initial_radius + clearance to have a inflated/deflated similar shape
391  int initial_radius = pad->GetRoundRectCornerRadius();
392  pad->SetSize( padPlotsSize );
393  pad->SetRoundRectCornerRadius( std::max( initial_radius + mask_clearance, 0 ) );
394 
395  itemplotter.PlotPad( pad, color, padPlotMode );
396  break;
397  }
398 
400  if( mask_clearance == 0 )
401  {
402  // the size can be slightly inflated by width_adj (PS/PDF only)
403  pad->SetSize( padPlotsSize );
404  itemplotter.PlotPad( pad, color, padPlotMode );
405  }
406  else
407  {
408  // Due to the polygonal shape of a CHAMFERED_RECT pad, the best way is to
409  // convert the pad shape to a full polygon, inflate/deflate the polygon
410  // and use a dummy CUSTOM pad to plot the final shape.
411  PAD dummy( *pad );
412  // Build the dummy pad outline with coordinates relative to the pad position
413  // and orientation 0. The actual pos and rotation will be taken in account
414  // later by the plot function
415  dummy.SetPosition( wxPoint( 0, 0 ) );
416  dummy.SetOrientation( 0 );
417  SHAPE_POLY_SET outline;
418  int maxError = aBoard->GetDesignSettings().m_MaxError;
419  int numSegs = GetArcToSegmentCount( mask_clearance, maxError, 360.0 );
420  dummy.TransformShapeWithClearanceToPolygon( outline, UNDEFINED_LAYER, 0,
421  maxError, ERROR_INSIDE );
422  outline.InflateWithLinkedHoles( mask_clearance, numSegs,
424 
425  // Initialize the dummy pad shape:
426  dummy.SetAnchorPadShape( PAD_SHAPE::CIRCLE );
427  dummy.SetShape( PAD_SHAPE::CUSTOM );
428  dummy.DeletePrimitivesList();
429  dummy.AddPrimitivePoly( outline, 0, true );
430 
431  // Be sure the anchor pad is not bigger than the deflated shape because this
432  // anchor will be added to the pad shape when plotting the pad.
433  // So we set the anchor size to 0
434  dummy.SetSize( wxSize( 0,0 ) );
435  dummy.SetPosition( pad->GetPosition() );
436  dummy.SetOrientation( pad->GetOrientation() );
437 
438  itemplotter.PlotPad( &dummy, color, padPlotMode );
439  }
440 
441  break;
442 
443  case PAD_SHAPE::CUSTOM:
444  {
445  // inflate/deflate a custom shape is a bit complex.
446  // so build a similar pad shape, and inflate/deflate the polygonal shape
447  PAD dummy( *pad );
448  SHAPE_POLY_SET shape;
449  pad->MergePrimitivesAsPolygon( &shape, UNDEFINED_LAYER );
450 
451  // Shape polygon can have holes so use InflateWithLinkedHoles(), not Inflate()
452  // which can create bad shapes if margin.x is < 0
453  int maxError = aBoard->GetDesignSettings().m_MaxError;
454  int numSegs = GetArcToSegmentCount( mask_clearance, maxError, 360.0 );
455  shape.InflateWithLinkedHoles( mask_clearance, numSegs, SHAPE_POLY_SET::PM_FAST );
456  dummy.DeletePrimitivesList();
457  dummy.AddPrimitivePoly( shape, 0, true );
458 
459  // Be sure the anchor pad is not bigger than the deflated shape because this
460  // anchor will be added to the pad shape when plotting the pad. So now the
461  // polygonal shape is built, we can clamp the anchor size
462  if( mask_clearance < 0 ) // we expect margin.x = margin.y for custom pads
463  dummy.SetSize( padPlotsSize );
464 
465  itemplotter.PlotPad( &dummy, color, padPlotMode );
466  break;
467  }
468  }
469 
470  // Restore the pad parameters modified by the plot code
471  pad->SetSize( padSize );
472  pad->SetDelta( padDelta );
473  pad->SetShape( padShape );
474  pad->SetRoundRectCornerRadius( padCornerRadius );
475  }
476 
477  aPlotter->EndBlock( nullptr );
478  }
479 
480  // Plot vias on copper layers, and if aPlotOpt.GetPlotViaOnMaskLayer() is true,
481  // plot them on solder mask
482 
483  GBR_METADATA gbr_metadata;
484 
485  bool isOnCopperLayer = ( aLayerMask & LSET::AllCuMask() ).any();
486 
487  if( isOnCopperLayer )
488  {
491  }
492 
493  aPlotter->StartBlock( nullptr );
494 
495  for( const PCB_TRACK* track : aBoard->Tracks() )
496  {
497  const PCB_VIA* via = dyn_cast<const PCB_VIA*>( track );
498 
499  if( !via )
500  continue;
501 
502  // vias are not plotted if not on selected layer, but if layer is SOLDERMASK_LAYER_BACK
503  // or SOLDERMASK_LAYER_FRONT, vias are drawn only if they are on the corresponding
504  // external copper layer
505  LSET via_mask_layer = via->GetLayerSet();
506 
507  if( aPlotOpt.GetPlotViaOnMaskLayer() )
508  {
509  if( via_mask_layer[B_Cu] )
510  via_mask_layer.set( B_Mask );
511 
512  if( via_mask_layer[F_Cu] )
513  via_mask_layer.set( F_Mask );
514  }
515 
516  if( !( via_mask_layer & aLayerMask ).any() )
517  continue;
518 
519  int via_margin = 0;
520  double width_adj = 0;
521 
522  // If the current layer is a solder mask, use the global mask clearance for vias
523  if( aLayerMask[B_Mask] || aLayerMask[F_Mask] )
524  via_margin = aBoard->GetDesignSettings().m_SolderMaskMargin;
525 
526  if( ( aLayerMask & LSET::AllCuMask() ).any() )
527  width_adj = itemplotter.getFineWidthAdj();
528 
529  int diameter = via->GetWidth() + 2 * via_margin + width_adj;
530 
532  if( onCopperLayer && !via->FlashLayer( aLayerMask ) )
533  continue;
534 
535  // Don't draw a null size item :
536  if( diameter <= 0 )
537  continue;
538 
539  // Some vias can be not connected (no net).
540  // Set the m_NotInNet for these vias to force a empty net name in gerber file
541  gbr_metadata.m_NetlistMetadata.m_NotInNet = via->GetNetname().IsEmpty();
542 
543  gbr_metadata.SetNetName( via->GetNetname() );
544 
545  COLOR4D color = aPlotOpt.ColorSettings()->GetColor(
546  LAYER_VIAS + static_cast<int>( via->GetViaType() ) );
547 
548  // Set plot color (change WHITE to LIGHTGRAY because the white items are not seen on a
549  // white paper or screen
550  aPlotter->SetColor( color != WHITE ? color : LIGHTGRAY );
551  aPlotter->FlashPadCircle( via->GetStart(), diameter, plotMode, &gbr_metadata );
552  }
553 
554  aPlotter->EndBlock( nullptr );
555  aPlotter->StartBlock( nullptr );
557 
558  // Plot tracks (not vias) :
559  for( const PCB_TRACK* track : aBoard->Tracks() )
560  {
561  if( track->Type() == PCB_VIA_T )
562  continue;
563 
564  if( !aLayerMask[track->GetLayer()] )
565  continue;
566 
567  // Some track segments can be not connected (no net).
568  // Set the m_NotInNet for these segments to force a empty net name in gerber file
569  gbr_metadata.m_NetlistMetadata.m_NotInNet = track->GetNetname().IsEmpty();
570 
571  gbr_metadata.SetNetName( track->GetNetname() );
572  int width = track->GetWidth() + itemplotter.getFineWidthAdj();
573  aPlotter->SetColor( itemplotter.getColor( track->GetLayer() ) );
574 
575  if( track->Type() == PCB_ARC_T )
576  {
577  const PCB_ARC* arc = static_cast<const PCB_ARC*>( track );
578  VECTOR2D center( arc->GetCenter() );
579  int radius = arc->GetRadius();
580  double start_angle = arc->GetArcAngleStart();
581  double end_angle = start_angle + arc->GetAngle();
582 
583  aPlotter->ThickArc( wxPoint( center.x, center.y ), -end_angle, -start_angle,
584  radius, width, plotMode, &gbr_metadata );
585  }
586  else
587  {
588  aPlotter->ThickSegment( track->GetStart(), track->GetEnd(), width, plotMode,
589  &gbr_metadata );
590  }
591  }
592 
593  aPlotter->EndBlock( nullptr );
594 
595  // Plot filled ares
596  aPlotter->StartBlock( nullptr );
597 
598  NETINFO_ITEM nonet( aBoard );
599 
600  for( const ZONE* zone : aBoard->Zones() )
601  {
602  for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() )
603  {
604  if( !aLayerMask[layer] )
605  continue;
606 
607  SHAPE_POLY_SET mainArea = zone->GetFilledPolysList( layer );
608  SHAPE_POLY_SET islands;
609 
610  for( int i = mainArea.OutlineCount() - 1; i >= 0; i-- )
611  {
612  if( zone->IsIsland( layer, i ) )
613  {
614  islands.AddOutline( mainArea.CPolygon( i )[0] );
615  mainArea.DeletePolygon( i );
616  }
617  }
618 
619  itemplotter.PlotFilledAreas( zone, mainArea );
620 
621  if( !islands.IsEmpty() )
622  {
623  ZONE dummy( *zone );
624  dummy.SetNet( &nonet );
625  itemplotter.PlotFilledAreas( &dummy, islands );
626  }
627  }
628  }
629 
630  aPlotter->EndBlock( nullptr );
631 
632  // Adding drill marks, if required and if the plotter is able to plot them:
634  itemplotter.PlotDrillMarks();
635 }
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:750
OUTLINE_MODE GetPlotMode() const
OUTLINE_MODE
Definition: outline_mode.h:24
smd pads, front layer
Definition: layer_ids.h:197
virtual wxPoint GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Definition: pcb_track.h:282
const POLYGON & CPolygon(int aIndex) const
int OutlineCount() const
Return the number of vertices in a given outline/hole.
virtual void EndBlock(void *aData)
calling this function allows one to define the end of a group of drawing items for instance in SVG or...
Definition: plotter.h:496
ZONES & Zones()
Definition: board.h:239
virtual void SetPosition(const wxPoint &aPos)
Definition: eda_item.h:253
void SetNetAttribType(int aNetAttribType)
Definition: gbr_metadata.h:219
smd pads, back layer
Definition: layer_ids.h:198
int color
Definition: DXF_plotter.cpp:60
bool IsEmpty() const
virtual void StartBlock(void *aData)
calling this function allows one to define the beginning of a group of drawing items,...
Definition: plotter.h:487
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:97
Definition: color4d.h:44
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:588
virtual void ThickSegment(const wxPoint &start, const wxPoint &end, int width, OUTLINE_MODE tracemode, void *aData)
Definition: plotter.cpp:522
void DeletePolygon(int aIdx)
static LIB_SYMBOL * dummy()
Used to draw a dummy shape when a LIB_SYMBOL is not found in library.
Definition: sch_symbol.cpp:71
PAD_SHAPE
The set of pad shapes, used with PAD::{Set,Get}Shape() DO NOT REORDER, legacy_plugin is dependent on ...
Definition: pad_shapes.h:33
like PAD_PTH, but not plated
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:502
Meta control for all vias opacity/visibility.
Definition: layer_ids.h:188
double GetArcAngleStart() const
Definition: pcb_track.cpp:988
Represent a set of closed polygons.
double GetRadius() const
Definition: pcb_track.cpp:970
FOOTPRINTS & Footprints()
Definition: board.h:233
bool GetSkipPlotNPTH_Pads() const
Handle a list of polygons defining a copper zone.
Definition: zone.h:56
Metadata which can be added in a gerber file as attribute in X2 format.
Definition: gbr_metadata.h:204
int NewOutline()
Creates a new hole in a given outline.
virtual void SetColor(const COLOR4D &color)=0
Definition: color4d.h:48
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new hole to the given outline (default: last) and returns its index.
void SetNetName(const wxString &aNetname)
Definition: gbr_metadata.h:229
COLOR4D GetColor(int aLayer) const
bool GetSketchPadsOnFabLayers() const
Handle the data for a net.
Definition: netinfo.h:64
double GetAngle() const
Definition: pcb_track.cpp:976
bool GetPlotViaOnMaskLayer() const
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:64
Definition: layer_ids.h:70
void InflateWithLinkedHoles(int aFactor, int aCircleSegmentsCount, POLYGON_MODE aFastMode)
Perform outline inflation/deflation, using round corners.
virtual void ThickArc(const wxPoint &centre, double StAngle, double EndAngle, int rayon, int width, OUTLINE_MODE tracemode, void *aData)
Definition: plotter.cpp:546
void SetApertureAttrib(GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB aApertAttribute)
Definition: gbr_metadata.h:209
COLOR_SETTINGS * ColorSettings() const
bool m_NotInNet
true if a pad of a footprint cannot be connected (for instance a mechanical NPTH, ot a not named pad)...
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
GBR_NETLIST_METADATA m_NetlistMetadata
An item to handle object attribute.
Definition: gbr_metadata.h:262
Definition: pad.h:57
DrillMarksType GetDrillMarksType() const
print info associated to a net (TO.N attribute)
int GetArcToSegmentCount(int aRadius, int aErrorMax, double aArcAngleDegree)
TRACKS & Tracks()
Definition: board.h:230
virtual void FlashPadCircle(const wxPoint &aPadPos, int aDiameter, OUTLINE_MODE aTraceMode, void *aData)=0
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Add a new vertex to the contour indexed by aOutline and aHole (defaults to the outline of the last po...
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:103

References SHAPE_POLY_SET::AddOutline(), LSET::AllCuMask(), SHAPE_POLY_SET::Append(), B_Cu, B_Fab, B_Mask, B_Paste, BLACK, CHAMFERED_RECT, CIRCLE, color, PCB_PLOT_PARAMS::ColorSettings(), SHAPE_POLY_SET::CPolygon(), CUSTOM, SHAPE_POLY_SET::DeletePolygon(), dummy(), PLOTTER::EndBlock(), ERROR_INSIDE, F_Cu, F_Fab, F_Mask, F_Paste, PLOTTER::FlashPadCircle(), BOARD::Footprints(), GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CONDUCTOR, GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_VIAPAD, GBR_NETLIST_METADATA::GBR_NETINFO_NET, PCB_ARC::GetAngle(), PCB_ARC::GetArcAngleStart(), GetArcToSegmentCount(), PCB_ARC::GetCenter(), COLOR_SETTINGS::GetColor(), BRDITEMS_PLOTTER::getColor(), BOARD::GetDesignSettings(), PCB_PLOT_PARAMS::GetDrillMarksType(), BRDITEMS_PLOTTER::getFineWidthAdj(), PCB_PLOT_PARAMS::GetPlotMode(), PCB_PLOT_PARAMS::GetPlotViaOnMaskLayer(), PCB_ARC::GetRadius(), PCB_PLOT_PARAMS::GetSketchPadsOnFabLayers(), PCB_PLOT_PARAMS::GetSkipPlotNPTH_Pads(), SHAPE_POLY_SET::InflateWithLinkedHoles(), SHAPE_POLY_SET::IsEmpty(), LAYER_PAD_BK, LAYER_PAD_FR, LAYER_VIAS, LIGHTGRAY, BOARD_DESIGN_SETTINGS::m_MaxError, GBR_METADATA::m_NetlistMetadata, GBR_NETLIST_METADATA::m_NotInNet, BOARD_DESIGN_SETTINGS::m_SolderMaskMargin, SHAPE_POLY_SET::NewOutline(), PCB_PLOT_PARAMS::NO_DRILL_SHAPE, NPTH, SHAPE_POLY_SET::OutlineCount(), OVAL, pad, PCB_ARC_T, PCB_VIA_T, BRDITEMS_PLOTTER::PlotBoardGraphicItems(), BRDITEMS_PLOTTER::PlotDrillMarks(), BRDITEMS_PLOTTER::PlotFilledAreas(), BRDITEMS_PLOTTER::PlotFootprintGraphicItems(), BRDITEMS_PLOTTER::PlotFootprintTextItems(), BRDITEMS_PLOTTER::PlotPad(), SHAPE_POLY_SET::PM_FAST, RECT, ROUNDRECT, GBR_METADATA::SetApertureAttrib(), PLOTTER::SetColor(), BRDITEMS_PLOTTER::SetLayerSet(), GBR_METADATA::SetNetAttribType(), GBR_METADATA::SetNetName(), EDA_ITEM::SetPosition(), SKETCH, PLOTTER::StartBlock(), PLOTTER::ThickArc(), PLOTTER::ThickSegment(), BOARD::Tracks(), TRAPEZOID, UNDEFINED_LAYER, via, WHITE, and BOARD::Zones().

Referenced by PlotOneBoardLayer(), and PlotSolderMaskLayer().

◆ StartPlotBoard()

PLOTTER* StartPlotBoard ( BOARD aBoard,
const 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.

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

Definition at line 1123 of file plot_board_layers.cpp.

1125 {
1126  // Create the plotter driver and set the few plotter specific options
1127  PLOTTER* plotter = nullptr;
1128 
1129  switch( aPlotOpts->GetFormat() )
1130  {
1131  case PLOT_FORMAT::DXF:
1132  DXF_PLOTTER* DXF_plotter;
1133  DXF_plotter = new DXF_PLOTTER();
1134  DXF_plotter->SetUnits( aPlotOpts->GetDXFPlotUnits() );
1135 
1136  plotter = DXF_plotter;
1137  break;
1138 
1139  case PLOT_FORMAT::POST:
1140  PS_PLOTTER* PS_plotter;
1141  PS_plotter = new PS_PLOTTER();
1142  PS_plotter->SetScaleAdjust( aPlotOpts->GetFineScaleAdjustX(),
1143  aPlotOpts->GetFineScaleAdjustY() );
1144  plotter = PS_plotter;
1145  break;
1146 
1147  case PLOT_FORMAT::PDF:
1148  plotter = new PDF_PLOTTER();
1149  break;
1150 
1151  case PLOT_FORMAT::HPGL:
1152  HPGL_PLOTTER* HPGL_plotter;
1153  HPGL_plotter = new HPGL_PLOTTER();
1154 
1155  // HPGL options are a little more convoluted to compute, so they get their own function
1156  ConfigureHPGLPenSizes( HPGL_plotter, aPlotOpts );
1157  plotter = HPGL_plotter;
1158  break;
1159 
1160  case PLOT_FORMAT::GERBER:
1161  plotter = new GERBER_PLOTTER();
1162  break;
1163 
1164  case PLOT_FORMAT::SVG:
1165  plotter = new SVG_PLOTTER();
1166  break;
1167 
1168  default:
1169  wxASSERT( false );
1170  return nullptr;
1171  }
1172 
1174  renderSettings->LoadColors( aPlotOpts->ColorSettings() );
1175  renderSettings->SetDefaultPenWidth( Millimeter2iu( 0.0212 ) ); // Hairline at 1200dpi
1176  plotter->SetRenderSettings( renderSettings );
1177 
1178  // Compute the viewport and set the other options
1179 
1180  // page layout is not mirrored, so temporarily change mirror option for the page layout
1181  PCB_PLOT_PARAMS plotOpts = *aPlotOpts;
1182 
1183  if( plotOpts.GetPlotFrameRef() && plotOpts.GetMirror() )
1184  plotOpts.SetMirror( false );
1185 
1186  initializePlotter( plotter, aBoard, &plotOpts );
1187 
1188  if( plotter->OpenFile( aFullFileName ) )
1189  {
1190  plotter->ClearHeaderLinesList();
1191 
1192  // For the Gerber "file function" attribute, set the layer number
1193  if( plotter->GetPlotterType() == PLOT_FORMAT::GERBER )
1194  {
1195  bool useX2mode = plotOpts.GetUseGerberX2format();
1196 
1197  GERBER_PLOTTER* gbrplotter = static_cast <GERBER_PLOTTER*> ( plotter );
1198  gbrplotter->DisableApertMacros( plotOpts.GetDisableGerberMacros() );
1199  gbrplotter->UseX2format( useX2mode );
1200  gbrplotter->UseX2NetAttributes( plotOpts.GetIncludeGerberNetlistInfo() );
1201 
1202  // Attributes can be added using X2 format or as comment (X1 format)
1203  AddGerberX2Attribute( plotter, aBoard, aLayer, not useX2mode );
1204  }
1205 
1206  plotter->StartPlot();
1207 
1208  // Plot the frame reference if requested
1209  if( aPlotOpts->GetPlotFrameRef() )
1210  {
1211  PlotDrawingSheet( plotter, aBoard->GetProject(), aBoard->GetTitleBlock(),
1212  aBoard->GetPageSettings(), "1", 1, aSheetDesc,
1213  aBoard->GetFileName() );
1214 
1215  if( aPlotOpts->GetMirror() )
1216  initializePlotter( plotter, aBoard, aPlotOpts );
1217  }
1218 
1219  // When plotting a negative board: draw a black rectangle (background for plot board
1220  // in white) and switch the current color to WHITE; note the color inversion is actually
1221  // done in the driver (if supported)
1222  if( aPlotOpts->GetNegative() )
1223  {
1224  EDA_RECT bbox = aBoard->ComputeBoundingBox();
1225  FillNegativeKnockout( plotter, bbox );
1226  }
1227 
1228  return plotter;
1229  }
1230 
1231  delete plotter->RenderSettings();
1232  delete plotter;
1233  return nullptr;
1234 }
const PAGE_INFO & GetPageSettings() const
Definition: board.h:535
virtual void LoadColors(const COLOR_SETTINGS *aSettings) override
Definition: pcb_painter.cpp:90
void UseX2NetAttributes(bool aEnable)
bool GetPlotFrameRef() const
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.
virtual bool OpenFile(const wxString &aFullFilename)
Open or create the plot file aFullFilename.
Definition: plotter.cpp:76
bool GetDisableGerberMacros() const
void SetScaleAdjust(double scaleX, double scaleY)
Set the 'fine' scaling for the postscript engine.
void SetRenderSettings(RENDER_SETTINGS *aSettings)
Definition: plotter.h:155
PROJECT * GetProject() const
Definition: board.h:360
void SetMirror(bool aFlag)
void UseX2format(bool aEnable)
static void ConfigureHPGLPenSizes(HPGL_PLOTTER *aPlotter, const PCB_PLOT_PARAMS *aPlotOpts)
Calculate the effective size of HPGL pens and set them in the plotter object.
void AddGerberX2Attribute(PLOTTER *aPlotter, const BOARD *aBoard, LAYER_NUM aLayer, bool aUseX1CompatibilityMode)
Calculate some X2 attributes as defined in the Gerber file format specification and add them to the g...
Definition: pcbplot.cpp:353
void SetUnits(DXF_UNITS aUnit)
Set the units to use for plotting the DXF file.
static void initializePlotter(PLOTTER *aPlotter, const BOARD *aBoard, const PCB_PLOT_PARAMS *aPlotOpts)
Set up most plot options for plotting a board (especially the viewport) Important thing: page size is...
const wxString & GetFileName() const
Definition: board.h:228
bool GetUseGerberX2format() const
bool GetMirror() const
PCB specific render settings.
Definition: pcb_painter.h:64
PLOT_FORMAT GetFormat() const
virtual PLOT_FORMAT GetPlotterType() const =0
Returns the effective plot engine in use.
bool GetIncludeGerberNetlistInfo() const
Parameters and options when plotting/printing a board.
double GetFineScaleAdjustX() const
void DisableApertMacros(bool aDisable)
Disable Aperture Macro (AM) command, only for broken Gerber Readers.
Base plotter engine class.
Definition: plotter.h:121
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:156
TITLE_BLOCK & GetTitleBlock()
Definition: board.h:541
void PlotDrawingSheet(PLOTTER *plotter, const PROJECT *aProject, const TITLE_BLOCK &aTitleBlock, const PAGE_INFO &aPageInfo, const wxString &aSheetNumber, int aSheetCount, const wxString &aSheetDesc, const wxString &aFilename, COLOR4D aColor, bool aIsFirstPage)
Handle the component boundary box.
Definition: eda_rect.h:42
void ClearHeaderLinesList()
Remove all lines from the list of free lines to print at the beginning of the file.
Definition: plotter.h:191
EDA_RECT ComputeBoundingBox(bool aBoardEdgesOnly=false) const
Calculate the bounding box containing all board items (or board edge segments).
Definition: board.cpp:1104
double GetFineScaleAdjustY() const
COLOR_SETTINGS * ColorSettings() const
DXF_UNITS GetDXFPlotUnits() const
bool GetNegative() const
void SetDefaultPenWidth(int aWidth)
static constexpr int Millimeter2iu(double mm)

References AddGerberX2Attribute(), PLOTTER::ClearHeaderLinesList(), PCB_PLOT_PARAMS::ColorSettings(), BOARD::ComputeBoundingBox(), ConfigureHPGLPenSizes(), GERBER_PLOTTER::DisableApertMacros(), DXF, FillNegativeKnockout(), GERBER, PCB_PLOT_PARAMS::GetDisableGerberMacros(), PCB_PLOT_PARAMS::GetDXFPlotUnits(), 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::GetProject(), BOARD::GetTitleBlock(), PCB_PLOT_PARAMS::GetUseGerberX2format(), HPGL, initializePlotter(), KIGFX::PCB_RENDER_SETTINGS::LoadColors(), Millimeter2iu(), PLOTTER::OpenFile(), PDF, PlotDrawingSheet(), POST, PLOTTER::RenderSettings(), KIGFX::RENDER_SETTINGS::SetDefaultPenWidth(), PCB_PLOT_PARAMS::SetMirror(), PLOTTER::SetRenderSettings(), PSLIKE_PLOTTER::SetScaleAdjust(), DXF_PLOTTER::SetUnits(), PLOTTER::StartPlot(), SVG, GERBER_PLOTTER::UseX2format(), and GERBER_PLOTTER::UseX2NetAttributes().

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