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