KiCad PCB EDA Suite
plot_board_layers.cpp
Go to the documentation of this file.
1 
8 /*
9  * This program source code file is part of KiCad, a free EDA CAD application.
10  *
11  * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, you may find one here:
25  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
26  * or you may search the http://www.gnu.org website for the version 2 license,
27  * or you may write to the Free Software Foundation, Inc.,
28  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
29  */
30 
31 
32 #include <fctsys.h>
33 #include <common.h>
34 #include <plot_common.h>
35 #include <base_struct.h>
36 #include <drawtxt.h>
37 #include <trigo.h>
38 #include <wxBasePcbFrame.h>
39 #include <macros.h>
40 
41 #include <class_board.h>
42 #include <class_module.h>
43 #include <class_track.h>
44 #include <class_edge_mod.h>
45 #include <class_pcb_text.h>
46 #include <class_zone.h>
47 #include <class_drawsegment.h>
48 #include <class_mire.h>
49 #include <class_dimension.h>
50 
51 #include <pcbnew.h>
52 #include <pcbplot.h>
53 #include <plot_auxiliary_data.h>
54 
55 // Local
56 /* Plot a solder mask layer.
57  * Solder mask layers have a minimum thickness value and cannot be drawn like standard layers,
58  * unless the minimum thickness is 0.
59  */
60 static void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter,
61  LSET aLayerMask, const PCB_PLOT_PARAMS& aPlotOpt,
62  int aMinThickness );
63 
64 /* Creates the plot for silkscreen layers
65  * Silkscreen layers have specific requirement for pads (not filled) and texts
66  * (with option to remove them from some copper areas (pads...)
67  */
68 void PlotSilkScreen( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask,
69  const PCB_PLOT_PARAMS& aPlotOpt )
70 {
71  BRDITEMS_PLOTTER itemplotter( aPlotter, aBoard, aPlotOpt );
72  itemplotter.SetLayerSet( aLayerMask );
73 
74  // Plot edge layer and graphic items
75  itemplotter.PlotBoardGraphicItems();
76 
77  // Plot footprint outlines :
78  itemplotter.Plot_Edges_Modules();
79 
80  // Plot pads (creates pads outlines, for pads on silkscreen layers)
81  LSET layersmask_plotpads = aLayerMask;
82 
83  // Calculate the mask layers of allowed layers for pads
84 
85  if( !aPlotOpt.GetPlotPadsOnSilkLayer() ) // Do not plot pads on silk screen layers
86  layersmask_plotpads.set( B_SilkS, false ).set( F_SilkS, false );
87 
88  if( layersmask_plotpads.any() )
89  {
90  for( MODULE* Module = aBoard->m_Modules; Module; Module = Module->Next() )
91  {
92  aPlotter->StartBlock( NULL );
93 
94  for( D_PAD* pad = Module->PadsList(); pad; pad = pad->Next() )
95  {
96  // See if the pad is on this layer
97  LSET masklayer = pad->GetLayerSet();
98  if( !( masklayer & layersmask_plotpads ).any() )
99  continue;
100 
102 
103  if( layersmask_plotpads[B_SilkS] )
104  color = aBoard->Colors().GetLayerColor( B_SilkS );
105 
106  if( layersmask_plotpads[F_SilkS] )
107  color = ( color == COLOR4D::BLACK) ? aBoard->Colors().GetLayerColor( F_SilkS ) : color;
108 
109  itemplotter.PlotPad( pad, color, SKETCH );
110  }
111 
112  aPlotter->EndBlock( NULL );
113  }
114  }
115 
116  // Plot footprints fields (ref, value ...)
117  for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
118  {
119  if( ! itemplotter.PlotAllTextsModule( module ) )
120  {
121  wxLogMessage( _( "Your BOARD has a bad layer number for footprint %s" ),
122  GetChars( module->GetReference() ) );
123  }
124  }
125 
126  // Plot filled areas
127  aPlotter->StartBlock( NULL );
128 
129  for( int ii = 0; ii < aBoard->GetAreaCount(); ii++ )
130  {
131  ZONE_CONTAINER* edge_zone = aBoard->GetArea( ii );
132 
133  if( !aLayerMask[ edge_zone->GetLayer() ] )
134  continue;
135 
136  itemplotter.PlotFilledAreas( edge_zone );
137  }
138 
139  aPlotter->EndBlock( NULL );
140 
141  // Plot segments used to fill zone areas (outdated, but here for old boards
142  // compatibility):
143  for( SEGZONE* seg = aBoard->m_Zone; seg; seg = seg->Next() )
144  {
145  if( !aLayerMask[ seg->GetLayer() ] )
146  continue;
147 
148  aPlotter->ThickSegment( seg->GetStart(), seg->GetEnd(), seg->GetWidth(),
149  itemplotter.GetPlotMode(), NULL );
150  }
151 }
152 
153 void PlotOneBoardLayer( BOARD *aBoard, PLOTTER* aPlotter, PCB_LAYER_ID aLayer,
154  const PCB_PLOT_PARAMS& aPlotOpt )
155 {
156  PCB_PLOT_PARAMS plotOpt = aPlotOpt;
157  int soldermask_min_thickness = aBoard->GetDesignSettings().m_SolderMaskMinWidth;
158 
159  // Set a default color and the text mode for this layer
160  aPlotter->SetColor( aPlotOpt.GetColor() );
161  aPlotter->SetTextMode( aPlotOpt.GetTextMode() );
162 
163  // Specify that the contents of the "Edges Pcb" layer are to be plotted
164  // in addition to the contents of the currently specified layer.
165  LSET layer_mask( aLayer );
166 
167  if( !aPlotOpt.GetExcludeEdgeLayer() )
168  layer_mask.set( Edge_Cuts );
169 
170  if( IsCopperLayer( aLayer ) )
171  {
172  // Skip NPTH pads on copper layers ( only if hole size == pad size ):
173  // Drill mark will be plotted,
174  // if drill mark is SMALL_DRILL_SHAPE or FULL_DRILL_SHAPE
175  if( plotOpt.GetFormat() == PLOT_FORMAT_DXF )
176  {
177  plotOpt.SetSkipPlotNPTH_Pads( false );
178  PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
179  }
180  else
181  {
182  plotOpt.SetSkipPlotNPTH_Pads( true );
183  PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
184  }
185  }
186  else
187  {
188  switch( aLayer )
189  {
190  case B_Mask:
191  case F_Mask:
192  plotOpt.SetSkipPlotNPTH_Pads( false );
193  // Disable plot pad holes
195 
196  // Plot solder mask:
197  if( soldermask_min_thickness == 0 )
198  {
199  if( plotOpt.GetFormat() == PLOT_FORMAT_DXF )
200  PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
201  else
202  PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
203  }
204  else
205  PlotSolderMaskLayer( aBoard, aPlotter, layer_mask, plotOpt,
206  soldermask_min_thickness );
207 
208  break;
209 
210  case B_Adhes:
211  case F_Adhes:
212  case B_Paste:
213  case F_Paste:
214  plotOpt.SetSkipPlotNPTH_Pads( false );
215  // Disable plot pad holes
217 
218  if( plotOpt.GetFormat() == PLOT_FORMAT_DXF )
219  PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
220  else
221  PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
222  break;
223 
224  case F_SilkS:
225  case B_SilkS:
226  if( plotOpt.GetFormat() == PLOT_FORMAT_DXF && plotOpt.GetDXFPlotPolygonMode() )
227  // PlotLayerOutlines() is designed only for DXF plotters.
228  // and must not be used for other plot formats
229  PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
230  else
231  PlotSilkScreen( aBoard, aPlotter, layer_mask, plotOpt );
232 
233  // Gerber: Subtract soldermask from silkscreen if enabled
234  if( aPlotter->GetPlotterType() == PLOT_FORMAT_GERBER
235  && plotOpt.GetSubtractMaskFromSilk() )
236  {
237  if( aLayer == F_SilkS )
238  layer_mask = LSET( F_Mask );
239  else
240  layer_mask = LSET( B_Mask );
241 
242  // Create the mask to subtract by creating a negative layer polarity
243  aPlotter->SetLayerPolarity( false );
244 
245  // Disable plot pad holes
247 
248  // Plot the mask
249  PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
250  }
251  break;
252 
253  // These layers are plotted like silk screen layers.
254  // Mainly, pads on these layers are not filled.
255  // This is not necessary the best choice.
256  case Dwgs_User:
257  case Cmts_User:
258  case Eco1_User:
259  case Eco2_User:
260  case Edge_Cuts:
261  case Margin:
262  case F_CrtYd:
263  case B_CrtYd:
264  case F_Fab:
265  case B_Fab:
266  plotOpt.SetSkipPlotNPTH_Pads( false );
268 
269  if( plotOpt.GetFormat() == PLOT_FORMAT_DXF && plotOpt.GetDXFPlotPolygonMode() )
270  // PlotLayerOutlines() is designed only for DXF plotters.
271  // and must not be used for other plot formats
272  PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
273  else
274  PlotSilkScreen( aBoard, aPlotter, layer_mask, plotOpt );
275  break;
276 
277  default:
278  plotOpt.SetSkipPlotNPTH_Pads( false );
280 
281  if( plotOpt.GetFormat() == PLOT_FORMAT_DXF && plotOpt.GetDXFPlotPolygonMode() )
282  // PlotLayerOutlines() is designed only for DXF plotters.
283  // and must not be used for other plot formats
284  PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
285  else
286  PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
287  break;
288  }
289  }
290 }
291 
292 
293 /* Plot a copper layer or mask.
294  * Silk screen layers are not plotted here.
295  */
296 void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter,
297  LSET aLayerMask, const PCB_PLOT_PARAMS& aPlotOpt )
298 {
299  BRDITEMS_PLOTTER itemplotter( aPlotter, aBoard, aPlotOpt );
300 
301  itemplotter.SetLayerSet( aLayerMask );
302 
303  EDA_DRAW_MODE_T plotMode = aPlotOpt.GetPlotMode();
304 
305  // Plot edge layer and graphic items
306  itemplotter.PlotBoardGraphicItems();
307 
308  // Draw footprint shapes without pads (pads will plotted later)
309  // We plot here module texts, but they are usually on silkscreen layer,
310  // so they are not plot here but plot by PlotSilkScreen()
311  // Plot footprints fields (ref, value ...)
312  for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
313  {
314  if( ! itemplotter.PlotAllTextsModule( module ) )
315  {
316  wxLogMessage( _( "Your BOARD has a bad layer number for footprint %s" ),
317  GetChars( module->GetReference() ) );
318  }
319  }
320 
321  for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
322  {
323  for( BOARD_ITEM* item = module->GraphicalItemsList(); item; item = item->Next() )
324  {
325  if( !aLayerMask[ item->GetLayer() ] )
326  continue;
327 
328  switch( item->Type() )
329  {
330  case PCB_MODULE_EDGE_T:
331  itemplotter.Plot_1_EdgeModule( (EDGE_MODULE*) item );
332  break;
333 
334  default:
335  break;
336  }
337  }
338  }
339 
340  // Plot footprint pads
341  for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
342  {
343  aPlotter->StartBlock( NULL );
344 
345  for( D_PAD* pad = module->PadsList(); pad; pad = pad->Next() )
346  {
347  if( (pad->GetLayerSet() & aLayerMask) == 0 )
348  continue;
349 
350  wxSize margin;
351  double width_adj = 0;
352 
353  if( ( aLayerMask & LSET::AllCuMask() ).any() )
354  width_adj = itemplotter.getFineWidthAdj();
355 
356  static const LSET speed( 4, B_Mask, F_Mask, B_Paste, F_Paste );
357 
358  LSET anded = ( speed & aLayerMask );
359 
360  if( anded == LSET( F_Mask ) || anded == LSET( B_Mask ) )
361  {
362  margin.x = margin.y = pad->GetSolderMaskMargin();
363  }
364  else if( anded == LSET( F_Paste ) || anded == LSET( B_Paste ) )
365  {
366  margin = pad->GetSolderPasteMargin();
367  }
368 
369  // Now offset the pad size by margin + width_adj
370  // this is easy for most shapes, but not for a trapezoid
371  wxSize padPlotsSize;
372  wxSize extraSize = margin * 2;
373  extraSize.x += width_adj;
374  extraSize.y += width_adj;
375  wxSize deltaSize = pad->GetDelta(); // has meaning only for trapezoidal pads
376 
377  if( pad->GetShape() == PAD_SHAPE_TRAPEZOID )
378  { // The easy way is to use BuildPadPolygon to calculate
379  // size and delta of the trapezoidal pad after offseting:
380  wxPoint coord[4];
381  pad->BuildPadPolygon( coord, extraSize/2, 0.0 );
382  // Calculate the size and delta from polygon corners coordinates:
383  // coord[0] is the lower left
384  // coord[1] is the upper left
385  // coord[2] is the upper right
386  // coord[3] is the lower right
387 
388  // the size is the distance between middle of segments
389  // (left/right or top/bottom)
390  // size X is the dist between left and right middle points:
391  padPlotsSize.x = ( ( -coord[0].x + coord[3].x ) // the lower segment X length
392  + ( -coord[1].x + coord[2].x ) ) // the upper segment X length
393  / 2; // the Y size is the half sum
394  // size Y is the dist between top and bottom middle points:
395  padPlotsSize.y = ( ( coord[0].y - coord[1].y ) // the left segment Y lenght
396  + ( coord[3].y - coord[2].y ) ) // the right segment Y lenght
397  / 2; // the Y size is the half sum
398 
399  // calculate the delta ( difference of lenght between 2 opposite edges )
400  // The delta.x is the delta along the X axis, therefore the delta of Y lenghts
401  wxSize delta;
402 
403  if( coord[0].y != coord[3].y )
404  delta.x = coord[0].y - coord[3].y;
405  else
406  delta.y = coord[1].x - coord[0].x;
407 
408  pad->SetDelta( delta );
409  }
410  else
411  padPlotsSize = pad->GetSize() + extraSize;
412 
413  // Don't draw a null size item :
414  if( padPlotsSize.x <= 0 || padPlotsSize.y <= 0 )
415  continue;
416 
418 
419  if( pad->GetLayerSet()[B_Cu] )
420  color = aBoard->Colors().GetItemColor( LAYER_PAD_BK );
421 
422  if( pad->GetLayerSet()[F_Cu] )
423  color = color.LegacyMix( aBoard->Colors().GetItemColor( LAYER_PAD_FR ) );
424 
425  // Temporary set the pad size to the required plot size:
426  wxSize tmppadsize = pad->GetSize();
427  pad->SetSize( padPlotsSize );
428 
429  switch( pad->GetShape() )
430  {
431  case PAD_SHAPE_CIRCLE:
432  case PAD_SHAPE_OVAL:
433  if( aPlotOpt.GetSkipPlotNPTH_Pads() &&
434  (pad->GetSize() == pad->GetDrillSize()) &&
435  (pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED) )
436  break;
437 
438  // Fall through:
439  case PAD_SHAPE_TRAPEZOID:
440  case PAD_SHAPE_RECT:
441  case PAD_SHAPE_ROUNDRECT:
442  default:
443  itemplotter.PlotPad( pad, color, plotMode );
444  break;
445  }
446 
447  pad->SetSize( tmppadsize ); // Restore the pad size
448  pad->SetDelta( deltaSize );
449  }
450 
451  aPlotter->EndBlock( NULL );
452  }
453 
454  // Plot vias on copper layers, and if aPlotOpt.GetPlotViaOnMaskLayer() is true,
455  // plot them on solder mask
456 
457  GBR_METADATA gbr_metadata;
458 
459  bool isOnCopperLayer = ( aLayerMask & LSET::AllCuMask() ).any();
460 
461  if( isOnCopperLayer )
462  {
465  }
466 
467  aPlotter->StartBlock( NULL );
468 
469  for( TRACK* track = aBoard->m_Track; track; track = track->Next() )
470  {
471  const VIA* Via = dyn_cast<const VIA*>( track );
472 
473  if( !Via )
474  continue;
475 
476  // vias are not plotted if not on selected layer, but if layer
477  // is SOLDERMASK_LAYER_BACK or SOLDERMASK_LAYER_FRONT,vias are drawn,
478  // only if they are on the corresponding external copper layer
479  LSET via_mask_layer = Via->GetLayerSet();
480 
481  if( aPlotOpt.GetPlotViaOnMaskLayer() )
482  {
483  if( via_mask_layer[B_Cu] )
484  via_mask_layer.set( B_Mask );
485 
486  if( via_mask_layer[F_Cu] )
487  via_mask_layer.set( F_Mask );
488  }
489 
490  if( !( via_mask_layer & aLayerMask ).any() )
491  continue;
492 
493  int via_margin = 0;
494  double width_adj = 0;
495 
496  // If the current layer is a solder mask, use the global mask
497  // clearance for vias
498  if( aLayerMask[B_Mask] || aLayerMask[F_Mask] )
499  via_margin = aBoard->GetDesignSettings().m_SolderMaskMargin;
500 
501  if( ( aLayerMask & LSET::AllCuMask() ).any() )
502  width_adj = itemplotter.getFineWidthAdj();
503 
504  int diameter = Via->GetWidth() + 2 * via_margin + width_adj;
505 
506  // Don't draw a null size item :
507  if( diameter <= 0 )
508  continue;
509 
510  // Some vias can be not connected (no net).
511  // Set the m_NotInNet for these vias to force a empty net name in gerber file
512  gbr_metadata.m_NetlistMetadata.m_NotInNet = Via->GetNetname().IsEmpty();
513 
514  gbr_metadata.SetNetName( Via->GetNetname() );
515 
516  COLOR4D color = aBoard->Colors().GetItemColor( LAYER_VIAS + Via->GetViaType() );
517  // Set plot color (change WHITE to LIGHTGRAY because
518  // the white items are not seen on a white paper or screen
519  aPlotter->SetColor( color != WHITE ? color : LIGHTGRAY);
520  aPlotter->FlashPadCircle( Via->GetStart(), diameter, plotMode, &gbr_metadata );
521  }
522 
523  aPlotter->EndBlock( NULL );
524  aPlotter->StartBlock( NULL );
526 
527  // Plot tracks (not vias) :
528  for( TRACK* track = aBoard->m_Track; track; track = track->Next() )
529  {
530  if( track->Type() == PCB_VIA_T )
531  continue;
532 
533  if( !aLayerMask[track->GetLayer()] )
534  continue;
535 
536  // Some track segments can be not connected (no net).
537  // Set the m_NotInNet for these segments to force a empty net name in gerber file
538  gbr_metadata.m_NetlistMetadata.m_NotInNet = track->GetNetname().IsEmpty();
539 
540  gbr_metadata.SetNetName( track->GetNetname() );
541  int width = track->GetWidth() + itemplotter.getFineWidthAdj();
542  aPlotter->SetColor( itemplotter.getColor( track->GetLayer() ) );
543  aPlotter->ThickSegment( track->GetStart(), track->GetEnd(), width, plotMode, &gbr_metadata );
544  }
545 
546  aPlotter->EndBlock( NULL );
547 
548  // Plot zones (outdated, for old boards compatibility):
549  for( TRACK* track = aBoard->m_Zone; track; track = track->Next() )
550  {
551  if( !aLayerMask[track->GetLayer()] )
552  continue;
553 
554  int width = track->GetWidth() + itemplotter.getFineWidthAdj();
555  aPlotter->SetColor( itemplotter.getColor( track->GetLayer() ) );
556  aPlotter->ThickSegment( track->GetStart(), track->GetEnd(), width, plotMode, NULL );
557  }
558 
559  // Plot filled ares
560  aPlotter->StartBlock( NULL );
561  for( int ii = 0; ii < aBoard->GetAreaCount(); ii++ )
562  {
563  ZONE_CONTAINER* zone = aBoard->GetArea( ii );
564 
565  if( !aLayerMask[zone->GetLayer()] )
566  continue;
567 
568  itemplotter.PlotFilledAreas( zone );
569  }
570  aPlotter->EndBlock( NULL );
571 
572  // Adding drill marks, if required and if the plotter is able to plot them:
574  itemplotter.PlotDrillMarks();
575 }
576 
577 
578 // Seems like we want to plot from back to front?
579 static const PCB_LAYER_ID plot_seq[] = {
580 
581  B_Adhes, // 32
582  F_Adhes,
583  B_Paste,
584  F_Paste,
585  B_SilkS,
586  B_Mask,
587  F_Mask,
588  Dwgs_User,
589  Cmts_User,
590  Eco1_User,
591  Eco2_User,
592  Edge_Cuts,
593  Margin,
594 
595  F_CrtYd, // CrtYd & Body are footprint only
596  B_CrtYd,
597  F_Fab,
598  B_Fab,
599 
600  B_Cu,
601  In30_Cu,
602  In29_Cu,
603  In28_Cu,
604  In27_Cu,
605  In26_Cu,
606  In25_Cu,
607  In24_Cu,
608  In23_Cu,
609  In22_Cu,
610  In21_Cu,
611  In20_Cu,
612  In19_Cu,
613  In18_Cu,
614  In17_Cu,
615  In16_Cu,
616  In15_Cu,
617  In14_Cu,
618  In13_Cu,
619  In12_Cu,
620  In11_Cu,
621  In10_Cu,
622  In9_Cu,
623  In8_Cu,
624  In7_Cu,
625  In6_Cu,
626  In5_Cu,
627  In4_Cu,
628  In3_Cu,
629  In2_Cu,
630  In1_Cu,
631  F_Cu,
632 
633  F_SilkS,
634 };
635 
636 
637 /* Plot outlines of copper, for copper layer
638  */
639 void PlotLayerOutlines( BOARD* aBoard, PLOTTER* aPlotter,
640  LSET aLayerMask, const PCB_PLOT_PARAMS& aPlotOpt )
641 {
642 
643  BRDITEMS_PLOTTER itemplotter( aPlotter, aBoard, aPlotOpt );
644  itemplotter.SetLayerSet( aLayerMask );
645 
646  SHAPE_POLY_SET outlines;
647 
648  for( LSEQ seq = aLayerMask.Seq( plot_seq, DIM( plot_seq ) ); seq; ++seq )
649  {
650  PCB_LAYER_ID layer = *seq;
651 
652  outlines.RemoveAllContours();
653  aBoard->ConvertBrdLayerToPolygonalContours( layer, outlines );
654 
655  outlines.Simplify( SHAPE_POLY_SET::PM_FAST );
656 
657  // Plot outlines
658  std::vector< wxPoint > cornerList;
659 
660  // Now we have one or more basic polygons: plot each polygon
661  for( int ii = 0; ii < outlines.OutlineCount(); ii++ )
662  {
663  for(int kk = 0; kk <= outlines.HoleCount (ii); kk++ )
664  {
665  cornerList.clear();
666  const SHAPE_LINE_CHAIN& path = (kk == 0) ? outlines.COutline( ii ) : outlines.CHole( ii, kk - 1 );
667 
668  for( int jj = 0; jj < path.PointCount(); jj++ )
669  cornerList.push_back( wxPoint( path.CPoint( jj ).x , path.CPoint( jj ).y ) );
670 
671 
672  // Ensure the polygon is closed
673  if( cornerList[0] != cornerList[cornerList.size() - 1] )
674  cornerList.push_back( cornerList[0] );
675 
676  aPlotter->PlotPoly( cornerList, NO_FILL );
677  }
678  }
679 
680  // Plot pad holes
682  {
683  for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
684  {
685  for( D_PAD* pad = module->PadsList(); pad; pad = pad->Next() )
686  {
687  wxSize hole = pad->GetDrillSize();
688 
689  if( hole.x == 0 || hole.y == 0 )
690  continue;
691 
692  if( hole.x == hole.y )
693  aPlotter->Circle( pad->GetPosition(), hole.x, NO_FILL );
694  else
695  {
696  wxPoint drl_start, drl_end;
697  int width;
698  pad->GetOblongDrillGeometry( drl_start, drl_end, width );
699  aPlotter->ThickSegment( pad->GetPosition() + drl_start,
700  pad->GetPosition() + drl_end, width, SKETCH, NULL );
701  }
702  }
703  }
704  }
705 
706  // Plot vias holes
707  for( TRACK* track = aBoard->m_Track; track; track = track->Next() )
708  {
709  const VIA* via = dyn_cast<const VIA*>( track );
710 
711  if( via && via->IsOnLayer( layer ) ) // via holes can be not through holes
712  {
713  aPlotter->Circle( via->GetPosition(), via->GetDrillValue(), NO_FILL );
714  }
715  }
716  }
717 }
718 
719 
720 /* Plot a solder mask layer.
721  * Solder mask layers have a minimum thickness value and cannot be drawn like standard layers,
722  * unless the minimum thickness is 0.
723  * Currently the algo is:
724  * 1 - build all pad shapes as polygons with a size inflated by
725  * mask clearance + (min width solder mask /2)
726  * 2 - Merge shapes
727  * 3 - deflate result by (min width solder mask /2)
728  * 4 - ORing result by all pad shapes as polygons with a size inflated by
729  * mask clearance only (because deflate sometimes creates shape artifacts)
730  * 5 - draw result as polygons
731  *
732  * TODO:
733  * make this calculation only for shapes with clearance near than (min width solder mask)
734  * (using DRC algo)
735  * plot all other shapes by flashing the basing shape
736  * (shapes will be better, and calculations faster)
737  */
738 void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter,
739  LSET aLayerMask, const PCB_PLOT_PARAMS& aPlotOpt,
740  int aMinThickness )
741 {
742  PCB_LAYER_ID layer = aLayerMask[B_Mask] ? B_Mask : F_Mask;
743  int inflate = aMinThickness/2;
744 
745  BRDITEMS_PLOTTER itemplotter( aPlotter, aBoard, aPlotOpt );
746  itemplotter.SetLayerSet( aLayerMask );
747 
748  // Plot edge layer and graphic items
749  // They do not have a solder Mask margin, because they are only graphic items
750  // on this layer (like logos), not actually areas around pads.
751  itemplotter.PlotBoardGraphicItems();
752 
753  for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
754  {
755  for( BOARD_ITEM* item = module->GraphicalItemsList(); item; item = item->Next() )
756  {
757  if( layer != item->GetLayer() )
758  continue;
759 
760  switch( item->Type() )
761  {
762  case PCB_MODULE_EDGE_T:
763  itemplotter.Plot_1_EdgeModule( (EDGE_MODULE*) item );
764  break;
765 
766  default:
767  break;
768  }
769  }
770  }
771 
772  // Build polygons for each pad shape.
773  // the size of the shape on solder mask should be:
774  // size of pad + clearance around the pad.
775  // clearance = solder mask clearance + extra margin
776  // extra margin is half the min width for solder mask
777  // This extra margin is used to merge too close shapes
778  // (distance < aMinThickness), and will be removed when creating
779  // the actual shapes
780  SHAPE_POLY_SET areas; // Contains shapes to plot
781  SHAPE_POLY_SET initialPolys; // Contains exact shapes to plot
782 
783  /* calculates the coeff to compensate radius reduction of holes clearance
784  * due to the segment approx ( 1 /cos( PI/circleToSegmentsCount )
785  */
786  int circleToSegmentsCount = 32;
787  double correction = 1.0 / cos( M_PI / circleToSegmentsCount );
788 
789  // Plot pads
790  for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
791  {
792  // add shapes with exact size
793  module->TransformPadsShapesWithClearanceToPolygon( layer,
794  initialPolys, 0,
795  circleToSegmentsCount, correction );
796  // add shapes inflated by aMinThickness/2
797  module->TransformPadsShapesWithClearanceToPolygon( layer,
798  areas, inflate,
799  circleToSegmentsCount, correction );
800  }
801 
802  // Plot vias on solder masks, if aPlotOpt.GetPlotViaOnMaskLayer() is true,
803  if( aPlotOpt.GetPlotViaOnMaskLayer() )
804  {
805  // The current layer is a solder mask,
806  // use the global mask clearance for vias
807  int via_clearance = aBoard->GetDesignSettings().m_SolderMaskMargin;
808  int via_margin = via_clearance + inflate;
809 
810  for( TRACK* track = aBoard->m_Track; track; track = track->Next() )
811  {
812  const VIA* via = dyn_cast<const VIA*>( track );
813 
814  if( !via )
815  continue;
816 
817  // vias are plotted only if they are on the corresponding
818  // external copper layer
819  LSET via_set = via->GetLayerSet();
820 
821  if( via_set[B_Cu] )
822  via_set.set( B_Mask );
823 
824  if( via_set[F_Cu] )
825  via_set.set( F_Mask );
826 
827  if( !( via_set & aLayerMask ).any() )
828  continue;
829 
830  via->TransformShapeWithClearanceToPolygon( areas, via_margin,
831  circleToSegmentsCount,
832  correction );
833  via->TransformShapeWithClearanceToPolygon( initialPolys, via_clearance,
834  circleToSegmentsCount,
835  correction );
836  }
837  }
838 
839  // Add filled zone areas.
840 #if 0 // Set to 1 if a solder mask margin must be applied to zones on solder mask
841  int zone_margin = aBoard->GetDesignSettings().m_SolderMaskMargin;
842 #else
843  int zone_margin = 0;
844 #endif
845 
846  for( int ii = 0; ii < aBoard->GetAreaCount(); ii++ )
847  {
848  ZONE_CONTAINER* zone = aBoard->GetArea( ii );
849 
850  if( zone->GetLayer() != layer )
851  continue;
852 
854  inflate+zone_margin, false );
856  zone_margin, false );
857  }
858 
859  // To avoid a lot of code, use a ZONE_CONTAINER
860  // to handle and plot polygons, because our polygons look exactly like
861  // filled areas in zones
862  // Note, also this code is not optimized: it creates a lot of copy/duplicate data
863  // However it is not complex, and fast enough for plot purposes (copy/convert data
864  // is only a very small calculation time for these calculations)
865  ZONE_CONTAINER zone( aBoard );
866  zone.SetArcSegmentCount( 32 );
867  zone.SetMinThickness( 0 ); // trace polygons only
868  zone.SetLayer ( layer );
869 
870  areas.BooleanAdd( initialPolys, SHAPE_POLY_SET::PM_FAST );
871  areas.Inflate( -inflate, circleToSegmentsCount );
872 
873  // Combine the current areas to initial areas. This is mandatory because
874  // inflate/deflate transform is not perfect, and we want the initial areas perfectly kept
875  areas.BooleanAdd( initialPolys, SHAPE_POLY_SET::PM_FAST );
877 
878  zone.AddFilledPolysList( areas );
879 
880  itemplotter.PlotFilledAreas( &zone );
881 }
882 
883 
884 
890 static void initializePlotter( PLOTTER *aPlotter, BOARD * aBoard,
891  PCB_PLOT_PARAMS *aPlotOpts )
892 {
893  PAGE_INFO pageA4( wxT( "A4" ) );
894  const PAGE_INFO& pageInfo = aBoard->GetPageSettings();
895  const PAGE_INFO* sheet_info;
896  double paperscale; // Page-to-paper ratio
897  wxSize paperSizeIU;
898  wxSize pageSizeIU( pageInfo.GetSizeIU() );
899  bool autocenter = false;
900 
901  /* Special options: to fit the sheet to an A4 sheet replace
902  the paper size. However there is a difference between
903  the autoscale and the a4paper option:
904  - Autoscale fits the board to the paper size
905  - A4paper fits the original paper size to an A4 sheet
906  - Both of them fit the board to an A4 sheet
907  */
908  if( aPlotOpts->GetA4Output() ) // Fit paper to A4
909  {
910  sheet_info = &pageA4;
911  paperSizeIU = pageA4.GetSizeIU();
912  paperscale = (double) paperSizeIU.x / pageSizeIU.x;
913  autocenter = true;
914  }
915  else
916  {
917  sheet_info = &pageInfo;
918  paperSizeIU = pageSizeIU;
919  paperscale = 1;
920 
921  // Need autocentering only if scale is not 1:1
922  autocenter = (aPlotOpts->GetScale() != 1.0);
923  }
924 
925  EDA_RECT bbox = aBoard->ComputeBoundingBox();
926  wxPoint boardCenter = bbox.Centre();
927  wxSize boardSize = bbox.GetSize();
928 
929  double compound_scale;
930 
931  /* Fit to 80% of the page if asked; it could be that the board is empty,
932  * in this case regress to 1:1 scale */
933  if( aPlotOpts->GetAutoScale() && boardSize.x > 0 && boardSize.y > 0 )
934  {
935  double xscale = (paperSizeIU.x * 0.8) / boardSize.x;
936  double yscale = (paperSizeIU.y * 0.8) / boardSize.y;
937 
938  compound_scale = std::min( xscale, yscale ) * paperscale;
939  }
940  else
941  compound_scale = aPlotOpts->GetScale() * paperscale;
942 
943 
944  /* For the plot offset we have to keep in mind the auxiliary origin
945  too: if autoscaling is off we check that plot option (i.e. autoscaling
946  overrides auxiliary origin) */
947  wxPoint offset( 0, 0);
948 
949  if( autocenter )
950  {
951  offset.x = KiROUND( boardCenter.x - ( paperSizeIU.x / 2.0 ) / compound_scale );
952  offset.y = KiROUND( boardCenter.y - ( paperSizeIU.y / 2.0 ) / compound_scale );
953  }
954  else
955  {
956  if( aPlotOpts->GetUseAuxOrigin() )
957  offset = aBoard->GetAuxOrigin();
958  }
959 
960  /* Configure the plotter object with all the stuff computed and
961  most of that taken from the options */
962  aPlotter->SetPageSettings( *sheet_info );
963 
964  aPlotter->SetViewport( offset, IU_PER_MILS/10, compound_scale,
965  aPlotOpts->GetMirror() );
966  // has meaning only for gerber plotter. Must be called only after SetViewport
967  aPlotter->SetGerberCoordinatesFormat( aPlotOpts->GetGerberPrecision() );
968 
969  aPlotter->SetDefaultLineWidth( aPlotOpts->GetLineWidth() );
970  aPlotter->SetCreator( wxT( "PCBNEW" ) );
971  aPlotter->SetColorMode( false ); // default is plot in Black and White.
972  aPlotter->SetTextMode( aPlotOpts->GetTextMode() );
973 }
974 
977 static void FillNegativeKnockout( PLOTTER *aPlotter, const EDA_RECT &aBbbox )
978 {
979  const int margin = 5 * IU_PER_MM; // Add a 5 mm margin around the board
980  aPlotter->SetNegative( true );
981  aPlotter->SetColor( WHITE ); // Which will be plotted as black
982  EDA_RECT area = aBbbox;
983  area.Inflate( margin );
984  aPlotter->Rect( area.GetOrigin(), area.GetEnd(), FILLED_SHAPE );
985  aPlotter->SetColor( BLACK );
986 }
987 
990 static void ConfigureHPGLPenSizes( HPGL_PLOTTER *aPlotter,
991  PCB_PLOT_PARAMS *aPlotOpts )
992 {
993  /* Compute pen_dim (the value is given in mils) in pcb units,
994  with plot scale (if Scale is 2, pen diameter value is always m_HPGLPenDiam
995  so apparent pen diam is actually pen diam / Scale */
996  int pen_diam = KiROUND( aPlotOpts->GetHPGLPenDiameter() * IU_PER_MILS /
997  aPlotOpts->GetScale() );
998 
999  // Set HPGL-specific options and start
1000  aPlotter->SetPenSpeed( aPlotOpts->GetHPGLPenSpeed() );
1001  aPlotter->SetPenNumber( aPlotOpts->GetHPGLPenNum() );
1002  aPlotter->SetPenDiameter( pen_diam );
1003 }
1004 
1011  int aLayer,
1012  const wxString& aFullFileName,
1013  const wxString& aSheetDesc )
1014 {
1015  // Create the plotter driver and set the few plotter specific
1016  // options
1017  PLOTTER* plotter = NULL;
1018 
1019  switch( aPlotOpts->GetFormat() )
1020  {
1021  case PLOT_FORMAT_DXF:
1022  plotter = new DXF_PLOTTER();
1023  break;
1024 
1025  case PLOT_FORMAT_POST:
1026  PS_PLOTTER* PS_plotter;
1027  PS_plotter = new PS_PLOTTER();
1028  PS_plotter->SetScaleAdjust( aPlotOpts->GetFineScaleAdjustX(),
1029  aPlotOpts->GetFineScaleAdjustY() );
1030  plotter = PS_plotter;
1031  break;
1032 
1033  case PLOT_FORMAT_PDF:
1034  plotter = new PDF_PLOTTER();
1035  break;
1036 
1037  case PLOT_FORMAT_HPGL:
1038  HPGL_PLOTTER* HPGL_plotter;
1039  HPGL_plotter = new HPGL_PLOTTER();
1040 
1041  /* HPGL options are a little more convoluted to compute, so
1042  they're split in an other function */
1043  ConfigureHPGLPenSizes( HPGL_plotter, aPlotOpts );
1044  plotter = HPGL_plotter;
1045  break;
1046 
1047  case PLOT_FORMAT_GERBER:
1048  plotter = new GERBER_PLOTTER();
1049  break;
1050 
1051  case PLOT_FORMAT_SVG:
1052  plotter = new SVG_PLOTTER();
1053  break;
1054 
1055  default:
1056  wxASSERT( false );
1057  return NULL;
1058  }
1059 
1060  // Compute the viewport and set the other options
1061 
1062  // page layout is not mirrored, so temporary change mirror option
1063  // just to plot the page layout
1064  PCB_PLOT_PARAMS plotOpts = *aPlotOpts;
1065 
1066  if( plotOpts.GetPlotFrameRef() && plotOpts.GetMirror() )
1067  plotOpts.SetMirror( false );
1068 
1069  initializePlotter( plotter, aBoard, &plotOpts );
1070 
1071  if( plotter->OpenFile( aFullFileName ) )
1072  {
1073  plotter->ClearHeaderLinesList();
1074 
1075  // For the Gerber "file function" attribute, set the layer number
1076  if( plotter->GetPlotterType() == PLOT_FORMAT_GERBER )
1077  {
1078  bool useX2mode = plotOpts.GetUseGerberAttributes();
1079 
1080  if( useX2mode )
1081  {
1082  AddGerberX2Attribute( plotter, aBoard, aLayer, false );
1083  GERBER_PLOTTER* gbrplotter = static_cast <GERBER_PLOTTER*> ( plotter );
1084  gbrplotter->UseX2Attributes( true );
1085  gbrplotter->UseX2NetAttributes( plotOpts.GetIncludeGerberNetlistInfo() );
1086  }
1087  else
1088  {
1089  AddGerberX2Attribute( plotter, aBoard, aLayer, true );
1090  }
1091  }
1092 
1093  plotter->StartPlot();
1094 
1095  // Plot the frame reference if requested
1096  if( aPlotOpts->GetPlotFrameRef() )
1097  {
1098  PlotWorkSheet( plotter, aBoard->GetTitleBlock(),
1099  aBoard->GetPageSettings(),
1100  1, 1, // Only one page
1101  aSheetDesc, aBoard->GetFileName() );
1102 
1103  if( aPlotOpts->GetMirror() )
1104  initializePlotter( plotter, aBoard, aPlotOpts );
1105  }
1106 
1107  /* When plotting a negative board: draw a black rectangle
1108  * (background for plot board in white) and switch the current
1109  * color to WHITE; note the color inversion is actually done
1110  * in the driver (if supported) */
1111  if( aPlotOpts->GetNegative() )
1112  {
1113  EDA_RECT bbox = aBoard->ComputeBoundingBox();
1114  FillNegativeKnockout( plotter, bbox );
1115  }
1116 
1117  return plotter;
1118  }
1119 
1120  delete plotter;
1121  return NULL;
1122 }
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:639
#define DIM(x)
of elements in an array
Definition: macros.h:98
int m_SolderMaskMargin
Solder mask margin.
bool GetMirror() const
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:78
bool GetSubtractMaskFromSilk() const
bool GetAutoScale() const
int GetHPGLPenDiameter() const
virtual void SetCreator(const wxString &aCreator)
Definition: plot_common.h:151
double GetScale() const
PCB_TARGET class definition.
void UseX2NetAttributes(bool aEnable)
Definition: plot_common.h:1112
virtual void EndBlock(void *aData)
calling this function allows to define the end of a group of drawing items for instance in SVG or Ger...
Definition: plot_common.h:433
TEXTE_PCB class definition.
virtual LSET GetLayerSet() const override
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
static int KiROUND(double v)
KiROUND rounds a floating point number to an int using "round halfway cases away from zero"...
Definition: common.h:107
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:65
static void initializePlotter(PLOTTER *aPlotter, BOARD *aBoard, PCB_PLOT_PARAMS *aPlotOpts)
Set up most plot options for plotting a board (especially the viewport) Important thing: page size is...
void BooleanAdd(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Performs boolean polyset union For aFastMode meaning, see function booleanOp
virtual bool StartPlot()=0
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class...
virtual void SetColor(COLOR4D color)=0
static void FillNegativeKnockout(PLOTTER *aPlotter, const EDA_RECT &aBbbox)
Prefill in black an area a little bigger than the board to prepare for the negative plot...
bool GetUseGerberAttributes() const
int PointCount() const
Function PointCount()
EDA_RECT ComputeBoundingBox(bool aBoardEdgesOnly=false) const
Function ComputeBoundingBox calculates the bounding box containing all board items (or board edge seg...
void PlotPad(D_PAD *aPad, COLOR4D aColor, EDA_DRAW_MODE_T aPlotMode)
Plot a pad.
a class to handle special data during plot.
virtual bool OpenFile(const wxString &aFullFilename)
Open or create the plot file aFullFilename.
void SetNetAttribType(int aNetAttribType)
Class BOARD to handle a board.
void SetScaleAdjust(double scaleX, double scaleY)
Set the 'fine' scaling for the postscript engine.
Definition: plot_common.h:661
virtual void SetLayerPolarity(bool aPositive)
Function SetLayerPolarity sets current Gerber layer polarity to positive or negative by writing %LPD*...
Definition: plot_common.h:398
static const PCB_LAYER_ID plot_seq[]
void PlotStandardLayer(BOARD *aBoard, PLOTTER *aPlotter, LSET aLayerMask, const PCB_PLOT_PARAMS &aPlotOpt)
Function PlotStandardLayer plot copper or technical layers.
MODULE * Next() const
Definition: class_module.h:100
void PlotSilkScreen(BOARD *aBoard, PLOTTER *aPlotter, LSET aLayerMask, const PCB_PLOT_PARAMS &aPlotOpt)
Function PlotSilkScreen plot silkscreen layers which have specific requirements, mainly for pads...
int HoleCount(int aOutline) const
Returns the number of holes in a given outline
void PlotDrillMarks()
Function PlotDrillMarks Draw a drill mark for pads and vias.
void SetMirror(bool aFlag)
virtual void SetPenDiameter(double diameter)
virtual void StartBlock(void *aData)
calling this function allows to define the beginning of a group of drawing items, for instance in SVG...
Definition: plot_common.h:424
bool PlotAllTextsModule(MODULE *aModule)
Classes to handle copper zones.
DLIST< SEGZONE > m_Zone
Definition: class_board.h:247
void SetArcSegmentCount(int aArcSegCount)
Definition: class_zone.h:197
void AddGerberX2Attribute(PLOTTER *aPlotter, const BOARD *aBoard, LAYER_NUM aLayer, bool aUseX1CompatibilityMode)
Calculates some X2 attributes, as defined in the Gerber file format specification and add them to the...
Definition: pcbplot.cpp:466
const SHAPE_LINE_CHAIN & CHole(int aOutline, int aHole) const
bool GetUseAuxOrigin() const
int OutlineCount() const
Returns the number of outlines in the set
void SetDrillMarksType(DrillMarksType aVal)
virtual void PlotPoly(const std::vector< wxPoint > &aCornerList, FILL_T aFill, int aWidth=USE_DEFAULT_LINE_WIDTH, void *aData=NULL)=0
Function PlotPoly.
virtual void SetPageSettings(const PAGE_INFO &aPageSettings)
void AddFilledPolysList(SHAPE_POLY_SET &aPolysList)
Function AddFilledPolysList sets the list of filled polygons.
Definition: class_zone.h:591
smd pads, back layer
void TransformOutlinesShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, int aMinClearanceValue, bool aUseNetClearance)
Function TransformOutlinesShapeWithClearanceToPolygon Convert the outlines shape to a polygon with no...
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:106
static const int delta[8][2]
Definition: solve.cpp:112
Casted dyn_cast(From aObject)
Function dyn_cast()
Definition: typeinfo.h:73
double GetFineScaleAdjustX() const
virtual void SetGerberCoordinatesFormat(int aResolution, bool aUseInches=false)
Definition: plot_common.h:412
void PlotWorkSheet(PLOTTER *plotter, const TITLE_BLOCK &aTitleBlock, const PAGE_INFO &aPageInfo, int aSheetNumber, int aNumberOfSheets, const wxString &aSheetDesc, const wxString &aFilename)
Functions relatives to tracks, vias and segments used to fill zones.
This file contains miscellaneous commonly used macros and functions.
bool GetA4Output() const
void PlotFilledAreas(ZONE_CONTAINER *aZone)
SEGZONE * Next() const
Definition: class_track.h:358
bool GetExcludeEdgeLayer() const
Board plot function definition file.
static void PlotSolderMaskLayer(BOARD *aBoard, PLOTTER *aPlotter, LSET aLayerMask, const PCB_PLOT_PARAMS &aPlotOpt, int aMinThickness)
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Function Seq returns an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:337
BOARD_ITEM * Next() const
COLOR4D GetItemColor(int aItemIdx) const
Function GetItemColor.
const wxPoint & GetOrigin() const
DIMENSION class definition.
virtual void FlashPadCircle(const wxPoint &aPadPos, int aDiameter, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadCircle
void PlotLayerOutlines(BOARD *aBoard, PLOTTER *aPlotter, LSET aLayerMask, const PCB_PLOT_PARAMS &aPlotOpt)
Function PlotLayerOutlines plot copper outline of a copper layer.
DrillMarksType GetDrillMarksType() const
PCB_LAYER_ID
A quick note on layer IDs:
bool GetIncludeGerberNetlistInfo() const
Class LSET is a set of PCB_LAYER_IDs.
Classes used in Pcbnew, CvPcb and GerbView.
void SetLayerSet(LSET aLayerMask)
Definition: pcbplot.h:104
void Inflate(int aFactor, int aCircleSegmentsCount)
Performs outline inflation/deflation, using round corners.
int GetLineWidth() const
VIATYPE_T GetViaType() const
Definition: class_track.h:439
void PlotOneBoardLayer(BOARD *aBoard, PLOTTER *aPlotter, PCB_LAYER_ID aLayer, const PCB_PLOT_PARAMS &aPlotOpt)
Function PlotOneBoardLayer main function to plot one copper or technical layer.
int GetHPGLPenNum() const
const wxString & GetFileName() const
Definition: class_board.h:234
Class SHAPE_POLY_SET.
EDA_DRAW_MODE_T
Definition: eda_text.h:62
const COLORS_DESIGN_SETTINGS & Colors() const
Function GetColorSettings.
Definition: class_board.h:563
PlotTextMode GetTextMode() const
Class PAGE_INFO describes the page size and margins of a paper page on which to eventually print or p...
void PlotBoardGraphicItems()
plot items like text and graphics, but not tracks and modules
virtual void SetTextMode(PlotTextMode mode)
Change the current text mode.
Definition: plot_common.h:407
const wxPoint & GetStart() const
Definition: class_track.h:121
virtual void SetPenSpeed(int speed)
Definition: plot_common.h:583
void Plot_1_EdgeModule(EDGE_MODULE *aEdge)
D_PAD * Next() const
Definition: class_pad.h:145
void SetSkipPlotNPTH_Pads(bool aSkip)
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:532
void ConvertBrdLayerToPolygonalContours(PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aOutlines)
Function ConvertBrdLayerToPolygonalContours Build a set of polygons which are the outlines of copper ...
bool GetPlotViaOnMaskLayer() const
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
Common plot library Plot settings, and plotting engines (Postscript, Gerber, HPGL and DXF) ...
void Simplify(POLYGON_MODE aFastMode)
Simplifies the polyset (merges overlapping polys, eliminates degeneracy/self-intersections) For aFast...
int GetAreaCount() const
Function GetAreaCount.
Definition: class_board.h:1011
static void ConfigureHPGLPenSizes(HPGL_PLOTTER *aPlotter, PCB_PLOT_PARAMS *aPlotOpts)
Calculate the effective size of HPGL pens and set them in the plotter object.
wxPoint Centre() const
PlotFormat GetFormat() const
Class PCB_PLOT_PARAMS handles plot parameters and options when plotting/printing a board...
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, int aClearanceValue, int aCircleToSegmentsCount, double aCorrectionFactor) const
Function TransformShapeWithClearanceToPolygon Convert the track shape to a closed polygon Used in fil...
PLOTTER * StartPlotBoard(BOARD *aBoard, PCB_PLOT_PARAMS *aPlotOpts, int aLayer, const wxString &aFullFileName, const wxString &aSheetDesc)
Open a new plotfile using the options (and especially the format) specified in the options and prepar...
void Fracture(POLYGON_MODE aFastMode)
Converts a set of polygons with holes to a singe outline with "slits"/"fractures" connecting the oute...
Class LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
const PAGE_INFO & GetPageSettings() const
Definition: class_board.h:547
COLOR4D GetColor() const
virtual void SetViewport(const wxPoint &aOffset, double aIusPerDecimil, double aScale, bool aMirror)=0
Set the plot offset and scaling for the current plot.
aperture used for connected items like tracks (not vias)
const wxPoint GetEnd() const
bool GetDXFPlotPolygonMode() const
virtual void SetDefaultLineWidth(int width)=0
Set the default line width.
const wxPoint & GetAuxOrigin() const
Definition: class_board.h:343
void SetNetName(const wxString &aNetname)
Base plotter engine class.
Definition: plot_common.h:86
PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
bool GetSkipPlotNPTH_Pads() const
TRACK * Next() const
Definition: class_track.h:98
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
smd pads, front layer
TITLE_BLOCK & GetTitleBlock()
Definition: class_board.h:553
const wxString & GetNetname() const
Function GetNetname.
ZONE_CONTAINER * GetArea(int index) const
Function GetArea returns the Area (Zone Container) at a given index.
Definition: class_board.h:982
Class to handle a graphic segment.
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:169
DLIST< MODULE > m_Modules
Definition: class_board.h:245
Class SHAPE_LINE_CHAIN.
bool GetNegative() const
int GetWidth() const
Definition: class_track.h:115
virtual PlotFormat GetPlotterType() const =0
Returns the effective plot engine in use.
virtual void ThickSegment(const wxPoint &start, const wxPoint &end, int width, EDA_DRAW_MODE_T tracemode, void *aData)
bool GetPlotFrameRef() const
virtual void SetPenNumber(int number)
Definition: plot_common.h:588
void RemoveAllContours()
Removes all outlines & holes (clears) the polygon set.
int GetHPGLPenSpeed() const
EDA_DRAW_MODE_T GetPlotMode() const
Class EDA_RECT handles the component boundary box.
bool GetPlotPadsOnSilkLayer() const
The common library.
virtual void Rect(const wxPoint &p1, const wxPoint &p2, FILL_T fill, int width=USE_DEFAULT_LINE_WIDTH)=0
COLOR4D GetLayerColor(LAYER_NUM aLayer) const
Function GetLayerColor.
const wxPoint & GetPosition() const override
Definition: class_track.h:411
void ClearHeaderLinesList()
Function ClearHeaderLinesList remove all lines from the list of free lines to print at the beginning ...
Definition: plot_common.h:175
Definition: colors.h:49
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
This file is part of the common libary.
void SetApertureAttrib(GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB aApertAttribute)
bool m_NotInNet
true if a pad of a footprint cannot be connected (for instance a mechanical NPTH, ot a not named pad)...
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:108
int getFineWidthAdj()
Definition: pcbplot.h:95
DLIST< TRACK > m_Track
Definition: class_board.h:246
GBR_NETLIST_METADATA m_NetlistMetadata
a item to handle object attribute:
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Function IsOnLayer tests to see if this object is on the given layer.
Module description (excepted pads)
Definition: colors.h:45
Basic classes for most KiCad items.
EDGE_MODULE class definition.
void SetMinThickness(int aMinThickness)
Definition: class_zone.h:210
const wxSize & GetSize() const
const VECTOR2I & CPoint(int aIndex) const
Function CPoint()
print info associated to a net (TO.N attribute)
void UseX2Attributes(bool aEnable)
Definition: plot_common.h:1111
COLOR4D getColor(LAYER_NUM aLayer)
Function getColor.
virtual void SetNegative(bool _negative)
Definition: plot_common.h:111
virtual void Circle(const wxPoint &pos, int diametre, FILL_T fill, int width=USE_DEFAULT_LINE_WIDTH)=0
virtual void SetColorMode(bool _color_mode)
Definition: plot_common.h:116
double GetFineScaleAdjustY() const
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
int m_SolderMaskMinWidth
Solder mask min width.
#define min(a, b)
Definition: auxiliary.h:85
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
int GetGerberPrecision() const