KiCad PCB EDA Suite
pns_solid.cpp
Go to the documentation of this file.
1 /*
2  * KiRouter - a push-and-(sometimes-)shove PCB router
3  *
4  * Copyright (C) 2013-2014 CERN
5  * Copyright (C) 2016-2020 KiCad Developers, see AUTHORS.txt for contributors.
6  * Author: Tomasz Wlostowski <[email protected]>
7  *
8  * This program is free software: you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by the
10  * Free Software Foundation, either version 3 of the License, or (at your
11  * option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include <math/vector2d.h>
23 
24 #include <geometry/shape.h>
26 #include <geometry/shape_rect.h>
27 #include <geometry/shape_circle.h>
28 #include <geometry/shape_simple.h>
31 
32 #include <wx/log.h>
33 
34 #include "pns_router.h"
35 #include "pns_solid.h"
36 #include "pns_utils.h"
37 
38 namespace PNS {
39 
40 static const SHAPE_LINE_CHAIN buildHullForPrimitiveShape( const SHAPE* aShape, int aClearance,
41  int aWalkaroundThickness )
42 {
43  int cl = aClearance + ( aWalkaroundThickness + 1 )/ 2;
44 
45  switch( aShape->Type() )
46  {
47  case SH_RECT:
48  {
49  const SHAPE_RECT* rect = static_cast<const SHAPE_RECT*>( aShape );
50  return OctagonalHull( rect->GetPosition(),
51  rect->GetSize(),
52  cl + 1,
53  0 );
54  }
55 
56  case SH_CIRCLE:
57  {
58  const SHAPE_CIRCLE* circle = static_cast<const SHAPE_CIRCLE*>( aShape );
59  int r = circle->GetRadius();
60  return OctagonalHull( circle->GetCenter() - VECTOR2I( r, r ),
61  VECTOR2I( 2 * r, 2 * r ),
62  cl + 1,
63  2.0 * ( 1.0 - M_SQRT1_2 ) * ( r + cl ) );
64  }
65 
66  case SH_SEGMENT:
67  {
68  const SHAPE_SEGMENT* seg = static_cast<const SHAPE_SEGMENT*>( aShape );
69  return SegmentHull( *seg, aClearance, aWalkaroundThickness );
70  }
71 
72  case SH_ARC:
73  {
74  const SHAPE_ARC* arc = static_cast<const SHAPE_ARC*>( aShape );
75  return ArcHull( *arc, aClearance, aWalkaroundThickness );
76  }
77 
78  case SH_SIMPLE:
79  {
80  const SHAPE_SIMPLE* convex = static_cast<const SHAPE_SIMPLE*>( aShape );
81 
82  return ConvexHull( *convex, cl );
83  }
84  default:
85  {
86  wxFAIL_MSG( wxString::Format( wxT( "Unsupported hull shape: %d (%s)." ),
87  aShape->Type(),
88  SHAPE_TYPE_asString( aShape->Type() ) ) );
89  break;
90  }
91  }
92 
93  return SHAPE_LINE_CHAIN();
94 }
95 
96 
97 const SHAPE_LINE_CHAIN SOLID::Hull( int aClearance, int aWalkaroundThickness, int aLayer ) const
98 {
99  if( !ROUTER::GetInstance()->GetInterface()->IsFlashedOnLayer( this, aLayer ) )
100  return HoleHull( aClearance, aWalkaroundThickness, aLayer );
101 
102  if( !m_shape )
103  return SHAPE_LINE_CHAIN();
104 
105  if( m_shape->Type() == SH_COMPOUND )
106  {
107  SHAPE_COMPOUND* cmpnd = static_cast<SHAPE_COMPOUND*>( m_shape );
108 
109  if ( cmpnd->Shapes().size() == 1 )
110  {
111  return buildHullForPrimitiveShape( cmpnd->Shapes()[0], aClearance,
112  aWalkaroundThickness );
113  }
114  else
115  {
116  SHAPE_POLY_SET hullSet;
117 
118  for( SHAPE* shape : cmpnd->Shapes() )
119  {
120  hullSet.AddOutline( buildHullForPrimitiveShape( shape, aClearance,
121  aWalkaroundThickness ) );
122  }
123 
125  return hullSet.Outline( 0 );
126  }
127  }
128  else
129  {
130  return buildHullForPrimitiveShape( m_shape, aClearance, aWalkaroundThickness );
131  }
132 }
133 
134 
135 const SHAPE_LINE_CHAIN SOLID::HoleHull( int aClearance, int aWalkaroundThickness, int aLayer ) const
136 {
137  if( !m_hole )
138  return SHAPE_LINE_CHAIN();
139 
140  if( m_hole->Type() == SH_COMPOUND )
141  {
142  SHAPE_COMPOUND* cmpnd = static_cast<SHAPE_COMPOUND*>( m_hole );
143 
144  if ( cmpnd->Shapes().size() == 1 )
145  {
146  return buildHullForPrimitiveShape( cmpnd->Shapes()[0], aClearance,
147  aWalkaroundThickness );
148  }
149  else
150  {
151  SHAPE_POLY_SET hullSet;
152 
153  for( SHAPE* shape : cmpnd->Shapes() )
154  {
155  hullSet.AddOutline( buildHullForPrimitiveShape( shape, aClearance,
156  aWalkaroundThickness ) );
157  }
158 
160  return hullSet.Outline( 0 );
161  }
162  }
163  else
164  {
165  return buildHullForPrimitiveShape( m_hole, aClearance, aWalkaroundThickness );
166  }
167 }
168 
169 
171 {
172  ITEM* solid = new SOLID( *this );
173  return solid;
174 }
175 
176 void SOLID::SetPos( const VECTOR2I& aCenter )
177 {
178  VECTOR2I delta = aCenter - m_pos;
179 
180  if( m_shape )
181  m_shape->Move( delta );
182 
183  if( m_hole )
184  m_hole->Move( delta );
185 
186  m_pos = aCenter;
187 }
188 
189 
190 }
compound shape, consisting of multiple simple shapes
Definition: shape.h:49
Base class for PNS router board items.
Definition: pns_item.h:55
const SHAPE_LINE_CHAIN ConvexHull(const SHAPE_SIMPLE &aConvex, int aClearance)
Function ConvexHull()
Definition: pns_utils.cpp:201
Represent a simple polygon consisting of a zero-thickness closed chain of connected line segments.
Definition: shape_simple.h:41
int GetRadius() const
Definition: shape_circle.h:107
static const SHAPE_LINE_CHAIN buildHullForPrimitiveShape(const SHAPE *aShape, int aClearance, int aWalkaroundThickness)
Definition: pns_solid.cpp:40
void SetPos(const VECTOR2I &aCenter)
Definition: pns_solid.cpp:176
const SHAPE_LINE_CHAIN HoleHull(int aClearance, int aWalkaroundThickness, int aLayer) const override
Definition: pns_solid.cpp:135
const VECTOR2I GetCenter() const
Definition: shape_circle.h:112
VECTOR2< int > VECTOR2I
Definition: vector2d.h:622
const SHAPE_LINE_CHAIN SegmentHull(const SHAPE_SEGMENT &aSeg, int aClearance, int aWalkaroundThickness)
Definition: pns_utils.cpp:144
SHAPE * m_shape
Definition: pns_solid.h:125
const VECTOR2I GetSize() const
Definition: shape_rect.h:124
ITEM * Clone() const override
Return a deep copy of the item.
Definition: pns_solid.cpp:170
Represent a set of closed polygons.
SHAPE_LINE_CHAIN & Outline(int aIndex)
const VECTOR2I & GetPosition() const
Definition: shape_rect.h:116
static wxString SHAPE_TYPE_asString(SHAPE_TYPE a)
Definition: shape.h:55
circular arc
Definition: shape.h:50
const SHAPE_LINE_CHAIN OctagonalHull(const VECTOR2I &aP0, const VECTOR2I &aSize, int aClearance, int aChamfer)
Definition: pns_utils.cpp:35
void Simplify(POLYGON_MODE aFastMode)
An abstract shape on 2D plane.
Definition: shape.h:116
E_SERIE r
Definition: eserie.cpp:41
circle
Definition: shape.h:46
SHAPE * m_hole
Definition: pns_solid.h:126
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new hole to the given outline (default: last) and returns its index.
const SHAPE_LINE_CHAIN ArcHull(const SHAPE_ARC &aSeg, int aClearance, int aWalkaroundThickness)
Various utility functions.
Definition: pns_utils.cpp:66
const std::vector< SHAPE * > & Shapes() const
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
constexpr int delta
axis-aligned rectangle
Definition: shape.h:43
virtual void Move(const VECTOR2I &aVector)=0
Push and Shove diff pair dimensions (gap) settings dialog.
simple polygon
Definition: shape.h:47
SHAPE_TYPE Type() const
Return the type of the shape.
Definition: shape.h:94
static ROUTER * GetInstance()
Definition: pns_router.cpp:78
const SHAPE_LINE_CHAIN Hull(int aClearance=0, int aWalkaroundThickness=0, int aLayer=-1) const override
Definition: pns_solid.cpp:97
line segment
Definition: shape.h:44
VECTOR2I m_pos
Definition: pns_solid.h:124