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 );
303 shape->SetEnd( center +
VECTOR2I( radius, 0 ) );
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 ) );
424 shape->SetEnd(
RelPos( end ) );
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" ) );
444 for(
int segId = 0; segId < chain.SegmentCount(); segId++ )
446 SEG seg = chain.CSegment( segId );
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;
670 if( ec_width && ec_height )
675 double rounding = 0.001;
676 fitXmm =
KiROUND( fitXmm / rounding ) * rounding;
677 fitYmm =
KiROUND( fitYmm / rounding ) * rounding;
682 field.
SetText( wxString::FromCDouble( fitXmm ) + wxS(
" " )
683 + wxString::FromCDouble( fitYmm ) );
689 wxArrayString orParts = wxSplit( *ec_origin,
',',
'\0' );
691 if( orParts.size() == 2 )
694 pos.
x =
Convert( orParts[0].Trim() );
695 pos.
y =
Convert( orParts[1].Trim() );
713 wxArrayString rotParts = wxSplit( *ec_rotation,
',',
'\0' );
715 if( rotParts.size() == 3 )
717 kmodelRotation.
x = -
Convert( rotParts[0].Trim() );
718 kmodelRotation.
y = -
Convert( rotParts[1].Trim() );
719 kmodelRotation.
z = -
Convert( rotParts[2].Trim() )
726 kmodelRotation.
z = 180 - kmodelRotation.
z;
732 +
EscapeString( modelTitle, ESCAPE_CONTEXT::CTX_FILENAME )
736 footprint->
Models().push_back( model );
740 if(
auto dataStr =
get_opt( attributes,
"d" ) )
750 std::unique_ptr<PCB_GROUP>
group;
753 group = std::make_unique<PCB_GROUP>( aContainer );
757 auto shape = std::make_unique<PCB_SHAPE>( aContainer, SHAPE_T::POLY );
759 shape->SetFilled(
true );
760 shape->SetPolyShape( poly );
761 shape->SetLayer( klayer );
762 shape->SetWidth( 0 );
765 group->AddItem( shape.get() );
767 aContainer->
Add( shape.release(), ADD_MODE::APPEND );
771 aContainer->
Add(
group.release(), ADD_MODE::APPEND );
777 THROW_IO_ERROR( wxString::Format(
_(
"Unknown SVGNODE nodeType %d" ), nodeType ) );
780 else if( elType == wxS(
"TEXT" ) )
783 wxString textType = arr[1];
786 if( footprint && textType == wxS(
"P" ) )
790 else if( footprint && textType == wxS(
"N" ) )
803 text->SetPosition( start );
806 text->SetTextThickness( thickness );
808 double rot =
Convert( arr[5] );
809 text->SetTextAngleDegrees( rot );
815 text->SetLayer( layer );
818 text->SetMirrored(
true );
823 wxString textStr = arr[10];
824 textStr.Replace( wxS(
"\\n" ), wxS(
"\n" ) );
829 text->SetVisible( arr[12] != wxS(
"none" ) );
831 wxString font = arr[14];
832 if( !font.IsEmpty() )
838 aContainer->
Add(
text, ADD_MODE::APPEND );
840 else if( elType == wxS(
"VIA" ) )
848 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( footprint );
850 pad->SetPosition( center );
852 pad->SetAttribute( PAD_ATTRIB::PTH );
855 pad->SetDrillShape( PAD_DRILL_SHAPE::CIRCLE );
858 footprint->
Add(
pad.release(), ADD_MODE::APPEND );
862 std::unique_ptr<PCB_VIA>
via = std::make_unique<PCB_VIA>( aContainer );
864 via->SetPosition( center );
867 via->SetNet( getOrAddNetItem( arr[4] ) );
868 via->SetDrill( kdrill );
870 aContainer->
Add(
via.release(), ADD_MODE::APPEND );
873 else if( elType == wxS(
"HOLE" ) )
879 wxString holeUuid = arr[4];
883 padContainer = footprint;
887 std::unique_ptr<FOOTPRINT> newFootprint =
888 std::make_unique<FOOTPRINT>(
dynamic_cast<BOARD*
>( aContainer ) );
890 wxString
name = wxS(
"Hole_" ) + holeUuid;
892 newFootprint->SetFPID(
LIB_ID( wxEmptyString,
name ) );
893 newFootprint->SetPosition( center );
894 newFootprint->SetLocked(
true );
896 newFootprint->Reference().SetText(
name );
897 newFootprint->Reference().SetVisible(
false );
899 newFootprint->Value().SetText(
name );
900 newFootprint->Value().SetVisible(
false );
903 padContainer = newFootprint.get();
904 aContainer->
Add( newFootprint.release(), ADD_MODE::APPEND );
907 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( padContainer );
909 pad->SetPosition( center );
911 pad->SetAttribute( PAD_ATTRIB::NPTH );
914 pad->SetDrillShape( PAD_DRILL_SHAPE::CIRCLE );
917 padContainer->
Add(
pad.release(), ADD_MODE::APPEND );
919 else if( elType == wxS(
"PAD" ) )
925 wxString padUuid = arr[12];
929 padContainer = footprint;
933 std::unique_ptr<FOOTPRINT> newFootprint =
934 std::make_unique<FOOTPRINT>(
dynamic_cast<BOARD*
>( aContainer ) );
936 wxString
name = wxS(
"Pad_" ) + padUuid;
938 newFootprint->SetFPID(
LIB_ID( wxEmptyString,
name ) );
939 newFootprint->SetPosition( center );
940 newFootprint->SetLocked(
true );
942 newFootprint->Reference().SetText(
name );
943 newFootprint->Reference().SetVisible(
false );
945 newFootprint->Value().SetText(
name );
946 newFootprint->Value().SetVisible(
false );
949 padContainer = newFootprint.get();
950 aContainer->
Add( newFootprint.release(), ADD_MODE::APPEND );
953 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( padContainer );
955 pad->SetNet( getOrAddNetItem( arr[7] ) );
956 pad->SetNumber( arr[8] );
957 pad->SetPosition( center );
959 pad->SetOrientationDegrees(
Convert( arr[11] ) );
962 wxString elayer = arr[6];
965 bool plated = arr[15] == wxS(
"Y" );
971 pad->SetAttribute( PAD_ATTRIB::SMD );
973 else if( klayer ==
B_Cu )
977 pad->SetAttribute( PAD_ATTRIB::SMD );
979 else if( elayer == wxS(
"11" ) )
982 pad->SetAttribute( plated ? PAD_ATTRIB::PTH : PAD_ATTRIB::NPTH );
986 pad->SetLayer( klayer );
987 pad->SetLayerSet(
LSET( { klayer } ) );
988 pad->SetAttribute( PAD_ATTRIB::SMD );
991 wxString padType = arr[1];
992 if( padType == wxS(
"ELLIPSE" ) )
996 else if( padType == wxS(
"RECT" ) )
1000 else if( padType == wxS(
"OVAL" ) )
1002 if(
pad->GetSizeX() ==
pad->GetSizeY() )
1007 else if( padType == wxS(
"POLYGON" ) )
1013 wxArrayString data = wxSplit( arr[10],
' ',
'\0' );
1016 for(
int i = 1; i < data.size(); i += 2 )
1025 chain.
Move( -center );
1030 wxString holeDia = arr[9];
1031 if( !holeDia.IsEmpty() )
1036 wxString holeLength = arr[13];
1037 if( !holeLength.IsEmpty() )
1042 pad->SetDrillShape( PAD_DRILL_SHAPE::OBLONG );
1044 if( size.
x < size.
y )
1051 pad->SetDrillShape( PAD_DRILL_SHAPE::CIRCLE );
1056 wxString pasteExp = arr[17];
1057 if( !pasteExp.IsEmpty() )
1060 pad->SetLocalSolderPasteMargin( pasteExpansion );
1063 wxString maskExp = arr[18];
1064 if( !maskExp.IsEmpty() )
1067 pad->SetLocalSolderMaskMargin( maskExpansion );
1070 padContainer->
Add(
pad.release(), ADD_MODE::APPEND );
1078 std::map<wxString, wxString> aParams,
1079 std::map<wxString, std::unique_ptr<FOOTPRINT>>& aFootprintMap, wxArrayString aShapes )
1081 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>( aParent );
1085 footprint->SetLayer(
B_Cu );
1086 footprint->SetOrientation( aOrientation -
ANGLE_180 );
1090 footprint->SetLayer(
F_Cu );
1091 footprint->SetOrientation( aOrientation );
1094 footprint->Value().SetText( aParams[wxS(
"package" )] );
1101 std::vector<PCB_SHAPE*> shapes;
1102 std::vector<std::unique_ptr<PCB_SHAPE>> newShapes;
1104 for(
BOARD_ITEM* item : footprint->GraphicalItems() )
1110 shapes.push_back(
static_cast<PCB_SHAPE*
>( item ) );
1115 for( std::unique_ptr<PCB_SHAPE>& ptr : newShapes )
1116 footprint->Add( ptr.release(), ADD_MODE::APPEND );
1118 return footprint.release();
1123 std::map<wxString, std::unique_ptr<FOOTPRINT>>& aFootprintMap,
1124 wxArrayString aShapes )
1131 std::vector<PCB_SHAPE*> shapes;
1132 std::vector<std::unique_ptr<PCB_SHAPE>> newShapes;
1140 shapes.push_back(
static_cast<PCB_SHAPE*
>( item ) );
1145 for( std::unique_ptr<PCB_SHAPE>& ptr : newShapes )
1146 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.
Represent a set of closed polygons.
void Fracture(POLYGON_MODE aFastMode)
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)
Tests 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
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
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