KiCad PCB EDA Suite
class_zone.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6  * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
31 #include <fctsys.h>
32 #include <wxstruct.h>
33 #include <trigo.h>
34 #include <class_pcb_screen.h>
35 #include <class_drawpanel.h>
36 #include <kicad_string.h>
37 #include <colors_selection.h>
38 #include <richio.h>
39 #include <macros.h>
40 #include <wxBasePcbFrame.h>
41 #include <msgpanel.h>
42 #include <bitmaps.h>
43 
44 #include <class_board.h>
45 #include <class_zone.h>
46 
47 #include <pcbnew.h>
48 #include <zones.h>
49 #include <math_for_graphics.h>
51 
52 
55 {
56  m_CornerSelection = nullptr; // no corner is selected
57  m_IsFilled = false; // fill status : true when the zone is filled
58  m_FillMode = 0; // How to fill areas: 0 = use filled polygons, != 0 fill with segments
59  m_priority = 0;
60  m_smoothedPoly = NULL;
62  SetIsKeepout( false );
63  SetDoNotAllowCopperPour( false ); // has meaning only if m_isKeepout == true
64  SetDoNotAllowVias( true ); // has meaning only if m_isKeepout == true
65  SetDoNotAllowTracks( true ); // has meaning only if m_isKeepout == true
66  m_cornerRadius = 0;
67  SetLocalFlags( 0 ); // flags tempoarry used in zone calculations
68  m_Poly = new SHAPE_POLY_SET(); // Outlines
69  aBoard->GetZoneSettings().ExportSetting( *this );
70 }
71 
72 
74  BOARD_CONNECTED_ITEM( aZone )
75 {
76  m_smoothedPoly = NULL;
77 
78  // Should the copy be on the same net?
79  SetNetCode( aZone.GetNetCode() );
80  m_Poly = new SHAPE_POLY_SET( *aZone.m_Poly );
81 
82  // For corner moving, corner index to drag, or nullptr if no selection
83  m_CornerSelection = nullptr;
84  m_IsFilled = aZone.m_IsFilled;
85  m_ZoneClearance = aZone.m_ZoneClearance; // clearance value
87  m_FillMode = aZone.m_FillMode; // Filling mode (segments/polygons)
88  m_priority = aZone.m_priority;
94  m_FillSegmList = aZone.m_FillSegmList; // vector <> copy
95 
96  m_isKeepout = aZone.m_isKeepout;
100 
103 
104  m_hatchStyle = aZone.m_hatchStyle;
105  m_hatchPitch = aZone.m_hatchPitch;
106  m_HatchLines = aZone.m_HatchLines;
107 
108  SetLocalFlags( aZone.GetLocalFlags() );
109 }
110 
111 
113 {
115 
116  // Replace the outlines for aOther outlines.
117  delete m_Poly;
118  m_Poly = new SHAPE_POLY_SET( *aOther.m_Poly );
119 
120  m_CornerSelection = nullptr; // for corner moving, corner index to (null if no selection)
121  m_ZoneClearance = aOther.m_ZoneClearance; // clearance value
123  m_FillMode = aOther.m_FillMode; // filling mode (segments/polygons)
128  SetHatchStyle( aOther.GetHatchStyle() );
129  SetHatchPitch( aOther.GetHatchPitch() );
130  m_HatchLines = aOther.m_HatchLines; // copy vector <SEG>
133  m_FillSegmList.clear();
135 
136  return *this;
137 }
138 
139 
141 {
142  delete m_Poly;
143  delete m_smoothedPoly;
144  delete m_CornerSelection;
145 }
146 
147 
149 {
150  return new ZONE_CONTAINER( *this );
151 }
152 
153 
155 {
156  bool change = ( !m_FilledPolysList.IsEmpty() ) ||
157  ( m_FillSegmList.size() > 0 );
158 
160  m_FillSegmList.clear();
161  m_IsFilled = false;
162 
163  return change;
164 }
165 
166 
168 {
169  const WX_VECTOR_CONVERTER* pos;
170 
171  // The retrieved vertex is a VECTOR2I. Casting it to a union WX_VECTOR_CONVERTER, we can later
172  // return the object shaped as a wxPoint. See the definition of the union in class_zone.h for
173  // more information on this hack.
174  pos = reinterpret_cast<const WX_VECTOR_CONVERTER*>( &GetCornerPosition( 0 ) );
175  return pos->wx;
176 }
177 
178 
179 void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMode,
180  const wxPoint& offset )
181 {
182  if( !DC )
183  return;
184 
185  wxPoint seg_start, seg_end;
186  PCB_LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
187  BOARD* brd = GetBoard();
188 
190 
191  if( brd->IsLayerVisible( m_Layer ) == false && !( aDrawMode & GR_HIGHLIGHT ) )
192  return;
193 
194  GRSetDrawMode( DC, aDrawMode );
195  DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();
196 
197  if( displ_opts->m_ContrastModeDisplay )
198  {
199  if( !IsOnLayer( curr_layer ) )
200  color = COLOR4D( DARKDARKGRAY );
201  }
202 
203  if( ( aDrawMode & GR_HIGHLIGHT ) && !( aDrawMode & GR_AND ) )
204  color.SetToLegacyHighlightColor();
205 
206  color.a = 0.588;
207 
208  // draw the lines
209  std::vector<wxPoint> lines;
210  lines.reserve( (GetNumCorners() * 2) + 2 );
211 
212  // Iterate through the segments of the outline
213  for( auto iterator = m_Poly->IterateSegmentsWithHoles(); iterator; iterator++ )
214  {
215  // Create the segment
216  SEG segment = *iterator;
217 
218  lines.push_back( static_cast<wxPoint>( segment.A ) + offset );
219  lines.push_back( static_cast<wxPoint>( segment.B ) + offset );
220  }
221 
222  GRLineArray( panel->GetClipBox(), DC, lines, 0, color );
223 
224  // draw hatches
225  lines.clear();
226  lines.reserve( (m_HatchLines.size() * 2) + 2 );
227 
228  for( unsigned ic = 0; ic < m_HatchLines.size(); ic++ )
229  {
230  seg_start = static_cast<wxPoint>( m_HatchLines[ic].A ) + offset;
231  seg_end = static_cast<wxPoint>( m_HatchLines[ic].B ) + offset;
232  lines.push_back( seg_start );
233  lines.push_back( seg_end );
234  }
235 
236  GRLineArray( panel->GetClipBox(), DC, lines, 0, color );
237 }
238 
239 
241  wxDC* DC, GR_DRAWMODE aDrawMode, const wxPoint& offset )
242 {
243  static std::vector <wxPoint> CornersBuffer;
244  DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();
245 
246  // outline_mode is false to show filled polys,
247  // and true to show polygons outlines only (test and debug purposes)
248  bool outline_mode = displ_opts->m_DisplayZonesMode == 2 ? true : false;
249 
250  if( DC == NULL )
251  return;
252 
253  if( displ_opts->m_DisplayZonesMode == 1 ) // Do not show filled areas
254  return;
255 
256  if( m_FilledPolysList.IsEmpty() ) // Nothing to draw
257  return;
258 
259  BOARD* brd = GetBoard();
260  PCB_LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
262 
263  if( brd->IsLayerVisible( m_Layer ) == false && !( aDrawMode & GR_HIGHLIGHT ) )
264  return;
265 
266  GRSetDrawMode( DC, aDrawMode );
267 
268  if( displ_opts->m_ContrastModeDisplay )
269  {
270  if( !IsOnLayer( curr_layer ) )
271  color = COLOR4D( DARKDARKGRAY );
272  }
273 
274  if( ( aDrawMode & GR_HIGHLIGHT ) && !( aDrawMode & GR_AND ) )
275  color.SetToLegacyHighlightColor();
276 
277  color.a = 0.588;
278 
279 
280  for ( int ic = 0; ic < m_FilledPolysList.OutlineCount(); ic++ )
281  {
282  const SHAPE_LINE_CHAIN& path = m_FilledPolysList.COutline( ic );
283 
284  CornersBuffer.clear();
285 
286  wxPoint p0;
287 
288  for( int j = 0; j < path.PointCount(); j++ )
289  {
290  const VECTOR2I& corner = path.CPoint( j );
291 
292  wxPoint coord( corner.x + offset.x, corner.y + offset.y );
293 
294  if( j == 0 )
295  p0 = coord;
296 
297  CornersBuffer.push_back( coord );
298  }
299 
300  CornersBuffer.push_back( p0 );
301 
302  // Draw outlines:
303  if( ( m_ZoneMinThickness > 1 ) || outline_mode )
304  {
305  int ilim = CornersBuffer.size() - 1;
306 
307  for( int is = 0, ie = ilim; is <= ilim; ie = is, is++ )
308  {
309  int x0 = CornersBuffer[is].x;
310  int y0 = CornersBuffer[is].y;
311  int x1 = CornersBuffer[ie].x;
312  int y1 = CornersBuffer[ie].y;
313 
314  // Draw only basic outlines, not extra segments.
315  if( !displ_opts->m_DisplayPcbTrackFill || GetState( FORCE_SKETCH ) )
316  GRCSegm( panel->GetClipBox(), DC,
317  x0, y0, x1, y1,
319  else
320  GRFillCSegm( panel->GetClipBox(), DC,
321  x0, y0, x1, y1, m_ZoneMinThickness, color );
322  }
323  }
324 
325  // Draw areas:
326  if( m_FillMode == 0 && !outline_mode )
327  GRPoly( panel->GetClipBox(), DC, CornersBuffer.size(), &CornersBuffer[0],
328  true, 0, color, color );
329  }
330 
331  if( m_FillMode == 1 && !outline_mode ) // filled with segments
332  {
333  for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
334  {
335  wxPoint start = m_FillSegmList[ic].m_Start + offset;
336  wxPoint end = m_FillSegmList[ic].m_End + offset;
337 
338  if( !displ_opts->m_DisplayPcbTrackFill || GetState( FORCE_SKETCH ) )
339  GRCSegm( panel->GetClipBox(), DC, start.x, start.y, end.x, end.y,
341  else
342  GRFillCSegm( panel->GetClipBox(), DC, start.x, start.y, end.x, end.y,
344  }
345  }
346 }
347 
348 
350 {
351  const int PRELOAD = 0x7FFFFFFF; // Biggest integer (32 bits)
352 
353  int ymax = -PRELOAD;
354  int ymin = PRELOAD;
355  int xmin = PRELOAD;
356  int xmax = -PRELOAD;
357 
358  int count = GetNumCorners();
359 
360  for( int i = 0; i<count; ++i )
361  {
362  wxPoint corner = static_cast<wxPoint>( GetCornerPosition( i ) );
363 
364  ymax = std::max( ymax, corner.y );
365  xmax = std::max( xmax, corner.x );
366  ymin = std::min( ymin, corner.y );
367  xmin = std::min( xmin, corner.x );
368  }
369 
370  EDA_RECT ret( wxPoint( xmin, ymin ), wxSize( xmax - xmin + 1, ymax - ymin + 1 ) );
371 
372  return ret;
373 }
374 
375 
377  GR_DRAWMODE draw_mode )
378 {
379  GR_DRAWMODE current_gr_mode = draw_mode;
380  bool is_close_segment = false;
381 
382  if( !DC )
383  return;
384 
385  PCB_LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
386  BOARD* brd = GetBoard();
388  DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();
389 
390  if( displ_opts->m_ContrastModeDisplay )
391  {
392  if( !IsOnLayer( curr_layer ) )
393  color = COLOR4D( DARKDARKGRAY );
394  }
395 
396  // Object to iterate through the corners of the outlines
398 
399  // Segment start and end
400  VECTOR2I seg_start, seg_end;
401 
402  // Remember the first point of this contour
403  VECTOR2I contour_first_point = *iterator;
404 
405  // Iterate through all the corners of the outlines and build the segments to draw
406  while( iterator )
407  {
408  // Get the first point of the current segment
409  seg_start = *iterator;
410 
411  // Get the last point of the current segment, handling the case where the end of the
412  // contour is reached, when the last point of the segment is the first point of the
413  // contour
414  if( !iterator.IsEndContour() )
415  {
416  // Set GR mode to default
417  current_gr_mode = draw_mode;
418 
419  SHAPE_POLY_SET::ITERATOR iterator_copy = iterator;
420  iterator_copy++;
421  if( iterator_copy.IsEndContour() )
422  current_gr_mode = GR_XOR;
423 
424  is_close_segment = false;
425 
426  iterator++;
427  seg_end = *iterator;
428  }
429  else
430  {
431  is_close_segment = true;
432 
433  seg_end = contour_first_point;
434 
435  // Reassign first point of the contour to the next contour start
436  iterator++;
437 
438  if( iterator )
439  contour_first_point = *iterator;
440 
441  // Set GR mode to XOR
442  current_gr_mode = GR_XOR;
443  }
444 
445  GRSetDrawMode( DC, current_gr_mode );
446 
447  if( is_close_segment )
448  GRLine( panel->GetClipBox(), DC, seg_start.x, seg_start.y, seg_end.x, seg_end.y, 0,
449  WHITE );
450  else
451  GRLine( panel->GetClipBox(), DC, seg_start.x, seg_start.y, seg_end.x, seg_end.y, 0,
452  color );
453  }
454 }
455 
456 
458 {
459  if( aPad == NULL || aPad->GetThermalGap() == 0 )
460  return m_ThermalReliefGap;
461  else
462  return aPad->GetThermalGap();
463 }
464 
465 
467 {
468  if( aPad == NULL || aPad->GetThermalWidth() == 0 )
470  else
471  return aPad->GetThermalWidth();
472 }
473 
474 
475 void ZONE_CONTAINER::SetCornerRadius( unsigned int aRadius )
476 {
477  m_cornerRadius = aRadius;
478  if( m_cornerRadius > (unsigned int) Mils2iu( MAX_ZONE_CORNER_RADIUS_MILS ) )
480 };
481 
482 
483 bool ZONE_CONTAINER::HitTest( const wxPoint& aPosition ) const
484 {
485  return HitTestForCorner( aPosition ) || HitTestForEdge( aPosition );
486 }
487 
488 
490 {
492 
493  // If there is some corner to be selected, assign it to m_CornerSelection
494  if( HitTestForCorner( aPosition, corner ) || HitTestForEdge( aPosition, corner ) )
495  {
496  if( m_CornerSelection == nullptr )
498 
499  *m_CornerSelection = corner;
500  }
501 }
502 
503 // Zones outlines have no thickness, so it Hit Test functions
504 // we must have a default distance between the test point
505 // and a corner or a zone edge:
506 #define MAX_DIST_IN_MM 0.25
507 
509  SHAPE_POLY_SET::VERTEX_INDEX& aCornerHit ) const
510 {
511  int distmax = Millimeter2iu( MAX_DIST_IN_MM );
512 
513  return m_Poly->CollideVertex( VECTOR2I( refPos ), aCornerHit, distmax );
514 }
515 
516 
517 bool ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos ) const
518 {
520  return HitTestForCorner( refPos, dummy );
521 }
522 
523 
525  SHAPE_POLY_SET::VERTEX_INDEX& aCornerHit ) const
526 {
527  int distmax = Millimeter2iu( MAX_DIST_IN_MM );
528 
529  return m_Poly->CollideEdge( VECTOR2I( refPos ), aCornerHit, distmax );
530 }
531 
532 
533 bool ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos ) const
534 {
536  return HitTestForEdge( refPos, dummy );
537 }
538 
539 
540 bool ZONE_CONTAINER::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
541 {
542  // Calculate bounding box for zone
543  EDA_RECT bbox = GetBoundingBox();
544  bbox.Normalize();
545 
546  EDA_RECT arect = aRect;
547  arect.Normalize();
548  arect.Inflate( aAccuracy );
549 
550  if( aContained )
551  {
552  return arect.Contains( bbox );
553  }
554  else // Test for intersection between aBox and the polygon
555  // For a polygon, using its bounding box has no sense here
556  {
557  // Fast test: if aBox is outside the polygon bounding box,
558  // rectangles cannot intersect
559  if( !arect.Intersects( bbox ) )
560  return false;
561 
562  // aBox is inside the polygon bounding box,
563  // and can intersect the polygon: use a fine test.
564  // aBox intersects the polygon if at least one aBox corner
565  // is inside the polygon
566 
567  /*
568  wxPoint origin = arect.GetOrigin();
569 
570  int w = arect.GetWidth();
571  int h = arect.GetHeight();
572 
573 
574  if ( HitTestInsideZone( origin ) ||
575  HitTestInsideZone( origin + wxPoint( w, 0 ) ) ||
576  HitTestInsideZone( origin + wxPoint( w, h ) ) ||
577  HitTestInsideZone( origin + wxPoint( 0, h ) ) )
578  {
579  return true;
580  }
581  */
582 
583  // No corner inside aBox, but outlines can intersect aBox
584  // if one of outline corners is inside aBox
585  int count = m_Poly->TotalVertices();
586  for( int ii =0; ii < count; ii++ )
587  {
588  auto vertex = m_Poly->Vertex( ii );
589  auto vertexNext = m_Poly->Vertex( ( ii + 1 ) % count );
590 
591  // Test if the point is within the rect
592  if( arect.Contains( ( wxPoint ) vertex ) )
593  {
594  return true;
595  }
596 
597  // Test if this edge intersects the rect
598  if( arect.Intersects( ( wxPoint ) vertex, ( wxPoint ) vertexNext ) )
599  {
600  return true;
601  }
602  }
603 
604  return false;
605  }
606 }
607 
608 
610 {
611  int myClearance = m_ZoneClearance;
612 
613 #if 0 // Maybe the netclass clearance should not come into play for a zone?
614  // At least the policy decision can be controlled by the zone
615  // itself, i.e. here. On reasons of insufficient documentation,
616  // the user will be less bewildered if we simply respect the
617  // "zone clearance" setting in the zone properties dialog. (At least
618  // until there is a UI boolean for this.)
619 
620  NETCLASSPTR myClass = GetNetClass();
621 
622  if( myClass )
623  myClearance = std::max( myClearance, myClass->GetClearance() );
624 #endif
625 
626  if( aItem )
627  {
628  int hisClearance = aItem->GetClearance( NULL );
629  myClearance = std::max( hisClearance, myClearance );
630  }
631 
632  return myClearance;
633 }
634 
635 
636 bool ZONE_CONTAINER::HitTestFilledArea( const wxPoint& aRefPos ) const
637 {
638  return m_FilledPolysList.Contains( VECTOR2I( aRefPos.x, aRefPos.y ) );
639 }
640 
641 
642 void ZONE_CONTAINER::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
643 {
644  wxString msg;
645 
646  msg = _( "Zone Outline" );
647 
648  // Display Cutout instead of Outline for holes inside a zone
649  // i.e. when num contour !=0
650  // Check whether the selected corner is in a hole; i.e., in any contour but the first one.
651  if( m_CornerSelection != nullptr && m_CornerSelection->m_contour > 0 )
652  msg << wxT( " " ) << _( "(Cutout)" );
653 
654  aList.push_back( MSG_PANEL_ITEM( _( "Type" ), msg, DARKCYAN ) );
655 
656  if( GetIsKeepout() )
657  {
658  msg.Empty();
659 
660  if( GetDoNotAllowVias() )
661  AccumulateDescription( msg, _( "No via" ) );
662 
663  if( GetDoNotAllowTracks() )
664  AccumulateDescription( msg, _("No track") );
665 
667  AccumulateDescription( msg, _("No copper pour") );
668 
669  aList.push_back( MSG_PANEL_ITEM( _( "Keepout" ), msg, RED ) );
670  }
671  else if( IsOnCopperLayer() )
672  {
673  if( GetNetCode() >= 0 )
674  {
675  NETINFO_ITEM* net = GetNet();
676 
677  if( net )
678  msg = net->GetNetname();
679  else // Should not occur
680  msg = _( "<unknown>" );
681  }
682  else // a netcode < 0 is an error
683  msg = wxT( "<error>" );
684 
685  aList.push_back( MSG_PANEL_ITEM( _( "NetName" ), msg, RED ) );
686 
687  // Display net code : (useful in test or debug)
688  msg.Printf( wxT( "%d" ), GetNetCode() );
689  aList.push_back( MSG_PANEL_ITEM( _( "NetCode" ), msg, RED ) );
690 
691  // Display priority level
692  msg.Printf( wxT( "%d" ), GetPriority() );
693  aList.push_back( MSG_PANEL_ITEM( _( "Priority" ), msg, BLUE ) );
694  }
695  else
696  {
697  aList.push_back( MSG_PANEL_ITEM( _( "Non Copper Zone" ), wxEmptyString, RED ) );
698  }
699 
700  aList.push_back( MSG_PANEL_ITEM( _( "Layer" ), GetLayerName(), BROWN ) );
701 
702  msg.Printf( wxT( "%d" ), (int) m_Poly->TotalVertices() );
703  aList.push_back( MSG_PANEL_ITEM( _( "Corners" ), msg, BLUE ) );
704 
705  if( m_FillMode )
706  msg = _( "Segments" );
707  else
708  msg = _( "Polygons" );
709 
710  aList.push_back( MSG_PANEL_ITEM( _( "Fill Mode" ), msg, BROWN ) );
711 
712  // Useful for statistics :
713  msg.Printf( wxT( "%d" ), (int) m_HatchLines.size() );
714  aList.push_back( MSG_PANEL_ITEM( _( "Hatch Lines" ), msg, BLUE ) );
715 
716  if( !m_FilledPolysList.IsEmpty() )
717  {
718  msg.Printf( wxT( "%d" ), m_FilledPolysList.TotalVertices() );
719  aList.push_back( MSG_PANEL_ITEM( _( "Corner Count" ), msg, BLUE ) );
720  }
721 }
722 
723 
724 /* Geometric transforms: */
725 
726 void ZONE_CONTAINER::Move( const wxPoint& offset )
727 {
728  /* move outlines */
729  m_Poly->Move( VECTOR2I( offset ) );
730 
731  Hatch();
732 
733  m_FilledPolysList.Move( VECTOR2I( offset.x, offset.y ) );
734 
735  for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
736  {
737  m_FillSegmList[ic].m_Start += offset;
738  m_FillSegmList[ic].m_End += offset;
739  }
740 }
741 
742 
743 void ZONE_CONTAINER::MoveEdge( const wxPoint& offset, int aEdge )
744 {
745  int next_corner;
746 
747  if( m_Poly->GetNeighbourIndexes( aEdge, nullptr, &next_corner ) )
748  {
749  m_Poly->Vertex( aEdge ) += VECTOR2I( offset );
750  m_Poly->Vertex( next_corner ) += VECTOR2I( offset );
751  Hatch();
752  }
753 }
754 
755 
756 void ZONE_CONTAINER::Rotate( const wxPoint& centre, double angle )
757 {
758  wxPoint pos;
759 
760  for( auto iterator = m_Poly->IterateWithHoles(); iterator; iterator++ )
761  {
762  pos = static_cast<wxPoint>( *iterator );
763  RotatePoint( &pos, centre, angle );
764  iterator->x = pos.x;
765  iterator->y = pos.y;
766  }
767 
768  Hatch();
769 
770  /* rotate filled areas: */
771  for( auto ic = m_FilledPolysList.Iterate(); ic; ++ic )
772  RotatePoint( &ic->x, &ic->y, centre.x, centre.y, angle );
773 
774  for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
775  {
776  RotatePoint( &m_FillSegmList[ic].m_Start, centre, angle );
777  RotatePoint( &m_FillSegmList[ic].m_End, centre, angle );
778  }
779 }
780 
781 
782 void ZONE_CONTAINER::Flip( const wxPoint& aCentre )
783 {
784  Mirror( aCentre );
785  int copperLayerCount = GetBoard()->GetCopperLayerCount();
786  SetLayer( FlipLayer( GetLayer(), copperLayerCount ) );
787 }
788 
789 
790 void ZONE_CONTAINER::Mirror( const wxPoint& mirror_ref )
791 {
792  for( auto iterator = m_Poly->IterateWithHoles(); iterator; iterator++ )
793  {
794  int py = mirror_ref.y - iterator->y;
795  iterator->y = py + mirror_ref.y;
796  }
797 
798  Hatch();
799 
800  for( auto ic = m_FilledPolysList.Iterate(); ic; ++ic )
801  {
802  int py = mirror_ref.y - ic->y;
803  ic->y = py + mirror_ref.y;
804  }
805 
806  for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
807  {
808  MIRROR( m_FillSegmList[ic].m_Start.y, mirror_ref.y );
809  MIRROR( m_FillSegmList[ic].m_End.y, mirror_ref.y );
810  }
811 }
812 
813 
815 {
816  if( aPad == NULL || aPad->GetZoneConnection() == PAD_ZONE_CONN_INHERITED )
817  return m_PadConnection;
818  else
819  return aPad->GetZoneConnection();
820 }
821 
822 
823 void ZONE_CONTAINER::AddPolygon( std::vector< wxPoint >& aPolygon )
824 {
825  if( aPolygon.empty() )
826  return;
827 
828  SHAPE_LINE_CHAIN outline;
829 
830  // Create an outline and populate it with the points of aPolygon
831  for( unsigned i = 0; i < aPolygon.size(); i++ )
832  {
833  outline.Append( VECTOR2I( aPolygon[i] ) );
834  }
835 
836  outline.SetClosed( true );
837 
838  // Add the outline as a new polygon in the polygon set
839  if( m_Poly->OutlineCount() == 0 )
840  m_Poly->AddOutline( outline );
841  else
842  m_Poly->AddHole( outline );
843 }
844 
845 
847 {
848  wxString text;
849  NETINFO_ITEM* net;
850  BOARD* board = GetBoard();
851 
852  // Check whether the selected contour is a hole (contour index > 0)
853  if( m_CornerSelection != nullptr && m_CornerSelection->m_contour > 0 )
854  text << wxT( " " ) << _( "(Cutout)" );
855 
856  if( GetIsKeepout() )
857  text << wxT( " " ) << _( "(Keepout)" );
858 
859  text << wxString::Format( wxT( " (%08lX)" ), m_TimeStamp );
860 
861  // Display net name for copper zones
862  if( !GetIsKeepout() )
863  {
864  if( GetNetCode() >= 0 )
865  {
866  if( board )
867  {
868  net = GetNet();
869 
870  if( net )
871  {
872  text << wxT( " [" ) << net->GetNetname() << wxT( "]" );
873  }
874  }
875  else
876  {
877  text << _( "** NO BOARD DEFINED **" );
878  }
879  }
880  else
881  { // A netcode < 0 is an error:
882  // Netname not found or area not initialised
883  text << wxT( " [" ) << GetNetname() << wxT( "]" );
884  text << wxT( " <" ) << _( "Not Found" ) << wxT( ">" );
885  }
886  }
887 
888  wxString msg;
889  msg.Printf( _( "Zone Outline %s on %s" ), GetChars( text ),
890  GetChars( GetLayerName() ) );
891 
892  return msg;
893 }
894 
895 
897 {
898  return m_hatchPitch;
899 }
900 
901 
902 void ZONE_CONTAINER::SetHatch( int aHatchStyle, int aHatchPitch, bool aRebuildHatch )
903 {
904  SetHatchPitch( aHatchPitch );
906 
907  if( aRebuildHatch )
908  Hatch();
909 }
910 
911 
913 {
914  m_hatchPitch = aPitch;
915 }
916 
917 
919 {
920  m_HatchLines.clear();
921 }
922 
923 
924 // Creates hatch lines inside the outline of the complex polygon
925 // sort function used in ::Hatch to sort points by descending wxPoint.x values
926 bool sortEndsByDescendingX( const VECTOR2I& ref, const VECTOR2I& tst )
927 {
928  return tst.x < ref.x;
929 }
930 
931 // Implementation copied from old CPolyLine
933 {
934  UnHatch();
935 
936  if( m_hatchStyle == NO_HATCH || m_hatchPitch == 0 || m_Poly->IsEmpty() )
937  return;
938 
939  // define range for hatch lines
940  int min_x = m_Poly->Vertex( 0 ).x;
941  int max_x = m_Poly->Vertex( 0 ).x;
942  int min_y = m_Poly->Vertex( 0 ).y;
943  int max_y = m_Poly->Vertex( 0 ).y;
944 
945  for( auto iterator = m_Poly->IterateWithHoles(); iterator; iterator++ )
946  {
947  if( iterator->x < min_x )
948  min_x = iterator->x;
949 
950  if( iterator->x > max_x )
951  max_x = iterator->x;
952 
953  if( iterator->y < min_y )
954  min_y = iterator->y;
955 
956  if( iterator->y > max_y )
957  max_y = iterator->y;
958  }
959 
960  // Calculate spacing between 2 hatch lines
961  int spacing;
962 
963  if( m_hatchStyle == DIAGONAL_EDGE )
964  spacing = m_hatchPitch;
965  else
966  spacing = m_hatchPitch * 2;
967 
968  // set the "length" of hatch lines (the length on horizontal axis)
969  int hatch_line_len = m_hatchPitch;
970 
971  // To have a better look, give a slope depending on the layer
972  LAYER_NUM layer = GetLayer();
973  int slope_flag = (layer & 1) ? 1 : -1; // 1 or -1
974  double slope = 0.707106 * slope_flag; // 45 degrees slope
975  int max_a, min_a;
976 
977  if( slope_flag == 1 )
978  {
979  max_a = KiROUND( max_y - slope * min_x );
980  min_a = KiROUND( min_y - slope * max_x );
981  }
982  else
983  {
984  max_a = KiROUND( max_y - slope * max_x );
985  min_a = KiROUND( min_y - slope * min_x );
986  }
987 
988  min_a = (min_a / spacing) * spacing;
989 
990  // calculate an offset depending on layer number,
991  // for a better look of hatches on a multilayer board
992  int offset = (layer * 7) / 8;
993  min_a += offset;
994 
995  // loop through hatch lines
996  #define MAXPTS 200 // Usually we store only few values per one hatch line
997  // depending on the complexity of the zone outline
998 
999  static std::vector<VECTOR2I> pointbuffer;
1000  pointbuffer.clear();
1001  pointbuffer.reserve( MAXPTS + 2 );
1002 
1003  for( int a = min_a; a < max_a; a += spacing )
1004  {
1005  // get intersection points for this hatch line
1006 
1007  // Note: because we should have an even number of intersections with the
1008  // current hatch line and the zone outline (a closed polygon,
1009  // or a set of closed polygons), if an odd count is found
1010  // we skip this line (should not occur)
1011  pointbuffer.clear();
1012 
1013  // Iterate through all vertices
1014  for( auto iterator = m_Poly->IterateSegmentsWithHoles(); iterator; iterator++ )
1015  {
1016  double x, y, x2, y2;
1017  int ok;
1018 
1019  SEG segment = *iterator;
1020 
1021  ok = FindLineSegmentIntersection( a, slope,
1022  segment.A.x, segment.A.y,
1023  segment.B.x, segment.B.y,
1024  &x, &y, &x2, &y2 );
1025 
1026  if( ok )
1027  {
1028  VECTOR2I point( KiROUND( x ), KiROUND( y ) );
1029  pointbuffer.push_back( point );
1030  }
1031 
1032  if( ok == 2 )
1033  {
1034  VECTOR2I point( KiROUND( x2 ), KiROUND( y2 ) );
1035  pointbuffer.push_back( point );
1036  }
1037 
1038  if( pointbuffer.size() >= MAXPTS ) // overflow
1039  {
1040  wxASSERT( 0 );
1041  break;
1042  }
1043  }
1044 
1045  // ensure we have found an even intersection points count
1046  // because intersections are the ends of segments
1047  // inside the polygon(s) and a segment has 2 ends.
1048  // if not, this is a strange case (a bug ?) so skip this hatch
1049  if( pointbuffer.size() % 2 != 0 )
1050  continue;
1051 
1052  // sort points in order of descending x (if more than 2) to
1053  // ensure the starting point and the ending point of the same segment
1054  // are stored one just after the other.
1055  if( pointbuffer.size() > 2 )
1056  sort( pointbuffer.begin(), pointbuffer.end(), sortEndsByDescendingX );
1057 
1058  // creates lines or short segments inside the complex polygon
1059  for( unsigned ip = 0; ip < pointbuffer.size(); ip += 2 )
1060  {
1061  int dx = pointbuffer[ip + 1].x - pointbuffer[ip].x;
1062 
1063  // Push only one line for diagonal hatch,
1064  // or for small lines < twice the line length
1065  // else push 2 small lines
1066  if( m_hatchStyle == DIAGONAL_FULL || fabs( dx ) < 2 * hatch_line_len )
1067  {
1068  m_HatchLines.push_back( SEG( pointbuffer[ip], pointbuffer[ip + 1] ) );
1069  }
1070  else
1071  {
1072  double dy = pointbuffer[ip + 1].y - pointbuffer[ip].y;
1073  slope = dy / dx;
1074 
1075  if( dx > 0 )
1076  dx = hatch_line_len;
1077  else
1078  dx = -hatch_line_len;
1079 
1080  int x1 = KiROUND( pointbuffer[ip].x + dx );
1081  int x2 = KiROUND( pointbuffer[ip + 1].x - dx );
1082  int y1 = KiROUND( pointbuffer[ip].y + dx * slope );
1083  int y2 = KiROUND( pointbuffer[ip + 1].y - dx * slope );
1084 
1085  m_HatchLines.push_back(SEG(pointbuffer[ip].x, pointbuffer[ip].y, x1, y1));
1086 
1087  m_HatchLines.push_back( SEG( pointbuffer[ip+1].x, pointbuffer[ip+1].y, x2, y2 ) );
1088  }
1089  }
1090  }
1091 }
1092 
1093 
1095 {
1096  return add_zone_xpm;
1097 }
Definition: colors.h:57
void SetDoNotAllowTracks(bool aEnable)
Definition: class_zone.h:662
void MoveEdge(const wxPoint &offset, int aEdge)
Function MoveEdge Move the outline Edge.
Definition: class_zone.cpp:743
COLOR4D GetLayerColor(PCB_LAYER_ID aLayer) const
Function GetLayerColor gets a layer color for any valid layer, including non-copper ones...
void SetHatchPitch(int aPitch)
Function SetHatchPitch sets the hatch pitch parameter for the zone.
Definition: class_zone.cpp:912
void Draw(EDA_DRAW_PANEL *panel, wxDC *DC, GR_DRAWMODE aDrawMode, const wxPoint &offset=ZeroOffset) override
Function Draw Draws the zone outline.
Definition: class_zone.cpp:179
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:78
void GRPoly(EDA_RECT *ClipBox, wxDC *DC, int n, wxPoint Points[], bool Fill, int width, COLOR4D Color, COLOR4D BgColor)
Definition: gr_basic.cpp:767
int m_ZoneClearance
Clearance value in internal units.
Definition: class_zone.h:749
void DrawWhileCreateOutline(EDA_DRAW_PANEL *panel, wxDC *DC, GR_DRAWMODE draw_mode=GR_OR)
Function DrawWhileCreateOutline Draws the zone outline when it is created.
Definition: class_zone.cpp:376
void GetMsgPanelInfo(std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfo populates aList of MSG_PANEL_ITEM objects with it's internal state for displ...
Definition: class_zone.cpp:642
const ZONE_SETTINGS & GetZoneSettings() const
Definition: class_board.h:554
int GetNumCorners(void) const
Access to m_Poly parameters.
Definition: class_zone.h:466
wxString GetSelectMenuText() const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
Definition: class_zone.cpp:846
PNG memory record (file in memory).
Definition: bitmap_types.h:38
void GRSetDrawMode(wxDC *DC, GR_DRAWMODE draw_mode)
Definition: gr_basic.cpp:290
static int KiROUND(double v)
KiROUND rounds a floating point number to an int using "round halfway cases away from zero"...
Definition: common.h:107
SEGMENT_ITERATOR IterateSegmentsWithHoles()
Returns an iterator object, for all outlines in the set (with holes)
bool HitTestForEdge(const wxPoint &refPos, SHAPE_POLY_SET::VERTEX_INDEX &aCornerHit) const
Function HitTestForEdge tests if the given wxPoint is near a segment defined by 2 corners...
Definition: class_zone.cpp:524
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Function IsOnLayer tests to see if this object is on the given layer.
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
Definition: class_zone.cpp:148
bool CollideEdge(const VECTOR2I &aPoint, VERTEX_INDEX &aClosestVertex, int aClearance=0)
Function CollideEdge Checks whether aPoint collides with any edge of any of the contours of the polyg...
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
bool GetDoNotAllowCopperPour() const
Definition: class_zone.h:655
bool m_doNotAllowTracks
Definition: class_zone.h:746
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox (virtual)
Definition: class_zone.cpp:349
time_t m_TimeStamp
Time stamp used for logical links.
Definition: base_struct.h:169
int PointCount() const
Function PointCount()
bool Contains(const wxPoint &aPoint) const
Function Contains.
void SetCornerRadius(unsigned int aRadius)
Definition: class_zone.cpp:475
SHAPE_POLY_SET::VERTEX_INDEX * m_CornerSelection
The index of the corner being moved or nullptr if no corner is selected.
Definition: class_zone.h:770
void GRLine(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, COLOR4D Color)
Definition: gr_basic.cpp:352
Class BOARD to handle a board.
void DrawFilledArea(EDA_DRAW_PANEL *panel, wxDC *DC, GR_DRAWMODE aDrawMode, const wxPoint &offset=ZeroOffset)
Function DrawDrawFilledArea Draws the filled area for this zone (polygon list .m_FilledPolysList) ...
Definition: class_zone.cpp:240
ZoneConnection
How pads are covered by copper in zone.
Definition: zones.h:55
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Function FlippedLayerNumber.
Definition: lset.cpp:445
int GetCopperLayerCount() const
Function GetCopperLayerCount.
class ZONE_CONTAINER, a zone area
Definition: typeinfo.h:114
int TotalVertices() const
Returns total number of vertices stored in the set.
Struct VERTEX_INDEX.
void GRCSegm(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, int aPenSize, COLOR4D Color)
Definition: gr_basic.cpp:481
Classes to handle copper zones.
void SetHatch(int aHatchStyle, int aHatchPitch, bool aRebuildHatch)
Function SetHatch sets all hatch parameters for the zone.
Definition: class_zone.cpp:902
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
ITERATOR Iterate(int aFirst, int aLast, bool aIterateHoles=false)
Function Iterate returns an object to iterate through the points of the polygons between aFirst and a...
int OutlineCount() const
Returns the number of outlines in the set
int GetState(int type) const
Definition: base_struct.h:237
VECTOR2< int > VECTOR2I
Definition: vector2d.h:590
int GetThermalReliefCopperBridge(D_PAD *aPad=NULL) const
Definition: class_zone.cpp:466
Class BOARD_CONNECTED_ITEM is a base class derived from BOARD_ITEM for items that can be connected an...
const VECTOR2I & GetCornerPosition(int aCornerIndex) const
Definition: class_zone.h:506
wxString GetLayerName() const
Function GetLayerName returns the name of the PCB layer on which the item resides.
int GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const override
Function GetClearance returns the clearance in 1/10000 inches.
Definition: class_zone.cpp:609
struct SHAPE_POLY_SET::VERTEX_INDEX VERTEX_INDEX
Struct VERTEX_INDEX.
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
void SetDoNotAllowVias(bool aEnable)
Definition: class_zone.h:661
bool IsEndContour() const
Function IsEndContour.
This file contains miscellaneous commonly used macros and functions.
VECTOR2I & Vertex(int aIndex, int aOutline, int aHole)
Returns the index-th vertex in a given hole outline within a given outline
void ExportSetting(ZONE_CONTAINER &aTarget, bool aFullExport=true) const
Function ExportSetting copy settings to a given zone.
bool GetIsKeepout() const
Accessors to parameters used in Keepout zones:
Definition: class_zone.h:654
bool GetNeighbourIndexes(int aGlobalIndex, int *aPrevious, int *aNext)
Returns the global indexes of the previous and the next corner of the aGlobalIndex-th corner of a con...
PCB_LAYER_ID m_Layer
void MIRROR(T &aPoint, const T &aMirrorRef)
Definition: macros.h:111
SHAPE_POLY_SET * m_smoothedPoly
Definition: class_zone.h:726
#define MAXPTS
void SetClosed(bool aClosed)
Function SetClosed()
bool m_DisplayPcbTrackFill
Definition: pcbstruct.h:71
bool sortEndsByDescendingX(const VECTOR2I &ref, const VECTOR2I &tst)
Definition: class_zone.cpp:926
int m_ArcToSegmentsCount
The number of segments to convert a circle to a polygon.
Definition: class_zone.h:754
PCB_LAYER_ID
A quick note on layer IDs:
double a
Alpha component.
Definition: color4d.h:284
int m_ThermalReliefCopperBridge
Definition: class_zone.h:763
ZoneConnection GetPadConnection(D_PAD *aPad=NULL) const
Definition: class_zone.cpp:814
Classes used in Pcbnew, CvPcb and GerbView.
std::vector< SEG > m_HatchLines
Definition: class_zone.h:792
ZoneConnection m_PadConnection
Definition: class_zone.h:748
void Move(const VECTOR2I &aVector) override
std::shared_ptr< NETCLASS > GetNetClass() const
Function GetNetClass returns the NETCLASS for this item.
ZONE_CONTAINER & operator=(const ZONE_CONTAINER &aOther)
Definition: class_zone.cpp:112
GR_DRAWMODE
Drawmode. Compositing mode plus a flag or two.
Definition: gr_basic.h:41
ITERATOR IterateWithHoles(int aOutline)
Function IterateWithHoles.
Class SHAPE_POLY_SET.
Base window classes and related definitions.
void GRFillCSegm(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, COLOR4D Color)
Definition: gr_basic.cpp:584
bool m_IsFilled
True when a zone was filled, false after deleting the filled areas.
Definition: class_zone.h:757
int m_FillMode
How to fill areas: 0 => use filled polygons, 1 => fill with segments.
Definition: class_zone.h:767
virtual void Flip(const wxPoint &aCentre) override
Function Flip Flip this object, i.e.
Definition: class_zone.cpp:782
ZoneConnection GetZoneConnection() const
Definition: class_pad.cpp:610
SHAPE_POLY_SET * m_Poly
Outline of the zone.
Definition: class_zone.h:725
int GetThermalReliefGap(D_PAD *aPad=NULL) const
Definition: class_zone.cpp:457
ZONE_CONTAINER(BOARD *parent)
Definition: class_zone.cpp:53
unsigned m_priority
Definition: class_zone.h:734
int GetThermalWidth() const
Definition: class_pad.cpp:621
bool m_ContrastModeDisplay
Definition: pcbstruct.h:85
void Rotate(const wxPoint &centre, double angle) override
Function Rotate Move the outlines.
Definition: class_zone.cpp:756
bool m_doNotAllowVias
Definition: class_zone.h:745
int GetThermalGap() const
Definition: class_pad.cpp:632
bool CollideVertex(const VECTOR2I &aPoint, VERTEX_INDEX &aClosestVertex, int aClearance=0)
Function CollideVertex Checks whether aPoint collides with any vertex of any of the contours of the p...
bool UnFill()
Function UnFill Removes the zone filling.
Definition: class_zone.cpp:154
int m_cornerSmoothingType
Definition: class_zone.h:727
EDA_RECT * GetClipBox()
bool SetNetCode(int aNetCode, bool aNoAssert=false)
Function SetNetCode sets net using a net code.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
int m_DisplayZonesMode
Definition: pcbstruct.h:77
Definition: colors.h:60
HATCH_STYLE
Zone hatch styles.
Definition: class_zone.h:85
virtual int GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const
Function GetClearance returns the clearance in 1/10000 inches.
bool FindLineSegmentIntersection(double a, double b, int xi, int yi, int xf, int yf, double *x1, double *y1, double *x2, double *y2, double *dist)
void AddPolygon(std::vector< wxPoint > &aPolygon)
add a polygon to the zone outline if the zone outline is empty, this is the main outline else it is a...
Definition: class_zone.cpp:823
EDA_ITEM & operator=(const EDA_ITEM &aItem)
Operator assignment is used to assign the members of aItem to another object.
SHAPE_POLY_SET m_FilledPolysList
Definition: class_zone.h:788
int AddHole(const SHAPE_LINE_CHAIN &aHole, int aOutline=-1)
Adds a new hole to the given outline (default: last) and returns its index
void SetSelectedCorner(int aCorner)
Definition: class_zone.h:221
unsigned int m_cornerRadius
Definition: class_zone.h:728
int LAYER_NUM
Type LAYER_NUM can be replaced with int and removed.
Class DISPLAY_OPTIONS handles display options like enable/disable some optional drawings.
Definition: pcbstruct.h:62
void Move(const wxPoint &offset) override
Function Move Move the outlines.
Definition: class_zone.cpp:726
int GetNetCode() const
Function GetNetCode.
HATCH_STYLE m_hatchStyle
Definition: class_zone.h:790
Definition: seg.h:37
const wxPoint & GetPosition() const override
Function GetPosition.
Definition: class_zone.cpp:167
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index
void Normalize()
Function Normalize ensures that the height ant width are positive.
void AccumulateDescription(wxString &aDesc, const wxString &aItem)
Utility to build comma separated lists in messages.
Definition: macros.h:65
void SetDoNotAllowCopperPour(bool aEnable)
Definition: class_zone.h:660
bool Intersects(const EDA_RECT &aRect) const
Function Intersects tests for a common area between rectangles.
Class NETINFO_ITEM handles the data for a net.
PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
bool m_doNotAllowCopperPour
Definition: class_zone.h:744
bool IsOnCopperLayer() const
Function IsOnCopperLayer.
Definition: class_zone.h:179
int m_ThermalReliefGap
Width of the copper bridge in thermal reliefs.
Definition: class_zone.h:760
bool GetDoNotAllowTracks() const
Definition: class_zone.h:657
int m_ZoneMinThickness
Minimum thickness value in filled areas.
Definition: class_zone.h:750
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
const wxString & GetNetname() const
Function GetNetname.
void UnHatch()
Function UnHatch clears the zone's hatch.
Definition: class_zone.cpp:918
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
int GetLocalFlags() const
Definition: class_zone.h:241
bool GetDoNotAllowVias() const
Definition: class_zone.h:656
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...
#define max(a, b)
Definition: auxiliary.h:86
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:166
Class SHAPE_LINE_CHAIN.
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
Class ITERATOR_TEMPLATE.
virtual bool HitTest(const wxPoint &aPosition) const override
Function HitTest tests if a point is near an outline edge or a corner of this zone.
Definition: class_zone.cpp:483
void RemoveAllContours()
Removes all outlines & holes (clears) the polygon set.
bool HitTestFilledArea(const wxPoint &aRefPos) const
Function HitTestFilledArea tests if the given wxPoint is within the bounds of a filled area of this z...
Definition: class_zone.cpp:636
VECTOR2I A
Definition: seg.h:47
Class EDA_RECT handles the component boundary box.
HATCH_STYLE GetHatchStyle() const
Definition: class_zone.h:554
void Hatch()
Function Hatch computes the hatch lines depending on the hatch parameters and stores it in the zone's...
Definition: class_zone.cpp:932
BASE_SCREEN * GetScreen()
Definition: draw_panel.cpp:188
void SetHatchStyle(HATCH_STYLE aStyle)
Definition: class_zone.h:559
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:151
void SetLocalFlags(int aFlags)
Definition: class_zone.h:242
void GRLineArray(EDA_RECT *aClipBox, wxDC *aDC, std::vector< wxPoint > &aLines, int aWidth, COLOR4D aColor)
Function GRLineArray draws an array of lines (not a polygon).
Definition: gr_basic.cpp:427
Definition: colors.h:49
virtual BOARD * GetBoard() const
Function GetBoard returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
#define MAX_DIST_IN_MM
Definition: class_zone.cpp:506
int GetHatchPitch() const
Hatch related methods.
Definition: class_zone.cpp:896
bool IsEmpty() const
Returns true if the set is empty (no polygons at all)
const wxString & GetNetname() const
Function GetNetname.
void * GetDisplayOptions()
Function GetDisplayOptions A way to pass info to draw functions.
Definition: draw_panel.cpp:182
void Mirror(const wxPoint &mirror_ref)
Function Mirror Mirror the outlines , relative to a given horizontal axis the layer is not changed...
Definition: class_zone.cpp:790
Class EDA_MSG_ITEM is used EDA_MSG_PANEL as the item type for displaying messages.
Definition: msgpanel.h:53
void SetIsKeepout(bool aEnable)
Definition: class_zone.h:659
unsigned GetPriority() const
Function GetPriority.
Definition: class_zone.h:119
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
Message panel definition file.
bool HitTestForCorner(const wxPoint &refPos, SHAPE_POLY_SET::VERTEX_INDEX &aCornerHit) const
Function HitTestForCorner tests if the given wxPoint is near a corner.
Definition: class_zone.cpp:508
#define FORCE_SKETCH
Definition: pcbnew.h:68
const VECTOR2I & CPoint(int aIndex) const
Function CPoint()
Union to handle conversion between references to wxPoint and to VECTOR2I.
Definition: class_zone.h:817
bool Contains(const VECTOR2I &aP, int aSubpolyIndex=-1) const
Returns true if a given subpolygon contains the point aP.
NETINFO_ITEM * GetNet() const
Function GetNet Returns NET_INFO object for a given item.
std::vector< SEGMENT > m_FillSegmList
Segments used to fill the zone (m_FillMode ==1 ), when fill zone by segment is used.
Definition: class_zone.h:778
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
#define min(a, b)
Definition: auxiliary.h:85
#define MAX_ZONE_CORNER_RADIUS_MILS
bool IsLayerVisible(PCB_LAYER_ID aLayer) const
Function IsLayerVisible is a proxy function that calls the correspondent function in m_BoardSettings ...
Definition: class_board.h:440
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline) ...
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
VECTOR2I B
Definition: seg.h:48
Definition: colors.h:62