You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

785 lines
27 KiB

14 years ago
8 years ago
14 years ago
14 years ago
  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) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. /**
  25. * @file class_zone.h
  26. * @brief Classes to handle copper zones
  27. */
  28. #ifndef CLASS_ZONE_H_
  29. #define CLASS_ZONE_H_
  30. #include <vector>
  31. #include <gr_basic.h>
  32. #include <class_board_item.h>
  33. #include <board_connected_item.h>
  34. #include <layers_id_colors_and_visibility.h>
  35. #include <PolyLine.h>
  36. #include <geometry/shape_poly_set.h>
  37. #include <zone_settings.h>
  38. class EDA_RECT;
  39. class LINE_READER;
  40. class EDA_DRAW_PANEL;
  41. class PCB_EDIT_FRAME;
  42. class BOARD;
  43. class ZONE_CONTAINER;
  44. class MSG_PANEL_ITEM;
  45. typedef std::vector<SEG> ZONE_SEGMENT_FILL;
  46. /**
  47. * Class ZONE_CONTAINER
  48. * handles a list of polygons defining a copper zone.
  49. * A zone is described by a main polygon, a time stamp, a layer, and a net name.
  50. * Other polygons inside the main polygon are holes in the zone.
  51. */
  52. class ZONE_CONTAINER : public BOARD_CONNECTED_ITEM
  53. {
  54. public:
  55. /**
  56. * Zone hatch styles
  57. */
  58. typedef enum HATCH_STYLE { NO_HATCH, DIAGONAL_FULL, DIAGONAL_EDGE } HATCH_STYLE;
  59. ZONE_CONTAINER( BOARD* parent );
  60. ZONE_CONTAINER( const ZONE_CONTAINER& aZone );
  61. ZONE_CONTAINER& operator=( const ZONE_CONTAINER &aOther );
  62. ~ZONE_CONTAINER();
  63. /**
  64. * Function GetPosition
  65. *
  66. * Returns a reference to the first corner of the polygon set.
  67. *
  68. * \warning The implementation of this function relies on the fact that wxPoint and VECTOR2I
  69. * have the same layout. If you intend to use the returned reference directly, please note
  70. * that you are _only_ allowed to use members x and y. Any use on anything that is not one of
  71. * these members will have undefined behaviour.
  72. *
  73. * @return a wxPoint, position of the first point of the outline
  74. */
  75. const wxPoint GetPosition() const override;
  76. void SetPosition( const wxPoint& aPos ) override {}
  77. /**
  78. * Function SetPriority
  79. * @param aPriority = the priority level
  80. */
  81. void SetPriority( unsigned aPriority ) { m_priority = aPriority; }
  82. /**
  83. * Function GetPriority
  84. * @return the priority level of this zone
  85. */
  86. unsigned GetPriority() const { return m_priority; }
  87. void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) override;
  88. void SetLayerSet( LSET aLayerSet );
  89. virtual LSET GetLayerSet() const override;
  90. /**
  91. * Function Draw
  92. * Draws the zone outline.
  93. * @param panel = current Draw Panel
  94. * @param DC = current Device Context
  95. * @param aDrawMode = GR_OR, GR_XOR, GR_COPY ..
  96. * @param offset = Draw offset (usually wxPoint(0,0))
  97. */
  98. void Draw( EDA_DRAW_PANEL* panel,
  99. wxDC* DC,
  100. GR_DRAWMODE aDrawMode,
  101. const wxPoint& offset = ZeroOffset ) override;
  102. /**
  103. * Function DrawDrawFilledArea
  104. * Draws the filled area for this zone (polygon list .m_FilledPolysList)
  105. * @param panel = current Draw Panel
  106. * @param DC = current Device Context
  107. * @param offset = Draw offset (usually wxPoint(0,0))
  108. * @param aDrawMode = GR_OR, GR_XOR, GR_COPY ..
  109. */
  110. void DrawFilledArea( EDA_DRAW_PANEL* panel,
  111. wxDC* DC,
  112. GR_DRAWMODE aDrawMode,
  113. const wxPoint& offset = ZeroOffset );
  114. /**
  115. * Function DrawWhileCreateOutline
  116. * Draws the zone outline when it is created.
  117. * The moving edges are in XOR graphic mode, old segment in draw_mode graphic mode
  118. * (usually GR_OR). The closing edge has its own shape.
  119. * @param panel = current Draw Panel
  120. * @param DC = current Device Context
  121. * @param draw_mode = draw mode: OR, XOR ..
  122. */
  123. void DrawWhileCreateOutline( EDA_DRAW_PANEL* panel, wxDC* DC,
  124. GR_DRAWMODE draw_mode = GR_OR );
  125. /** Function GetBoundingBox (virtual)
  126. * @return an EDA_RECT that is the bounding box of the zone outline
  127. */
  128. const EDA_RECT GetBoundingBox() const override;
  129. int GetClearance( BOARD_CONNECTED_ITEM* aItem = NULL ) const override;
  130. /**
  131. * Function IsOnCopperLayer
  132. * @return true if this zone is on a copper layer, false if on a technical layer
  133. */
  134. bool IsOnCopperLayer() const;
  135. /**
  136. * Function CommonLayerExist
  137. * Test if this zone shares a common layer with the given layer set
  138. */
  139. bool CommonLayerExists( const LSET aLayerSet ) const;
  140. virtual void SetLayer( PCB_LAYER_ID aLayer ) override;
  141. virtual PCB_LAYER_ID GetLayer() const override;
  142. virtual bool IsOnLayer( PCB_LAYER_ID ) const override;
  143. virtual void ViewGetLayers( int aLayers[], int& aCount ) const override;
  144. void SetFillMode( ZONE_FILL_MODE aFillMode ) { m_FillMode = aFillMode; }
  145. ZONE_FILL_MODE GetFillMode() const { return m_FillMode; }
  146. void SetThermalReliefGap( int aThermalReliefGap ) { m_ThermalReliefGap = aThermalReliefGap; }
  147. int GetThermalReliefGap( D_PAD* aPad = NULL ) const;
  148. void SetThermalReliefCopperBridge( int aThermalReliefCopperBridge )
  149. {
  150. m_ThermalReliefCopperBridge = aThermalReliefCopperBridge;
  151. }
  152. int GetThermalReliefCopperBridge( D_PAD* aPad = NULL ) const;
  153. void SetArcSegmentCount( int aArcSegCount ) { m_ArcToSegmentsCount = aArcSegCount; }
  154. int GetArcSegmentCount() const { return m_ArcToSegmentsCount; }
  155. bool IsFilled() const { return m_IsFilled; }
  156. void SetIsFilled( bool isFilled ) { m_IsFilled = isFilled; }
  157. int GetZoneClearance() const { return m_ZoneClearance; }
  158. void SetZoneClearance( int aZoneClearance ) { m_ZoneClearance = aZoneClearance; }
  159. ZoneConnection GetPadConnection( D_PAD* aPad = NULL ) const;
  160. void SetPadConnection( ZoneConnection aPadConnection ) { m_PadConnection = aPadConnection; }
  161. int GetMinThickness() const { return m_ZoneMinThickness; }
  162. void SetMinThickness( int aMinThickness ) { m_ZoneMinThickness = aMinThickness; }
  163. int GetSelectedCorner() const
  164. {
  165. // Transform relative indices to global index
  166. int globalIndex;
  167. m_Poly->GetGlobalIndex( *m_CornerSelection, globalIndex );
  168. return globalIndex;
  169. }
  170. void SetSelectedCorner( int aCorner )
  171. {
  172. SHAPE_POLY_SET::VERTEX_INDEX selectedCorner;
  173. // If the global index of the corner is correct, assign it to m_CornerSelection
  174. if( m_Poly->GetRelativeIndices( aCorner, &selectedCorner ) )
  175. {
  176. if( m_CornerSelection == nullptr )
  177. m_CornerSelection = new SHAPE_POLY_SET::VERTEX_INDEX;
  178. *m_CornerSelection = selectedCorner;
  179. }
  180. else
  181. throw( std::out_of_range( "aCorner-th vertex does not exist" ) );
  182. }
  183. ///
  184. // Like HitTest but selects the current corner to be operated on
  185. void SetSelectedCorner( const wxPoint& aPosition );
  186. int GetLocalFlags() const { return m_localFlgs; }
  187. void SetLocalFlags( int aFlags ) { m_localFlgs = aFlags; }
  188. ZONE_SEGMENT_FILL& FillSegments() { return m_FillSegmList; }
  189. const ZONE_SEGMENT_FILL& FillSegments() const { return m_FillSegmList; }
  190. SHAPE_POLY_SET* Outline() { return m_Poly; }
  191. const SHAPE_POLY_SET* Outline() const { return const_cast< SHAPE_POLY_SET* >( m_Poly ); }
  192. void SetOutline( SHAPE_POLY_SET* aOutline ) { m_Poly = aOutline; }
  193. /**
  194. * Function HitTest
  195. * tests if a point is near an outline edge or a corner of this zone.
  196. * @param aPosition the wxPoint to test
  197. * @return bool - true if a hit, else false
  198. */
  199. virtual bool HitTest( const wxPoint& aPosition ) const override;
  200. /**
  201. * Function HitTest
  202. * tests if a point is inside the zone area, i.e. inside the main outline
  203. * and outside holes.
  204. * @param aPosition : the wxPoint to test
  205. * @return bool - true if a hit, else false
  206. */
  207. bool HitTestInsideZone( const wxPoint& aPosition ) const
  208. {
  209. return m_Poly->Contains( VECTOR2I( aPosition ), 0 );
  210. }
  211. /**
  212. * Function HitTestFilledArea
  213. * tests if the given wxPoint is within the bounds of a filled area of this zone.
  214. * @param aRefPos A wxPoint to test
  215. * @return bool - true if a hit, else false
  216. */
  217. bool HitTestFilledArea( const wxPoint& aRefPos ) const;
  218. /**
  219. * Function TransformSolidAreasShapesToPolygonSet
  220. * Convert solid areas full shapes to polygon set
  221. * (the full shape is the polygon area with a thick outline)
  222. * Used in 3D view
  223. * Arcs (ends of segments) are approximated by segments
  224. * @param aCornerBuffer = a buffer to store the polygons
  225. * @param aCircleToSegmentsCount = the number of segments to approximate a circle
  226. * @param aCorrectionFactor = the correction to apply to arcs radius to roughly
  227. * keep arc radius when approximated by segments
  228. */
  229. void TransformSolidAreasShapesToPolygonSet( SHAPE_POLY_SET& aCornerBuffer,
  230. int aCircleToSegmentsCount,
  231. double aCorrectionFactor ) const;
  232. /**
  233. * Function TransformOutlinesShapeWithClearanceToPolygon
  234. * Convert the outlines shape to a polygon with no holes
  235. * inflated (optional) by max( aClearanceValue, the zone clearance)
  236. * (holes are linked to external outline by overlapping segments)
  237. * Used in filling zones calculations
  238. * Circles (vias) and arcs (ends of tracks) are approximated by segments
  239. * @param aCornerBuffer = a buffer to store the polygon
  240. * @param aMinClearanceValue = the min clearance around outlines
  241. * @param aUseNetClearance = true to use a clearance which is the max value between
  242. * aMinClearanceValue and the net clearance
  243. * false to use aMinClearanceValue only
  244. * if both aMinClearanceValue = 0 and aUseNetClearance = false: create the zone outline polygon.
  245. */
  246. void TransformOutlinesShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
  247. int aMinClearanceValue,
  248. bool aUseNetClearance ) const;
  249. void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
  250. int aClearanceValue,
  251. int aCircleToSegmentsCount,
  252. double aCorrectionFactor ) const override;
  253. /**
  254. * Function HitTestForCorner
  255. * tests if the given wxPoint is near a corner.
  256. * @param refPos is the wxPoint to test.
  257. * @param aCornerHit [out] is the index of the closest vertex found, useless when return
  258. * value is false.
  259. * @return bool - true if some corner was found to be closer to refPos than aClearance; false
  260. * otherwise.
  261. */
  262. bool HitTestForCorner( const wxPoint& refPos, SHAPE_POLY_SET::VERTEX_INDEX& aCornerHit ) const;
  263. /**
  264. * Function HitTestForCorner
  265. * tests if the given wxPoint is near a corner.
  266. * @param refPos is the wxPoint to test.
  267. * @return bool - true if some corner was found to be closer to refPos than aClearance; false
  268. * otherwise.
  269. */
  270. bool HitTestForCorner( const wxPoint& refPos ) const;
  271. /**
  272. * Function HitTestForEdge
  273. * tests if the given wxPoint is near a segment defined by 2 corners.
  274. * @param refPos is the wxPoint to test.
  275. * @param aCornerHit [out] is the index of the closest vertex found, useless when return
  276. * value is false.
  277. * @return bool - true if some edge was found to be closer to refPos than aClearance.
  278. */
  279. bool HitTestForEdge( const wxPoint& refPos, SHAPE_POLY_SET::VERTEX_INDEX& aCornerHit ) const;
  280. /**
  281. * Function HitTestForEdge
  282. * tests if the given wxPoint is near a segment defined by 2 corners.
  283. * @param refPos is the wxPoint to test.
  284. * @return bool - true if some edge was found to be closer to refPos than aClearance.
  285. */
  286. bool HitTestForEdge( const wxPoint& refPos ) const;
  287. /** @copydoc BOARD_ITEM::HitTest(const EDA_RECT& aRect,
  288. * bool aContained = true, int aAccuracy ) const
  289. */
  290. bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const override;
  291. /**
  292. * Function UnFill
  293. * Removes the zone filling
  294. * @return true if a previous filling is removed, false if no change
  295. * (when no filling found)
  296. */
  297. bool UnFill();
  298. /* Geometric transformations: */
  299. /**
  300. * Function Move
  301. * Move the outlines
  302. * @param offset = moving vector
  303. */
  304. void Move( const wxPoint& offset ) override;
  305. /**
  306. * Function MoveEdge
  307. * Move the outline Edge
  308. * @param offset = moving vector
  309. * @param aEdge = start point of the outline edge
  310. */
  311. void MoveEdge( const wxPoint& offset, int aEdge );
  312. /**
  313. * Function Rotate
  314. * Move the outlines
  315. * @param centre = rot centre
  316. * @param angle = in 0.1 degree
  317. */
  318. void Rotate( const wxPoint& centre, double angle ) override;
  319. /**
  320. * Function Flip
  321. * Flip this object, i.e. change the board side for this object
  322. * (like Mirror() but changes layer)
  323. * @param aCentre - the rotation point.
  324. */
  325. virtual void Flip( const wxPoint& aCentre ) override;
  326. /**
  327. * Function Mirror
  328. * Mirror the outlines , relative to a given horizontal axis
  329. * the layer is not changed
  330. * @param mirror_ref = vertical axis position
  331. */
  332. void Mirror( const wxPoint& mirror_ref );
  333. /**
  334. * Function GetClass
  335. * returns the class name.
  336. * @return wxString
  337. */
  338. wxString GetClass() const override
  339. {
  340. return wxT( "ZONE_CONTAINER" );
  341. }
  342. /** Access to m_Poly parameters
  343. */
  344. int GetNumCorners( void ) const
  345. {
  346. return m_Poly->TotalVertices();
  347. }
  348. /**
  349. * Function Iterate
  350. * returns an iterator to visit all points of the zone's main outline without holes.
  351. * @return SHAPE_POLY_SET::ITERATOR - an iterator to visit the zone vertices without holes.
  352. */
  353. SHAPE_POLY_SET::ITERATOR Iterate()
  354. {
  355. return m_Poly->Iterate();
  356. }
  357. /**
  358. * Function IterateWithHoles
  359. * returns an iterator to visit all points of the zone's main outline with holes.
  360. * @return SHAPE_POLY_SET::ITERATOR - an iterator to visit the zone vertices with holes.
  361. */
  362. SHAPE_POLY_SET::ITERATOR IterateWithHoles()
  363. {
  364. return m_Poly->IterateWithHoles();
  365. }
  366. /**
  367. * Function CIterateWithHoles
  368. * returns an iterator to visit all points of the zone's main outline with holes.
  369. * @return SHAPE_POLY_SET::ITERATOR - an iterator to visit the zone vertices with holes.
  370. */
  371. SHAPE_POLY_SET::CONST_ITERATOR CIterateWithHoles() const
  372. {
  373. return m_Poly->CIterateWithHoles();
  374. }
  375. void RemoveAllContours( void )
  376. {
  377. m_Poly->RemoveAllContours();
  378. }
  379. const VECTOR2I& GetCornerPosition( int aCornerIndex ) const
  380. {
  381. SHAPE_POLY_SET::VERTEX_INDEX index;
  382. // Convert global to relative indices
  383. if( !m_Poly->GetRelativeIndices( aCornerIndex, &index ) )
  384. throw( std::out_of_range( "aCornerIndex-th vertex does not exist" ) );
  385. return m_Poly->CVertex( index );
  386. }
  387. void SetCornerPosition( int aCornerIndex, wxPoint new_pos )
  388. {
  389. SHAPE_POLY_SET::VERTEX_INDEX relativeIndices;
  390. // Convert global to relative indices
  391. if( m_Poly->GetRelativeIndices( aCornerIndex, &relativeIndices ) )
  392. {
  393. m_Poly->Vertex( relativeIndices ).x = new_pos.x;
  394. m_Poly->Vertex( relativeIndices ).y = new_pos.y;
  395. }
  396. else
  397. throw( std::out_of_range( "aCornerIndex-th vertex does not exist" ) );
  398. }
  399. /**
  400. * Function NewHole
  401. * creates a new hole on the zone; i.e., a new contour on the zone's outline.
  402. */
  403. void NewHole()
  404. {
  405. m_Poly->NewHole();
  406. }
  407. /**
  408. * Add a new corner to the zone outline (to the main outline or a hole)
  409. * @param aPosition is the position of the new corner.
  410. * @param aHoleIdx is the index of the hole (-1 for the main outline, >= 0 for hole).
  411. * @param aAllowDuplication is a flag to indicate whether it is allowed to add this corner
  412. * even if it is duplicated.
  413. * @return true if the corner was added, false if error (aHoleIdx > hole count -1)
  414. */
  415. bool AppendCorner( wxPoint aPosition, int aHoleIdx, bool aAllowDuplication = false );
  416. HATCH_STYLE GetHatchStyle() const
  417. {
  418. return m_hatchStyle;
  419. }
  420. void SetHatchStyle( HATCH_STYLE aStyle )
  421. {
  422. m_hatchStyle = aStyle;
  423. }
  424. /**
  425. * Function IsSame
  426. * tests if 2 zones are equivalent:
  427. * 2 zones are equivalent if they have same parameters and same outlines
  428. * info, filling is not taken into account
  429. * @param aZoneToCompare = zone to compare with "this"
  430. */
  431. bool IsSame( const ZONE_CONTAINER &aZoneToCompare );
  432. /**
  433. * Function ClearFilledPolysList
  434. * clears the list of filled polygons.
  435. */
  436. void ClearFilledPolysList()
  437. {
  438. m_FilledPolysList.RemoveAllContours();
  439. }
  440. /**
  441. * Function GetFilledPolysList
  442. * returns a reference to the list of filled polygons.
  443. * @return Reference to the list of filled polygons.
  444. */
  445. //TODO - This should be called for each layer on which the zone exists
  446. const SHAPE_POLY_SET& GetFilledPolysList() const
  447. {
  448. return m_FilledPolysList;
  449. }
  450. void CacheTriangulation();
  451. /**
  452. * Function SetFilledPolysList
  453. * sets the list of filled polygons.
  454. */
  455. void SetFilledPolysList( SHAPE_POLY_SET& aPolysList )
  456. {
  457. m_FilledPolysList = aPolysList;
  458. }
  459. /**
  460. * Function SetFilledPolysList
  461. * sets the list of filled polygons.
  462. */
  463. void SetRawPolysList( SHAPE_POLY_SET& aPolysList )
  464. {
  465. m_RawPolysList = aPolysList;
  466. }
  467. /**
  468. * Function GetSmoothedPoly
  469. * returns a pointer to the corner-smoothed version of
  470. * m_Poly if it exists, otherwise it returns m_Poly.
  471. * @return SHAPE_POLY_SET* - pointer to the polygon.
  472. */
  473. bool BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly ) const;
  474. void SetCornerSmoothingType( int aType ) { m_cornerSmoothingType = aType; };
  475. int GetCornerSmoothingType() const { return m_cornerSmoothingType; };
  476. void SetCornerRadius( unsigned int aRadius );
  477. unsigned int GetCornerRadius() const { return m_cornerRadius; };
  478. /**
  479. * add a polygon to the zone outline
  480. * if the zone outline is empty, this is the main outline
  481. * else it is a hole inside the main outline
  482. */
  483. void AddPolygon( std::vector< wxPoint >& aPolygon );
  484. void SetFillSegments( const ZONE_SEGMENT_FILL& aSegments )
  485. {
  486. m_FillSegmList = aSegments;
  487. }
  488. SHAPE_POLY_SET& RawPolysList()
  489. {
  490. return m_RawPolysList;
  491. }
  492. wxString GetSelectMenuText() const override;
  493. BITMAP_DEF GetMenuImage() const override;
  494. EDA_ITEM* Clone() const override;
  495. /**
  496. * Accessors to parameters used in Keepout zones:
  497. */
  498. bool GetIsKeepout() const { return m_isKeepout; }
  499. bool GetDoNotAllowCopperPour() const { return m_doNotAllowCopperPour; }
  500. bool GetDoNotAllowVias() const { return m_doNotAllowVias; }
  501. bool GetDoNotAllowTracks() const { return m_doNotAllowTracks; }
  502. void SetIsKeepout( bool aEnable ) { m_isKeepout = aEnable; }
  503. void SetDoNotAllowCopperPour( bool aEnable ) { m_doNotAllowCopperPour = aEnable; }
  504. void SetDoNotAllowVias( bool aEnable ) { m_doNotAllowVias = aEnable; }
  505. void SetDoNotAllowTracks( bool aEnable ) { m_doNotAllowTracks = aEnable; }
  506. /**
  507. * Hatch related methods
  508. */
  509. /**
  510. * Function GetHatchPitch
  511. * @return int - the zone hatch pitch in iu.
  512. */
  513. int GetHatchPitch() const;
  514. /**
  515. * Function GetDefaultHatchPitchMils
  516. * @return int - the default hatch pitch in internal units.
  517. */
  518. static int GetDefaultHatchPitch();
  519. /**
  520. * Function SetHatch
  521. * sets all hatch parameters for the zone.
  522. * @param aHatchStyle is the style of the hatch, specified as one of HATCH_STYLE possible
  523. * values.
  524. * @param aHatchPitch is the hatch pitch in iu.
  525. * @param aRebuildHatch is a flag to indicate whether to re-hatch after having set the
  526. * previous parameters.
  527. */
  528. void SetHatch( int aHatchStyle, int aHatchPitch, bool aRebuildHatch );
  529. /**
  530. * Function SetHatchPitch
  531. * sets the hatch pitch parameter for the zone.
  532. * @param aPitch is the hatch pitch in iu.
  533. */
  534. void SetHatchPitch( int aPitch );
  535. /**
  536. * Function UnHatch
  537. * clears the zone's hatch.
  538. */
  539. void UnHatch();
  540. /**
  541. * Function Hatch
  542. * computes the hatch lines depending on the hatch parameters and stores it in the zone's
  543. * attribute m_HatchLines.
  544. */
  545. void Hatch();
  546. const std::vector<SEG>& GetHatchLines() const { return m_HatchLines; }
  547. bool GetHV45() const { return m_hv45; }
  548. void SetHV45( bool aConstrain ) { m_hv45 = aConstrain; }
  549. #if defined(DEBUG)
  550. virtual void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
  551. #endif
  552. virtual void SwapData( BOARD_ITEM* aImage ) override;
  553. private:
  554. SHAPE_POLY_SET* m_Poly; ///< Outline of the zone.
  555. int m_cornerSmoothingType;
  556. unsigned int m_cornerRadius;
  557. LSET m_layerSet;
  558. /* Priority: when a zone outline is inside and other zone, if its priority is higher
  559. * the other zone priority, it will be created inside.
  560. * if priorities are equal, a DRC error is set
  561. */
  562. unsigned m_priority;
  563. /* A zone outline can be a keepout zone.
  564. * It will be never filled, and DRC should test for pads, tracks and vias
  565. */
  566. bool m_isKeepout;
  567. /* For keepout zones only:
  568. * what is not allowed inside the keepout ( pads, tracks and vias )
  569. */
  570. bool m_doNotAllowCopperPour;
  571. bool m_doNotAllowVias;
  572. bool m_doNotAllowTracks;
  573. ZoneConnection m_PadConnection;
  574. int m_ZoneClearance; ///< Clearance value in internal units.
  575. int m_ZoneMinThickness; ///< Minimum thickness value in filled areas.
  576. /** The number of segments to convert a circle to a polygon. Valid values are
  577. #ARC_APPROX_SEGMENTS_COUNT_LOW_DEF or #ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF. */
  578. int m_ArcToSegmentsCount;
  579. /** True when a zone was filled, false after deleting the filled areas. */
  580. bool m_IsFilled;
  581. ///< Width of the gap in thermal reliefs.
  582. int m_ThermalReliefGap;
  583. ///< Width of the copper bridge in thermal reliefs.
  584. int m_ThermalReliefCopperBridge;
  585. /// How to fill areas: ZFM_POLYGONS => use filled polygons, ZFM_SEGMENTS => fill with segments.
  586. ZONE_FILL_MODE m_FillMode;
  587. /// The index of the corner being moved or nullptr if no corner is selected.
  588. SHAPE_POLY_SET::VERTEX_INDEX* m_CornerSelection;
  589. /// Variable used in polygon calculations.
  590. int m_localFlgs;
  591. /** Segments used to fill the zone (#m_FillMode ==1 ), when fill zone by segment is used.
  592. * In this case the segments have #m_ZoneMinThickness width.
  593. */
  594. ZONE_SEGMENT_FILL m_FillSegmList;
  595. /* set of filled polygons used to draw a zone as a filled area.
  596. * from outlines (m_Poly) but unlike m_Poly these filled polygons have no hole
  597. * (they are all in one piece) In very simple cases m_FilledPolysList is same
  598. * as m_Poly. In less simple cases (when m_Poly has holes) m_FilledPolysList is
  599. * a polygon equivalent to m_Poly, without holes but with extra outline segment
  600. * connecting "holes" with external main outline. In complex cases an outline
  601. * described by m_Poly can have many filled areas
  602. */
  603. SHAPE_POLY_SET m_FilledPolysList;
  604. SHAPE_POLY_SET m_RawPolysList;
  605. HATCH_STYLE m_hatchStyle; // hatch style, see enum above
  606. int m_hatchPitch; // for DIAGONAL_EDGE, distance between 2 hatch lines
  607. std::vector<SEG> m_HatchLines; // hatch lines
  608. std::vector<int> m_insulatedIslands;
  609. bool m_hv45; // constrain edges to horizontal, vertical or 45º
  610. /**
  611. * Union to handle conversion between references to wxPoint and to VECTOR2I.
  612. *
  613. * The function GetPosition(), that returns a reference to a wxPoint, needs some existing
  614. * wxPoint object that it can point to. The header of this function cannot be changed, as it
  615. * overrides the function from the base class BOARD_ITEM. This made sense when ZONE_CONTAINER
  616. * was implemented using the legacy CPolyLine class, that worked with wxPoints. However,
  617. * m_Poly is now a SHAPE_POLY_SET, whose corners are objects of type VECTOR2I, not wxPoint.
  618. * Thus, we cannot directly reference the first corner of m_Poly, so a modified version of it
  619. * that can be read as a wxPoint needs to be handled.
  620. * Taking advantage of the fact that both wxPoint and VECTOR2I have the same memory layout
  621. * (two integers: x, y), this union let us convert a reference to a VECTOR2I into a reference
  622. * to a wxPoint.
  623. *
  624. * The idea is the following: in GetPosition(), m_Poly->GetCornerPosition( 0 ) returns a
  625. * reference to the first corner of the polygon set. If we retrieve its memory direction, we
  626. * can tell the compiler to cast that pointer to a WX_VECTOR_CONVERTER pointer. We can finally
  627. * shape that memory layout as a wxPoint picking the wx member of the union.
  628. *
  629. * Although this solution is somewhat unstable, as it relies on the fact that the memory
  630. * layout is exactly the same, it is the best attempt to keep backwards compatibility while
  631. * using the new SHAPE_POLY_SET.
  632. */
  633. typedef union {
  634. wxPoint wx;
  635. VECTOR2I vector;
  636. } WX_VECTOR_CONVERTER;
  637. // Sanity check: assure that the conversion VECTOR2I->wxPoint using the previous union is
  638. // correct, making sure that the access for x and y attributes is still safe.
  639. static_assert(offsetof(wxPoint,x) == offsetof(VECTOR2I,x),
  640. "wxPoint::x and VECTOR2I::x have different offsets");
  641. static_assert(offsetof(wxPoint,y) == offsetof(VECTOR2I,y),
  642. "wxPoint::y and VECTOR2I::y have different offsets");
  643. };
  644. #endif // CLASS_ZONE_H_