KiCad PCB EDA Suite
Loading...
Searching...
No Matches
export_hyperlynx.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) 2019 CERN
5 * Copyright The 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#include <cstdio>
26#include <vector>
27
28#include <wx/log.h>
29#include <wx/filedlg.h>
30
31#include <kiface_base.h>
32#include <macros.h>
33#include <pcb_edit_frame.h>
34#include <board.h>
36#include <board_item.h>
37#include <footprint.h>
38#include <pad.h>
39#include <pcb_track.h>
40#include <zone.h>
41#include <ki_exception.h>
42#include <locale_io.h>
43#include <reporter.h>
44#include <richio.h>
45#include <string_utils.h>
48
49
50static double iu2hyp( double iu )
51{
52 return iu / 1e9 / 0.0254;
53}
54
55
57
59{
60public:
61 friend class HYPERLYNX_EXPORTER;
62
63 HYPERLYNX_PAD_STACK( BOARD* aBoard, const PAD* aPad );
64 HYPERLYNX_PAD_STACK( BOARD* aBoard, const PCB_VIA* aVia );
66
67 bool IsThrough() const
68 {
70 }
71
72 bool operator==( const HYPERLYNX_PAD_STACK& other ) const
73 {
74 if( m_shape != other.m_shape )
75 return false;
76
77 if( m_type != other.m_type )
78 return false;
79
80 if( IsThrough() && other.IsThrough() && m_drill != other.m_drill )
81 return false;
82
83 if( m_sx != other.m_sx )
84 return false;
85
86 if( m_sy != other.m_sy )
87 return false;
88
89 if( m_layers != other.m_layers )
90 return false;
91
92 if( m_angle != other.m_angle )
93 return false;
94
95 return true;
96 }
97
98 void SetId( int id )
99 {
100 m_id = id;
101 }
102
103 int GetId() const
104 {
105 return m_id;
106 }
107
108 bool IsEmpty() const
109 {
110 LSET outLayers = m_layers & LSET::AllCuMask( m_board->GetCopperLayerCount() );
111
112 return outLayers.none();
113 }
114
115private:
117 int m_id;
120 int m_sx, m_sy;
121 double m_angle;
124};
125
126
128{
129public:
131 {
132 }
133
135
136 virtual bool Run() override;
137
138private:
140 {
142 {
143 if( *p == stack )
144 return p;
145 }
146
147 stack.SetId( m_padStacks.size() );
148 m_padStacks.push_back( new HYPERLYNX_PAD_STACK( stack ) );
149
150 return m_padStacks.back();
151 }
152
153 const std::string formatPadShape( const HYPERLYNX_PAD_STACK& aStack )
154 {
155 int shapeId = 0;
156 char buf[1024];
157
158 switch( aStack.m_shape )
159 {
161 case PAD_SHAPE::OVAL:
162 shapeId = 0;
163 break;
164
166 shapeId = 2;
167 break;
168
170 shapeId = 1;
171 break;
172
173 default:
174 if( m_reporter )
175 {
176 m_reporter->Report( _( "File contains pad shapes that are not supported by the "
177 "Hyperlynx exporter (supported shapes are oval, rectangle, "
178 "rounded rectangle, and circle)." ),
180 m_reporter->Report( _( "They have been exported as oval pads." ),
182 }
183
184 shapeId = 0;
185 break;
186 }
187
188 snprintf( buf, sizeof( buf ), "%d, %.9f, %.9f, %.1f, M",
189 shapeId,
190 iu2hyp( aStack.m_sx ),
191 iu2hyp( aStack.m_sy ),
192 aStack.m_angle );
193
194 return buf;
195 }
196
197 bool generateHeaders();
198 bool writeBoardInfo();
199 bool writeStackupInfo();
200 bool writeDevices();
201 bool writePadStacks();
202 bool writeNets();
203 bool writeNetObjects( const std::vector<BOARD_ITEM*>& aObjects );
204
205
207
208 const std::vector<BOARD_ITEM*> collectNetObjects( int netcode );
209
210private:
211 std::vector<HYPERLYNX_PAD_STACK*> m_padStacks;
212 std::map<BOARD_ITEM*, HYPERLYNX_PAD_STACK*> m_padMap;
213
214 std::shared_ptr<FILE_OUTPUTFORMATTER> m_out;
216};
217
218
220{
221 // TODO(JE) padstacks
222 m_board = aBoard;
225 m_angle = 180.0 - aPad->GetOrientation().AsDegrees();
226
227 if( m_angle < 0.0 )
228 m_angle += 360.0;
229
230 m_layers = aPad->GetLayerSet();
231 m_drill = aPad->GetDrillSize().x;
234 m_id = 0;
235}
236
237
239{
240 m_board = aBoard;
241 // TODO(JE) padstacks
243 m_angle = 0;
244 m_layers = aVia->GetLayerSet();
245 m_drill = aVia->GetDrillValue();
248 m_id = 0;
249}
250
251
253{
254 m_out->Print( 0, "{VERSION=2.14}\n" );
255 m_out->Print( 0, "{UNITS=ENGLISH LENGTH}\n\n" );
256 return true;
257}
258
259
261{
262 LSET layerMask = LSET::AllCuMask( m_board->GetCopperLayerCount() );
263 LSET outLayers = aStack.m_layers & layerMask;
264
265 if( outLayers.none() )
266 return;
267
268 m_out->Print( 0, "{PADSTACK=%d, %.9f\n", aStack.m_id, iu2hyp( aStack.m_drill ) );
269
270 if( outLayers == layerMask )
271 {
272 m_out->Print( 1, "(\"MDEF\", %s)\n", formatPadShape( aStack ).c_str() );
273 }
274 else
275 {
276 for( PCB_LAYER_ID l : outLayers.Seq() )
277 {
278 m_out->Print( 1, "(\"%s\", %s)\n",
279 (const char*) m_board->GetLayerName( l ).c_str(),
280 formatPadShape( aStack ).c_str() );
281 }
282 }
283
284 m_out->Print( 0, "}\n\n" );
285}
286
287
289{
290 SHAPE_POLY_SET outlines;
291
292 m_out->Print( 0, "{BOARD \"%s\"\n", (const char*) m_board->GetFileName().c_str() );
293
294 if( !m_board->GetBoardPolygonOutlines( outlines ) )
295 {
296 wxLogError( _( "Board outline is malformed. Run DRC for a full analysis." ) );
297 return false;
298 }
299
300 for( int o = 0; o < outlines.OutlineCount(); o++ )
301 {
302 const SHAPE_LINE_CHAIN& outl = outlines.COutline( o );
303
304 for( int i = 0; i < outl.SegmentCount(); i++ )
305 {
306 const SEG& s = outl.CSegment( i );
307 m_out->Print( 1, "(PERIMETER_SEGMENT X1=%.9f Y1=%.9f X2=%.9f Y2=%.9f)\n",
308 iu2hyp( s.A.x ),
309 iu2hyp( -s.A.y ),
310 iu2hyp( s.B.x ),
311 iu2hyp( -s.B.y ) );
312 }
313 }
314
315 m_out->Print( 0, "}\n\n" );
316
317 return true;
318}
319
320
322{
323 /* Format:
324 * {STACKUP
325 * (SIGNAL T=thickness [P=plating_thickness] [C=constant] L=layer_name [M=material_name]) [comment]
326 * (DIELECTRIC T=thickness [C=constant] [L=layer_name] [M=material_name]) [comment]
327 * }
328 * name length is <= 20 chars
329 */
330
331 LSEQ layers = m_board->GetDesignSettings().GetEnabledLayers().CuStack();
332
333 // Get the board physical stackup structure
334 const BOARD_STACKUP& stackup = m_board->GetDesignSettings().GetStackupDescriptor();
335
336 m_out->Print( 0, "{STACKUP\n" );
337
338 wxString layer_name; // The last copper layer name used in stackup
339
340 for( BOARD_STACKUP_ITEM* item: stackup.GetList() )
341 {
342 if( item->GetType() == BS_ITEM_TYPE_COPPER )
343 {
344 layer_name = m_board->GetLayerName( item->GetBrdLayerId() );
345 int plating_thickness = 0;
346 double resistivity = 1.724e-8; // Good for copper
347 m_out->Print( 1, "(SIGNAL T=%g P=%g C=%g L=\"%.20s\" M=COPPER)\n",
348 iu2hyp( item->GetThickness( 0 ) ),
349 iu2hyp( plating_thickness ),
350 resistivity,
351 TO_UTF8( layer_name ) );
352 }
353 else if( item->GetType() == BS_ITEM_TYPE_DIELECTRIC )
354 {
355 if( item->GetSublayersCount() < 2 )
356 {
357 m_out->Print( 1, "(DIELECTRIC T=%g C=%g L=\"DE_%.17s\" M=\"%.20s\")\n",
358 iu2hyp( item->GetThickness( 0 ) ),
359 item->GetEpsilonR( 0 ),
360 TO_UTF8( layer_name ),
361 TO_UTF8( item->GetMaterial( 0 ) ) );
362 }
363 else for( int idx = 0; idx < item->GetSublayersCount(); idx++ )
364 {
365 m_out->Print( 1, "(DIELECTRIC T=%g C=%g L=\"DE%d_%.16s\" M=\"%.20s\")\n",
366 iu2hyp( item->GetThickness( idx ) ),
367 item->GetEpsilonR( idx ),
368 idx,
369 TO_UTF8( layer_name ),
370 TO_UTF8( item->GetMaterial( idx ) ) );
371 }
372 }
373 }
374
375 m_out->Print( 0, "}\n\n" );
376
377 return true;
378}
379
380
382{
383 m_out->Print( 0, "{DEVICES\n" );
384
385 for( FOOTPRINT* footprint : m_board->Footprints() )
386 {
387 wxString ref = footprint->GetReference();
388 wxString layerName = m_board->GetLayerName( footprint->GetLayer() );
389
390 if( ref.IsEmpty() )
391 ref = wxT( "EMPTY" );
392
393 m_out->Print( 1, "(? REF=\"%s\" L=\"%s\")\n",
394 (const char*) ref.c_str(),
395 (const char*) layerName.c_str() );
396 }
397 m_out->Print( 0, "}\n\n" );
398
399 return true;
400}
401
402
404{
405 for( FOOTPRINT* footprint : m_board->Footprints() )
406 {
407 for( PAD* pad : footprint->Pads() )
408 {
410 m_padMap[pad] = ps;
411 }
412 }
413
414 for( PCB_TRACK* track : m_board->Tracks() )
415 {
416 if( PCB_VIA* via = dyn_cast<PCB_VIA*>( track ) )
417 {
419 m_padMap[via] = ps;
420 }
421 }
422
423 for( HYPERLYNX_PAD_STACK* pstack : m_padStacks )
424 writeSinglePadStack( *pstack );
425
426 return true;
427}
428
429
430bool HYPERLYNX_EXPORTER::writeNetObjects( const std::vector<BOARD_ITEM*>& aObjects )
431{
432 for( BOARD_ITEM* item : aObjects )
433 {
434 if( PAD* pad = dyn_cast<PAD*>( item ) )
435 {
436 auto pstackIter = m_padMap.find( pad );
437
438 if( pstackIter != m_padMap.end() )
439 {
440 wxString ref = pad->GetParentFootprint()->GetReference();
441
442 if( ref.IsEmpty() )
443 ref = wxT( "EMPTY" );
444
445 wxString padName = pad->GetNumber();
446
447 if( padName.IsEmpty() )
448 padName = wxT( "1" );
449
450
451 m_out->Print( 1, "(PIN X=%.10f Y=%.10f R=\"%s.%s\" P=%d)\n",
452 iu2hyp( pad->GetPosition().x ),
453 iu2hyp( -pad->GetPosition().y ),
454 (const char*) ref.c_str(),
455 (const char*) padName.c_str(),
456 pstackIter->second->GetId() );
457 }
458 }
459 else if( PCB_VIA* via = dyn_cast<PCB_VIA*>( item ) )
460 {
461 auto pstackIter = m_padMap.find( via );
462
463 if( pstackIter != m_padMap.end() )
464 {
465 m_out->Print( 1, "(VIA X=%.10f Y=%.10f P=%d)\n",
466 iu2hyp( via->GetPosition().x ),
467 iu2hyp( -via->GetPosition().y ),
468 pstackIter->second->GetId() );
469 }
470 }
471 else if( PCB_TRACK* track = dyn_cast<PCB_TRACK*>( item ) )
472 {
473 const wxString layerName = m_board->GetLayerName( track->GetLayer() );
474
475 m_out->Print( 1, "(SEG X1=%.10f Y1=%.10f X2=%.10f Y2=%.10f W=%.10f L=\"%s\")\n",
476 iu2hyp( track->GetStart().x ),
477 iu2hyp( -track->GetStart().y ),
478 iu2hyp( track->GetEnd().x ),
479 iu2hyp( -track->GetEnd().y ),
480 iu2hyp( track->GetWidth() ),
481 (const char*) layerName.c_str() );
482 }
483 else if( PCB_ARC* arc = dyn_cast<PCB_ARC*>( item ) )
484 {
485 const wxString layerName = m_board->GetLayerName( arc->GetLayer() );
486 VECTOR2I start = arc->GetStart();
487 VECTOR2I end = arc->GetEnd();
488
489 if( arc->IsCCW() )
490 std::swap( start, end );
491
492 m_out->Print( 1, "(ARC X1=%.10f Y1=%.10f X2=%.10f Y2=%.10f XC=%.10f YC=%.10f R=%.10f W=%.10f L=\"%s\")\n",
493 iu2hyp( start.x ),
494 iu2hyp( -start.y ),
495 iu2hyp( end.x ),
496 iu2hyp( -end.y ),
497 iu2hyp( arc->GetCenter().x ),
498 iu2hyp( -arc->GetCenter().y ),
499 iu2hyp( arc->GetRadius() ),
500 iu2hyp( arc->GetWidth() ),
501 (const char*) layerName.c_str() );
502 }
503 else if( ZONE* zone = dyn_cast<ZONE*>( item ) )
504 {
505 for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() )
506 {
507 const wxString layerName = m_board->GetLayerName( layer );
508 SHAPE_POLY_SET fill = zone->GetFilledPolysList( layer )->CloneDropTriangulation();
509
510 fill.Simplify();
511
512 for( int i = 0; i < fill.OutlineCount(); i++ )
513 {
514 const SHAPE_LINE_CHAIN& outl = fill.COutline( i );
515 const VECTOR2I p0 = outl.CPoint( 0 );
516
517 m_out->Print( 1, "{POLYGON T=POUR L=\"%s\" ID=%d X=%.10f Y=%.10f\n",
518 (const char*) layerName.c_str(),
519 m_polyId,
520 iu2hyp( p0.x ),
521 iu2hyp( -p0.y ) );
522
523 for( int v = 0; v < outl.PointCount(); v++ )
524 {
525 m_out->Print( 2, "(LINE X=%.10f Y=%.10f)\n",
526 iu2hyp( outl.CPoint( v ).x ),
527 iu2hyp( -outl.CPoint( v ).y ) );
528 }
529
530 m_out->Print( 2, "(LINE X=%.10f Y=%.10f)\n", iu2hyp( p0.x ), iu2hyp( -p0.y ) );
531 m_out->Print( 1, "}\n" );
532
533 for( int h = 0; h < fill.HoleCount( i ); h++ )
534 {
535 const SHAPE_LINE_CHAIN& holeShape = fill.CHole( i, h );
536 const VECTOR2I ph0 = holeShape.CPoint( 0 );
537
538 m_out->Print( 1, "{POLYVOID ID=%d X=%.10f Y=%.10f\n",
539 m_polyId,
540 iu2hyp( ph0.x ),
541 iu2hyp( -ph0.y ) );
542
543 for( int v = 0; v < holeShape.PointCount(); v++ )
544 {
545 m_out->Print( 2, "(LINE X=%.10f Y=%.10f)\n",
546 iu2hyp( holeShape.CPoint( v ).x ),
547 iu2hyp( -holeShape.CPoint( v ).y ) );
548 }
549
550 m_out->Print( 2, "(LINE X=%.10f Y=%.10f)\n",
551 iu2hyp( ph0.x ),
552 iu2hyp( -ph0.y ) );
553 m_out->Print( 1, "}\n" );
554 }
555
556 m_polyId++;
557 }
558 }
559 }
560 }
561
562 return true;
563}
564
565
566const std::vector<BOARD_ITEM*> HYPERLYNX_EXPORTER::collectNetObjects( int netcode )
567{
568 std::vector<BOARD_ITEM*> rv;
569
570 auto check =
571 [&]( BOARD_CONNECTED_ITEM* item ) -> bool
572 {
573 if( ( item->GetLayerSet() & LSET::AllCuMask() ).none() )
574 return false;
575
576 if( item->GetNetCode() == netcode || ( netcode < 0 && item->GetNetCode() <= 0 ) )
577 return true;
578
579 return false;
580 };
581
582 for( FOOTPRINT* footprint : m_board->Footprints() )
583 {
584 for( PAD* pad : footprint->Pads() )
585 {
586 if( check( pad ) )
587 rv.push_back( pad );
588 }
589 }
590
591 for( PCB_TRACK* item : m_board->Tracks() )
592 {
593 if( check( item ) )
594 rv.push_back( item );
595 }
596
597 for( ZONE* zone : m_board->Zones() )
598 {
599 if( check( zone ) )
600 rv.push_back( zone );
601 }
602
603 return rv;
604}
605
606
608{
609 m_polyId = 1;
610
611 for( const NETINFO_ITEM* netInfo : m_board->GetNetInfo() )
612 {
613 int netcode = netInfo->GetNetCode();
614 bool isNullNet = netInfo->GetNetCode() <= 0 || netInfo->GetNetname().IsEmpty();
615
616 if( isNullNet )
617 continue;
618
619 const std::vector<BOARD_ITEM*> netObjects = collectNetObjects( netcode );
620
621 if( netObjects.size() )
622 {
623 m_out->Print( 0, "{NET=\"%s\"\n", (const char*) netInfo->GetNetname().c_str() );
624 writeNetObjects( netObjects );
625 m_out->Print( 0, "}\n\n" );
626 }
627 }
628
629 const std::vector<BOARD_ITEM*> nullNetObjects = collectNetObjects( -1 );
630
631 int idx = 0;
632
633 for( BOARD_ITEM* item : nullNetObjects )
634 {
635 m_out->Print( 0, "{NET=\"EmptyNet%d\"\n", idx );
636 writeNetObjects( { item } );
637 m_out->Print( 0, "}\n\n" );
638 idx++;
639 }
640
641 return true;
642}
643
644
646{
647 LOCALE_IO toggle; // toggles on, then off, the C locale.
648
649 try
650 {
651 m_out.reset( new FILE_OUTPUTFORMATTER( m_outputFilePath.GetFullPath() ) );
652
656 writeDevices();
658 writeNets();
659 }
660 catch( IO_ERROR& )
661 {
662 return false;
663 }
664
665 return true;
666}
667
668
670{
671 wxString wildcard = wxT( "*.hyp" );
672 BOARD* board = m_frame->GetBoard();
673 wxFileName fn = board->GetFileName();
674
675 fn.SetExt( wxT("hyp") );
676
677 wxFileDialog dlg( m_frame, _( "Export Hyperlynx Layout" ), fn.GetPath(), fn.GetFullName(),
678 wildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
679
680 if( dlg.ShowModal() != wxID_OK )
681 return 0;
682
683 fn = dlg.GetPath();
684
685 // always enforce filename extension, user may not have entered it.
686 fn.SetExt( wxT( "hyp" ) );
687
688 HYPERLYNX_EXPORTER exporter;
689 exporter.SetBoard( board );
690 exporter.SetOutputFilename( fn );
691 exporter.Run();
692
693 return 0;
694}
@ BS_ITEM_TYPE_COPPER
@ BS_ITEM_TYPE_DIELECTRIC
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
int ExportHyperlynx(const TOOL_EVENT &aEvent)
void SetOutputFilename(const wxFileName &aPath)
void SetBoard(BOARD *aBoard)
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:79
Manage one layer needed to make a physical board.
Manage layers needed to make a physical board.
const std::vector< BOARD_STACKUP_ITEM * > & GetList() const
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:317
double AsDegrees() const
Definition eda_angle.h:116
Used for text file output.
Definition richio.h:491
virtual bool Run() override
void writeSinglePadStack(HYPERLYNX_PAD_STACK &aStack)
const std::string formatPadShape(const HYPERLYNX_PAD_STACK &aStack)
std::vector< HYPERLYNX_PAD_STACK * > m_padStacks
std::map< BOARD_ITEM *, HYPERLYNX_PAD_STACK * > m_padMap
bool writeNetObjects(const std::vector< BOARD_ITEM * > &aObjects)
HYPERLYNX_PAD_STACK * addPadStack(HYPERLYNX_PAD_STACK stack)
std::shared_ptr< FILE_OUTPUTFORMATTER > m_out
const std::vector< BOARD_ITEM * > collectNetObjects(int netcode)
friend class HYPERLYNX_EXPORTER
HYPERLYNX_PAD_STACK(BOARD *aBoard, const PAD *aPad)
bool operator==(const HYPERLYNX_PAD_STACK &other) const
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition locale_io.h:41
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
Definition lseq.h:47
LSET is a set of PCB_LAYER_IDs.
Definition lset.h:37
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition lset.cpp:296
static LSET AllCuMask(int aCuLayerCount)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition lset.cpp:582
static LSET AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
Definition lset.cpp:591
Handle the data for a net.
Definition netinfo.h:54
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
Definition padstack.h:145
Definition pad.h:54
LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition pad.h:437
const VECTOR2I & GetDrillSize() const
Definition pad.h:305
PAD_SHAPE GetShape(PCB_LAYER_ID aLayer) const
Definition pad.h:195
EDA_ANGLE GetOrientation() const
Return the rotation angle of the pad.
Definition pad.h:408
const VECTOR2I & GetSize(PCB_LAYER_ID aLayer) const
Definition pad.h:264
BOARD * board() const
int GetWidth() const override
int GetDrillValue() const
Calculate the drill value for vias (m_drill if > 0, or default drill value for the board).
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition seg.h:42
VECTOR2I A
Definition seg.h:49
VECTOR2I B
Definition seg.h:50
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
int PointCount() const
Return the number of points (vertices) in this 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.
int HoleCount(int aOutline) const
Returns the number of holes in a given outline.
void Simplify()
Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections)
const SHAPE_LINE_CHAIN & CHole(int aOutline, int aHole) const
int OutlineCount() const
Return the number of outlines in the set.
SHAPE_POLY_SET CloneDropTriangulation() const
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
Generic, UI-independent tool event.
Definition tool_event.h:171
Handle a list of polygons defining a copper zone.
Definition zone.h:74
#define _(s)
static double iu2hyp(double iu)
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:60
This file contains miscellaneous commonly used macros and functions.
PAD_ATTRIB
The set of pad shapes, used with PAD::{Set,Get}Attribute().
Definition padstack.h:81
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
Definition padstack.h:87
@ PTH
Plated through hole pad.
Definition padstack.h:82
PAD_SHAPE
The set of pad shapes, used with PAD::{Set,Get}Shape()
Definition padstack.h:52
@ ROUNDRECT
Definition padstack.h:57
@ RECTANGLE
Definition padstack.h:54
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_INFO
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
VECTOR2I end
Casted dyn_cast(From aObject)
A lightweight dynamic downcast.
Definition typeinfo.h:61
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695