29#include <nlohmann/json.hpp>
69 int elayer = wxAtoi( aLayer );
85 case 13:
return F_Fab;
86 case 14:
return B_Fab;
137 wxString key = !aLibName.empty() ? ( aLibName +
':' + libReference ) : libReference;
140 libId.
Parse( key,
true );
148 std::map<wxString, std::unique_ptr<FOOTPRINT>>& aFootprintMap, wxArrayString aShapes )
151 const wxString easyedaModelDir = wxS(
"EASYEDA_MODELS" );
152 wxString kicadModelPrefix = wxS(
"${KIPRJMOD}/" ) + easyedaModelDir + wxS(
"/" );
154 BOARD* board = aParent ? aParent :
dynamic_cast<BOARD*
>( aContainer );
157 auto getOrAddNetItem = [&](
const wxString& aNetName ) ->
NETINFO_ITEM*
162 if( aNetName.empty() )
172 board->
Add( item, ADD_MODE::APPEND );
184 for( wxString shape : aShapes )
186 wxArrayString arr = wxSplit( shape,
'~',
'\0' );
188 wxString elType = arr[0];
189 if( elType == wxS(
"LIB" ) )
191 shape.Replace( wxS(
"#@$" ),
"\n" );
192 wxArrayString parts = wxSplit( shape,
'\n',
'\0' );
194 if( parts.size() < 1 )
197 wxArrayString paramsRoot = wxSplit( parts[0],
'~',
'\0' );
199 if( paramsRoot.size() < 4 )
204 wxString packageName =
205 wxString::Format( wxS(
"Unknown_%s_%s" ), paramsRoot[1], paramsRoot[2] );
207 wxArrayString paramParts = wxSplit( paramsRoot[3],
'`',
'\0' );
210 if( !paramsRoot[4].IsEmpty() )
215 if( !paramsRoot[7].IsEmpty() )
216 layer =
Convert( paramsRoot[7] );
218 std::map<wxString, wxString> paramMap;
220 for(
int i = 1; i < paramParts.size(); i += 2 )
222 wxString key = paramParts[i - 1];
223 wxString value = paramParts[i];
225 if( key == wxS(
"package" ) )
228 paramMap[key] = value;
235 aFootprintMap, parts );
244 aContainer->
Add( fp, ADD_MODE::APPEND );
246 else if( elType == wxS(
"TRACK" ) )
250 wxString netname = arr[3];
251 wxArrayString data = wxSplit( arr[4],
' ',
'\0' );
253 for(
int i = 3; i < data.size(); i += 2 )
263 std::unique_ptr<PCB_TRACK> track = std::make_unique<PCB_TRACK>( aContainer );
265 track->SetLayer( layer );
266 track->SetWidth( width );
267 track->SetStart( start );
268 track->SetEnd(
end );
269 track->SetNet( getOrAddNetItem( netname ) );
271 aContainer->
Add( track.release(), ADD_MODE::APPEND );
275 std::unique_ptr<PCB_SHAPE> seg =
276 std::make_unique<PCB_SHAPE>( aContainer, SHAPE_T::SEGMENT );
278 seg->SetLayer( layer );
279 seg->SetWidth( width );
280 seg->SetStart( start );
283 aContainer->
Add( seg.release(), ADD_MODE::APPEND );
287 else if( elType == wxS(
"CIRCLE" ) )
289 auto shape = std::make_unique<PCB_SHAPE>( aContainer, SHAPE_T::CIRCLE );
291 shape->SetWidth( width );
294 shape->SetLayer( layer );
302 shape->SetCenter(
center );
306 shape->SetNet( getOrAddNetItem( arr[8] ) );
308 aContainer->
Add( shape.release(), ADD_MODE::APPEND );
310 else if( elType == wxS(
"RECT" ) )
312 auto shape = std::make_unique<PCB_SHAPE>( aContainer, SHAPE_T::RECTANGLE );
314 shape->SetWidth( width );
317 shape->SetLayer( layer );
319 bool filled = arr[9] != wxS(
"none" );
320 shape->SetFilled( filled );
330 shape->SetStart( start );
331 shape->SetEnd( start + size );
334 shape->SetNet( getOrAddNetItem( arr[11] ) );
336 aContainer->
Add( shape.release(), ADD_MODE::APPEND );
338 else if( elType == wxS(
"ARC" ) )
340 std::unique_ptr<PCB_SHAPE> shape =
341 std::make_unique<PCB_SHAPE>( aContainer, SHAPE_T::ARC );
344 shape->SetWidth( width );
347 shape->SetLayer( layer );
350 shape->SetNet( getOrAddNetItem( arr[3] ) );
358 wxString data = arr[4];
359 auto readNumber = [&]( wxString& aOut )
361 wxUniChar ch = data[pos];
363 while( ch ==
' ' || ch ==
',' )
366 while( isdigit( ch ) || ch ==
'.' || ch ==
'-' )
371 if( pos == data.size() )
380 wxUniChar sym = data[pos++];
390 else if( sym ==
'A' )
392 wxString radX, radY,
unknown, farFlag, cwFlag, endX, endY;
396 readNumber( farFlag );
397 readNumber( cwFlag );
401 isFar = farFlag == wxS(
"1" );
402 cw = cwFlag == wxS(
"1" );
406 }
while( pos < data.size() );
410 double d =
delta.EuclideanNorm();
411 double h = sqrt( std::max( 0.0, rad.
x * rad.
x - d * d / 4 ) );
418 start +
delta / 2 +
delta.Perpendicular().Resize( ( isFar ^
cw ) ? h : -h );
421 std::swap( start,
end );
423 shape->SetStart(
RelPos( start ) );
425 shape->SetCenter(
RelPos( arcCenter ) );
427 aContainer->
Add( shape.release(), ADD_MODE::APPEND );
429 else if( elType == wxS(
"DIMENSION" ) )
433 wxString shapeData = arr[2].Trim();
436 std::vector<SHAPE_LINE_CHAIN> lineChains =
439 std::unique_ptr<PCB_GROUP>
group = std::make_unique<PCB_GROUP>( aContainer );
440 group->SetName( wxS(
"Dimension" ) );
447 auto shape = std::make_unique<PCB_SHAPE>( aContainer, SHAPE_T::SEGMENT );
449 shape->SetLayer( layer );
450 shape->SetWidth( lineWidth );
451 shape->SetStart( seg.
A );
452 shape->SetEnd( seg.
B );
454 group->AddItem( shape.get() );
456 aContainer->
Add( shape.release(), ADD_MODE::APPEND );
460 aContainer->
Add(
group.release(), ADD_MODE::APPEND );
462 else if( elType == wxS(
"SOLIDREGION" ) )
464 wxString layer = arr[1];
469 if( layer == wxS(
"11" ) )
473 auto shape = std::make_unique<PCB_SHAPE>( aContainer, SHAPE_T::POLY );
476 shape->SetFilled(
false );
478 shape->SetPolyShape( poly );
480 aContainer->
Add( shape.release(), ADD_MODE::APPEND );
485 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aContainer );
488 zone->SetLayer( klayer );
491 zone->SetNet( getOrAddNetItem( arr[2] ) );
494 zone->Outline()->AddPolygon( poly );
496 if( arr[4].Lower() == wxS(
"cutout" ) )
498 zone->SetIsRuleArea(
true );
499 zone->SetDoNotAllowCopperPour(
true );
500 zone->SetDoNotAllowTracks(
false );
501 zone->SetDoNotAllowVias(
false );
502 zone->SetDoNotAllowPads(
false );
503 zone->SetDoNotAllowFootprints(
false );
507 zone->SetFilledPolysList( klayer, polySet );
508 zone->SetPadConnection( ZONE_CONNECTION::FULL );
509 zone->SetIsFilled(
true );
510 zone->SetNeedRefill(
false );
513 zone->SetMinThickness( 0 );
514 zone->SetLocalClearance( 0 );
515 zone->SetAssignedPriority( 100 );
517 aContainer->
Add( zone.release(), ADD_MODE::APPEND );
520 else if( elType == wxS(
"COPPERAREA" ) )
522 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aContainer );
525 zone->SetLayer( layer );
527 wxString netname = arr[3];
530 zone->SetNet( getOrAddNetItem( netname ) );
533 zone->SetThermalReliefGap( zone->GetLocalClearance().value() );
535 wxString fillStyle = arr[5];
536 if( fillStyle == wxS(
"none" ) )
545 zone->Outline()->AddPolygon( poly );
547 wxString thermal = arr[8];
548 if( thermal == wxS(
"direct" ) )
549 zone->SetPadConnection( ZONE_CONNECTION::FULL );
551 wxString keepIsland = arr[9];
552 if( keepIsland == wxS(
"yes" ) )
553 zone->SetIslandRemovalMode( ISLAND_REMOVAL_MODE::NEVER );
555 wxString fillData = arr[10];
559 for(
const nlohmann::json& polyData : nlohmann::json::parse( fillData ) )
561 for(
const nlohmann::json& contourData : polyData )
568 for(
int i = 1; i < contourPolySet.
OutlineCount(); i++ )
571 fillPolySet.
Append( currentOutline );
577 zone->SetFilledPolysList( layer, fillPolySet );
578 zone->SetIsFilled(
true );
579 zone->SetNeedRefill(
false );
581 catch( nlohmann::json::exception& e )
585 int fillOrder = wxAtoi( arr[13] );
586 zone->SetAssignedPriority( 100 - fillOrder );
588 wxString improveFabrication = arr[17];
589 if( improveFabrication == wxS(
"none" ) )
591 zone->SetMinThickness( 0 );
598 zone->SetMinThickness( minThickness );
601 if( arr.size() > 18 )
603 zone->SetThermalReliefSpokeWidth( std::max(
int(
ConvertSize( arr[18] ) ),
604 zone->GetMinThickness() ) );
608 wxFAIL_MSG( wxString::Format(
"COPPERAREA unexpected size %d: %s ",
612 zone->SetThermalReliefSpokeWidth( zone->GetMinThickness() );
615 aContainer->
Add( zone.release(), ADD_MODE::APPEND );
617 else if( elType == wxS(
"SVGNODE" ) )
619 nlohmann::json nodeData = nlohmann::json::parse( arr[1] );
621 int nodeType = nodeData.at(
"nodeType" );
622 wxString layer = nodeData.at(
"layerid" );
627 std::map<wxString, wxString> attributes = nodeData.at(
"attrs" );
629 if( layer == wxS(
"19" ) )
634 auto ec_eType =
get_opt( attributes,
"c_etype" );
635 auto ec_rotation =
get_opt( attributes,
"c_rotation" );
636 auto ec_origin =
get_opt( attributes,
"c_origin" );
637 auto ec_width =
get_opt( attributes,
"c_width" );
638 auto ec_height =
get_opt( attributes,
"c_height" );
639 auto ez =
get_opt( attributes,
"z" );
640 auto etitle =
get_opt( attributes,
"title" );
641 auto euuid =
get_opt( attributes,
"uuid" );
642 auto etransform =
get_opt( attributes,
"transform" );
644 if( !ec_eType || *ec_eType != wxS(
"outline3D" ) || !etitle )
647 wxString modelTitle = *etitle;
658 footprint->
Add( field );
671 if( ec_width && ec_height )
676 double rounding = 0.001;
677 fitXmm =
KiROUND( fitXmm / rounding ) * rounding;
678 fitYmm =
KiROUND( fitYmm / rounding ) * rounding;
684 field->
SetText( wxString::FromCDouble( fitXmm ) + wxS(
" " )
685 + wxString::FromCDouble( fitYmm ) );
686 footprint->
Add( field );
691 wxArrayString orParts = wxSplit( *ec_origin,
',',
'\0' );
693 if( orParts.size() == 2 )
696 pos.
x =
Convert( orParts[0].Trim() );
697 pos.
y =
Convert( orParts[1].Trim() );
715 wxArrayString rotParts = wxSplit( *ec_rotation,
',',
'\0' );
717 if( rotParts.size() == 3 )
719 kmodelRotation.
x = -
Convert( rotParts[0].Trim() );
720 kmodelRotation.
y = -
Convert( rotParts[1].Trim() );
721 kmodelRotation.
z = -
Convert( rotParts[2].Trim() )
728 kmodelRotation.
z = 180 - kmodelRotation.
z;
734 +
EscapeString( modelTitle, ESCAPE_CONTEXT::CTX_FILENAME )
738 footprint->
Models().push_back( model );
742 if(
auto dataStr =
get_opt( attributes,
"d" ) )
752 std::unique_ptr<PCB_GROUP>
group;
755 group = std::make_unique<PCB_GROUP>( aContainer );
759 auto shape = std::make_unique<PCB_SHAPE>( aContainer, SHAPE_T::POLY );
761 shape->SetFilled(
true );
762 shape->SetPolyShape( poly );
763 shape->SetLayer( klayer );
764 shape->SetWidth( 0 );
767 group->AddItem( shape.get() );
769 aContainer->
Add( shape.release(), ADD_MODE::APPEND );
773 aContainer->
Add(
group.release(), ADD_MODE::APPEND );
779 THROW_IO_ERROR( wxString::Format(
_(
"Unknown SVGNODE nodeType %d" ), nodeType ) );
782 else if( elType == wxS(
"TEXT" ) )
785 wxString textType = arr[1];
787 if( footprint && textType == wxS(
"P" ) )
791 else if( footprint && textType == wxS(
"N" ) )
795 else if( arr[12] == wxS(
"none" ) )
803 aContainer->
Add(
text, ADD_MODE::APPEND );
809 text->SetPosition( start );
812 text->SetTextThickness( thickness );
814 double rot =
Convert( arr[5] );
815 text->SetTextAngleDegrees( rot );
821 text->SetLayer( layer );
824 text->SetMirrored(
true );
829 wxString textStr = arr[10];
830 textStr.Replace( wxS(
"\\n" ), wxS(
"\n" ) );
835 wxString font = arr[14];
836 if( !font.IsEmpty() )
841 else if( elType == wxS(
"VIA" ) )
849 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( footprint );
853 pad->SetAttribute( PAD_ATTRIB::PTH );
856 pad->SetDrillShape( PAD_DRILL_SHAPE::CIRCLE );
859 footprint->
Add(
pad.release(), ADD_MODE::APPEND );
863 std::unique_ptr<PCB_VIA>
via = std::make_unique<PCB_VIA>( aContainer );
868 via->SetNet( getOrAddNetItem( arr[4] ) );
869 via->SetDrill( kdrill );
871 aContainer->
Add(
via.release(), ADD_MODE::APPEND );
874 else if( elType == wxS(
"HOLE" ) )
880 wxString holeUuid = arr[4];
884 padContainer = footprint;
888 std::unique_ptr<FOOTPRINT> newFootprint =
889 std::make_unique<FOOTPRINT>(
dynamic_cast<BOARD*
>( aContainer ) );
891 wxString
name = wxS(
"Hole_" ) + holeUuid;
893 newFootprint->SetFPID(
LIB_ID( wxEmptyString,
name ) );
894 newFootprint->SetPosition(
center );
895 newFootprint->SetLocked(
true );
897 newFootprint->Reference().SetText(
name );
898 newFootprint->Reference().SetVisible(
false );
900 newFootprint->Value().SetText(
name );
901 newFootprint->Value().SetVisible(
false );
904 padContainer = newFootprint.get();
905 aContainer->
Add( newFootprint.release(), ADD_MODE::APPEND );
908 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( padContainer );
912 pad->SetAttribute( PAD_ATTRIB::NPTH );
915 pad->SetDrillShape( PAD_DRILL_SHAPE::CIRCLE );
918 padContainer->
Add(
pad.release(), ADD_MODE::APPEND );
920 else if( elType == wxS(
"PAD" ) )
926 wxString padUuid = arr[12];
930 padContainer = footprint;
934 std::unique_ptr<FOOTPRINT> newFootprint =
935 std::make_unique<FOOTPRINT>(
dynamic_cast<BOARD*
>( aContainer ) );
937 wxString
name = wxS(
"Pad_" ) + padUuid;
939 newFootprint->SetFPID(
LIB_ID( wxEmptyString,
name ) );
940 newFootprint->SetPosition(
center );
941 newFootprint->SetLocked(
true );
943 newFootprint->Reference().SetText(
name );
944 newFootprint->Reference().SetVisible(
false );
946 newFootprint->Value().SetText(
name );
947 newFootprint->Value().SetVisible(
false );
950 padContainer = newFootprint.get();
951 aContainer->
Add( newFootprint.release(), ADD_MODE::APPEND );
954 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( padContainer );
956 pad->SetNet( getOrAddNetItem( arr[7] ) );
957 pad->SetNumber( arr[8] );
960 pad->SetOrientationDegrees(
Convert( arr[11] ) );
963 wxString elayer = arr[6];
966 bool plated = arr[15] == wxS(
"Y" );
972 pad->SetAttribute( PAD_ATTRIB::SMD );
974 else if( klayer ==
B_Cu )
978 pad->SetAttribute( PAD_ATTRIB::SMD );
980 else if( elayer == wxS(
"11" ) )
983 pad->SetAttribute( plated ? PAD_ATTRIB::PTH : PAD_ATTRIB::NPTH );
987 pad->SetLayer( klayer );
988 pad->SetLayerSet(
LSET( { klayer } ) );
989 pad->SetAttribute( PAD_ATTRIB::SMD );
992 wxString padType = arr[1];
993 if( padType == wxS(
"ELLIPSE" ) )
997 else if( padType == wxS(
"RECT" ) )
1001 else if( padType == wxS(
"OVAL" ) )
1003 if(
pad->GetSizeX() ==
pad->GetSizeY() )
1008 else if( padType == wxS(
"POLYGON" ) )
1014 wxArrayString data = wxSplit( arr[10],
' ',
'\0' );
1017 for(
int i = 1; i < data.size(); i += 2 )
1031 wxString holeDia = arr[9];
1032 if( !holeDia.IsEmpty() )
1037 wxString holeLength = arr[13];
1038 if( !holeLength.IsEmpty() )
1043 pad->SetDrillShape( PAD_DRILL_SHAPE::OBLONG );
1045 if( size.
x < size.
y )
1052 pad->SetDrillShape( PAD_DRILL_SHAPE::CIRCLE );
1057 wxString pasteExp = arr[17];
1058 if( !pasteExp.IsEmpty() )
1061 pad->SetLocalSolderPasteMargin( pasteExpansion );
1064 wxString maskExp = arr[18];
1065 if( !maskExp.IsEmpty() )
1068 pad->SetLocalSolderMaskMargin( maskExpansion );
1071 padContainer->
Add(
pad.release(), ADD_MODE::APPEND );
1079 std::map<wxString, wxString> aParams,
1080 std::map<wxString, std::unique_ptr<FOOTPRINT>>& aFootprintMap, wxArrayString aShapes )
1082 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>( aParent );
1086 footprint->SetLayer(
B_Cu );
1087 footprint->SetOrientation( aOrientation -
ANGLE_180 );
1091 footprint->SetLayer(
F_Cu );
1092 footprint->SetOrientation( aOrientation );
1095 footprint->Value().SetText( aParams[wxS(
"package" )] );
1102 std::vector<PCB_SHAPE*> shapes;
1103 std::vector<std::unique_ptr<PCB_SHAPE>> newShapes;
1105 for(
BOARD_ITEM* item : footprint->GraphicalItems() )
1111 shapes.push_back(
static_cast<PCB_SHAPE*
>( item ) );
1116 for( std::unique_ptr<PCB_SHAPE>& ptr : newShapes )
1117 footprint->Add( ptr.release(), ADD_MODE::APPEND );
1119 return footprint.release();
1124 std::map<wxString, std::unique_ptr<FOOTPRINT>>& aFootprintMap,
1125 wxArrayString aShapes )
1132 std::vector<PCB_SHAPE*> shapes;
1133 std::vector<std::unique_ptr<PCB_SHAPE>> newShapes;
1141 shapes.push_back(
static_cast<PCB_SHAPE*
>( item ) );
1146 for( std::unique_ptr<PCB_SHAPE>& ptr : newShapes )
1147 aBoard->
Add( ptr.release(), ADD_MODE::APPEND );
constexpr EDA_IU_SCALE pcbIUScale
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Abstract interface for BOARD_ITEMs capable of storing other items inside.
virtual void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false)=0
Adds an item to the container.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Information pertinent to a Pcbnew printed circuit board.
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
unsigned GetNetCount() const
const DRAWINGS & Drawings() const
double ConvertSize(const wxString &aValue)
std::vector< SHAPE_LINE_CHAIN > ParseLineChains(const wxString &aData, int aArcMinSegLen, bool aForceClosed)
static double Convert(const wxString &aValue)
double RelPosX(double aValue)
double RelPosY(double aValue)
VECTOR2< T > RelPos(const VECTOR2< T > &aVec)
void TransformTextToBaseline(EDA_TEXT *textItem, const wxString &baselineAlign)
virtual void SetVisible(bool aVisible)
virtual void SetText(const wxString &aText)
VECTOR3D m_Offset
3D model offset (mm)
VECTOR3D m_Rotation
3D model rotation (degrees)
wxString m_Filename
The 3D shape filename in 3D library.
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false, const std::vector< wxString > *aEmbeddedFiles=nullptr, bool aForDrawingSheet=false)
A logical library item identifier and consists of various portions much like a URI.
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
LSET is a set of PCB_LAYER_IDs.
Handle the data for a net.
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
static LSET PTHMask()
layer set for a through hole pad
static LSET UnplatedHoleMask()
layer set for a mechanical unplated through hole pad
static LSET SMDMask()
layer set for a SMD pad on Front layer
PCB_IO_EASYEDA_PARSER(PROGRESS_REPORTER *aProgressReporter)
void ParseToBoardItemContainer(BOARD_ITEM_CONTAINER *aContainer, BOARD *aParent, std::map< wxString, wxString > paramMap, std::map< wxString, std::unique_ptr< FOOTPRINT > > &aFootprintMap, wxArrayString shapes)
FOOTPRINT * ParseFootprint(const VECTOR2D &aOrigin, const EDA_ANGLE &aOrientation, int aLayer, BOARD *aParent, std::map< wxString, wxString > aParams, std::map< wxString, std::unique_ptr< FOOTPRINT > > &aFootprintMap, wxArrayString aShapes)
double ScaleSize(double aValue) override
void ParseBoard(BOARD *aBoard, const VECTOR2D &aOrigin, std::map< wxString, std::unique_ptr< FOOTPRINT > > &aFootprintMap, wxArrayString aShapes)
PCB_LAYER_ID LayerToKi(const wxString &aLayer)
A progress reporter interface for use in multi-threaded environments.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void Move(const VECTOR2I &aVector) override
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
void Rotate(const EDA_ANGLE &aAngle, const VECTOR2I &aCenter={ 0, 0 }) override
Rotate all vertices by a given angle.
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 Fracture()
Convert a set of polygons with holes to a single outline with "slits"/"fractures" connecting the oute...
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
std::vector< SHAPE_LINE_CHAIN > POLYGON
represents a single polygon outline with holes.
int AddHole(const SHAPE_LINE_CHAIN &aHole, int aOutline=-1)
Adds a new hole to the given outline (default: last) and returns its index.
void RebuildHolesFromContours()
Extract all contours from this polygon set, then recreate polygons with holes.
int OutlineCount() const
Return the number of outlines in the set.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
const std::vector< POLYGON > & CPolygons() const
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_180
void ConnectBoardShapes(std::vector< PCB_SHAPE * > &aShapeList, std::vector< std::unique_ptr< PCB_SHAPE > > &aNewShapes, int aChainingEpsilon)
Connects shapes to each other, making continious contours (adjacent shapes will have a common vertex)...
#define THROW_IO_ERROR(msg)
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a back layer.
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
PCB_LAYER_ID
A quick note on layer IDs:
std::optional< V > get_opt(const std::map< wxString, V > &aMap, const wxString &aKey)
Class to handle a set of BOARD_ITEMs.
static const wxString MODEL_SIZE_KEY
static const wxString DIRECT_MODEL_UUID_KEY
static const int SHAPE_JOIN_DISTANCE
static const VECTOR2I HIDDEN_TEXT_SIZE(pcbIUScale.mmToIU(0.5), pcbIUScale.mmToIU(0.5))
static LIB_ID EasyEdaToKiCadLibID(const wxString &aLibName, const wxString &aLibReference)
static LIB_ID EasyEdaToKiCadLibID(const wxString &aLibName, const wxString &aLibReference)
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
wxString UnescapeHTML(const wxString &aString)
Return a new wxString unescaped from HTML format.
constexpr double IUTomm(int iu) const
constexpr int mmToIU(double mm) const
const SHAPE_LINE_CHAIN chain
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D