KiCad PCB EDA Suite
shape_compound.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) 2020 KiCad Developers
5  * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
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 #include <sstream>
26 #include <string>
27 
29 
30 const std::string SHAPE_COMPOUND::Format() const
31 {
32  std::stringstream ss;
33 
34  ss << "compound( ";
35 
36  for( auto shape : m_shapes )
37  ss << shape->Format() << " ";
38 
39  return ss.str();
40 }
41 
42 SHAPE_COMPOUND::SHAPE_COMPOUND( const std::vector<SHAPE*>& aShapes ) :
43  SHAPE( SH_COMPOUND ),
44  m_dirty( true ),
45  m_shapes( aShapes )
46 {
47 
48 }
49 
50 
52  : SHAPE( SH_COMPOUND )
53 {
54  for ( const SHAPE* shape : aOther.Shapes() )
55  m_shapes.push_back( shape->Clone() );
56 
57  m_dirty = true;
58 }
59 
60 
61 
62 
64 {
65  for( auto shape : m_shapes )
66  delete shape;
67 }
68 
69 
71 {
72  return new SHAPE_COMPOUND( *this );
73 }
74 
75 
76 const BOX2I SHAPE_COMPOUND::BBox( int aClearance ) const
77 {
78  BOX2I bb;
79 
80  if ( m_shapes.size() < 1 )
81  return bb;
82 
83  bb = m_shapes[0]->BBox();
84 
85  for( size_t i = 1; i < m_shapes.size(); i++ )
86  bb.Merge( m_shapes[i]->BBox() );
87 
88  return bb;
89 }
90 
91 void SHAPE_COMPOUND::Move ( const VECTOR2I& aVector )
92 {
93  for( auto& item : m_shapes )
94  item->Move( aVector );
95 }
96 
97 
98 int SHAPE_COMPOUND::Distance( const SEG& aSeg ) const
99 {
100  assert(false);
101  return 0; // Make compiler happy
102 }
103 
104 
105 void SHAPE_COMPOUND::Rotate( double aAngle, const VECTOR2I& aCenter )
106 {
107  assert( false );
108 }
109 
110 
112 {
113  return true;
114 }
115 
116 
117 bool SHAPE_COMPOUND::Collide( const SEG& aSeg, int aClearance, int* aActual,
118  VECTOR2I* aLocation ) const
119 {
120  int closest_dist = std::numeric_limits<int>::max();
121  VECTOR2I nearest;
122 
123  for( SHAPE* item : m_shapes )
124  {
125  int actual = 0;
126  VECTOR2I pn;
127 
128  if( item->Collide( aSeg, aClearance,
129  aActual || aLocation ? &actual : nullptr,
130  aLocation ? &pn : nullptr ) )
131  {
132  if( actual < closest_dist )
133  {
134  nearest = pn;
135  closest_dist = actual;
136 
137  if( closest_dist == 0 || !aActual )
138  break;
139  }
140  }
141  }
142 
143  if( closest_dist == 0 || closest_dist < aClearance )
144  {
145  if( aLocation )
146  *aLocation = nearest;
147 
148  if( aActual )
149  *aActual = closest_dist;
150 
151  return true;
152  }
153 
154  return false;
155 }
156 
157 
159 {
160  return false;
161 }
compound shape, consisting of multiple simple shapes
Definition: shape.h:49
Represent a simple polygon consisting of a zero-thickness closed chain of connected line segments.
Definition: shape_simple.h:41
void Move(const VECTOR2I &aVector) override
bool IsSolid() const override
void Rotate(double aAngle, const VECTOR2I &aCenter={ 0, 0 }) override
int Distance(const SEG &aSeg) const
SHAPE_COMPOUND * Clone() const override
Return a dynamically allocated copy of the shape.
An abstract shape on 2D plane.
Definition: shape.h:116
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:363
bool Collide(const SEG &aSeg, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Check if the boundary of shape (this) lies closer to the segment aSeg than aClearance,...
Definition: seg.h:40
const std::vector< SHAPE * > & Shapes() const
std::vector< SHAPE * > m_shapes
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
const std::string Format() const override
bool ConvertToSimplePolygon(SHAPE_SIMPLE *aOut) const