KiCad PCB EDA Suite
Loading...
Searching...
No Matches
playground.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, 2024 KiCad Developers.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24
25// WARNING - this Tom's crappy PNS hack tool code. Please don't complain about its quality
26// (unless you want to improve it).
27
28#include <pgm_base.h>
30
32#include "label_manager.h"
33
34#include <geometry/shape_arc.h>
35
36#include <pad.h>
37
43static const wxChar tracePnsPlayground[] = wxT( "KICAD_PNS_PLAYGROUND" );
44
45
46std::shared_ptr<PNS_LOG_VIEWER_OVERLAY> overlay;
47
48
49static inline bool collide( const SHAPE_LINE_CHAIN& aLhs, const SHAPE_LINE_CHAIN& aRhs,
50 int aClearance, int* aDistance = nullptr, VECTOR2I* aPt1 = nullptr )
51{
52 wxCHECK( aLhs.PointCount() && aRhs.PointCount(), false );
53
54 VECTOR2I pt1;
55 bool retv = false;
56 int dist = std::numeric_limits<int>::max();
57 int tmp = dist;
58
59 SHAPE_LINE_CHAIN lhs( aLhs );
60 SHAPE_LINE_CHAIN rhs( aRhs );
61
62 lhs.SetClosed( false );
63 lhs.Append( lhs.CPoint( 0 ) );
64 rhs.SetClosed( false );
65 rhs.Append( rhs.CPoint( 0 ) );
66
67 for( int i = 0; i < rhs.SegmentCount(); i ++ )
68 {
69 if( lhs.Collide( rhs.CSegment( i ), tmp, &tmp, &pt1 ) )
70 {
71 retv = true;
72
73 if( tmp < dist )
74 dist = tmp;
75
76 if( aDistance )
77 *aDistance = dist;
78
79 if( aPt1 )
80 *aPt1 = pt1;
81 }
82 }
83
84 return retv;
85}
86
87
88static bool collide( const SHAPE_POLY_SET& aLhs, const SHAPE_LINE_CHAIN& aRhs, int aClearance,
89 int* aDistance = nullptr, VECTOR2I* aPt1 = nullptr )
90{
91 VECTOR2I pt1;
92 bool retv = false;
93 int tmp = std::numeric_limits<int>::max();
94 int dist = tmp;
95
96 for( int i = 0; i < aLhs.OutlineCount(); i++ )
97 {
98 if( collide( aLhs.Outline( i ), aRhs, aClearance, &tmp, &pt1 ) )
99 {
100 retv = true;
101
102 if( tmp < dist )
103 {
104 dist = tmp;
105
106 if( aDistance )
107 *aDistance = dist;
108
109 if( aPt1 )
110 *aPt1 = pt1;
111 }
112 }
113
114 for( int j = 0; j < aLhs.HoleCount( i ); i++ )
115 {
116 if( collide( aLhs.CHole( i, j ), aRhs, aClearance, &tmp, &pt1 ) )
117 {
118 retv = true;
119
120 if( tmp < dist )
121 {
122 dist = tmp;
123
124 if( aDistance )
125 *aDistance = dist;
126
127 if( aPt1 )
128 *aPt1 = pt1;
129 }
130 }
131 }
132 }
133
134 return retv;
135}
136
137
138bool collideArc2Arc( const SHAPE_ARC& a1, const SHAPE_ARC& a2, int clearance, SEG& minDistSeg )
139{
140 SEG mediatrix( a1.GetCenter(), a2.GetCenter() );
141
142 std::vector<VECTOR2I> ips;
143
144 // Basic case - arcs intersect
145 if( a1.Intersect( a2, &ips ) > 0 )
146 {
147 minDistSeg.A = minDistSeg.B = ips[0];
148 return true;
149 }
150
151 // Arcs don't intersect, build a list of points to check
152 std::vector<VECTOR2I> ptsA;
153 std::vector<VECTOR2I> ptsB;
154
155 bool cocentered = ( mediatrix.A == mediatrix.B );
156
157 // 1: Interior points of both arcs, which are on the line segment between the two centres
158 if( !cocentered )
159 {
160 a1.IntersectLine( mediatrix, &ptsA );
161 a2.IntersectLine( mediatrix, &ptsB );
162 }
163
164 // 2: Check arc end points
165 ptsA.push_back( a1.GetP0() );
166 ptsA.push_back( a1.GetP1() );
167 ptsB.push_back( a2.GetP0() );
168 ptsB.push_back( a2.GetP1() );
169
170 // 3: Endpoint of one and "projected" point on the other, which is on the
171 // line segment through that endpoint and the centre of the other arc
172 a1.IntersectLine( SEG( a2.GetP0(), a1.GetCenter() ), &ptsA );
173 a1.IntersectLine( SEG( a2.GetP1(), a1.GetCenter() ), &ptsA );
174
175 a2.IntersectLine( SEG( a1.GetP0(), a2.GetCenter() ), &ptsB );
176 a2.IntersectLine( SEG( a1.GetP1(), a2.GetCenter() ), &ptsB );
177
178 double minDist = std::numeric_limits<double>::max();
179 bool minDistFound = false;
180
181 // @todo performance might be improved by only checking certain points (e.g only check end
182 // points against other end points or their corresponding "projected" points)
183 for( const VECTOR2I& ptA : ptsA )
184 {
185 for( const VECTOR2I& ptB : ptsB )
186 {
187 double dist = ( ptA - ptB ).EuclideanNorm() - a1.GetWidth() / 2.0 - a2.GetWidth() / 2.0;
188
189 if( dist < clearance )
190 {
191 if( !minDistFound || dist < minDist )
192 {
193 minDist = dist;
194 minDistSeg = SEG( ptA, ptB );
195 }
196
197 minDistFound = true;
198 }
199 }
200 }
201
202 return minDistFound;
203}
204
205
206int playground_main_func( int argc, char* argv[] )
207{
208 auto frame = new PNS_LOG_VIEWER_FRAME( nullptr );
209 Pgm().App().SetTopWindow( frame ); // wxApp gets a face.
210 frame->Show();
211
212 struct ARC_DATA
213 {
214 double cx, cy, sx, sy, ca, w;
215 };
216
217 const ARC_DATA test_data [] =
218 {
219 {73.843527, 74.355869, 71.713528, 72.965869, -76.36664803, 0.2},
220 {71.236473, 74.704131, 73.366472, 76.094131, -76.36664803, 0.2},
221 {82.542335, 74.825975, 80.413528, 73.435869, -76.4, 0.2},
222 {76.491192, 73.839894, 78.619999, 75.23, -76.4, 0.2},
223 {89.318807, 74.810106, 87.19, 73.42, -76.4, 0.2},
224 {87.045667, 74.632941, 88.826472, 75.794131, -267.9, 0.2},
225 {94.665667, 73.772941, 96.446472, 74.934131, -267.9, 0.2},
226 {94.750009, 73.74012, 93.6551, 73.025482, -255.5, 0.2},
227 {72.915251, 80.493054, 73.570159, 81.257692, -260.5, 0.2}, // end points clearance false positive
228 {73.063537, 82.295989, 71.968628, 81.581351, -255.5, 0.2},
229 {79.279991, 80.67988, 80.3749, 81.394518, -255.5, 0.2},
230 {79.279991, 80.67988, 80.3749, 81.694518, -255.5, 0.2 },
231 {88.495265, 81.766089, 90.090174, 82.867869, -255.5, 0.2},
232 {86.995265, 81.387966, 89.090174, 82.876887, -255.5, 0.2},
233 {96.149734, 81.792126, 94.99, 83.37, -347.2, 0.2},
234 {94.857156, 81.240589, 95.91, 83.9, -288.5, 0.2},
235 {72.915251, 86.493054, 73.970159, 87.257692, -260.5, 0.2}, // end points clearance #1
236 {73.063537, 88.295989, 71.968628, 87.581351, -255.5, 0.2},
237 {78.915251, 86.393054, 79.970159, 87.157692, 99.5, 0.2}, // end points clearance #2 - false positive
238 {79.063537, 88.295989, 77.968628, 87.581351, -255.5, 0.2},
239 {85.915251, 86.993054, 86.970159, 87.757692, 99.5, 0.2}, // intersection - false negative
240 {86.063537, 88.295989, 84.968628, 87.581351, -255.5, 0.2},
241 {94.6551, 88.295989, 95.6551, 88.295989, 90.0, 0.2 }, // simulating diff pair
242 {94.6551, 88.295989, 95.8551, 88.295989, 90.0, 0.2 },
243 {73.77532, 93.413654, 75.70532, 93.883054, 60.0, 0.1 }, // one arc fully enclosed in other
244 {73.86532, 93.393054, 75.86532, 93.393054, 90.0, 0.3 },
245 {79.87532, 93.413654, 81.64532, 94.113054, 60.0, 0.1 }, // concentric
246 {79.87532, 93.413654, 81.86532, 93.393054, 90.0, 0.3 }
247 };
248
249
250 overlay = frame->GetOverlay();
251
252
253 overlay->SetIsFill( false );
254 overlay->SetLineWidth( 10000 );
255
256 std::vector<SHAPE_ARC> arcs;
257 int n_arcs = sizeof( test_data ) / sizeof( ARC_DATA );
258
259 BOX2I vp;
260
261 for( int i = 0; i < n_arcs; i++ )
262 {
263 const ARC_DATA& d = test_data[i];
264
265 SHAPE_ARC arc( VECTOR2D( pcbIUScale.mmToIU( d.cx ), pcbIUScale.mmToIU( d.cy ) ),
266 VECTOR2D( pcbIUScale.mmToIU( d.sx ), pcbIUScale.mmToIU( d.sy ) ),
267 EDA_ANGLE( d.ca, DEGREES_T ), pcbIUScale.mmToIU( d.w ) );
268
269 arcs.push_back( arc );
270
271 if( i == 0 )
272 vp = arc.BBox();
273 else
274 vp.Merge( arc.BBox() );
275 }
276
277
278 PAD pad1( nullptr );
279 pad1.SetX( pcbIUScale.mmToIU( 84.0 ) );
280 pad1.SetY( pcbIUScale.mmToIU( 66.0 ) );
281 pad1.SetSizeX( pcbIUScale.mmToIU( 7.0 ) );
282 pad1.SetSizeY( pcbIUScale.mmToIU( 7.0 ) );
283 pad1.SetDrillSizeX( pcbIUScale.mmToIU( 3.5 ) );
284 pad1.SetDrillSizeY( pcbIUScale.mmToIU( 3.5 ) );
285 vp.Merge( pad1.GetBoundingBox() );
286
287 PAD pad2( nullptr );
288 pad2.SetX( pcbIUScale.mmToIU( 87.125 ) );
289 pad2.SetY( pcbIUScale.mmToIU( 66.0 ) );
290 pad2.SetSizeX( pcbIUScale.mmToIU( 0.8 ) );
291 pad2.SetSizeY( pcbIUScale.mmToIU( 0.8 ) );
292 pad2.SetDrillSizeX( pcbIUScale.mmToIU( 0.5 ) );
293 pad2.SetDrillSizeY( pcbIUScale.mmToIU( 0.5 ) );
294 vp.Merge( pad2.GetBoundingBox() );
295
296 SHAPE_POLY_SET pad1Outline;
297 SHAPE_POLY_SET pad1Hole;
298
299 pad1.TransformShapeToPolygon( pad1Outline, UNDEFINED_LAYER, 0, 4, ERROR_OUTSIDE );
300 pad1.TransformHoleToPolygon( pad1Hole, 0, 4, ERROR_INSIDE );
301 pad1Outline.AddHole( pad1Hole.Outline( 0 ), 0 );
302
303 SHAPE_POLY_SET pad2Outline;
304
305 // pad2.TransformShapeToPolygon( pad2Outline, UNDEFINED_LAYER, 0, 4, ERROR_OUTSIDE );
306 pad2.TransformHoleToPolygon( pad2Outline, 0, 4, ERROR_INSIDE );
307
308 SHAPE_POLY_SET xorPad1ToPad2 = pad1Outline;
309
310 xorPad1ToPad2.BooleanXor( pad2Outline );
311 xorPad1ToPad2.Move( VECTOR2I( pcbIUScale.mmToIU( 10 ), 0 ) );
312
313 SHAPE_POLY_SET andPad1ToPad2 = pad2Outline;
314
315 andPad1ToPad2.BooleanIntersection( pad1Outline );
316 andPad1ToPad2.Move( VECTOR2I( pcbIUScale.mmToIU( 20 ), 0 ) );
317
318 std::shared_ptr<SHAPE_SEGMENT> slot = pad2.GetEffectiveHoleShape();
319
320 printf("Read %zu arcs\n", arcs.size() );
321
322 LABEL_MANAGER labelMgr( frame->GetPanel()->GetGAL() );
323 frame->GetPanel()->GetView()->SetViewport( BOX2D( vp.GetOrigin(), vp.GetSize() ) );
324
325 for( int i = 0; i < arcs.size(); i+= 2 )
326 {
327 SEG closestDist;
328 std::vector<VECTOR2I> ips;
329 bool collides = collideArc2Arc( arcs[i], arcs[i+1], 0, closestDist );
330 int ni = arcs[i].Intersect( arcs[i+1], &ips );
331
332 overlay->SetLineWidth( 10000.0 );
333 overlay->SetStrokeColor( GREEN );
334
335 for( int j = 0; j < ni; j++ )
336 overlay->AnnotatedPoint( ips[j], arcs[i].GetWidth() );
337
338 if( collides )
339 {
340 overlay->SetStrokeColor( YELLOW );
341 overlay->Line( closestDist.A, closestDist.B );
342 overlay->SetLineWidth( 10000 );
343 overlay->SetGlyphSize( { 100000, 100000 } );
344 overlay->BitmapText( wxString::Format( "dist=%d", closestDist.Length() ),
345 closestDist.A + VECTOR2I( 0, -arcs[i].GetWidth() ),
347 }
348
349 overlay->SetLineWidth( 10000 );
350 overlay->SetStrokeColor( CYAN );
351 overlay->AnnotatedPoint( arcs[i].GetP0(), arcs[i].GetWidth() / 2 );
352 overlay->AnnotatedPoint( arcs[i + 1].GetP0(), arcs[i + 1].GetWidth() / 2 );
353 overlay->AnnotatedPoint( arcs[i].GetArcMid(), arcs[i].GetWidth() / 2 );
354 overlay->AnnotatedPoint( arcs[i + 1].GetArcMid(), arcs[i + 1].GetWidth() / 2 );
355 overlay->AnnotatedPoint( arcs[i].GetP1(), arcs[i].GetWidth() / 2 );
356 overlay->AnnotatedPoint( arcs[i + 1].GetP1(), arcs[i + 1].GetWidth() / 2 );
357
358
359 overlay->SetStrokeColor( RED );
360 overlay->Arc( arcs[i] );
361 overlay->SetStrokeColor( MAGENTA );
362 overlay->Arc( arcs[i + 1] );
363 }
364
365 overlay->SetLineWidth( 2000 );
366 overlay->SetStrokeColor( CYAN );
367 overlay->AnnotatedPolyset( pad1Outline, "Raw Pads" );
368 overlay->SetStrokeColor( RED );
369 overlay->AnnotatedPolyset( pad2Outline );
370 overlay->SetStrokeColor( CYAN );
371 overlay->AnnotatedPolyset( xorPad1ToPad2, "XOR Pads" );
372 overlay->AnnotatedPolyset( andPad1ToPad2, "AND Pads" );
373
374 wxLogTrace( tracePnsPlayground, wxS( "Pad 1 has %d outlines." ), pad1Outline.OutlineCount() );
375
376 wxLogTrace( tracePnsPlayground, wxS( "Pad 2 has %d outlines." ), pad2Outline.OutlineCount() );
377
378 VECTOR2I pt1, pt2;
379 int dist = std::numeric_limits<int>::max();
380
381 collide( pad1Outline, pad2Outline.Outline( 0 ), dist, &dist, &pt1 );
382
383 wxLogDebug( tracePnsPlayground, wxS( "Nearest distance between pad 1 and pad 2 is %0.6f mm "
384 "at X=%0.6f mm, Y=%0.6f mm." ),
385 pcbIUScale.IUTomm( dist ), pcbIUScale.IUTomm( pt1.x ),
386 pcbIUScale.IUTomm( pt1.y ) );
387
388 overlay->SetStrokeColor( YELLOW );
389 overlay->SetGlyphSize( { 100000, 100000 } );
390 overlay->BitmapText( wxString::Format( "dist=%0.3f mm", pcbIUScale.IUTomm( dist ) ),
391 pt1 + VECTOR2I( 0, -56000 ), ANGLE_HORIZONTAL );
392
393 overlay = nullptr;
394
395 return 0;
396}
397
398
399
400int drawShapes( int argc, char* argv[] )
401{
402 SHAPE_ARC arc( VECTOR2I( 206000000, 140110000 ), VECTOR2I( 201574617, 139229737 ),
403 VECTOR2I( 197822958, 136722959 ), 250000 );
404
405 SHAPE_LINE_CHAIN lc( { /* VECTOR2I( 159600000, 142500000 ), VECTOR2I( 159600000, 142600000 ),
406 VECTOR2I( 166400000, 135800000 ), VECTOR2I( 166400000, 111600000 ),
407 VECTOR2I( 190576804, 111600000 ), VECTOR2I( 192242284, 113265480 ),
408 VECTOR2I( 192255720, 113265480 ),*/
409 VECTOR2I( 203682188, 124691948 ), VECTOR2I( 203682188, 140332188 ),
410 /* VECTOR2I( 206000000, 142650000 ) */ },
411 false );
412
413 auto frame = new PNS_LOG_VIEWER_FRAME( nullptr );
414 Pgm().App().SetTopWindow( frame ); // wxApp gets a face.
415 frame->Show();
416
417 overlay = frame->GetOverlay();
418
419
420 overlay->SetIsFill( false );
421 overlay->SetLineWidth( arc.GetWidth() );
422 overlay->SetStrokeColor( RED );
423 overlay->Arc( arc );
424 overlay->SetLineWidth( arc.GetWidth() / 20 );
425 overlay->SetStrokeColor( GREEN );
426 overlay->Polyline( lc );
427
428 overlay->SetLineWidth( 80000.0 );
429 overlay->SetStrokeColor( CYAN );
430
431 for( int i = 0; i < lc.PointCount(); ++i )
432 {
433 int mult = ( i % 2 ) ? 1 : -1;
434 overlay->AnnotatedPoint( lc.GetPoint( i ), arc.GetWidth() * 2 );
435 overlay->SetGlyphSize( { 800000, 800000 } );
436 overlay->BitmapText( wxString::Format( "x=%d, y=%d",
437 lc.GetPoint( i ).x,
438 lc.GetPoint( i ).y ),
439 lc.GetPoint( i ) + VECTOR2I( 0, mult*arc.GetWidth() * 4 ),
441 }
442
443 arc.Collide( &lc, 100000 );
444
445 BOX2I vp = arc.BBox();
446 vp.Merge( lc.BBox() );
447 vp.Inflate( (800000 + arc.GetWidth() * 4 )*2);
448 frame->GetPanel()->GetView()->SetViewport( BOX2D( vp.GetOrigin(), vp.GetSize() ) );
449
450 overlay = nullptr;
451
452 return 0;
453}
454
455
457 "playground",
458 "Geometry/drawing playground",
460} );
461
462
464 "drawShapes",
465 "drawing shapes",
467} );
@ ERROR_OUTSIDE
Definition: approximation.h:33
@ ERROR_INSIDE
Definition: approximation.h:34
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:108
BOX2< VECTOR2D > BOX2D
Definition: box2.h:923
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:558
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:658
constexpr const Vec & GetOrigin() const
Definition: box2.h:210
constexpr const SizeVec & GetSize() const
Definition: box2.h:206
Definition: pad.h:54
const BOX2I GetBoundingBox() const override
The bounding box is cached, so this will be efficient most of the time.
Definition: pad.cpp:802
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aMaxError, ERROR_LOC aErrorLoc=ERROR_INSIDE, bool ignoreLineWidth=false) const override
Convert the pad shape to a closed polygon.
Definition: pad.cpp:1876
void SetDrillSizeX(const int aX)
Definition: pad.cpp:419
void SetY(int y)
Definition: pad.h:258
void SetX(int x)
Definition: pad.h:259
void SetSizeX(const int aX)
Definition: pad.h:273
void SetDrillSizeY(const int aY)
Definition: pad.h:310
std::shared_ptr< SHAPE_SEGMENT > GetEffectiveHoleShape() const override
Return a SHAPE_SEGMENT object representing the pad's hole.
Definition: pad.cpp:545
bool TransformHoleToPolygon(SHAPE_POLY_SET &aBuffer, int aClearance, int aError, ERROR_LOC aErrorLoc=ERROR_INSIDE) const
Build the corner list of the polygonal drill shape in the board coordinate system.
Definition: pad.cpp:1859
void SetSizeY(const int aY)
Definition: pad.h:284
virtual wxApp & App()
Returns a bare naked wxApp which may come from wxPython, SINGLE_TOP, or kicad.exe.
Definition: pgm_base.cpp:182
Definition: seg.h:42
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50
int Length() const
Return the length (this).
Definition: seg.h:333
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
Definition: shape_arc.cpp:403
int Intersect(const CIRCLE &aArc, std::vector< VECTOR2I > *aIpsBuffer) const
Find intersection points between this arc and a CIRCLE.
Definition: shape_arc.cpp:316
int GetWidth() const
Definition: shape_arc.h:168
const VECTOR2I & GetP1() const
Definition: shape_arc.h:115
int IntersectLine(const SEG &aSeg, std::vector< VECTOR2I > *aIpsBuffer) const
Find intersection points between this arc and aSeg, treating aSeg as an infinite line.
Definition: shape_arc.cpp:295
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: shape_arc.cpp:244
const VECTOR2I & GetP0() const
Definition: shape_arc.h:114
const VECTOR2I & GetCenter() const
Definition: shape_arc.cpp:523
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
int PointCount() const
Return the number of points (vertices) in this line chain.
virtual bool Collide(const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Check if point aP lies closer to us than aClearance.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
int SegmentCount() const
Return the number of segments in this line chain.
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
Represent a set of closed polygons.
void BooleanXor(const SHAPE_POLY_SET &b)
Perform boolean polyset exclusive or.
int HoleCount(int aOutline) const
Returns the number of holes in a given outline.
int AddHole(const SHAPE_LINE_CHAIN &aHole, int aOutline=-1)
Adds a new hole to the given outline (default: last) and returns its index.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
void BooleanIntersection(const SHAPE_POLY_SET &b)
Perform boolean polyset intersection.
const SHAPE_LINE_CHAIN & CHole(int aOutline, int aHole) const
int OutlineCount() const
Return the number of outlines in the set.
void Move(const VECTOR2I &aVector) override
static bool Register(const KI_TEST::UTILITY_PROGRAM &aProgInfo)
Register a utility program factory function against an ID string.
@ MAGENTA
Definition: color4d.h:60
@ GREEN
Definition: color4d.h:57
@ CYAN
Definition: color4d.h:58
@ YELLOW
Definition: color4d.h:67
@ RED
Definition: color4d.h:59
@ DEGREES_T
Definition: eda_angle.h:31
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
Definition: eda_angle.h:397
static const wxChar tracePnsPlayground[]
Flag to enable PNS playground debugging output.
Definition: playground.cpp:43
@ UNDEFINED_LAYER
Definition: layer_ids.h:61
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1060
see class PGM_BASE
static bool registered
Definition: playground.cpp:456
int playground_main_func(int argc, char *argv[])
Definition: playground.cpp:206
static bool registered1
Definition: playground.cpp:463
int drawShapes(int argc, char *argv[])
Definition: playground.cpp:400
static bool collide(const SHAPE_LINE_CHAIN &aLhs, const SHAPE_LINE_CHAIN &aRhs, int aClearance, int *aDistance=nullptr, VECTOR2I *aPt1=nullptr)
Definition: playground.cpp:49
bool collideArc2Arc(const SHAPE_ARC &a1, const SHAPE_ARC &a2, int clearance, SEG &minDistSeg)
Definition: playground.cpp:138
std::shared_ptr< PNS_LOG_VIEWER_OVERLAY > overlay
Definition: playground.cpp:46
constexpr double IUTomm(int iu) const
Definition: base_units.h:86
constexpr int mmToIU(double mm) const
Definition: base_units.h:88
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:691
VECTOR2< double > VECTOR2D
Definition: vector2d.h:690