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:57
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:590
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:796
LAYER_T GetLayerType(PCB_LAYER_ID aLayer) const
Return the type of the copper layer given by aLayer.
Definition: board.cpp:396
Definition: layer_ids.h:71
int GetCopperLayerCount() const
Definition: board.cpp:455
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:796
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:71

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 705 of file plot_board_layers.cpp.

707 {
708  BRDITEMS_PLOTTER itemplotter( aPlotter, aBoard, aPlotOpt );
709  itemplotter.SetLayerSet( aLayerMask );
710 
711  SHAPE_POLY_SET outlines;
712 
713  for( LSEQ seq = aLayerMask.Seq( plot_seq, arrayDim( plot_seq ) ); seq; ++seq )
714  {
715  PCB_LAYER_ID layer = *seq;
716 
717  outlines.RemoveAllContours();
718  aBoard->ConvertBrdLayerToPolygonalContours( layer, outlines );
719 
720  outlines.Simplify( SHAPE_POLY_SET::PM_FAST );
721 
722  // Plot outlines
723  std::vector<wxPoint> cornerList;
724 
725  // Now we have one or more basic polygons: plot each polygon
726  for( int ii = 0; ii < outlines.OutlineCount(); ii++ )
727  {
728  for( int kk = 0; kk <= outlines.HoleCount(ii); kk++ )
729  {
730  cornerList.clear();
731  const SHAPE_LINE_CHAIN& path =
732  ( kk == 0 ) ? outlines.COutline( ii ) : outlines.CHole( ii, kk - 1 );
733 
734  aPlotter->PlotPoly( path, FILL_T::NO_FILL );
735  }
736  }
737 
738  // Plot pad holes
740  {
741  int smallDrill = (aPlotOpt.GetDrillMarksType() == PCB_PLOT_PARAMS::SMALL_DRILL_SHAPE)
743 
744  for( FOOTPRINT* footprint : aBoard->Footprints() )
745  {
746  for( PAD* pad : footprint->Pads() )
747  {
748  wxSize hole = pad->GetDrillSize();
749 
750  if( hole.x == 0 || hole.y == 0 )
751  continue;
752 
753  if( hole.x == hole.y )
754  {
755  hole.x = std::min( smallDrill, hole.x );
756  aPlotter->Circle( pad->GetPosition(), hole.x, FILL_T::NO_FILL );
757  }
758  else
759  {
760  // Note: small drill marks have no significance when applied to slots
761  const SHAPE_SEGMENT* seg = pad->GetEffectiveHoleShape();
762  aPlotter->ThickSegment( (wxPoint) seg->GetSeg().A,
763  (wxPoint) seg->GetSeg().B,
764  seg->GetWidth(), SKETCH, nullptr );
765  }
766  }
767  }
768  }
769 
770  // Plot vias holes
771  for( PCB_TRACK* track : aBoard->Tracks() )
772  {
773  const PCB_VIA* via = dyn_cast<const PCB_VIA*>( track );
774 
775  if( via && via->IsOnLayer( layer ) ) // via holes can be not through holes
776  aPlotter->Circle( via->GetPosition(), via->GetDrillValue(), FILL_T::NO_FILL );
777  }
778  }
779 }
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,...
virtual void PlotPoly(const std::vector< wxPoint > &aCornerList, FILL_T aFill, int aWidth=USE_DEFAULT_LINE_WIDTH, void *aData=nullptr)=0
Draw a polygon ( filled or not ).
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:525
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)
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:465
Represent a polyline (an zero-thickness chain of connected line segments).
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
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
virtual void Circle(const wxPoint &pos, int diametre, FILL_T fill, int width=USE_DEFAULT_LINE_WIDTH)=0
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 68 of file plot_board_layers.cpp.

70 {
71  PCB_PLOT_PARAMS plotOpt = aPlotOpt;
72  int soldermask_min_thickness = aBoard->GetDesignSettings().m_SolderMaskMinWidth;
73 
74  // Set a default color and the text mode for this layer
75  aPlotter->SetColor( BLACK );
76  aPlotter->SetTextMode( aPlotOpt.GetTextMode() );
77 
78  // Specify that the contents of the "Edges Pcb" layer are to be plotted in addition to the
79  // contents of the currently specified layer.
80  LSET layer_mask( aLayer );
81 
82  if( !aPlotOpt.GetExcludeEdgeLayer() )
83  layer_mask.set( Edge_Cuts );
84 
85  if( IsCopperLayer( aLayer ) )
86  {
87  // Skip NPTH pads on copper layers ( only if hole size == pad size ):
88  // Drill mark will be plotted if drill mark is SMALL_DRILL_SHAPE or FULL_DRILL_SHAPE
89  if( plotOpt.GetFormat() == PLOT_FORMAT::DXF )
90  {
91  plotOpt.SetSkipPlotNPTH_Pads( false );
92  PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
93  }
94  else
95  {
96  plotOpt.SetSkipPlotNPTH_Pads( true );
97  PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
98  }
99  }
100  else
101  {
102  switch( aLayer )
103  {
104  case B_Mask:
105  case F_Mask:
106  plotOpt.SetSkipPlotNPTH_Pads( false );
107  // Disable plot pad holes
109 
110  // Plot solder mask:
111  if( soldermask_min_thickness == 0 )
112  {
113  if( plotOpt.GetFormat() == PLOT_FORMAT::DXF )
114  PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
115  else
116  PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
117  }
118  else
119  {
120  PlotSolderMaskLayer( aBoard, aPlotter, layer_mask, plotOpt,
121  soldermask_min_thickness );
122  }
123 
124  break;
125 
126  case B_Adhes:
127  case F_Adhes:
128  case B_Paste:
129  case F_Paste:
130  plotOpt.SetSkipPlotNPTH_Pads( false );
131  // Disable plot pad holes
133 
134  if( plotOpt.GetFormat() == PLOT_FORMAT::DXF )
135  PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
136  else
137  PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
138 
139  break;
140 
141  case F_SilkS:
142  case B_SilkS:
143  if( plotOpt.GetFormat() == PLOT_FORMAT::DXF && plotOpt.GetDXFPlotPolygonMode() )
144  // PlotLayerOutlines() is designed only for DXF plotters.
145  // and must not be used for other plot formats
146  PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
147  else
148  PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
149 
150  // Gerber: Subtract soldermask from silkscreen if enabled
151  if( aPlotter->GetPlotterType() == PLOT_FORMAT::GERBER
152  && plotOpt.GetSubtractMaskFromSilk() )
153  {
154  if( aLayer == F_SilkS )
155  layer_mask = LSET( F_Mask );
156  else
157  layer_mask = LSET( B_Mask );
158 
159  // Create the mask to subtract by creating a negative layer polarity
160  aPlotter->SetLayerPolarity( false );
161 
162  // Disable plot pad holes
164 
165  // Plot the mask
166  PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
167  }
168 
169  break;
170 
171  // These layers are plotted like silk screen layers.
172  // Mainly, pads on these layers are not filled.
173  // This is not necessary the best choice.
174  case Dwgs_User:
175  case Cmts_User:
176  case Eco1_User:
177  case Eco2_User:
178  case Edge_Cuts:
179  case Margin:
180  case F_CrtYd:
181  case B_CrtYd:
182  case F_Fab:
183  case B_Fab:
184  plotOpt.SetSkipPlotNPTH_Pads( false );
186 
187  if( plotOpt.GetFormat() == PLOT_FORMAT::DXF && plotOpt.GetDXFPlotPolygonMode() )
188  // PlotLayerOutlines() is designed only for DXF plotters.
189  // and must not be used for other plot formats
190  PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
191  else
192  PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
193 
194  break;
195 
196  default:
197  plotOpt.SetSkipPlotNPTH_Pads( false );
199 
200  if( plotOpt.GetFormat() == PLOT_FORMAT::DXF && plotOpt.GetDXFPlotPolygonMode() )
201  // PlotLayerOutlines() is designed only for DXF plotters.
202  // and must not be used for other plot formats
203  PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
204  else
205  PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
206 
207  break;
208  }
209  }
210 }
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:590
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:504
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:796
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 218 of file plot_board_layers.cpp.

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

1128 {
1129  // Create the plotter driver and set the few plotter specific options
1130  PLOTTER* plotter = nullptr;
1131 
1132  switch( aPlotOpts->GetFormat() )
1133  {
1134  case PLOT_FORMAT::DXF:
1135  DXF_PLOTTER* DXF_plotter;
1136  DXF_plotter = new DXF_PLOTTER();
1137  DXF_plotter->SetUnits( aPlotOpts->GetDXFPlotUnits() );
1138 
1139  plotter = DXF_plotter;
1140  break;
1141 
1142  case PLOT_FORMAT::POST:
1143  PS_PLOTTER* PS_plotter;
1144  PS_plotter = new PS_PLOTTER();
1145  PS_plotter->SetScaleAdjust( aPlotOpts->GetFineScaleAdjustX(),
1146  aPlotOpts->GetFineScaleAdjustY() );
1147  plotter = PS_plotter;
1148  break;
1149 
1150  case PLOT_FORMAT::PDF:
1151  plotter = new PDF_PLOTTER();
1152  break;
1153 
1154  case PLOT_FORMAT::HPGL:
1155  HPGL_PLOTTER* HPGL_plotter;
1156  HPGL_plotter = new HPGL_PLOTTER();
1157 
1158  // HPGL options are a little more convoluted to compute, so they get their own function
1159  ConfigureHPGLPenSizes( HPGL_plotter, aPlotOpts );
1160  plotter = HPGL_plotter;
1161  break;
1162 
1163  case PLOT_FORMAT::GERBER:
1164  plotter = new GERBER_PLOTTER();
1165  break;
1166 
1167  case PLOT_FORMAT::SVG:
1168  plotter = new SVG_PLOTTER();
1169  break;
1170 
1171  default:
1172  wxASSERT( false );
1173  return nullptr;
1174  }
1175 
1177  renderSettings->LoadColors( aPlotOpts->ColorSettings() );
1178  renderSettings->SetDefaultPenWidth( Millimeter2iu( 0.0212 ) ); // Hairline at 1200dpi
1179  plotter->SetRenderSettings( renderSettings );
1180 
1181  // Compute the viewport and set the other options
1182 
1183  // page layout is not mirrored, so temporarily change mirror option for the page layout
1184  PCB_PLOT_PARAMS plotOpts = *aPlotOpts;
1185 
1186  if( plotOpts.GetPlotFrameRef() && plotOpts.GetMirror() )
1187  plotOpts.SetMirror( false );
1188 
1189  initializePlotter( plotter, aBoard, &plotOpts );
1190 
1191  if( plotter->OpenFile( aFullFileName ) )
1192  {
1193  plotter->ClearHeaderLinesList();
1194 
1195  // For the Gerber "file function" attribute, set the layer number
1196  if( plotter->GetPlotterType() == PLOT_FORMAT::GERBER )
1197  {
1198  bool useX2mode = plotOpts.GetUseGerberX2format();
1199 
1200  GERBER_PLOTTER* gbrplotter = static_cast <GERBER_PLOTTER*> ( plotter );
1201  gbrplotter->DisableApertMacros( plotOpts.GetDisableGerberMacros() );
1202  gbrplotter->UseX2format( useX2mode );
1203  gbrplotter->UseX2NetAttributes( plotOpts.GetIncludeGerberNetlistInfo() );
1204 
1205  // Attributes can be added using X2 format or as comment (X1 format)
1206  AddGerberX2Attribute( plotter, aBoard, aLayer, not useX2mode );
1207  }
1208 
1209  plotter->StartPlot();
1210 
1211  // Plot the frame reference if requested
1212  if( aPlotOpts->GetPlotFrameRef() )
1213  {
1214  PlotDrawingSheet( plotter, aBoard->GetProject(), aBoard->GetTitleBlock(),
1215  aBoard->GetPageSettings(), "1", 1, aSheetDesc,
1216  aBoard->GetFileName() );
1217 
1218  if( aPlotOpts->GetMirror() )
1219  initializePlotter( plotter, aBoard, aPlotOpts );
1220  }
1221 
1222  // When plotting a negative board: draw a black rectangle (background for plot board
1223  // in white) and switch the current color to WHITE; note the color inversion is actually
1224  // done in the driver (if supported)
1225  if( aPlotOpts->GetNegative() )
1226  {
1227  EDA_RECT bbox = aBoard->ComputeBoundingBox();
1228  FillNegativeKnockout( plotter, bbox );
1229  }
1230 
1231  return plotter;
1232  }
1233 
1234  delete plotter->RenderSettings();
1235  delete plotter;
1236  return nullptr;
1237 }
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:1082
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().