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) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6  * Copyright (C) 1992-2017 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 <richio.h>
38 #include <macros.h>
39 #include <wxBasePcbFrame.h>
40 #include <msgpanel.h>
41 #include <bitmaps.h>
42 
43 #include <convert_to_biu.h>
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 
189  auto frame = static_cast<PCB_BASE_FRAME*> ( panel->GetParent() );
190 
191  auto color = frame->Settings().Colors().GetLayerColor( m_Layer );
192 
193  if( brd->IsLayerVisible( m_Layer ) == false && !( aDrawMode & GR_HIGHLIGHT ) )
194  return;
195 
196  GRSetDrawMode( DC, aDrawMode );
197  DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();
198 
199  if( displ_opts->m_ContrastModeDisplay )
200  {
201  if( !IsOnLayer( curr_layer ) )
203  }
204 
205  if( ( aDrawMode & GR_HIGHLIGHT ) && !( aDrawMode & GR_AND ) )
206  color.SetToLegacyHighlightColor();
207 
208  color.a = 0.588;
209 
210  // draw the lines
211  std::vector<wxPoint> lines;
212  lines.reserve( (GetNumCorners() * 2) + 2 );
213 
214  // Iterate through the segments of the outline
215  for( auto iterator = m_Poly->IterateSegmentsWithHoles(); iterator; iterator++ )
216  {
217  // Create the segment
218  SEG segment = *iterator;
219 
220  lines.push_back( static_cast<wxPoint>( segment.A ) + offset );
221  lines.push_back( static_cast<wxPoint>( segment.B ) + offset );
222  }
223 
224  GRLineArray( panel->GetClipBox(), DC, lines, 0, color );
225 
226  // draw hatches
227  lines.clear();
228  lines.reserve( (m_HatchLines.size() * 2) + 2 );
229 
230  for( unsigned ic = 0; ic < m_HatchLines.size(); ic++ )
231  {
232  seg_start = static_cast<wxPoint>( m_HatchLines[ic].A ) + offset;
233  seg_end = static_cast<wxPoint>( m_HatchLines[ic].B ) + offset;
234  lines.push_back( seg_start );
235  lines.push_back( seg_end );
236  }
237 
238  GRLineArray( panel->GetClipBox(), DC, lines, 0, color );
239 }
240 
241 
243  wxDC* DC, GR_DRAWMODE aDrawMode, const wxPoint& offset )
244 {
245  static std::vector <wxPoint> CornersBuffer;
246  DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();
247 
248  // outline_mode is false to show filled polys,
249  // and true to show polygons outlines only (test and debug purposes)
250  bool outline_mode = displ_opts->m_DisplayZonesMode == 2 ? true : false;
251 
252  if( DC == NULL )
253  return;
254 
255  if( displ_opts->m_DisplayZonesMode == 1 ) // Do not show filled areas
256  return;
257 
258  if( m_FilledPolysList.IsEmpty() ) // Nothing to draw
259  return;
260 
261  BOARD* brd = GetBoard();
262  PCB_LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
263 
264  auto frame = static_cast<PCB_BASE_FRAME*> ( panel->GetParent() );
265  auto color = frame->Settings().Colors().GetLayerColor( m_Layer );
266 
267  if( brd->IsLayerVisible( m_Layer ) == false && !( aDrawMode & GR_HIGHLIGHT ) )
268  return;
269 
270  GRSetDrawMode( DC, aDrawMode );
271 
272  if( displ_opts->m_ContrastModeDisplay )
273  {
274  if( !IsOnLayer( curr_layer ) )
276  }
277 
278  if( ( aDrawMode & GR_HIGHLIGHT ) && !( aDrawMode & GR_AND ) )
279  color.SetToLegacyHighlightColor();
280 
281  color.a = 0.588;
282 
283 
284  for ( int ic = 0; ic < m_FilledPolysList.OutlineCount(); ic++ )
285  {
286  const SHAPE_LINE_CHAIN& path = m_FilledPolysList.COutline( ic );
287 
288  CornersBuffer.clear();
289 
290  wxPoint p0;
291 
292  for( int j = 0; j < path.PointCount(); j++ )
293  {
294  const VECTOR2I& corner = path.CPoint( j );
295 
296  wxPoint coord( corner.x + offset.x, corner.y + offset.y );
297 
298  if( j == 0 )
299  p0 = coord;
300 
301  CornersBuffer.push_back( coord );
302  }
303 
304  CornersBuffer.push_back( p0 );
305 
306  // Draw outlines:
307  if( ( m_ZoneMinThickness > 1 ) || outline_mode )
308  {
309  int ilim = CornersBuffer.size() - 1;
310 
311  for( int is = 0, ie = ilim; is <= ilim; ie = is, is++ )
312  {
313  int x0 = CornersBuffer[is].x;
314  int y0 = CornersBuffer[is].y;
315  int x1 = CornersBuffer[ie].x;
316  int y1 = CornersBuffer[ie].y;
317 
318  // Draw only basic outlines, not extra segments.
319  if( !displ_opts->m_DisplayPcbTrackFill || GetState( FORCE_SKETCH ) )
320  GRCSegm( panel->GetClipBox(), DC,
321  x0, y0, x1, y1,
323  else
324  GRFillCSegm( panel->GetClipBox(), DC,
325  x0, y0, x1, y1, m_ZoneMinThickness, color );
326  }
327  }
328 
329  // Draw areas:
330  if( m_FillMode == 0 && !outline_mode )
331  GRPoly( panel->GetClipBox(), DC, CornersBuffer.size(), &CornersBuffer[0],
332  true, 0, color, color );
333  }
334 
335  if( m_FillMode == 1 && !outline_mode ) // filled with segments
336  {
337  for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
338  {
339  wxPoint start = m_FillSegmList[ic].m_Start + offset;
340  wxPoint end = m_FillSegmList[ic].m_End + offset;
341 
342  if( !displ_opts->m_DisplayPcbTrackFill || GetState( FORCE_SKETCH ) )
343  GRCSegm( panel->GetClipBox(), DC, start.x, start.y, end.x, end.y,
345  else
346  GRFillCSegm( panel->GetClipBox(), DC, start.x, start.y, end.x, end.y,
348  }
349  }
350 }
351 
352 
354 {
355  const int PRELOAD = 0x7FFFFFFF; // Biggest integer (32 bits)
356 
357  int ymax = -PRELOAD;
358  int ymin = PRELOAD;
359  int xmin = PRELOAD;
360  int xmax = -PRELOAD;
361 
362  int count = GetNumCorners();
363 
364  for( int i = 0; i<count; ++i )
365  {
366  wxPoint corner = static_cast<wxPoint>( GetCornerPosition( i ) );
367 
368  ymax = std::max( ymax, corner.y );
369  xmax = std::max( xmax, corner.x );
370  ymin = std::min( ymin, corner.y );
371  xmin = std::min( xmin, corner.x );
372  }
373 
374  EDA_RECT ret( wxPoint( xmin, ymin ), wxSize( xmax - xmin + 1, ymax - ymin + 1 ) );
375 
376  return ret;
377 }
378 
379 
381  GR_DRAWMODE draw_mode )
382 {
383  GR_DRAWMODE current_gr_mode = draw_mode;
384  bool is_close_segment = false;
385 
386  if( !DC )
387  return;
388 
389  PCB_LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
390 
391  auto frame = static_cast<PCB_BASE_FRAME*> ( panel->GetParent() );
392  auto color = frame->Settings().Colors().GetLayerColor( m_Layer );
393 
394  DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();
395 
396  if( displ_opts->m_ContrastModeDisplay )
397  {
398  if( !IsOnLayer( curr_layer ) )
400  }
401 
402  // Object to iterate through the corners of the outlines
404 
405  // Segment start and end
406  VECTOR2I seg_start, seg_end;
407 
408  // Remember the first point of this contour
409  VECTOR2I contour_first_point = *iterator;
410 
411  // Iterate through all the corners of the outlines and build the segments to draw
412  while( iterator )
413  {
414  // Get the first point of the current segment
415  seg_start = *iterator;
416 
417  // Get the last point of the current segment, handling the case where the end of the
418  // contour is reached, when the last point of the segment is the first point of the
419  // contour
420  if( !iterator.IsEndContour() )
421  {
422  // Set GR mode to default
423  current_gr_mode = draw_mode;
424 
425  SHAPE_POLY_SET::ITERATOR iterator_copy = iterator;
426  iterator_copy++;
427  if( iterator_copy.IsEndContour() )
428  current_gr_mode = GR_XOR;
429 
430  is_close_segment = false;
431 
432  iterator++;
433  seg_end = *iterator;
434  }
435  else
436  {
437  is_close_segment = true;
438 
439  seg_end = contour_first_point;
440 
441  // Reassign first point of the contour to the next contour start
442  iterator++;
443 
444  if( iterator )
445  contour_first_point = *iterator;
446 
447  // Set GR mode to XOR
448  current_gr_mode = GR_XOR;
449  }
450 
451  GRSetDrawMode( DC, current_gr_mode );
452 
453  if( is_close_segment )
454  GRLine( panel->GetClipBox(), DC, seg_start.x, seg_start.y, seg_end.x, seg_end.y, 0,
455  WHITE );
456  else
457  GRLine( panel->GetClipBox(), DC, seg_start.x, seg_start.y, seg_end.x, seg_end.y, 0,
458  color );
459  }
460 }
461 
462 
464 {
465  if( aPad == NULL || aPad->GetThermalGap() == 0 )
466  return m_ThermalReliefGap;
467  else
468  return aPad->GetThermalGap();
469 }
470 
471 
473 {
474  if( aPad == NULL || aPad->GetThermalWidth() == 0 )
476  else
477  return aPad->GetThermalWidth();
478 }
479 
480 
481 void ZONE_CONTAINER::SetCornerRadius( unsigned int aRadius )
482 {
483  m_cornerRadius = aRadius;
484  if( m_cornerRadius > (unsigned int) Mils2iu( MAX_ZONE_CORNER_RADIUS_MILS ) )
486 };
487 
488 
489 bool ZONE_CONTAINER::HitTest( const wxPoint& aPosition ) const
490 {
491  return HitTestForCorner( aPosition ) || HitTestForEdge( aPosition );
492 }
493 
494 
496 {
498 
499  // If there is some corner to be selected, assign it to m_CornerSelection
500  if( HitTestForCorner( aPosition, corner ) || HitTestForEdge( aPosition, corner ) )
501  {
502  if( m_CornerSelection == nullptr )
504 
505  *m_CornerSelection = corner;
506  }
507 }
508 
509 // Zones outlines have no thickness, so it Hit Test functions
510 // we must have a default distance between the test point
511 // and a corner or a zone edge:
512 #define MAX_DIST_IN_MM 0.25
513 
515  SHAPE_POLY_SET::VERTEX_INDEX& aCornerHit ) const
516 {
517  int distmax = Millimeter2iu( MAX_DIST_IN_MM );
518 
519  return m_Poly->CollideVertex( VECTOR2I( refPos ), aCornerHit, distmax );
520 }
521 
522 
523 bool ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos ) const
524 {
526  return HitTestForCorner( refPos, dummy );
527 }
528 
529 
531  SHAPE_POLY_SET::VERTEX_INDEX& aCornerHit ) const
532 {
533  int distmax = Millimeter2iu( MAX_DIST_IN_MM );
534 
535  return m_Poly->CollideEdge( VECTOR2I( refPos ), aCornerHit, distmax );
536 }
537 
538 
539 bool ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos ) const
540 {
542  return HitTestForEdge( refPos, dummy );
543 }
544 
545 
546 bool ZONE_CONTAINER::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
547 {
548  // Calculate bounding box for zone
549  EDA_RECT bbox = GetBoundingBox();
550  bbox.Normalize();
551 
552  EDA_RECT arect = aRect;
553  arect.Normalize();
554  arect.Inflate( aAccuracy );
555 
556  if( aContained )
557  {
558  return arect.Contains( bbox );
559  }
560  else // Test for intersection between aBox and the polygon
561  // For a polygon, using its bounding box has no sense here
562  {
563  // Fast test: if aBox is outside the polygon bounding box,
564  // rectangles cannot intersect
565  if( !arect.Intersects( bbox ) )
566  return false;
567 
568  // aBox is inside the polygon bounding box,
569  // and can intersect the polygon: use a fine test.
570  // aBox intersects the polygon if at least one aBox corner
571  // is inside the polygon
572 
573  /*
574  wxPoint origin = arect.GetOrigin();
575 
576  int w = arect.GetWidth();
577  int h = arect.GetHeight();
578 
579 
580  if ( HitTestInsideZone( origin ) ||
581  HitTestInsideZone( origin + wxPoint( w, 0 ) ) ||
582  HitTestInsideZone( origin + wxPoint( w, h ) ) ||
583  HitTestInsideZone( origin + wxPoint( 0, h ) ) )
584  {
585  return true;
586  }
587  */
588 
589  // No corner inside aBox, but outlines can intersect aBox
590  // if one of outline corners is inside aBox
591  int count = m_Poly->TotalVertices();
592  for( int ii =0; ii < count; ii++ )
593  {
594  auto vertex = m_Poly->Vertex( ii );
595  auto vertexNext = m_Poly->Vertex( ( ii + 1 ) % count );
596 
597  // Test if the point is within the rect
598  if( arect.Contains( ( wxPoint ) vertex ) )
599  {
600  return true;
601  }
602 
603  // Test if this edge intersects the rect
604  if( arect.Intersects( ( wxPoint ) vertex, ( wxPoint ) vertexNext ) )
605  {
606  return true;
607  }
608  }
609 
610  return false;
611  }
612 }
613 
614 
616 {
617  int myClearance = m_ZoneClearance;
618 
619 #if 0 // Maybe the netclass clearance should not come into play for a zone?
620  // At least the policy decision can be controlled by the zone
621  // itself, i.e. here. On reasons of insufficient documentation,
622  // the user will be less bewildered if we simply respect the
623  // "zone clearance" setting in the zone properties dialog. (At least
624  // until there is a UI boolean for this.)
625 
626  NETCLASSPTR myClass = GetNetClass();
627 
628  if( myClass )
629  myClearance = std::max( myClearance, myClass->GetClearance() );
630 #endif
631 
632  if( aItem )
633  {
634  int hisClearance = aItem->GetClearance( NULL );
635  myClearance = std::max( hisClearance, myClearance );
636  }
637 
638  return myClearance;
639 }
640 
641 
642 bool ZONE_CONTAINER::HitTestFilledArea( const wxPoint& aRefPos ) const
643 {
644  return m_FilledPolysList.Contains( VECTOR2I( aRefPos.x, aRefPos.y ) );
645 }
646 
647 
648 void ZONE_CONTAINER::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
649 {
650  wxString msg;
651 
652  msg = _( "Zone Outline" );
653 
654  // Display Cutout instead of Outline for holes inside a zone
655  // i.e. when num contour !=0
656  // Check whether the selected corner is in a hole; i.e., in any contour but the first one.
657  if( m_CornerSelection != nullptr && m_CornerSelection->m_contour > 0 )
658  msg << wxT( " " ) << _( "(Cutout)" );
659 
660  aList.push_back( MSG_PANEL_ITEM( _( "Type" ), msg, DARKCYAN ) );
661 
662  if( GetIsKeepout() )
663  {
664  msg.Empty();
665 
666  if( GetDoNotAllowVias() )
667  AccumulateDescription( msg, _( "No via" ) );
668 
669  if( GetDoNotAllowTracks() )
670  AccumulateDescription( msg, _("No track") );
671 
673  AccumulateDescription( msg, _("No copper pour") );
674 
675  aList.push_back( MSG_PANEL_ITEM( _( "Keepout" ), msg, RED ) );
676  }
677  else if( IsOnCopperLayer() )
678  {
679  if( GetNetCode() >= 0 )
680  {
681  NETINFO_ITEM* net = GetNet();
682 
683  if( net )
684  msg = net->GetNetname();
685  else // Should not occur
686  msg = _( "<unknown>" );
687  }
688  else // a netcode < 0 is an error
689  msg = wxT( "<error>" );
690 
691  aList.push_back( MSG_PANEL_ITEM( _( "NetName" ), msg, RED ) );
692 
693  // Display net code : (useful in test or debug)
694  msg.Printf( wxT( "%d" ), GetNetCode() );
695  aList.push_back( MSG_PANEL_ITEM( _( "NetCode" ), msg, RED ) );
696 
697  // Display priority level
698  msg.Printf( wxT( "%d" ), GetPriority() );
699  aList.push_back( MSG_PANEL_ITEM( _( "Priority" ), msg, BLUE ) );
700  }
701  else
702  {
703  aList.push_back( MSG_PANEL_ITEM( _( "Non Copper Zone" ), wxEmptyString, RED ) );
704  }
705 
706  aList.push_back( MSG_PANEL_ITEM( _( "Layer" ), GetLayerName(), BROWN ) );
707 
708  msg.Printf( wxT( "%d" ), (int) m_Poly->TotalVertices() );
709  aList.push_back( MSG_PANEL_ITEM( _( "Corners" ), msg, BLUE ) );
710 
711  if( m_FillMode )
712  msg = _( "Segments" );
713  else
714  msg = _( "Polygons" );
715 
716  aList.push_back( MSG_PANEL_ITEM( _( "Fill Mode" ), msg, BROWN ) );
717 
718  // Useful for statistics :
719  msg.Printf( wxT( "%d" ), (int) m_HatchLines.size() );
720  aList.push_back( MSG_PANEL_ITEM( _( "Hatch Lines" ), msg, BLUE ) );
721 
722  if( !m_FilledPolysList.IsEmpty() )
723  {
724  msg.Printf( wxT( "%d" ), m_FilledPolysList.TotalVertices() );
725  aList.push_back( MSG_PANEL_ITEM( _( "Corner Count" ), msg, BLUE ) );
726  }
727 }
728 
729 
730 /* Geometric transforms: */
731 
732 void ZONE_CONTAINER::Move( const wxPoint& offset )
733 {
734  /* move outlines */
735  m_Poly->Move( VECTOR2I( offset ) );
736 
737  Hatch();
738 
739  m_FilledPolysList.Move( VECTOR2I( offset.x, offset.y ) );
740 
741  for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
742  {
743  m_FillSegmList[ic].m_Start += offset;
744  m_FillSegmList[ic].m_End += offset;
745  }
746 }
747 
748 
749 void ZONE_CONTAINER::MoveEdge( const wxPoint& offset, int aEdge )
750 {
751  int next_corner;
752 
753  if( m_Poly->GetNeighbourIndexes( aEdge, nullptr, &next_corner ) )
754  {
755  m_Poly->Vertex( aEdge ) += VECTOR2I( offset );
756  m_Poly->Vertex( next_corner ) += VECTOR2I( offset );
757  Hatch();
758  }
759 }
760 
761 
762 void ZONE_CONTAINER::Rotate( const wxPoint& centre, double angle )
763 {
764  wxPoint pos;
765 
766  for( auto iterator = m_Poly->IterateWithHoles(); iterator; iterator++ )
767  {
768  pos = static_cast<wxPoint>( *iterator );
769  RotatePoint( &pos, centre, angle );
770  iterator->x = pos.x;
771  iterator->y = pos.y;
772  }
773 
774  Hatch();
775 
776  /* rotate filled areas: */
777  for( auto ic = m_FilledPolysList.Iterate(); ic; ++ic )
778  RotatePoint( &ic->x, &ic->y, centre.x, centre.y, angle );
779 
780  for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
781  {
782  RotatePoint( &m_FillSegmList[ic].m_Start, centre, angle );
783  RotatePoint( &m_FillSegmList[ic].m_End, centre, angle );
784  }
785 }
786 
787 
788 void ZONE_CONTAINER::Flip( const wxPoint& aCentre )
789 {
790  Mirror( aCentre );
791  int copperLayerCount = GetBoard()->GetCopperLayerCount();
792  SetLayer( FlipLayer( GetLayer(), copperLayerCount ) );
793 }
794 
795 
796 void ZONE_CONTAINER::Mirror( const wxPoint& mirror_ref )
797 {
798  for( auto iterator = m_Poly->IterateWithHoles(); iterator; iterator++ )
799  {
800  int py = mirror_ref.y - iterator->y;
801  iterator->y = py + mirror_ref.y;
802  }
803 
804  Hatch();
805 
806  for( auto ic = m_FilledPolysList.Iterate(); ic; ++ic )
807  {
808  int py = mirror_ref.y - ic->y;
809  ic->y = py + mirror_ref.y;
810  }
811 
812  for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
813  {
814  MIRROR( m_FillSegmList[ic].m_Start.y, mirror_ref.y );
815  MIRROR( m_FillSegmList[ic].m_End.y, mirror_ref.y );
816  }
817 }
818 
819 
821 {
822  if( aPad == NULL || aPad->GetZoneConnection() == PAD_ZONE_CONN_INHERITED )
823  return m_PadConnection;
824  else
825  return aPad->GetZoneConnection();
826 }
827 
828 
829 void ZONE_CONTAINER::AddPolygon( std::vector< wxPoint >& aPolygon )
830 {
831  if( aPolygon.empty() )
832  return;
833 
834  SHAPE_LINE_CHAIN outline;
835 
836  // Create an outline and populate it with the points of aPolygon
837  for( unsigned i = 0; i < aPolygon.size(); i++ )
838  {
839  outline.Append( VECTOR2I( aPolygon[i] ) );
840  }
841 
842  outline.SetClosed( true );
843 
844  // Add the outline as a new polygon in the polygon set
845  if( m_Poly->OutlineCount() == 0 )
846  m_Poly->AddOutline( outline );
847  else
848  m_Poly->AddHole( outline );
849 }
850 
851 
852 bool ZONE_CONTAINER::AppendCorner( wxPoint aPosition, int aHoleIdx, bool aAllowDuplication )
853 {
854  // Ensure the main outline exists:
855  if( m_Poly->OutlineCount() == 0 )
856  m_Poly->NewOutline();
857 
858  // If aHoleIdx >= 0, the corner musty be added to the hole, index aHoleIdx.
859  // (remember: the index of the first hole is 0)
860  // Return error if if does dot exist.
861  if( aHoleIdx >= m_Poly->HoleCount( 0 ) )
862  return false;
863 
864  m_Poly->Append( aPosition.x, aPosition.y, -1, aHoleIdx, aAllowDuplication );
865 
866  return true;
867 }
868 
869 
871 {
872  wxString text;
873  NETINFO_ITEM* net;
874  BOARD* board = GetBoard();
875 
876  // Check whether the selected contour is a hole (contour index > 0)
877  if( m_CornerSelection != nullptr && m_CornerSelection->m_contour > 0 )
878  text << wxT( " " ) << _( "(Cutout)" );
879 
880  if( GetIsKeepout() )
881  text << wxT( " " ) << _( "(Keepout)" );
882 
883  text << wxString::Format( wxT( " (%08lX)" ), m_TimeStamp );
884 
885  // Display net name for copper zones
886  if( !GetIsKeepout() )
887  {
888  if( GetNetCode() >= 0 )
889  {
890  if( board )
891  {
892  net = GetNet();
893 
894  if( net )
895  {
896  text << wxT( " [" ) << net->GetNetname() << wxT( "]" );
897  }
898  }
899  else
900  {
901  text << _( "** NO BOARD DEFINED **" );
902  }
903  }
904  else
905  { // A netcode < 0 is an error:
906  // Netname not found or area not initialised
907  text << wxT( " [" ) << GetNetname() << wxT( "]" );
908  text << wxT( " <" ) << _( "Not Found" ) << wxT( ">" );
909  }
910  }
911 
912  wxString msg;
913  msg.Printf( _( "Zone Outline %s on %s" ), GetChars( text ),
914  GetChars( GetLayerName() ) );
915 
916  return msg;
917 }
918 
919 
921 {
922  return m_hatchPitch;
923 }
924 
925 
926 void ZONE_CONTAINER::SetHatch( int aHatchStyle, int aHatchPitch, bool aRebuildHatch )
927 {
928  SetHatchPitch( aHatchPitch );
930 
931  if( aRebuildHatch )
932  Hatch();
933 }
934 
935 
937 {
938  m_hatchPitch = aPitch;
939 }
940 
941 
943 {
944  m_HatchLines.clear();
945 }
946 
947 
948 // Creates hatch lines inside the outline of the complex polygon
949 // sort function used in ::Hatch to sort points by descending wxPoint.x values
950 bool sortEndsByDescendingX( const VECTOR2I& ref, const VECTOR2I& tst )
951 {
952  return tst.x < ref.x;
953 }
954 
955 
957 {
958  UnHatch();
959 
960  if( m_hatchStyle == NO_HATCH || m_hatchPitch == 0 || m_Poly->IsEmpty() )
961  return;
962 
963  // define range for hatch lines
964  int min_x = m_Poly->Vertex( 0 ).x;
965  int max_x = m_Poly->Vertex( 0 ).x;
966  int min_y = m_Poly->Vertex( 0 ).y;
967  int max_y = m_Poly->Vertex( 0 ).y;
968 
969  for( auto iterator = m_Poly->IterateWithHoles(); iterator; iterator++ )
970  {
971  if( iterator->x < min_x )
972  min_x = iterator->x;
973 
974  if( iterator->x > max_x )
975  max_x = iterator->x;
976 
977  if( iterator->y < min_y )
978  min_y = iterator->y;
979 
980  if( iterator->y > max_y )
981  max_y = iterator->y;
982  }
983 
984  // Calculate spacing between 2 hatch lines
985  int spacing;
986 
987  if( m_hatchStyle == DIAGONAL_EDGE )
988  spacing = m_hatchPitch;
989  else
990  spacing = m_hatchPitch * 2;
991 
992  // set the "length" of hatch lines (the length on horizontal axis)
993  int hatch_line_len = m_hatchPitch;
994 
995  // To have a better look, give a slope depending on the layer
996  LAYER_NUM layer = GetLayer();
997  int slope_flag = (layer & 1) ? 1 : -1; // 1 or -1
998  double slope = 0.707106 * slope_flag; // 45 degrees slope
999  int max_a, min_a;
1000 
1001  if( slope_flag == 1 )
1002  {
1003  max_a = KiROUND( max_y - slope * min_x );
1004  min_a = KiROUND( min_y - slope * max_x );
1005  }
1006  else
1007  {
1008  max_a = KiROUND( max_y - slope * max_x );
1009  min_a = KiROUND( min_y - slope * min_x );
1010  }
1011 
1012  min_a = (min_a / spacing) * spacing;
1013 
1014  // calculate an offset depending on layer number,
1015  // for a better look of hatches on a multilayer board
1016  int offset = (layer * 7) / 8;
1017  min_a += offset;
1018 
1019  // loop through hatch lines
1020  #define MAXPTS 200 // Usually we store only few values per one hatch line
1021  // depending on the complexity of the zone outline
1022 
1023  static std::vector<VECTOR2I> pointbuffer;
1024  pointbuffer.clear();
1025  pointbuffer.reserve( MAXPTS + 2 );
1026 
1027  for( int a = min_a; a < max_a; a += spacing )
1028  {
1029  // get intersection points for this hatch line
1030 
1031  // Note: because we should have an even number of intersections with the
1032  // current hatch line and the zone outline (a closed polygon,
1033  // or a set of closed polygons), if an odd count is found
1034  // we skip this line (should not occur)
1035  pointbuffer.clear();
1036 
1037  // Iterate through all vertices
1038  for( auto iterator = m_Poly->IterateSegmentsWithHoles(); iterator; iterator++ )
1039  {
1040  double x, y, x2, y2;
1041  int ok;
1042 
1043  SEG segment = *iterator;
1044 
1045  ok = FindLineSegmentIntersection( a, slope,
1046  segment.A.x, segment.A.y,
1047  segment.B.x, segment.B.y,
1048  &x, &y, &x2, &y2 );
1049 
1050  if( ok )
1051  {
1052  VECTOR2I point( KiROUND( x ), KiROUND( y ) );
1053  pointbuffer.push_back( point );
1054  }
1055 
1056  if( ok == 2 )
1057  {
1058  VECTOR2I point( KiROUND( x2 ), KiROUND( y2 ) );
1059  pointbuffer.push_back( point );
1060  }
1061 
1062  if( pointbuffer.size() >= MAXPTS ) // overflow
1063  {
1064  wxASSERT( 0 );
1065  break;
1066  }
1067  }
1068 
1069  // ensure we have found an even intersection points count
1070  // because intersections are the ends of segments
1071  // inside the polygon(s) and a segment has 2 ends.
1072  // if not, this is a strange case (a bug ?) so skip this hatch
1073  if( pointbuffer.size() % 2 != 0 )
1074  continue;
1075 
1076  // sort points in order of descending x (if more than 2) to
1077  // ensure the starting point and the ending point of the same segment
1078  // are stored one just after the other.
1079  if( pointbuffer.size() > 2 )
1080  sort( pointbuffer.begin(), pointbuffer.end(), sortEndsByDescendingX );
1081 
1082  // creates lines or short segments inside the complex polygon
1083  for( unsigned ip = 0; ip < pointbuffer.size(); ip += 2 )
1084  {
1085  int dx = pointbuffer[ip + 1].x - pointbuffer[ip].x;
1086 
1087  // Push only one line for diagonal hatch,
1088  // or for small lines < twice the line length
1089  // else push 2 small lines
1090  if( m_hatchStyle == DIAGONAL_FULL || fabs( dx ) < 2 * hatch_line_len )
1091  {
1092  m_HatchLines.push_back( SEG( pointbuffer[ip], pointbuffer[ip + 1] ) );
1093  }
1094  else
1095  {
1096  double dy = pointbuffer[ip + 1].y - pointbuffer[ip].y;
1097  slope = dy / dx;
1098 
1099  if( dx > 0 )
1100  dx = hatch_line_len;
1101  else
1102  dx = -hatch_line_len;
1103 
1104  int x1 = KiROUND( pointbuffer[ip].x + dx );
1105  int x2 = KiROUND( pointbuffer[ip + 1].x - dx );
1106  int y1 = KiROUND( pointbuffer[ip].y + dx * slope );
1107  int y2 = KiROUND( pointbuffer[ip + 1].y - dx * slope );
1108 
1109  m_HatchLines.push_back(SEG(pointbuffer[ip].x, pointbuffer[ip].y, x1, y1));
1110 
1111  m_HatchLines.push_back( SEG( pointbuffer[ip+1].x, pointbuffer[ip+1].y, x2, y2 ) );
1112  }
1113  }
1114  }
1115 }
1116 
1117 
1119 {
1120  return Mils2iu( 20 );
1121 }
1122 
1123 
1125 {
1126  return add_zone_xpm;
1127 }
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:749
void SetHatchPitch(int aPitch)
Function SetHatchPitch sets the hatch pitch parameter for the zone.
Definition: class_zone.cpp:936
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:747
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:380
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:648
const ZONE_SETTINGS & GetZoneSettings() const
Definition: class_board.h:556
int GetNumCorners(void) const
Access to m_Poly parameters.
Definition: class_zone.h:465
wxString GetSelectMenuText() const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
Definition: class_zone.cpp:870
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:530
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:744
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox (virtual)
Definition: class_zone.cpp:353
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:481
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:768
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:242
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 HoleCount(int aOutline) const
Returns the number of holes in a given outline
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:926
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:472
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:505
wxString GetLayerName() const
Function GetLayerName returns the name of the PCB layer on which the item resides.
static int GetDefaultHatchPitch()
Function GetDefaultHatchPitchMils.
int GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const override
Function GetClearance returns the clearance in internal units.
Definition: class_zone.cpp:615
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:724
#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:950
int m_ArcToSegmentsCount
The number of segments to convert a circle to a polygon.
Definition: class_zone.h:752
PCB_LAYER_ID
A quick note on layer IDs:
int m_ThermalReliefCopperBridge
Definition: class_zone.h:761
ZoneConnection GetPadConnection(D_PAD *aPad=NULL) const
Definition: class_zone.cpp:820
Classes used in Pcbnew, CvPcb and GerbView.
std::vector< SEG > m_HatchLines
Definition: class_zone.h:791
ZoneConnection m_PadConnection
Definition: class_zone.h:746
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:755
int m_FillMode
How to fill areas: 0 => use filled polygons, 1 => fill with segments.
Definition: class_zone.h:765
virtual void Flip(const wxPoint &aCentre) override
Function Flip Flip this object, i.e.
Definition: class_zone.cpp:788
ZoneConnection GetZoneConnection() const
Definition: class_pad.cpp:610
SHAPE_POLY_SET * m_Poly
Outline of the zone.
Definition: class_zone.h:723
int GetThermalReliefGap(D_PAD *aPad=NULL) const
Definition: class_zone.cpp:463
ZONE_CONTAINER(BOARD *parent)
Definition: class_zone.cpp:53
unsigned m_priority
Definition: class_zone.h:732
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:762
bool m_doNotAllowVias
Definition: class_zone.h:743
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:725
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
EDA_DRAW_FRAME * GetParent() const
Definition: draw_panel.cpp:175
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 internal units.
bool FindLineSegmentIntersection(double a, double b, int xi, int yi, int xf, int yf, double *x1, double *y1, double *x2, double *y2, double *dist)
int NewOutline()
Creates a new empty polygon in the set and returns its index
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:829
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:786
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:726
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:732
int GetNetCode() const
Function GetNetCode.
HATCH_STYLE m_hatchStyle
Definition: class_zone.h:789
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.
Definition: class_netinfo.h:69
PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
bool m_doNotAllowCopperPour
Definition: class_zone.h:742
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:758
bool GetDoNotAllowTracks() const
Definition: class_zone.h:657
int m_ZoneMinThickness
Minimum thickness value in filled areas.
Definition: class_zone.h:748
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:942
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:169
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:489
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:642
VECTOR2I A
Definition: seg.h:47
Class EDA_RECT handles the component boundary box.
HATCH_STYLE GetHatchStyle() const
Definition: class_zone.h:549
void Hatch()
Function Hatch computes the hatch lines depending on the hatch parameters and stores it in the zone's...
Definition: class_zone.cpp:956
BASE_SCREEN * GetScreen()
Definition: draw_panel.cpp:188
void SetHatchStyle(HATCH_STYLE aStyle)
Definition: class_zone.h:554
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:512
bool AppendCorner(wxPoint aPosition, int aHoleIdx, bool aAllowDuplication=false)
Add a new corner to the zone outline (to the main outline or a hole)
Definition: class_zone.cpp:852
int GetHatchPitch() const
Hatch related methods.
Definition: class_zone.cpp:920
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:796
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:514
#define FORCE_SKETCH
Definition: pcbnew.h:68
const VECTOR2I & CPoint(int aIndex) const
Function CPoint()
class PCB_BASE_FRAME basic PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer...
Union to handle conversion between references to wxPoint and to VECTOR2I.
Definition: class_zone.h:816
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:776
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:451
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