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 {
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  // see if we want to plot VALUE and REF fields
214  bool trace_val = GetPlotValue();
215  bool trace_ref = GetPlotReference();
216 
217  TEXTE_MODULE* textModule = &aModule->Reference();
218  LAYER_NUM textLayer = textModule->GetLayer();
219 
220  if( textLayer >= PCB_LAYER_ID_COUNT ) // how will this ever be true?
221  return false;
222 
223  if( !m_layerMask[textLayer] )
224  trace_ref = false;
225 
226  if( !textModule->IsVisible() && !GetPlotInvisibleText() )
227  trace_ref = false;
228 
229  textModule = &aModule->Value();
230  textLayer = textModule->GetLayer();
231 
232  if( textLayer > PCB_LAYER_ID_COUNT ) // how will this ever be true?
233  return false;
234 
235  if( !m_layerMask[textLayer] )
236  trace_val = false;
237 
238  if( !textModule->IsVisible() && !GetPlotInvisibleText() )
239  trace_val = false;
240 
241  // Plot text fields, if allowed
242  if( trace_ref )
243  {
244  PlotTextModule( &aModule->Reference(), getColor( textLayer ) );
245  }
246 
247  if( trace_val )
248  {
249  PlotTextModule( &aModule->Value(), getColor( textLayer ) );
250  }
251 
252  for( BOARD_ITEM* item = aModule->GraphicalItemsList().GetFirst(); item; item = item->Next() )
253  {
254  textModule = dyn_cast<TEXTE_MODULE*>( item );
255 
256  if( !textModule )
257  continue;
258 
259  if( !textModule->IsVisible() )
260  continue;
261 
262  textLayer = textModule->GetLayer();
263 
264  if( textLayer >= PCB_LAYER_ID_COUNT )
265  return false;
266 
267  if( !m_layerMask[textLayer] )
268  continue;
269 
270  if( textModule->GetText() == wxT( "%R" ) && !GetPlotReference() )
271  continue;
272 
273  if( textModule->GetText() == wxT( "%V" ) && !GetPlotValue() )
274  continue;
275 
276  PlotTextModule( textModule, getColor( textLayer ) );
277  }
278 
279  return true;
280 }
281 
282 
283 // plot items like text and graphics, but not tracks and module
285 {
286  for( auto item : m_board->Drawings() )
287  {
288  switch( item->Type() )
289  {
290  case PCB_LINE_T:
291  PlotDrawSegment( (DRAWSEGMENT*) item);
292  break;
293 
294  case PCB_TEXT_T:
295  PlotTextePcb( (TEXTE_PCB*) item );
296  break;
297 
298  case PCB_DIMENSION_T:
299  PlotDimension( (DIMENSION*) item );
300  break;
301 
302  case PCB_TARGET_T:
303  PlotPcbTarget( (PCB_TARGET*) item );
304  break;
305 
306  case PCB_MARKER_T:
307  default:
308  break;
309  }
310  }
311 }
312 
314 {
315  wxSize size;
316  wxPoint pos;
317  double orient;
318  int thickness;
319 
320  if( aColor == COLOR4D::WHITE )
321  aColor = COLOR4D( LIGHTGRAY );
322 
323  m_plotter->SetColor( aColor );
324 
325  // calculate some text parameters :
326  size = pt_texte->GetTextSize();
327  pos = pt_texte->GetTextPos();
328 
329  orient = pt_texte->GetDrawRotation();
330 
331  thickness = pt_texte->GetThickness();
332 
333  if( pt_texte->IsMirrored() )
334  size.x = -size.x; // Text is mirrored
335 
336  // Non bold texts thickness is clamped at 1/6 char size by the low level draw function.
337  // but in Pcbnew we do not manage bold texts and thickness up to 1/4 char size
338  // (like bold text) and we manage the thickness.
339  // So we set bold flag to true
340  bool allow_bold = pt_texte->IsBold() || thickness;
341 
342  GBR_METADATA gbr_metadata;
344  MODULE* parent = static_cast<MODULE*> ( pt_texte->GetParent() );
345  gbr_metadata.SetCmpReference( parent->GetReference() );
346 
347  m_plotter->Text( pos, aColor,
348  pt_texte->GetShownText(),
349  orient, size,
350  pt_texte->GetHorizJustify(), pt_texte->GetVertJustify(),
351  thickness, pt_texte->IsItalic(), allow_bold, false, &gbr_metadata );
352 }
353 
354 
356 {
357  if( !m_layerMask[aDim->GetLayer()] )
358  return;
359 
360  DRAWSEGMENT draw;
361 
362  draw.SetWidth( aDim->GetWidth() );
363  draw.SetLayer( aDim->GetLayer() );
364 
366 
367  // Set plot color (change WHITE to LIGHTGRAY because
368  // the white items are not seen on a white paper or screen
369  m_plotter->SetColor( color != WHITE ? color : LIGHTGRAY);
370 
371  PlotTextePcb( &aDim->Text() );
372 
373  draw.SetStart( aDim->m_crossBarO );
374  draw.SetEnd( aDim->m_crossBarF );
375  PlotDrawSegment( &draw );
376 
377  draw.SetStart( aDim->m_featureLineGO);
378  draw.SetEnd( aDim->m_featureLineGF );
379  PlotDrawSegment( &draw );
380 
381  draw.SetStart( aDim->m_featureLineDO );
382  draw.SetEnd( aDim->m_featureLineDF );
383  PlotDrawSegment( &draw );
384 
385  draw.SetStart( aDim->m_crossBarF );
386  draw.SetEnd( aDim->m_arrowD1F );
387  PlotDrawSegment( &draw );
388 
389  draw.SetStart( aDim->m_crossBarF );
390  draw.SetEnd( aDim->m_arrowD2F );
391  PlotDrawSegment( &draw );
392 
393  draw.SetStart( aDim->m_crossBarO );
394  draw.SetEnd( aDim->m_arrowG1F );
395  PlotDrawSegment( &draw );
396 
397  draw.SetStart( aDim->m_crossBarO );
398  draw.SetEnd( aDim->m_arrowG2F );
399  PlotDrawSegment( &draw );
400 }
401 
402 
404 {
405  int dx1, dx2, dy1, dy2, radius;
406 
407  if( !m_layerMask[aMire->GetLayer()] )
408  return;
409 
410  m_plotter->SetColor( getColor( aMire->GetLayer() ) );
411 
412  DRAWSEGMENT draw;
413 
414  draw.SetShape( S_CIRCLE );
415  draw.SetWidth( aMire->GetWidth() );
416  draw.SetLayer( aMire->GetLayer() );
417  draw.SetStart( aMire->GetPosition() );
418  radius = aMire->GetSize() / 3;
419 
420  if( aMire->GetShape() ) // shape X
421  radius = aMire->GetSize() / 2;
422 
423  // Draw the circle
424  draw.SetEnd( wxPoint( draw.GetStart().x + radius, draw.GetStart().y ));
425 
426  PlotDrawSegment( &draw );
427 
428  draw.SetShape( S_SEGMENT );
429 
430  radius = aMire->GetSize() / 2;
431  dx1 = radius;
432  dy1 = 0;
433  dx2 = 0;
434  dy2 = radius;
435 
436  if( aMire->GetShape() ) // Shape X
437  {
438  dx1 = dy1 = radius;
439  dx2 = dx1;
440  dy2 = -dy1;
441  }
442 
443  wxPoint mirePos( aMire->GetPosition() );
444 
445  // Draw the X or + shape:
446  draw.SetStart( wxPoint( mirePos.x - dx1, mirePos.y - dy1 ));
447  draw.SetEnd( wxPoint( mirePos.x + dx1, mirePos.y + dy1 ));
448  PlotDrawSegment( &draw );
449 
450  draw.SetStart( wxPoint( mirePos.x - dx2, mirePos.y - dy2 ));
451  draw.SetEnd( wxPoint( mirePos.x + dx2, mirePos.y + dy2 ));
452  PlotDrawSegment( &draw );
453 }
454 
455 
456 // Plot footprints graphic items (outlines)
458 {
459  for( MODULE* module = m_board->m_Modules; module; module = module->Next() )
460  {
461  for( BOARD_ITEM* item = module->GraphicalItemsList().GetFirst(); item; item = item->Next() )
462  {
463  EDGE_MODULE* edge = dyn_cast<EDGE_MODULE*>( item );
464 
465  if( edge && m_layerMask[edge->GetLayer()] )
466  Plot_1_EdgeModule( edge );
467  }
468  }
469 }
470 
471 
472 //* Plot a graphic item (outline) relative to a footprint
474 {
475  int type_trace; // Type of item to plot.
476  int thickness; // Segment thickness.
477  int radius; // Circle radius.
478 
479  if( aEdge->Type() != PCB_MODULE_EDGE_T )
480  return;
481 
482  m_plotter->SetColor( getColor( aEdge->GetLayer() ) );
483 
484  type_trace = aEdge->GetShape();
485  thickness = aEdge->GetWidth();
486 
487  wxPoint pos( aEdge->GetStart() );
488  wxPoint end( aEdge->GetEnd() );
489 
490  GBR_METADATA gbr_metadata;
492  MODULE* parent = static_cast<MODULE*> ( aEdge->GetParent() );
493  gbr_metadata.SetCmpReference( parent->GetReference() );
494 
495  bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
496 
497  if( isOnCopperLayer )
498  {
499  gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_ETCHEDCMP );
500  gbr_metadata.SetCopper( true );
501  }
502  else if( aEdge->GetLayer() == Edge_Cuts ) // happens also when plotting copper layers
503  {
504  gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_NONCONDUCTOR );
505  }
506 
507  switch( type_trace )
508  {
509  case S_SEGMENT:
510  m_plotter->ThickSegment( pos, end, thickness, GetPlotMode(), &gbr_metadata );
511  break;
512 
513  case S_CIRCLE:
514  radius = KiROUND( GetLineLength( end, pos ) );
515  m_plotter->ThickCircle( pos, radius * 2, thickness, GetPlotMode(), &gbr_metadata );
516  break;
517 
518  case S_ARC:
519  {
520  radius = KiROUND( GetLineLength( end, pos ) );
521  double startAngle = ArcTangente( end.y - pos.y, end.x - pos.x );
522  double endAngle = startAngle + aEdge->GetAngle();
523 
524  // when startAngle == endAngle ThickArc() doesn't know whether it's 0 deg and 360 deg
525  if( std::abs( aEdge->GetAngle() ) == 3600.0 )
526  m_plotter->ThickCircle( pos, radius * 2, thickness, GetPlotMode(), &gbr_metadata );
527  else
528  m_plotter->ThickArc( pos, -endAngle, -startAngle, radius, thickness, GetPlotMode(), &gbr_metadata );
529  }
530  break;
531 
532  case S_POLYGON:
533  if( aEdge->IsPolyShapeValid() )
534  {
535  const std::vector<wxPoint>& polyPoints = aEdge->BuildPolyPointsList();
536 
537  // We must compute true coordinates from m_PolyList
538  // which are relative to module position, orientation 0
539  MODULE* module = aEdge->GetParentModule();
540 
541  std::vector< wxPoint > cornerList;
542 
543  cornerList.reserve( polyPoints.size() );
544 
545  for( unsigned ii = 0; ii < polyPoints.size(); ii++ )
546  {
547  wxPoint corner = polyPoints[ii];
548 
549  if( module )
550  {
551  RotatePoint( &corner, module->GetOrientation() );
552  corner += module->GetPosition();
553  }
554 
555  cornerList.push_back( corner );
556  }
557 
558  m_plotter->PlotPoly( cornerList, FILLED_SHAPE, thickness, &gbr_metadata );
559  }
560  break;
561  }
562 }
563 
564 
565 // Plot a PCB Text, i.e. a text found on a copper or technical layer
567 {
568  double orient;
569  int thickness;
570  wxPoint pos;
571  wxSize size;
572  wxString shownText( pt_texte->GetShownText() );
573 
574  if( shownText.IsEmpty() )
575  return;
576 
577  if( !m_layerMask[pt_texte->GetLayer()] )
578  return;
579 
580  GBR_METADATA gbr_metadata;
581 
582  if( IsCopperLayer( pt_texte->GetLayer() ) )
583  {
585  }
586 
587  COLOR4D color = getColor( pt_texte->GetLayer() );
588  m_plotter->SetColor( color );
589 
590  size = pt_texte->GetTextSize();
591  pos = pt_texte->GetTextPos();
592  orient = pt_texte->GetTextAngle();
593  thickness = pt_texte->GetThickness();
594 
595  if( pt_texte->IsMirrored() )
596  size.x = -size.x;
597 
598  // Non bold texts thickness is clamped at 1/6 char size by the low level draw function.
599  // but in Pcbnew we do not manage bold texts and thickness up to 1/4 char size
600  // (like bold text) and we manage the thickness.
601  // So we set bold flag to true
602  bool allow_bold = pt_texte->IsBold() || thickness;
603 
604  if( pt_texte->IsMultilineAllowed() )
605  {
606  std::vector<wxPoint> positions;
607  wxArrayString strings_list;
608  wxStringSplit( shownText, strings_list, '\n' );
609  positions.reserve( strings_list.Count() );
610 
611  pt_texte->GetPositionsOfLinesOfMultilineText( positions, strings_list.Count() );
612 
613  for( unsigned ii = 0; ii < strings_list.Count(); ii++ )
614  {
615  wxString& txt = strings_list.Item( ii );
616  m_plotter->Text( positions[ii], color, txt, orient, size,
617  pt_texte->GetHorizJustify(), pt_texte->GetVertJustify(),
618  thickness, pt_texte->IsItalic(), allow_bold, false, &gbr_metadata );
619  }
620  }
621  else
622  {
623  m_plotter->Text( pos, color, shownText, orient, size,
624  pt_texte->GetHorizJustify(), pt_texte->GetVertJustify(),
625  thickness, pt_texte->IsItalic(), allow_bold, false, &gbr_metadata );
626  }
627 }
628 
629 
630 /* Plot areas (given by .m_FilledPolysList member) in a zone
631  */
633 {
634  const SHAPE_POLY_SET& polysList = aZone->GetFilledPolysList();
635 
636  if( polysList.IsEmpty() )
637  return;
638 
639  GBR_METADATA gbr_metadata;
640 
641  bool isOnCopperLayer = aZone->IsOnCopperLayer();
642 
643  if( isOnCopperLayer )
644  {
645  gbr_metadata.SetNetName( aZone->GetNetname() );
646  gbr_metadata.SetCopper( true );
647 
648  // Zones with no net name can exist.
649  // they are not used to connect items, so the aperture attribute cannot
650  // be set as conductor
651  if( aZone->GetNetname().IsEmpty() )
653  else
654  {
657  }
658  }
659 
660  // We need a buffer to store corners coordinates:
661  static std::vector< wxPoint > cornerList;
662  cornerList.clear();
663 
664  m_plotter->SetColor( getColor( aZone->GetLayer() ) );
665 
666  /* Plot all filled areas: filled areas have a filled area and a thick
667  * outline we must plot the filled area itself ( as a filled polygon
668  * OR a set of segments ) and plot the thick outline itself
669  *
670  * in non filled mode the outline is plotted, but not the filling items
671  */
672  for( auto ic = polysList.CIterate(); ic; ++ic )
673  {
674  wxPoint pos( ic->x, ic->y );
675  cornerList.push_back( pos );
676 
677  if( ic.IsEndContour() ) // Plot the current filled area outline
678  {
679  // First, close the outline
680  if( cornerList[0] != cornerList[cornerList.size() - 1] )
681  {
682  cornerList.push_back( cornerList[0] );
683  }
684 
685  // Plot the current filled area and its outline
686  if( GetPlotMode() == FILLED )
687  {
688  // Plot the filled area polygon.
689  // The area can be filled by segments or uses solid polygons
690  if( aZone->GetFillMode() == 0 ) // We are using solid polygons
691  {
692  m_plotter->PlotPoly( cornerList, FILLED_SHAPE, aZone->GetMinThickness(), &gbr_metadata );
693  }
694  else // We are using areas filled by segments: plot segments and outline
695  {
696  for( unsigned iseg = 0; iseg < aZone->FillSegments().size(); iseg++ )
697  {
698  wxPoint start = (wxPoint) aZone->FillSegments()[iseg].A;
699  wxPoint end = (wxPoint) aZone->FillSegments()[iseg].B;
700  m_plotter->ThickSegment( start, end,
701  aZone->GetMinThickness(),
702  GetPlotMode(), &gbr_metadata );
703  }
704 
705  // Plot the area outline only
706  if( aZone->GetMinThickness() > 0 )
707  m_plotter->PlotPoly( cornerList, NO_FILL, aZone->GetMinThickness() );
708  }
709  }
710  else
711  {
712  if( aZone->GetMinThickness() > 0 )
713  {
714  for( unsigned jj = 1; jj<cornerList.size(); jj++ )
715  m_plotter->ThickSegment( cornerList[jj -1], cornerList[jj],
716  aZone->GetMinThickness(),
717  GetPlotMode(), &gbr_metadata );
718  }
719 
721  }
722 
723  cornerList.clear();
724  }
725  }
726 }
727 
728 
729 /* Plot items type DRAWSEGMENT on layers allowed by aLayerMask
730  */
732 {
733  if( !m_layerMask[aSeg->GetLayer()] )
734  return;
735 
736  int radius = 0;
737  double StAngle = 0, EndAngle = 0;
738  int thickness = aSeg->GetWidth();
739 
740  m_plotter->SetColor( getColor( aSeg->GetLayer() ) );
741 
742  wxPoint start( aSeg->GetStart() );
743  wxPoint end( aSeg->GetEnd() );
744 
745  GBR_METADATA gbr_metadata;
746 
747  bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
748 
749  if( isOnCopperLayer && aSeg->GetLayer() == Edge_Cuts ) // can happens when plotting copper layers
750  {
752  }
753 
754  switch( aSeg->GetShape() )
755  {
756  case S_CIRCLE:
757  radius = KiROUND( GetLineLength( end, start ) );
758  m_plotter->ThickCircle( start, radius * 2, thickness, GetPlotMode(), &gbr_metadata );
759  break;
760 
761  case S_ARC:
762  radius = KiROUND( GetLineLength( end, start ) );
763  StAngle = ArcTangente( end.y - start.y, end.x - start.x );
764  EndAngle = StAngle + aSeg->GetAngle();
765 
766  // when startAngle == endAngle ThickArc() doesn't know whether it's 0 deg and 360 deg
767  if( std::abs( aSeg->GetAngle() ) == 3600.0 )
768  m_plotter->ThickCircle( start, radius * 2, thickness, GetPlotMode(), &gbr_metadata );
769  else
770  m_plotter->ThickArc( start, -EndAngle, -StAngle, radius, thickness, GetPlotMode(), &gbr_metadata );
771  break;
772 
773  case S_CURVE:
774  {
775  m_plotter->SetCurrentLineWidth( thickness, &gbr_metadata );
776  const std::vector<wxPoint>& bezierPoints = aSeg->GetBezierPoints();
777 
778  for( unsigned i = 1; i < bezierPoints.size(); i++ )
779  m_plotter->ThickSegment( bezierPoints[i - 1], bezierPoints[i],
780  thickness, GetPlotMode(), &gbr_metadata );
781  }
782  break;
783 
784  case S_POLYGON:
785  {
786  m_plotter->SetCurrentLineWidth( thickness, &gbr_metadata );
787  // Draw the polygon: only one polygon is expected
788  // However we provide a multi polygon shape drawing
789  // ( for the future or to show a non expected shape )
790  for( int jj = 0; jj < aSeg->GetPolyShape().OutlineCount(); ++jj )
791  {
792  SHAPE_LINE_CHAIN& poly = aSeg->GetPolyShape().Outline( jj );
793  m_plotter->PlotPoly( poly, FILLED_SHAPE, thickness, &gbr_metadata );
794  }
795  }
796  break;
797 
798  default:
799  m_plotter->ThickSegment( start, end, thickness, GetPlotMode(), &gbr_metadata );
800  }
801 }
802 
803 
808  const wxPoint &aDrillPos, wxSize aDrillSize,
809  const wxSize &aPadSize,
810  double aOrientation, int aSmallDrill )
811 {
812  // Small drill marks have no significance when applied to slots
813  if( aSmallDrill && aDrillShape == PAD_DRILL_SHAPE_CIRCLE )
814  aDrillSize.x = std::min( aSmallDrill, aDrillSize.x );
815 
816  // Round holes only have x diameter, slots have both
817  aDrillSize.x -= getFineWidthAdj();
818  aDrillSize.x = Clamp( 1, aDrillSize.x, aPadSize.x - 1 );
819 
820  if( aDrillShape == PAD_DRILL_SHAPE_OBLONG )
821  {
822  aDrillSize.y -= getFineWidthAdj();
823  aDrillSize.y = Clamp( 1, aDrillSize.y, aPadSize.y - 1 );
824  m_plotter->FlashPadOval( aDrillPos, aDrillSize, aOrientation, GetPlotMode(), NULL );
825  }
826  else
827  m_plotter->FlashPadCircle( aDrillPos, aDrillSize.x, GetPlotMode(), NULL );
828 }
829 
830 
832 {
833  /* If small drills marks were requested prepare a clamp value to pass
834  to the helper function */
835  int small_drill = (GetDrillMarksType() == PCB_PLOT_PARAMS::SMALL_DRILL_SHAPE) ?
836  SMALL_DRILL : 0;
837 
838  /* In the filled trace mode drill marks are drawn white-on-black to scrape
839  the underlying pad. This works only for drivers supporting color change,
840  obviously... it means that:
841  - PS, SVG and PDF output is correct (i.e. you have a 'donut' pad)
842  - In HPGL you can't see them
843  - In gerbers you can't see them, too. This is arguably the right thing to
844  do since having drill marks and high speed drill stations is a sure
845  recipe for broken tools and angry manufacturers. If you *really* want them
846  you could start a layer with negative polarity to scrape the film.
847  - In DXF they go into the 'WHITE' layer. This could be useful.
848  */
849  if( GetPlotMode() == FILLED )
851 
852  for( TRACK* pts = m_board->m_Track; pts != NULL; pts = pts->Next() )
853  {
854  const VIA* via = dyn_cast<const VIA*>( pts );
855 
856  if( via )
858  wxSize( via->GetDrillValue(), 0 ),
859  wxSize( via->GetWidth(), 0 ), 0, small_drill );
860  }
861 
862  for( MODULE* Module = m_board->m_Modules; Module != NULL; Module = Module->Next() )
863  {
864  for( D_PAD* pad = Module->PadsList(); pad != NULL; pad = pad->Next() )
865  {
866  if( pad->GetDrillSize().x == 0 )
867  continue;
868 
869  plotOneDrillMark( pad->GetDrillShape(),
870  pad->GetPosition(), pad->GetDrillSize(),
871  pad->GetSize(), pad->GetOrientation(),
872  small_drill );
873  }
874  }
875 
876  if( GetPlotMode() == FILLED )
878 }
void wxStringSplit(const wxString &aText, wxArrayString &aStrings, wxChar aSplitter)
Split aString to a string list separated at aSplitter.
Definition: common.cpp:131
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
KICAD_T Type() const
Function Type()
Definition: base_struct.h:209
a class to handle special data (items attributes) during plot.
void SetPadName(const wxString &aPadname)
Definition: gbr_metadata.h:130
#define SMALL_DRILL
Definition: pcbplot.h:73
BOARD_ITEM_CONTAINER * GetParent() const
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:60
aperture used for etched components
Definition: gbr_metadata.h:50
TEXTE_MODULE & Reference()
Definition: class_module.h:502
void SetShape(STROKE_T aShape)
aperture used for edge connecto pad (outer layers)
Definition: gbr_metadata.h:60
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
bool IsMultilineAllowed() const
Definition: eda_text.h:186
double GetDrawRotation() const
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...
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:127
PAD_ATTR_T GetAttribute() const
Definition: class_pad.h:405
TEXTE_PCB class definition.
const wxPoint & GetTextPos() const
Definition: eda_text.h:222
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:106
bool IsItalic() const
Definition: eda_text.h:168
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:65
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
int GetMinThickness() const
Definition: class_zone.h:198
wxPoint m_crossBarF
int GetWidth() const
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
void BuildPadPolygon(wxPoint aCoord[4], wxSize aInflateValue, double aRotation) const
Function BuildPadPolygon Has meaning only for polygonal pads (trapezoid and rectangular) Build the Co...
virtual void ThickCircle(const wxPoint &pos, int diametre, int width, EDA_DRAW_MODE_T tracemode, void *aData)
Definition: plotter.cpp:512
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
void PlotPad(D_PAD *aPad, COLOR4D aColor, EDA_DRAW_MODE_T aPlotMode)
Plot a pad.
int GetWidth() const
void SetNetAttribType(int aNetAttribType)
Definition: gbr_metadata.h:119
Class BOARD to handle a board.
void PlotDimension(DIMENSION *Dimension)
int GetRoundRectCornerRadius() const
Function GetRoundRectCornerRadius Has meaning only for rounded rect pads.
Definition: class_pad.h:524
int color
Definition: DXF_plotter.cpp:62
polygon (not yet used for tracks, but could be in microwave apps)
MODULE * Next() const
Definition: class_module.h:121
MODULE * GetParent() const
Definition: class_pad.h:162
Smd pad, appears on the solder paste layer (default)
Definition: pad_shapes.h:61
CONST_ITERATOR CIterate(int aFirst, int aLast, bool aIterateHoles=false) const
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:79
ZONE_SEGMENT_FILL & FillSegments()
Definition: class_zone.h:233
void PlotDrillMarks()
Function PlotDrillMarks Draw a drill mark for pads and vias.
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:92
aperture used for through hole component on outer layer
Definition: gbr_metadata.h:55
bool PlotAllTextsModule(MODULE *aModule)
Classes to handle copper zones.
usual segment : line with rounded ends
wxPoint m_featureLineDF
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
bool IsPolyShapeValid() const
int OutlineCount() const
Returns the number of outlines in the set
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.
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:216
#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
EDA_TEXT_HJUSTIFY_T GetHorizJustify() const
Definition: eda_text.h:188
bool GetPlotValue() const
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:80
double GetTextAngle() const
Definition: eda_text.h:162
bool IsBold() const
Definition: eda_text.h:171
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:474
virtual void FlashPadCustom(const wxPoint &aPadPos, const wxSize &aSize, SHAPE_POLY_SET *aPolygons, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadCustom
int GetThickness() const
Function GetThickness returns pen width.
Definition: eda_text.h:152
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
virtual wxString GetShownText() const
Returns the string actually shown after processing of the base text.
Definition: eda_text.h:133
BOARD_ITEM * Next() const
DIMENSION class definition.
aperture used for BGA pad with a solder mask defined by the solder mask
Definition: gbr_metadata.h:59
virtual void FlashPadCircle(const wxPoint &aPadPos, int aDiameter, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadCircle
DrillMarksType GetDrillMarksType() const
STROKE_T GetShape() const
int GetShape() const
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
void CustomShapeAsPolygonToBoardPosition(SHAPE_POLY_SET *aMergedPolygon, wxPoint aPosition, double aRotation) const
When created, the corners coordinates are relative to the pad position, orientation 0...
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:170
void PlotPcbTarget(PCB_TARGET *PtMire)
double GetOrientation() const
Definition: class_module.h:187
Class SHAPE_POLY_SET.
TEXTE_MODULE & Value()
read/write accessors:
Definition: class_module.h:501
SHAPE_LINE_CHAIN & Outline(int aIndex)
Returns the reference to aIndex-th outline in the set
EDA_DRAW_MODE_T
Definition: eda_text.h:62
const COLORS_DESIGN_SETTINGS & Colors() const
Function GetColorSettings.
Definition: class_board.h:564
void PlotBoardGraphicItems()
plot items like text and graphics, but not tracks and modules
const wxPoint & GetStart() const
Definition: class_track.h:122
const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:128
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:402
wxPoint m_arrowG1F
void Plot_1_EdgeModule(EDGE_MODULE *aEdge)
wxPoint m_arrowD2F
wxPoint m_arrowG2F
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
D_PAD * Next() const
Definition: class_pad.h:160
ZONE_FILL_MODE GetFillMode() const
Definition: class_zone.h:175
static LSET ExternalCuMask()
Function ExternalCuMask returns a mask holding the Front and Bottom layers.
Definition: lset.cpp:703
const wxSize & GetSize() const
Definition: class_pad.h:269
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:314
const wxString & GetName() const
Definition: class_pad.h:190
aperture used for mechanical pads (NPTH)
Definition: gbr_metadata.h:61
SHAPE_POLY_SET & GetPolyShape()
Bezier Curve.
bool GetPlotReference() const
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 SHAPE_POLY_SET & GetFilledPolysList() const
Function GetFilledPolysList returns a reference to the list of filled polygons.
Definition: class_zone.h:534
COLOR4D GetColor() const
aperture used for connected items like tracks (not vias)
Definition: gbr_metadata.h:51
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.
const std::vector< wxPoint > & GetBezierPoints() const
EDA_TEXT_VJUSTIFY_T GetVertJustify() const
Definition: eda_text.h:189
void SetNetName(const wxString &aNetname)
Definition: gbr_metadata.h:129
virtual void FlashPadRect(const wxPoint &aPadPos, const wxSize &aSize, double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadRect
bool IsOnCopperLayer() const
Function IsOnCopperLayer.
Definition: class_zone.cpp:181
class MARKER_PCB, a marker used to show something
Definition: typeinfo.h:99
TRACK * Next() const
Definition: class_track.h:99
double GetAngle() const
bool GetPlotInvisibleText() const
const wxString & GetNetname() const
Function GetNetname.
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.
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
const wxString & GetReference() const
Function GetReference.
Definition: class_module.h:458
virtual void FlashPadOval(const wxPoint &aPadPos, const wxSize &aSize, double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadOval
bool IsMirrored() const
Definition: eda_text.h:177
DLIST< MODULE > m_Modules
Definition: class_board.h:245
Class SHAPE_LINE_CHAIN.
bool IsVisible() const
Definition: eda_text.h:174
int GetWidth() const
Definition: class_track.h:116
virtual void ThickSegment(const wxPoint &start, const wxPoint &end, int width, EDA_DRAW_MODE_T tracemode, void *aData)
Definition: plotter.cpp:457
LSET m_layerMask
Definition: pcbplot.h:81
TEXTE_PCB & Text()
size_t i
Definition: json11.cpp:597
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees, but soon degrees.
Definition: class_pad.h:382
EDA_DRAW_MODE_T GetPlotMode() 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:57
The common library.
int GetWidth() const
COLOR4D GetLayerColor(LAYER_NUM aLayer) const
Function GetLayerColor.
void PlotTextePcb(TEXTE_PCB *pt_texte)
Definition: colors.h:49
wxPoint ShapePos() const
Definition: class_pad.cpp:500
void SetEnd(const wxPoint &aEnd)
int GetSize() const
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
MODULE * GetParentModule() const
Function GetParentModule returns a pointer to the parent module, or NULL if DRAWSEGMENT does not belo...
static LSET AllBoardTechMask()
Function AllTechMask returns a mask holding board technical layers (no CU layer) on both side...
Definition: lset.cpp:750
wxPoint m_crossBarO
PCB_TARGET class definition.
void SetApertureAttrib(GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB aApertAttribute)
Definition: gbr_metadata.h:109
DLIST< BOARD_ITEM > & GraphicalItemsList()
Definition: class_module.h:164
bool m_NotInNet
true if a pad of a footprint cannot be connected (for instance a mechanical NPTH, ot a not named pad)...
int getFineWidthAdj()
Definition: pcbplot.h:96
DLIST< TRACK > m_Track
Definition: class_board.h:246
GBR_NETLIST_METADATA m_NetlistMetadata
a item to handle object attribute:
Definition: gbr_metadata.h:148
Module description (excepted pads)
bool IsEmpty() const
Returns true if the set is empty (no polygons at all)
const wxSize & GetTextSize() const
Definition: eda_text.h:213
Basic classes for most KiCad items.
aperture used for not connected items (texts, outlines on copper)
Definition: gbr_metadata.h:53
EDGE_MODULE class definition.
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:91
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
void SetCopper(bool aValue)
Definition: gbr_metadata.h:138
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
wxPoint m_featureLineDO
print info associated to a net (TO.N attribute)
const wxPoint GetPosition() const override
Definition: class_module.h:182
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:796
void SetCmpReference(const wxString &aComponentRef)
Definition: gbr_metadata.h:131
COLOR4D getColor(LAYER_NUM aLayer)
Function getColor.
Class DIMENSION.
DLIST_ITERATOR_WRAPPER< BOARD_ITEM > Drawings()
Definition: class_board.h:252
const wxPoint GetPosition() const override
#define GBR_NETINFO_ALL
#define min(a, b)
Definition: auxiliary.h:85
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)