KiCad PCB EDA Suite
plot_brditems_plotter.cpp
Go to the documentation of this file.
1 
7 /*
8  * This program source code file is part of KiCad, a free EDA CAD application.
9  *
10  * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, you may find one here:
24  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
25  * or you may search the http://www.gnu.org website for the version 2 license,
26  * or you may write to the Free Software Foundation, Inc.,
27  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
28  */
29 
30 #include <fctsys.h>
31 #include <common.h>
32 #include <plotter.h>
33 #include <base_struct.h>
34 #include <draw_graphic_text.h>
35 #include <trigo.h>
36 #include <macros.h>
37 #include <pcb_base_frame.h>
38 
39 #include <class_board.h>
40 #include <class_module.h>
41 #include <class_track.h>
42 #include <class_edge_mod.h>
43 #include <class_pcb_text.h>
44 #include <class_zone.h>
45 #include <class_drawsegment.h>
46 #include <class_pcb_target.h>
47 #include <class_dimension.h>
48 
49 #include <pcbnew.h>
50 #include <pcbplot.h>
51 #include <gbr_metadata.h>
52 
53 /* class BRDITEMS_PLOTTER is a helper class to plot board items
54  * and a group of board items
55  */
56 
58 {
59  COLOR4D color = m_board->Colors().GetLayerColor( aLayer );
60 
61  // A hack to avoid plotting ahite itmen in white color, expecting the paper
62  // is also white: use a non white color:
63  if( color == COLOR4D::WHITE )
64  color = COLOR4D( LIGHTGRAY );
65 
66  return color;
67 }
68 
69 
70 void BRDITEMS_PLOTTER::PlotPad( D_PAD* aPad, COLOR4D aColor, EDA_DRAW_MODE_T aPlotMode )
71 {
72  wxPoint shape_pos = aPad->ShapePos();
73  GBR_METADATA gbr_metadata;
74 
75  bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
76  bool isOnExternalCopperLayer = ( m_layerMask & LSET::ExternalCuMask() ).any();
77  bool isPadOnBoardTechLayers = ( aPad->GetLayerSet() & LSET::AllBoardTechMask() ).any();
78 
79  gbr_metadata.SetCmpReference( aPad->GetParent()->GetReference() );
80 
81  if( isOnCopperLayer )
82  {
83  gbr_metadata.SetNetAttribType( GBR_NETINFO_ALL );
84  gbr_metadata.SetCopper( true );
85 
86  if( isOnExternalCopperLayer )
87  gbr_metadata.SetPadName( aPad->GetName() );
88 
89  gbr_metadata.SetNetName( aPad->GetNetname() );
90 
91  // Some pads are mechanical pads ( through hole or smd )
92  // when this is the case, they have no pad name and/or are not plated.
93  // In this case gerber files have slightly different attributes.
95  aPad->GetName().IsEmpty() )
96  gbr_metadata.m_NetlistMetadata.m_NotInNet = true;
97 
98  if( !isOnExternalCopperLayer || !isPadOnBoardTechLayers )
99  {
100  // On internal layers one cannot use the GBR_NETLIST_METADATA::GBR_INFO_FLASHED_PAD
101  // attribute when the component is on an external layer (most of the case)
102  // Also, if a SMD pad is not on a tech layer (masks) use also net+cmp attribute, because
103  // it is not really a pad (can be a "pad", actually a node in a virtual component)
106 
107  if( !isPadOnBoardTechLayers )
108  // such a pad is not soldered and is not a connecting point.
109  // Just set aperture attribute as conductor
110  // If it is a through hole pad, it will be adjusted later
112 
113  switch( aPad->GetAttribute() )
114  {
115  case PAD_ATTRIB_HOLE_NOT_PLATED: // Mechanical pad through hole
117  break;
118 
119  case PAD_ATTRIB_STANDARD : // Pad through hole, a hole is also expected
121  break;
122 
123  default:
124  break;
125  }
126  }
127  else // Some attributes are reserved to the external copper layers
128  {
129  switch( aPad->GetAttribute() )
130  {
131  case PAD_ATTRIB_HOLE_NOT_PLATED: // Mechanical pad through hole
133  break;
134 
135  case PAD_ATTRIB_STANDARD : // Pad through hole, a hole is also expected
137  break;
138 
139  case PAD_ATTRIB_CONN: // Connector pads have no solder paste.
141  break;
142 
143  case PAD_ATTRIB_SMD: // SMD pads (One external copper layer only) with solder paste
144  if( aPad->GetShape() == PAD_SHAPE_CIRCLE ) // perhaps a BGA pad
146  else
148  break;
149  }
150  }
151 
154  }
155  else
156  {
158  }
159 
160  // Set plot color (change WHITE to LIGHTGRAY because
161  // the white items are not seen on a white paper or screen
162  m_plotter->SetColor( aColor != WHITE ? aColor : LIGHTGRAY);
163 
164  switch( aPad->GetShape() )
165  {
166  case PAD_SHAPE_CIRCLE:
167  m_plotter->FlashPadCircle( shape_pos, aPad->GetSize().x, aPlotMode, &gbr_metadata );
168  break;
169 
170  case PAD_SHAPE_OVAL:
171  m_plotter->FlashPadOval( shape_pos, aPad->GetSize(),
172  aPad->GetOrientation(), aPlotMode, &gbr_metadata );
173  break;
174 
175  case PAD_SHAPE_TRAPEZOID:
176  {
177  wxPoint coord[4];
178  aPad->BuildPadPolygon( coord, wxSize(0,0), 0 );
179  m_plotter->FlashPadTrapez( shape_pos, coord,
180  aPad->GetOrientation(), aPlotMode, &gbr_metadata );
181  }
182  break;
183 
184  case PAD_SHAPE_ROUNDRECT:
185  m_plotter->FlashPadRoundRect( shape_pos, aPad->GetSize(), aPad->GetRoundRectCornerRadius(),
186  aPad->GetOrientation(), aPlotMode, &gbr_metadata );
187  break;
188 
189  case PAD_SHAPE_CUSTOM:
190  {
191  SHAPE_POLY_SET polygons;
192  aPad->MergePrimitivesAsPolygon(&polygons, 64 );
193 
194  if( polygons.OutlineCount() == 0 )
195  break;
196 
197  aPad->CustomShapeAsPolygonToBoardPosition( &polygons, shape_pos, aPad->GetOrientation() );
198  m_plotter->FlashPadCustom( shape_pos, aPad->GetSize(), &polygons, aPlotMode, &gbr_metadata );
199  }
200  break;
201 
202  case PAD_SHAPE_RECT:
203  default:
204  m_plotter->FlashPadRect( shape_pos, aPad->GetSize(),
205  aPad->GetOrientation(), aPlotMode, &gbr_metadata );
206  break;
207  }
208 }
209 
210 
212 {
213  TEXTE_MODULE* textModule = &aModule->Reference();
214  LAYER_NUM textLayer = textModule->GetLayer();
215 
216  if( GetPlotReference() && m_layerMask[textLayer]
217  && ( textModule->IsVisible() || GetPlotInvisibleText() ) )
218  {
219  PlotTextModule( textModule, getColor( textLayer ) );
220  }
221 
222  textModule = &aModule->Value();
223  textLayer = textModule->GetLayer();
224 
225  if( GetPlotValue() && m_layerMask[textLayer]
226  && ( textModule->IsVisible() || GetPlotInvisibleText() ) )
227  {
228  PlotTextModule( textModule, getColor( textLayer ) );
229  }
230 
231  for( BOARD_ITEM* item = aModule->GraphicalItemsList().GetFirst(); item; item = item->Next() )
232  {
233  textModule = dyn_cast<TEXTE_MODULE*>( item );
234 
235  if( !textModule )
236  continue;
237 
238  if( !textModule->IsVisible() )
239  continue;
240 
241  textLayer = textModule->GetLayer();
242 
243  if( textLayer >= PCB_LAYER_ID_COUNT )
244  return false;
245 
246  if( !m_layerMask[textLayer] )
247  continue;
248 
249  if( textModule->GetText() == wxT( "%R" ) && !GetPlotReference() )
250  continue;
251 
252  if( textModule->GetText() == wxT( "%V" ) && !GetPlotValue() )
253  continue;
254 
255  PlotTextModule( textModule, getColor( textLayer ) );
256  }
257 
258  return true;
259 }
260 
261 
262 // plot items like text and graphics, but not tracks and module
264 {
265  for( auto item : m_board->Drawings() )
266  {
267  switch( item->Type() )
268  {
269  case PCB_LINE_T:
270  PlotDrawSegment( (DRAWSEGMENT*) item);
271  break;
272 
273  case PCB_TEXT_T:
274  PlotTextePcb( (TEXTE_PCB*) item );
275  break;
276 
277  case PCB_DIMENSION_T:
278  PlotDimension( (DIMENSION*) item );
279  break;
280 
281  case PCB_TARGET_T:
282  PlotPcbTarget( (PCB_TARGET*) item );
283  break;
284 
285  case PCB_MARKER_T:
286  default:
287  break;
288  }
289  }
290 }
291 
293 {
294  wxSize size;
295  wxPoint pos;
296  double orient;
297  int thickness;
298 
299  if( aColor == COLOR4D::WHITE )
300  aColor = COLOR4D( LIGHTGRAY );
301 
302  m_plotter->SetColor( aColor );
303 
304  // calculate some text parameters :
305  size = pt_texte->GetTextSize();
306  pos = pt_texte->GetTextPos();
307 
308  orient = pt_texte->GetDrawRotation();
309 
310  thickness = pt_texte->GetThickness();
311 
312  if( pt_texte->IsMirrored() )
313  size.x = -size.x; // Text is mirrored
314 
315  // Non bold texts thickness is clamped at 1/6 char size by the low level draw function.
316  // but in Pcbnew we do not manage bold texts and thickness up to 1/4 char size
317  // (like bold text) and we manage the thickness.
318  // So we set bold flag to true
319  bool allow_bold = pt_texte->IsBold() || thickness;
320 
321  GBR_METADATA gbr_metadata;
323  MODULE* parent = static_cast<MODULE*> ( pt_texte->GetParent() );
324  gbr_metadata.SetCmpReference( parent->GetReference() );
325 
326  m_plotter->Text( pos, aColor,
327  pt_texte->GetShownText(),
328  orient, size,
329  pt_texte->GetHorizJustify(), pt_texte->GetVertJustify(),
330  thickness, pt_texte->IsItalic(), allow_bold, false, &gbr_metadata );
331 }
332 
333 
335 {
336  if( !m_layerMask[aDim->GetLayer()] )
337  return;
338 
339  DRAWSEGMENT draw;
340 
341  draw.SetWidth( aDim->GetWidth() );
342  draw.SetLayer( aDim->GetLayer() );
343 
345 
346  // Set plot color (change WHITE to LIGHTGRAY because
347  // the white items are not seen on a white paper or screen
349 
350  PlotTextePcb( &aDim->Text() );
351 
352  draw.SetStart( aDim->m_crossBarO );
353  draw.SetEnd( aDim->m_crossBarF );
354  PlotDrawSegment( &draw );
355 
356  draw.SetStart( aDim->m_featureLineGO);
357  draw.SetEnd( aDim->m_featureLineGF );
358  PlotDrawSegment( &draw );
359 
360  draw.SetStart( aDim->m_featureLineDO );
361  draw.SetEnd( aDim->m_featureLineDF );
362  PlotDrawSegment( &draw );
363 
364  draw.SetStart( aDim->m_crossBarF );
365  draw.SetEnd( aDim->m_arrowD1F );
366  PlotDrawSegment( &draw );
367 
368  draw.SetStart( aDim->m_crossBarF );
369  draw.SetEnd( aDim->m_arrowD2F );
370  PlotDrawSegment( &draw );
371 
372  draw.SetStart( aDim->m_crossBarO );
373  draw.SetEnd( aDim->m_arrowG1F );
374  PlotDrawSegment( &draw );
375 
376  draw.SetStart( aDim->m_crossBarO );
377  draw.SetEnd( aDim->m_arrowG2F );
378  PlotDrawSegment( &draw );
379 }
380 
381 
383 {
384  int dx1, dx2, dy1, dy2, radius;
385 
386  if( !m_layerMask[aMire->GetLayer()] )
387  return;
388 
389  m_plotter->SetColor( getColor( aMire->GetLayer() ) );
390 
391  DRAWSEGMENT draw;
392 
393  draw.SetShape( S_CIRCLE );
394  draw.SetWidth( aMire->GetWidth() );
395  draw.SetLayer( aMire->GetLayer() );
396  draw.SetStart( aMire->GetPosition() );
397  radius = aMire->GetSize() / 3;
398 
399  if( aMire->GetShape() ) // shape X
400  radius = aMire->GetSize() / 2;
401 
402  // Draw the circle
403  draw.SetEnd( wxPoint( draw.GetStart().x + radius, draw.GetStart().y ));
404 
405  PlotDrawSegment( &draw );
406 
407  draw.SetShape( S_SEGMENT );
408 
409  radius = aMire->GetSize() / 2;
410  dx1 = radius;
411  dy1 = 0;
412  dx2 = 0;
413  dy2 = radius;
414 
415  if( aMire->GetShape() ) // Shape X
416  {
417  dx1 = dy1 = radius;
418  dx2 = dx1;
419  dy2 = -dy1;
420  }
421 
422  wxPoint mirePos( aMire->GetPosition() );
423 
424  // Draw the X or + shape:
425  draw.SetStart( wxPoint( mirePos.x - dx1, mirePos.y - dy1 ));
426  draw.SetEnd( wxPoint( mirePos.x + dx1, mirePos.y + dy1 ));
427  PlotDrawSegment( &draw );
428 
429  draw.SetStart( wxPoint( mirePos.x - dx2, mirePos.y - dy2 ));
430  draw.SetEnd( wxPoint( mirePos.x + dx2, mirePos.y + dy2 ));
431  PlotDrawSegment( &draw );
432 }
433 
434 
435 // Plot footprints graphic items (outlines)
437 {
438  for( MODULE* module = m_board->m_Modules; module; module = module->Next() )
439  {
440  for( BOARD_ITEM* item = module->GraphicalItemsList().GetFirst(); item; item = item->Next() )
441  {
442  EDGE_MODULE* edge = dyn_cast<EDGE_MODULE*>( item );
443 
444  if( edge && m_layerMask[edge->GetLayer()] )
445  Plot_1_EdgeModule( edge );
446  }
447  }
448 }
449 
450 
451 //* Plot a graphic item (outline) relative to a footprint
453 {
454  int type_trace; // Type of item to plot.
455  int thickness; // Segment thickness.
456  int radius; // Circle radius.
457 
458  if( aEdge->Type() != PCB_MODULE_EDGE_T )
459  return;
460 
461  m_plotter->SetColor( getColor( aEdge->GetLayer() ) );
462 
463  type_trace = aEdge->GetShape();
464  thickness = aEdge->GetWidth();
465 
466  wxPoint pos( aEdge->GetStart() );
467  wxPoint end( aEdge->GetEnd() );
468 
469  GBR_METADATA gbr_metadata;
471  MODULE* parent = static_cast<MODULE*> ( aEdge->GetParent() );
472  gbr_metadata.SetCmpReference( parent->GetReference() );
473 
474  bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
475 
476  if( isOnCopperLayer )
477  {
478  gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_ETCHEDCMP );
479  gbr_metadata.SetCopper( true );
480  }
481  else if( aEdge->GetLayer() == Edge_Cuts ) // happens also when plotting copper layers
482  {
483  gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_NONCONDUCTOR );
484  }
485 
486  switch( type_trace )
487  {
488  case S_SEGMENT:
489  m_plotter->ThickSegment( pos, end, thickness, GetPlotMode(), &gbr_metadata );
490  break;
491 
492  case S_CIRCLE:
493  radius = KiROUND( GetLineLength( end, pos ) );
494  m_plotter->ThickCircle( pos, radius * 2, thickness, GetPlotMode(), &gbr_metadata );
495  break;
496 
497  case S_ARC:
498  {
499  radius = KiROUND( GetLineLength( end, pos ) );
500  double startAngle = ArcTangente( end.y - pos.y, end.x - pos.x );
501  double endAngle = startAngle + aEdge->GetAngle();
502 
503  // when startAngle == endAngle ThickArc() doesn't know whether it's 0 deg and 360 deg
504  if( std::abs( aEdge->GetAngle() ) == 3600.0 )
505  m_plotter->ThickCircle( pos, radius * 2, thickness, GetPlotMode(), &gbr_metadata );
506  else
507  m_plotter->ThickArc( pos, -endAngle, -startAngle, radius, thickness, GetPlotMode(), &gbr_metadata );
508  }
509  break;
510 
511  case S_POLYGON:
512  if( aEdge->IsPolyShapeValid() )
513  {
514  const std::vector<wxPoint>& polyPoints = aEdge->BuildPolyPointsList();
515 
516  // We must compute true coordinates from m_PolyList
517  // which are relative to module position, orientation 0
518  MODULE* module = aEdge->GetParentModule();
519 
520  std::vector< wxPoint > cornerList;
521 
522  cornerList.reserve( polyPoints.size() );
523 
524  for( unsigned ii = 0; ii < polyPoints.size(); ii++ )
525  {
526  wxPoint corner = polyPoints[ii];
527 
528  if( module )
529  {
530  RotatePoint( &corner, module->GetOrientation() );
531  corner += module->GetPosition();
532  }
533 
534  cornerList.push_back( corner );
535  }
536 
537  if( !aEdge->IsPolygonFilled() )
538  {
539  for( size_t i = 1; i < cornerList.size(); i++ )
540  {
541  m_plotter->ThickSegment( cornerList[i-1], cornerList[i],
542  thickness, GetPlotMode(), &gbr_metadata );
543  }
544 
545  m_plotter->ThickSegment( cornerList.back(), cornerList.front(),
546  thickness, GetPlotMode(), &gbr_metadata );
547 
548  }
549  else
550  {
551  m_plotter->PlotPoly( cornerList, FILLED_SHAPE, thickness, &gbr_metadata );
552  }
553  }
554  break;
555  }
556 }
557 
558 
559 // Plot a PCB Text, i.e. a text found on a copper or technical layer
561 {
562  double orient;
563  int thickness;
564  wxPoint pos;
565  wxSize size;
566  wxString shownText( pt_texte->GetShownText() );
567 
568  if( shownText.IsEmpty() )
569  return;
570 
571  if( !m_layerMask[pt_texte->GetLayer()] )
572  return;
573 
574  GBR_METADATA gbr_metadata;
575 
576  if( IsCopperLayer( pt_texte->GetLayer() ) )
577  {
579  }
580 
581  COLOR4D color = getColor( pt_texte->GetLayer() );
583 
584  size = pt_texte->GetTextSize();
585  pos = pt_texte->GetTextPos();
586  orient = pt_texte->GetTextAngle();
587  thickness = pt_texte->GetThickness();
588 
589  if( pt_texte->IsMirrored() )
590  size.x = -size.x;
591 
592  // Non bold texts thickness is clamped at 1/6 char size by the low level draw function.
593  // but in Pcbnew we do not manage bold texts and thickness up to 1/4 char size
594  // (like bold text) and we manage the thickness.
595  // So we set bold flag to true
596  bool allow_bold = pt_texte->IsBold() || thickness;
597 
598  if( pt_texte->IsMultilineAllowed() )
599  {
600  std::vector<wxPoint> positions;
601  wxArrayString strings_list;
602  wxStringSplit( shownText, strings_list, '\n' );
603  positions.reserve( strings_list.Count() );
604 
605  pt_texte->GetPositionsOfLinesOfMultilineText( positions, strings_list.Count() );
606 
607  for( unsigned ii = 0; ii < strings_list.Count(); ii++ )
608  {
609  wxString& txt = strings_list.Item( ii );
610  m_plotter->Text( positions[ii], color, txt, orient, size,
611  pt_texte->GetHorizJustify(), pt_texte->GetVertJustify(),
612  thickness, pt_texte->IsItalic(), allow_bold, false, &gbr_metadata );
613  }
614  }
615  else
616  {
617  m_plotter->Text( pos, color, shownText, orient, size,
618  pt_texte->GetHorizJustify(), pt_texte->GetVertJustify(),
619  thickness, pt_texte->IsItalic(), allow_bold, false, &gbr_metadata );
620  }
621 }
622 
623 
624 /* Plot areas (given by .m_FilledPolysList member) in a zone
625  */
627 {
628  const SHAPE_POLY_SET& polysList = aZone->GetFilledPolysList();
629 
630  if( polysList.IsEmpty() )
631  return;
632 
633  GBR_METADATA gbr_metadata;
634 
635  bool isOnCopperLayer = aZone->IsOnCopperLayer();
636 
637  if( isOnCopperLayer )
638  {
639  gbr_metadata.SetNetName( aZone->GetNetname() );
640  gbr_metadata.SetCopper( true );
641 
642  // Zones with no net name can exist.
643  // they are not used to connect items, so the aperture attribute cannot
644  // be set as conductor
645  if( aZone->GetNetname().IsEmpty() )
647  else
648  {
651  }
652  }
653 
654  // We need a buffer to store corners coordinates:
655  static std::vector< wxPoint > cornerList;
656  cornerList.clear();
657 
658  m_plotter->SetColor( getColor( aZone->GetLayer() ) );
659 
660  /* Plot all filled areas: filled areas have a filled area and a thick
661  * outline we must plot the filled area itself ( as a filled polygon
662  * OR a set of segments ) and plot the thick outline itself
663  *
664  * in non filled mode the outline is plotted, but not the filling items
665  */
666  for( auto ic = polysList.CIterate(); ic; ++ic )
667  {
668  wxPoint pos( ic->x, ic->y );
669  cornerList.push_back( pos );
670 
671  if( ic.IsEndContour() ) // Plot the current filled area outline
672  {
673  // First, close the outline
674  if( cornerList[0] != cornerList[cornerList.size() - 1] )
675  {
676  cornerList.push_back( cornerList[0] );
677  }
678 
679  // Plot the current filled area and its outline
680  if( GetPlotMode() == FILLED )
681  {
682  // Plot the filled area polygon.
683  // The area can be filled by segments or uses solid polygons
684  if( aZone->GetFillMode() == 0 ) // We are using solid polygons
685  {
686  m_plotter->PlotPoly( cornerList, FILLED_SHAPE, aZone->GetMinThickness(), &gbr_metadata );
687  }
688  else // We are using areas filled by segments: plot segments and outline
689  {
690  for( unsigned iseg = 0; iseg < aZone->FillSegments().size(); iseg++ )
691  {
692  wxPoint start = (wxPoint) aZone->FillSegments()[iseg].A;
693  wxPoint end = (wxPoint) aZone->FillSegments()[iseg].B;
694  m_plotter->ThickSegment( start, end,
695  aZone->GetMinThickness(),
696  GetPlotMode(), &gbr_metadata );
697  }
698 
699  // Plot the area outline only
700  if( aZone->GetMinThickness() > 0 )
701  m_plotter->PlotPoly( cornerList, NO_FILL, aZone->GetMinThickness() );
702  }
703  }
704  else
705  {
706  if( aZone->GetMinThickness() > 0 )
707  {
708  for( unsigned jj = 1; jj<cornerList.size(); jj++ )
709  m_plotter->ThickSegment( cornerList[jj -1], cornerList[jj],
710  aZone->GetMinThickness(),
711  GetPlotMode(), &gbr_metadata );
712  }
713 
715  }
716 
717  cornerList.clear();
718  }
719  }
720 }
721 
722 
723 /* Plot items type DRAWSEGMENT on layers allowed by aLayerMask
724  */
726 {
727  if( !m_layerMask[aSeg->GetLayer()] )
728  return;
729 
730  int radius = 0;
731  double StAngle = 0, EndAngle = 0;
732  int thickness = aSeg->GetWidth();
733 
734  m_plotter->SetColor( getColor( aSeg->GetLayer() ) );
735 
736  wxPoint start( aSeg->GetStart() );
737  wxPoint end( aSeg->GetEnd() );
738 
739  GBR_METADATA gbr_metadata;
740 
741  bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
742 
743  if( isOnCopperLayer && aSeg->GetLayer() == Edge_Cuts ) // can happens when plotting copper layers
744  {
746  }
747 
748  switch( aSeg->GetShape() )
749  {
750  case S_CIRCLE:
751  radius = KiROUND( GetLineLength( end, start ) );
752  m_plotter->ThickCircle( start, radius * 2, thickness, GetPlotMode(), &gbr_metadata );
753  break;
754 
755  case S_ARC:
756  radius = KiROUND( GetLineLength( end, start ) );
757  StAngle = ArcTangente( end.y - start.y, end.x - start.x );
758  EndAngle = StAngle + aSeg->GetAngle();
759 
760  // when startAngle == endAngle ThickArc() doesn't know whether it's 0 deg and 360 deg
761  if( std::abs( aSeg->GetAngle() ) == 3600.0 )
762  m_plotter->ThickCircle( start, radius * 2, thickness, GetPlotMode(), &gbr_metadata );
763  else
764  m_plotter->ThickArc( start, -EndAngle, -StAngle, radius, thickness, GetPlotMode(), &gbr_metadata );
765  break;
766 
767  case S_CURVE:
768  {
769  m_plotter->SetCurrentLineWidth( thickness, &gbr_metadata );
770  const std::vector<wxPoint>& bezierPoints = aSeg->GetBezierPoints();
771 
772  for( unsigned i = 1; i < bezierPoints.size(); i++ )
773  m_plotter->ThickSegment( bezierPoints[i - 1], bezierPoints[i],
774  thickness, GetPlotMode(), &gbr_metadata );
775  }
776  break;
777 
778  case S_POLYGON:
779  {
780  if( !aSeg->IsPolygonFilled() )
781  {
782  for( auto it = aSeg->GetPolyShape().IterateSegments( 0 ); it; it++ )
783  {
784  auto seg = it.Get();
785  m_plotter->ThickSegment( wxPoint( seg.A ), wxPoint( seg.B ),
786  thickness, GetPlotMode(), &gbr_metadata );
787  }
788  }
789  else
790  {
791  m_plotter->SetCurrentLineWidth( thickness, &gbr_metadata );
792  // Draw the polygon: only one polygon is expected
793  // However we provide a multi polygon shape drawing
794  // ( for the future or to show a non expected shape )
795  // This must be simplified and fractured to prevent overlapping polygons
796  // from generating invalid Gerber files
797  auto tmpPoly = SHAPE_POLY_SET( aSeg->GetPolyShape() );
799 
800  for( int jj = 0; jj < tmpPoly.OutlineCount(); ++jj )
801  {
802  SHAPE_LINE_CHAIN& poly = tmpPoly.Outline( jj );
803  m_plotter->PlotPoly( poly, FILLED_SHAPE, thickness, &gbr_metadata );
804  }
805  }
806  }
807  break;
808 
809  default:
810  m_plotter->ThickSegment( start, end, thickness, GetPlotMode(), &gbr_metadata );
811  }
812 }
813 
814 
819  const wxPoint &aDrillPos, wxSize aDrillSize,
820  const wxSize &aPadSize,
821  double aOrientation, int aSmallDrill )
822 {
823  // Small drill marks have no significance when applied to slots
824  if( aSmallDrill && aDrillShape == PAD_DRILL_SHAPE_CIRCLE )
825  aDrillSize.x = std::min( aSmallDrill, aDrillSize.x );
826 
827  // Round holes only have x diameter, slots have both
828  aDrillSize.x -= getFineWidthAdj();
829  aDrillSize.x = Clamp( 1, aDrillSize.x, aPadSize.x - 1 );
830 
831  if( aDrillShape == PAD_DRILL_SHAPE_OBLONG )
832  {
833  aDrillSize.y -= getFineWidthAdj();
834  aDrillSize.y = Clamp( 1, aDrillSize.y, aPadSize.y - 1 );
835  m_plotter->FlashPadOval( aDrillPos, aDrillSize, aOrientation, GetPlotMode(), NULL );
836  }
837  else
838  m_plotter->FlashPadCircle( aDrillPos, aDrillSize.x, GetPlotMode(), NULL );
839 }
840 
841 
843 {
844  /* If small drills marks were requested prepare a clamp value to pass
845  to the helper function */
846  int small_drill = (GetDrillMarksType() == PCB_PLOT_PARAMS::SMALL_DRILL_SHAPE) ?
847  SMALL_DRILL : 0;
848 
849  /* In the filled trace mode drill marks are drawn white-on-black to scrape
850  the underlying pad. This works only for drivers supporting color change,
851  obviously... it means that:
852  - PS, SVG and PDF output is correct (i.e. you have a 'donut' pad)
853  - In HPGL you can't see them
854  - In gerbers you can't see them, too. This is arguably the right thing to
855  do since having drill marks and high speed drill stations is a sure
856  recipe for broken tools and angry manufacturers. If you *really* want them
857  you could start a layer with negative polarity to scrape the film.
858  - In DXF they go into the 'WHITE' layer. This could be useful.
859  */
860  if( GetPlotMode() == FILLED )
862 
863  for( TRACK* pts = m_board->m_Track; pts != NULL; pts = pts->Next() )
864  {
865  const VIA* via = dyn_cast<const VIA*>( pts );
866 
867  if( via )
869  wxSize( via->GetDrillValue(), 0 ),
870  wxSize( via->GetWidth(), 0 ), 0, small_drill );
871  }
872 
873  for( MODULE* Module = m_board->m_Modules; Module != NULL; Module = Module->Next() )
874  {
875  for( D_PAD* pad = Module->PadsList(); pad != NULL; pad = pad->Next() )
876  {
877  if( pad->GetDrillSize().x == 0 )
878  continue;
879 
880  plotOneDrillMark( pad->GetDrillShape(),
881  pad->GetPosition(), pad->GetDrillSize(),
882  pad->GetSize(), pad->GetOrientation(),
883  small_drill );
884  }
885  }
886 
887  if( GetPlotMode() == FILLED )
889 }
D_PAD * Next() const
Definition: class_pad.h:160
void wxStringSplit(const wxString &aText, wxArrayString &aStrings, wxChar aSplitter)
Split aString to a string list separated at aSplitter.
Definition: common.cpp:187
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:676
a class to handle special data (items attributes) during plot.
bool IsBold() const
Definition: eda_text.h:186
void SetPadName(const wxString &aPadname)
Definition: gbr_metadata.h:163
#define SMALL_DRILL
Definition: pcbplot.h:72
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:59
double GetOrientation() const
Definition: class_module.h:188
aperture used for etched components
Definition: gbr_metadata.h:83
TEXTE_MODULE & Reference()
Definition: class_module.h:512
void SetShape(STROKE_T aShape)
int OutlineCount() const
Returns the number of outlines in the set
aperture used for edge connecto pad (outer layers)
Definition: gbr_metadata.h:93
EDA_TEXT_VJUSTIFY_T GetVertJustify() const
Definition: eda_text.h:204
bool IsMirrored() const
Definition: eda_text.h:192
int GetWidth() const
double GetLineLength(const wxPoint &aPointA, const wxPoint &aPointB)
Function GetLineLength returns the length of a line segment defined by aPointA and aPointB...
Definition: trigo.h:191
const T & Clamp(const T &lower, const T &value, const T &upper)
Function Clamp limits value within the range lower <= value <= upper.
Definition: macros.h:130
TEXTE_PCB class definition.
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:121
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:65
bool MergePrimitivesAsPolygon(SHAPE_POLY_SET *aMergedPolygon=NULL, int aCircleToSegmentsCount=ARC_APPROX_SEGMENTS_COUNT_HIGH_DEF)
Merge all basic shapes, converted to a polygon in one polygon, in m_customShapeAsPolygon.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
wxPoint m_crossBarF
print info associated to a component (TO.C attribute)
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class...
wxPoint m_arrowD1F
virtual void SetColor(COLOR4D color)=0
virtual void ThickCircle(const wxPoint &pos, int diametre, int width, EDA_DRAW_MODE_T tracemode, void *aData)
Definition: plotter.cpp:511
const wxPoint & GetStart() const
Definition: class_track.h:126
STROKE_T GetShape() const
void PlotPad(D_PAD *aPad, COLOR4D aColor, EDA_DRAW_MODE_T aPlotMode)
Plot a pad.
int GetSize() const
bool IsVisible() const
Definition: eda_text.h:189
void SetNetAttribType(int aNetAttribType)
Definition: gbr_metadata.h:152
Class BOARD to handle a board.
void PlotDimension(DIMENSION *Dimension)
int color
Definition: DXF_plotter.cpp:62
polygon (not yet used for tracks, but could be in microwave apps)
bool IsEmpty() const
Returns true if the set is empty (no polygons at all)
Smd pad, appears on the solder paste layer (default)
Definition: pad_shapes.h:61
virtual PCB_LAYER_ID GetLayer() const override
Function GetLayer returns the primary layer this item is on.
Definition: class_zone.cpp:175
PLOTTER * m_plotter
Definition: pcbplot.h:78
ZONE_SEGMENT_FILL & FillSegments()
Definition: class_zone.h:240
void PlotDrillMarks()
Function PlotDrillMarks Draw a drill mark for pads and vias.
double GetTextAngle() const
Definition: eda_text.h:177
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:92
aperture used for through hole component on outer layer
Definition: gbr_metadata.h:88
bool PlotAllTextsModule(MODULE *aModule)
Classes to handle copper zones.
int GetThickness() const
Function GetThickness returns pen width.
Definition: eda_text.h:167
usual segment : line with rounded ends
const std::vector< wxPoint > & GetBezierPoints() const
wxPoint m_featureLineDF
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
const std::vector< wxPoint > BuildPolyPointsList() const
Build and return the list of corners in a std::vector<wxPoint> It must be used only to convert the SH...
virtual wxString GetShownText() const override
Returns the string actually shown after processing of the base text.
virtual void PlotPoly(const std::vector< wxPoint > &aCornerList, FILL_T aFill, int aWidth=USE_DEFAULT_LINE_WIDTH, void *aData=NULL)=0
Function PlotPoly.
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
#define abs(a)
Definition: auxiliary.h:84
PAD_DRILL_SHAPE_T
Enum PAD_DRILL_SHAPE_T is the set of pad drill shapes, used with D_PAD::{Set,Get}DrillShape() ...
Definition: pad_shapes.h:46
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:94
Casted dyn_cast(From aObject)
Function dyn_cast()
Definition: typeinfo.h:61
BOARD * m_board
Definition: pcbplot.h:79
PAD_ATTR_T GetAttribute() const
Definition: class_pad.h:412
Functions relatives to tracks, vias and segments used to fill zones.
virtual void ThickArc(const wxPoint &centre, double StAngle, double EndAngle, int rayon, int width, EDA_DRAW_MODE_T tracemode, void *aData)
Definition: plotter.cpp:473
virtual void FlashPadCustom(const wxPoint &aPadPos, const wxSize &aSize, SHAPE_POLY_SET *aPolygons, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadCustom
This file contains miscellaneous commonly used macros and functions.
virtual void Text(const wxPoint &aPos, const COLOR4D aColor, const wxString &aText, double aOrient, const wxSize &aSize, enum EDA_TEXT_HJUSTIFY_T aH_justify, enum EDA_TEXT_VJUSTIFY_T aV_justify, int aWidth, bool aItalic, bool aBold, bool aMultilineAllowed=false, void *aData=NULL)
Draws text with the plotter.
void PlotFilledAreas(ZONE_CONTAINER *aZone)
Classes used in Pcbnew, CvPcb and GerbView.
Board plot function definition file.
wxPoint m_featureLineGO
bool IsItalic() const
Definition: eda_text.h:183
DIMENSION class definition.
COLOR4D GetLayerColor(LAYER_NUM aLayer) const
Function GetLayerColor.
aperture used for BGA pad with a solder mask defined by the solder mask
Definition: gbr_metadata.h:92
virtual void FlashPadCircle(const wxPoint &aPadPos, int aDiameter, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadCircle
int GetWidth() const
EDA_TEXT_HJUSTIFY_T GetHorizJustify() const
Definition: eda_text.h:203
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:170
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
void PlotPcbTarget(PCB_TARGET *PtMire)
const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:143
Class SHAPE_POLY_SET.
TEXTE_MODULE & Value()
read/write accessors:
Definition: class_module.h:511
EDA_DRAW_MODE_T
Definition: eda_text.h:77
void PlotBoardGraphicItems()
plot items like text and graphics, but not tracks and modules
COLOR4D GetColor() const
ZONE_FILL_MODE GetFillMode() const
Definition: class_zone.h:180
const wxSize & GetTextSize() const
Definition: eda_text.h:228
Arcs (with rounded ends)
virtual void FlashPadRoundRect(const wxPoint &aPadPos, const wxSize &aSize, int aCornerRadius, double aOrient, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadRoundRect
LSET GetLayerSet() const override
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
Definition: class_pad.h:409
wxPoint m_arrowG1F
void Plot_1_EdgeModule(EDGE_MODULE *aEdge)
wxPoint m_arrowD2F
wxPoint m_arrowG2F
const wxString & GetReference() const
Function GetReference.
Definition: class_module.h:462
MODULE * GetParentModule() const
Function GetParentModule returns a pointer to the parent module, or NULL if DRAWSEGMENT does not belo...
static LSET ExternalCuMask()
Function ExternalCuMask returns a mask holding the Front and Bottom layers.
Definition: lset.cpp:706
const wxString & GetName() const
Definition: class_pad.h:190
aperture used for mechanical pads (NPTH)
Definition: gbr_metadata.h:94
SHAPE_POLY_SET & GetPolyShape()
Bezier Curve.
const wxString & GetNetname() const
Function GetNetname.
T * GetFirst() const
Function GetFirst returns the first T* in the list without removing it, or NULL if the list is empty...
Definition: dlist.h:163
Like smd, does not appear on the solder paste layer (default) note also has a special attribute in Ge...
Definition: pad_shapes.h:62
class DIMENSION, a dimension (graphic item)
Definition: typeinfo.h:100
CONST_ITERATOR CIterate(int aFirst, int aLast, bool aIterateHoles=false) const
void Fracture(POLYGON_MODE aFastMode)
Converts a set of polygons with holes to a singe outline with "slits"/"fractures" connecting the oute...
int GetWidth() const
bool IsMultilineAllowed() const
Definition: eda_text.h:201
aperture used for connected items like tracks (not vias)
Definition: gbr_metadata.h:84
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:101
void SetStart(const wxPoint &aStart)
int LAYER_NUM
Type LAYER_NUM can be replaced with int and removed.
bool GetPlotValue() const
MODULE * GetParent() const
Definition: class_pad.h:162
void BuildPadPolygon(wxPoint aCoord[4], wxSize aInflateValue, double aRotation) const
Function BuildPadPolygon Has meaning only for polygonal pads (trapezoid and rectangular) Build the Co...
void SetNetName(const wxString &aNetname)
Definition: gbr_metadata.h:162
double GetAngle() const
const COLORS_DESIGN_SETTINGS & Colors() const
Function GetColorSettings.
Definition: class_board.h:572
virtual void FlashPadRect(const wxPoint &aPadPos, const wxSize &aSize, double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadRect
class MARKER_PCB, a marker used to show something
Definition: typeinfo.h:99
BOARD_ITEM * Next() const
int GetWidth() const
Definition: class_track.h:120
TRACK * Next() const
Definition: class_track.h:103
Class to handle a graphic segment.
void plotOneDrillMark(PAD_DRILL_SHAPE_T aDrillShape, const wxPoint &aDrillPos, wxSize aDrillSize, const wxSize &aPadSize, double aOrientation, int aSmallDrill)
Helper function to plot a single drill mark.
virtual void FlashPadOval(const wxPoint &aPadPos, const wxSize &aSize, double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadOval
DLIST< MODULE > m_Modules
Definition: class_board.h:249
Class SHAPE_LINE_CHAIN.
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees, but soon degrees.
Definition: class_pad.h:389
virtual void ThickSegment(const wxPoint &start, const wxPoint &end, int width, EDA_DRAW_MODE_T tracemode, void *aData)
Definition: plotter.cpp:456
void CustomShapeAsPolygonToBoardPosition(SHAPE_POLY_SET *aMergedPolygon, wxPoint aPosition, double aRotation) const
When created, the corners coordinates are relative to the pad position, orientation 0...
LSET m_layerMask
Definition: pcbplot.h:80
TEXTE_PCB & Text()
size_t i
Definition: json11.cpp:597
wxPoint ShapePos() const
Definition: class_pad.cpp:550
int GetShape() const
Usual pad.
Definition: pad_shapes.h:60
aperture used for SMD pad with a solder mask defined by the solder mask
Definition: gbr_metadata.h:90
The common library.
int GetMinThickness() const
Definition: class_zone.h:203
bool GetPlotInvisibleText() const
bool IsPolyShapeValid() const
void PlotTextePcb(TEXTE_PCB *pt_texte)
Definition: colors.h:49
void SetEnd(const wxPoint &aEnd)
int GetRoundRectCornerRadius() const
Function GetRoundRectCornerRadius Has meaning only for rounded rect pads.
Definition: class_pad.h:538
MODULE * Next() const
Definition: class_module.h:122
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
static LSET AllBoardTechMask()
Function AllTechMask returns a mask holding board technical layers (no CU layer) on both side...
Definition: lset.cpp:753
const wxPoint & GetTextPos() const
Definition: eda_text.h:237
void GetPositionsOfLinesOfMultilineText(std::vector< wxPoint > &aPositions, int aLineCount) const
Function GetPositionsOfLinesOfMultilineText Populates aPositions with the position of each line of a ...
Definition: eda_text.cpp:315
wxPoint m_crossBarO
PCB_TARGET class definition.
void SetApertureAttrib(GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB aApertAttribute)
Definition: gbr_metadata.h:142
DLIST< BOARD_ITEM > & GraphicalItemsList()
Definition: class_module.h:165
bool m_NotInNet
true if a pad of a footprint cannot be connected (for instance a mechanical NPTH, ot a not named pad)...
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
int getFineWidthAdj()
Definition: pcbplot.h:95
DLIST< TRACK > m_Track
Definition: class_board.h:250
GBR_NETLIST_METADATA m_NetlistMetadata
a item to handle object attribute:
Definition: gbr_metadata.h:181
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:216
Module description (excepted pads)
virtual wxString GetShownText() const
Returns the string actually shown after processing of the base text.
Definition: eda_text.h:148
Basic classes for most KiCad items.
aperture used for not connected items (texts, outlines on copper)
Definition: gbr_metadata.h:86
const wxSize & GetSize() const
Definition: class_pad.h:269
EDGE_MODULE class definition.
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:91
BOARD_ITEM_CONTAINER * GetParent() const
void SetCopper(bool aValue)
Definition: gbr_metadata.h:171
virtual void FlashPadTrapez(const wxPoint &aPadPos, const wxPoint *aCorners, double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadTrapez flash a trapezoidal pad
double GetDrawRotation() const
DrillMarksType GetDrillMarksType() const
wxPoint m_featureLineDO
print info associated to a net (TO.N attribute)
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
bool IsPolygonFilled() const
Polygonal shape is not always filled.
bool GetPlotReference() const
const wxPoint GetPosition() const override
Definition: class_module.h:183
bool IsOnCopperLayer() const
Function IsOnCopperLayer.
Definition: class_zone.cpp:181
void SetCmpReference(const wxString &aComponentRef)
Definition: gbr_metadata.h:164
COLOR4D getColor(LAYER_NUM aLayer)
Function getColor.
Class DIMENSION.
DLIST_ITERATOR_WRAPPER< BOARD_ITEM > Drawings()
Definition: class_board.h:256
const wxPoint GetPosition() const override
#define GBR_NETINFO_ALL
SEGMENT_ITERATOR IterateSegments(int aFirst, int aLast, bool aIterateHoles=false)
Returns an iterator object, for iterating between aFirst and aLast outline, with or without holes (de...
KICAD_T Type() const
Function Type()
Definition: base_struct.h:201
#define min(a, b)
Definition: auxiliary.h:85
const SHAPE_POLY_SET & GetFilledPolysList() const
Function GetFilledPolysList returns a reference to the list of filled polygons.
Definition: class_zone.h:559
EDA_DRAW_MODE_T GetPlotMode() const
virtual void SetCurrentLineWidth(int width, void *aData=NULL)=0
Set the line width for the next drawing.
void PlotDrawSegment(DRAWSEGMENT *PtSegm)
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
wxPoint m_featureLineGF
void SetWidth(int aWidth)
void PlotTextModule(TEXTE_MODULE *aTextMod, COLOR4D aColor)