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