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 std::unique_ptr<PCB_SHAPE> shape =
290 std::make_unique<PCB_SHAPE>( aContainer, SHAPE_T::CIRCLE );
293 shape->SetWidth( width );
296 shape->SetLayer( layer );
304 shape->SetCenter( center );
305 shape->SetEnd( center +
VECTOR2I( radius, 0 ) );
308 shape->SetNet( getOrAddNetItem( arr[8] ) );
310 aContainer->
Add( shape.release(), ADD_MODE::APPEND );
312 else if( elType == wxS(
"RECT" ) )
314 std::unique_ptr<PCB_SHAPE> shape =
315 std::make_unique<PCB_SHAPE>( aContainer, SHAPE_T::RECTANGLE );
318 shape->SetWidth( width );
321 shape->SetLayer( layer );
323 bool filled = arr[9] != wxS(
"none" );
324 shape->SetFilled( filled );
334 shape->SetStart( start );
335 shape->SetEnd( start + size );
338 shape->SetNet( getOrAddNetItem( arr[11] ) );
340 aContainer->
Add( shape.release(), ADD_MODE::APPEND );
342 else if( elType == wxS(
"ARC" ) )
344 std::unique_ptr<PCB_SHAPE> shape =
345 std::make_unique<PCB_SHAPE>( aContainer, SHAPE_T::ARC );
348 shape->SetWidth( width );
351 shape->SetLayer( layer );
354 shape->SetNet( getOrAddNetItem( arr[3] ) );
362 wxString data = arr[4];
363 auto readNumber = [&]( wxString& aOut )
365 wxUniChar ch = data[pos];
367 while( ch ==
' ' || ch ==
',' )
370 while( isdigit( ch ) || ch ==
'.' || ch ==
'-' )
375 if( pos == data.size() )
384 wxUniChar sym = data[pos++];
394 else if( sym ==
'A' )
396 wxString radX, radY,
unknown, farFlag, cwFlag, endX, endY;
400 readNumber( farFlag );
401 readNumber( cwFlag );
405 isFar = farFlag == wxS(
"1" );
406 cw = cwFlag == wxS(
"1" );
410 }
while( pos < data.size() );
414 double d =
delta.EuclideanNorm();
415 double h = sqrt( std::max( 0.0, rad.
x * rad.
x - d * d / 4 ) );
422 start +
delta / 2 +
delta.Perpendicular().Resize( ( isFar ^ cw ) ? h : -h );
425 std::swap( start, end );
427 shape->SetStart(
RelPos( start ) );
428 shape->SetEnd(
RelPos( end ) );
429 shape->SetCenter(
RelPos( arcCenter ) );
431 aContainer->
Add( shape.release(), ADD_MODE::APPEND );
433 else if( elType == wxS(
"SOLIDREGION" ) )
435 wxString layer = arr[1];
439 if( layer == wxS(
"11" ) )
443 std::unique_ptr<PCB_SHAPE> shape =
444 std::make_unique<PCB_SHAPE>( aContainer, SHAPE_T::POLY );
447 shape->SetFilled(
false );
449 shape->SetPolyShape( poly );
451 aContainer->
Add( shape.release(), ADD_MODE::APPEND );
456 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aContainer );
459 zone->SetLayer( klayer );
462 zone->SetNet( getOrAddNetItem( arr[2] ) );
465 zone->Outline()->AddPolygon( poly );
467 if( arr[4].Lower() == wxS(
"cutout" ) )
469 zone->SetIsRuleArea(
true );
470 zone->SetDoNotAllowCopperPour(
true );
471 zone->SetDoNotAllowTracks(
false );
472 zone->SetDoNotAllowVias(
false );
473 zone->SetDoNotAllowPads(
false );
474 zone->SetDoNotAllowFootprints(
false );
478 zone->SetFilledPolysList( klayer, polySet );
479 zone->SetPadConnection( ZONE_CONNECTION::FULL );
480 zone->SetIsFilled(
true );
481 zone->SetNeedRefill(
false );
484 zone->SetMinThickness( 0 );
485 zone->SetLocalClearance( 0 );
486 zone->SetAssignedPriority( 100 );
488 aContainer->
Add( zone.release(), ADD_MODE::APPEND );
491 else if( elType == wxS(
"COPPERAREA" ) )
493 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aContainer );
496 zone->SetLayer( layer );
498 wxString netname = arr[3];
500 zone->SetNet( getOrAddNetItem( netname ) );
503 zone->SetThermalReliefGap( zone->GetLocalClearance() );
505 wxString fillStyle = arr[5];
506 if( fillStyle == wxS(
"none" ) )
514 zone->Outline()->AddPolygon( poly );
516 wxString thermal = arr[8];
517 if( thermal == wxS(
"direct" ) )
518 zone->SetPadConnection( ZONE_CONNECTION::FULL );
520 wxString keepIsland = arr[9];
521 if( keepIsland == wxS(
"yes" ) )
522 zone->SetIslandRemovalMode( ISLAND_REMOVAL_MODE::NEVER );
524 wxString fillData = arr[10];
528 for(
const nlohmann::json& polyData : nlohmann::json::parse( fillData ) )
530 for(
const nlohmann::json& contourData : polyData )
537 for(
int i = 1; i < contourPolySet.
OutlineCount(); i++ )
540 fillPolySet.
Append( currentOutline );
546 zone->SetFilledPolysList( layer, fillPolySet );
547 zone->SetIsFilled(
true );
548 zone->SetNeedRefill(
false );
550 catch( nlohmann::json::exception& e )
554 int fillOrder = wxAtoi( arr[13] );
555 zone->SetAssignedPriority( 100 - fillOrder );
557 wxString improveFabrication = arr[17];
558 if( improveFabrication == wxS(
"none" ) )
560 zone->SetMinThickness( 0 );
567 zone->SetMinThickness( minThickness );
570 if( arr.size() > 18 )
572 zone->SetThermalReliefSpokeWidth(
573 std::max(
int(
ConvertSize( arr[18] ) ), zone->GetMinThickness() ) );
577 wxFAIL_MSG( wxString::Format(
"COPPERAREA unexpected size %d: %s ", arr.size(),
580 zone->SetThermalReliefSpokeWidth( zone->GetMinThickness() );
583 aContainer->
Add( zone.release(), ADD_MODE::APPEND );
585 else if( elType == wxS(
"SVGNODE" ) )
587 nlohmann::json nodeData = nlohmann::json::parse( arr[1] );
589 int nodeType = nodeData.at(
"nodeType" );
590 wxString layer = nodeData.at(
"layerid" );
595 std::map<wxString, wxString> attributes = nodeData.at(
"attrs" );
597 if( layer == wxS(
"19" ) )
602 auto ec_eType =
get_opt( attributes,
"c_etype" );
603 auto ec_rotation =
get_opt( attributes,
"c_rotation" );
604 auto ec_origin =
get_opt( attributes,
"c_origin" );
605 auto ec_width =
get_opt( attributes,
"c_width" );
606 auto ec_height =
get_opt( attributes,
"c_height" );
607 auto ez =
get_opt( attributes,
"z" );
608 auto etitle =
get_opt( attributes,
"title" );
609 auto euuid =
get_opt( attributes,
"uuid" );
610 auto etransform =
get_opt( attributes,
"transform" );
612 if( !ec_eType || *ec_eType != wxS(
"outline3D" ) || !etitle )
615 wxString modelTitle = *etitle;
638 if( ec_width && ec_height )
643 double rounding = 0.001;
644 fitXmm =
KiROUND( fitXmm / rounding ) * rounding;
645 fitYmm =
KiROUND( fitYmm / rounding ) * rounding;
650 field.
SetText( wxString::FromCDouble( fitXmm ) + wxS(
" " )
651 + wxString::FromCDouble( fitYmm ) );
657 wxArrayString orParts = wxSplit( *ec_origin,
',',
'\0' );
659 if( orParts.size() == 2 )
662 pos.
x =
Convert( orParts[0].Trim() );
663 pos.
y =
Convert( orParts[1].Trim() );
681 wxArrayString rotParts = wxSplit( *ec_rotation,
',',
'\0' );
683 if( rotParts.size() == 3 )
685 kmodelRotation.
x = -
Convert( rotParts[0].Trim() );
686 kmodelRotation.
y = -
Convert( rotParts[1].Trim() );
687 kmodelRotation.
z = -
Convert( rotParts[2].Trim() )
694 kmodelRotation.
z = 180 - kmodelRotation.
z;
700 +
EscapeString( modelTitle, ESCAPE_CONTEXT::CTX_FILENAME )
704 footprint->
Models().push_back( model );
708 if(
auto dataStr =
get_opt( attributes,
"d" ) )
717 std::unique_ptr<PCB_GROUP>
group;
720 group = std::make_unique<PCB_GROUP>( aContainer );
724 std::unique_ptr<PCB_SHAPE> shape =
725 std::make_unique<PCB_SHAPE>( aContainer, SHAPE_T::POLY );
727 shape->SetFilled(
true );
728 shape->SetPolyShape( poly );
729 shape->SetLayer( klayer );
730 shape->SetWidth( 0 );
733 group->AddItem( shape.get() );
735 aContainer->
Add( shape.release(), ADD_MODE::APPEND );
739 aContainer->
Add(
group.release(), ADD_MODE::APPEND );
745 THROW_IO_ERROR( wxString::Format(
_(
"Unknown SVGNODE nodeType %d" ), nodeType ) );
748 else if( elType == wxS(
"TEXT" ) )
751 wxString textType = arr[1];
754 if( textType == wxS(
"P" ) )
758 else if( textType == wxS(
"N" ) )
771 text->SetPosition( start );
774 text->SetTextThickness( thickness );
776 double rot =
Convert( arr[5] );
777 text->SetTextAngleDegrees( rot );
783 text->SetLayer( layer );
786 text->SetMirrored(
true );
795 text->SetVisible( arr[12] != wxS(
"none" ) );
797 wxString font = arr[14];
798 if( !font.IsEmpty() )
802 aContainer->
Add(
text, ADD_MODE::APPEND );
804 else if( elType == wxS(
"VIA" ) )
812 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( footprint );
814 pad->SetPosition( center );
816 pad->SetAttribute( PAD_ATTRIB::PTH );
817 pad->SetShape( PAD_SHAPE::CIRCLE );
822 footprint->
Add(
pad.release(), ADD_MODE::APPEND );
826 std::unique_ptr<PCB_VIA>
via = std::make_unique<PCB_VIA>( aContainer );
828 via->SetPosition( center );
830 via->SetWidth( kdia );
831 via->SetNet( getOrAddNetItem( arr[4] ) );
832 via->SetDrill( kdrill );
834 aContainer->
Add(
via.release(), ADD_MODE::APPEND );
837 else if( elType == wxS(
"HOLE" ) )
843 wxString holeUuid = arr[4];
847 padContainer = footprint;
851 std::unique_ptr<FOOTPRINT> newFootprint =
852 std::make_unique<FOOTPRINT>(
dynamic_cast<BOARD*
>( aContainer ) );
854 wxString
name = wxS(
"Hole_" ) + holeUuid;
856 newFootprint->SetFPID(
LIB_ID( wxEmptyString,
name ) );
857 newFootprint->SetPosition( center );
858 newFootprint->SetLocked(
true );
860 newFootprint->Reference().SetText(
name );
861 newFootprint->Reference().SetVisible(
false );
863 newFootprint->Value().SetText(
name );
864 newFootprint->Value().SetVisible(
false );
867 padContainer = newFootprint.get();
868 aContainer->
Add( newFootprint.release(), ADD_MODE::APPEND );
871 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( padContainer );
873 pad->SetPosition( center );
875 pad->SetAttribute( PAD_ATTRIB::NPTH );
876 pad->SetShape( PAD_SHAPE::CIRCLE );
881 padContainer->
Add(
pad.release(), ADD_MODE::APPEND );
883 else if( elType == wxS(
"PAD" ) )
889 wxString padUuid = arr[12];
893 padContainer = footprint;
897 std::unique_ptr<FOOTPRINT> newFootprint =
898 std::make_unique<FOOTPRINT>(
dynamic_cast<BOARD*
>( aContainer ) );
900 wxString
name = wxS(
"Pad_" ) + padUuid;
902 newFootprint->SetFPID(
LIB_ID( wxEmptyString,
name ) );
903 newFootprint->SetPosition( center );
904 newFootprint->SetLocked(
true );
906 newFootprint->Reference().SetText(
name );
907 newFootprint->Reference().SetVisible(
false );
909 newFootprint->Value().SetText(
name );
910 newFootprint->Value().SetVisible(
false );
913 padContainer = newFootprint.get();
914 aContainer->
Add( newFootprint.release(), ADD_MODE::APPEND );
917 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( padContainer );
919 pad->SetNet( getOrAddNetItem( arr[7] ) );
920 pad->SetNumber( arr[8] );
921 pad->SetPosition( center );
922 pad->SetSize( size );
923 pad->SetOrientationDegrees(
Convert( arr[11] ) );
926 wxString elayer = arr[6];
929 bool plated = arr[15] == wxS(
"Y" );
935 pad->SetAttribute( PAD_ATTRIB::SMD );
937 else if( klayer ==
B_Cu )
941 pad->SetAttribute( PAD_ATTRIB::SMD );
943 else if( elayer == wxS(
"11" ) )
946 pad->SetAttribute( plated ? PAD_ATTRIB::PTH : PAD_ATTRIB::NPTH );
950 pad->SetLayer( klayer );
951 pad->SetLayerSet(
LSET( 1, klayer ) );
952 pad->SetAttribute( PAD_ATTRIB::SMD );
955 wxString padType = arr[1];
956 if( padType == wxS(
"ELLIPSE" ) )
958 pad->SetShape( PAD_SHAPE::OVAL );
960 else if( padType == wxS(
"RECT" ) )
962 pad->SetShape( PAD_SHAPE::RECTANGLE );
964 else if( padType == wxS(
"OVAL" ) )
966 if(
pad->GetSizeX() ==
pad->GetSizeY() )
967 pad->SetShape( PAD_SHAPE::CIRCLE );
969 pad->SetShape( PAD_SHAPE::OVAL );
971 else if( padType == wxS(
"POLYGON" ) )
973 pad->SetShape( PAD_SHAPE::CUSTOM );
974 pad->SetAnchorPadShape( PAD_SHAPE::CIRCLE );
975 pad->SetSize( { 1, 1 } );
977 wxArrayString data = wxSplit( arr[10],
' ',
'\0' );
980 for(
int i = 1; i < data.size(); i += 2 )
989 chain.
Move( -center );
991 pad->AddPrimitivePoly( chain, 0,
true );
994 wxString holeDia = arr[9];
995 if( !holeDia.IsEmpty() )
1000 wxString holeLength = arr[13];
1001 if( !holeLength.IsEmpty() )
1008 if( size.
x < size.
y )
1020 wxString pasteExp = arr[17];
1021 if( !pasteExp.IsEmpty() )
1024 pad->SetLocalSolderPasteMargin( pasteExpansion );
1027 wxString maskExp = arr[18];
1028 if( !maskExp.IsEmpty() )
1031 pad->SetLocalSolderMaskMargin( maskExpansion );
1034 padContainer->
Add(
pad.release(), ADD_MODE::APPEND );
1042 std::map<wxString, wxString> aParams,
1043 std::map<wxString, std::unique_ptr<FOOTPRINT>>& aFootprintMap, wxArrayString aShapes )
1045 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>( aParent );
1049 footprint->SetLayer(
B_Cu );
1050 footprint->SetOrientation( aOrientation -
ANGLE_180 );
1054 footprint->SetLayer(
F_Cu );
1055 footprint->SetOrientation( aOrientation );
1058 footprint->Value().SetText( aParams[wxS(
"package" )] );
1065 std::vector<PCB_SHAPE*> shapes;
1066 std::vector<std::unique_ptr<PCB_SHAPE>> newShapes;
1068 for(
BOARD_ITEM* item : footprint->GraphicalItems() )
1074 shapes.push_back(
static_cast<PCB_SHAPE*
>( item ) );
1079 for( std::unique_ptr<PCB_SHAPE>& ptr : newShapes )
1080 footprint->Add( ptr.release(), ADD_MODE::APPEND );
1082 return footprint.release();
1087 std::map<wxString, std::unique_ptr<FOOTPRINT>>& aFootprintMap,
1088 wxArrayString aShapes )
1095 std::vector<PCB_SHAPE*> shapes;
1096 std::vector<std::unique_ptr<PCB_SHAPE>> newShapes;
1104 shapes.push_back(
static_cast<PCB_SHAPE*
>( item ) );
1109 for( std::unique_ptr<PCB_SHAPE>& ptr : newShapes )
1110 aBoard->
Add( ptr.release(), ADD_MODE::APPEND );
constexpr EDA_IU_SCALE pcbIUScale
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
double ConvertSize(const wxString &aValue)
std::vector< SHAPE_LINE_CHAIN > ParseLineChains(const wxString &aData, int aArcMinSegLen)
static double Convert(const wxString &aValue)
double RelPosX(double aValue)
double RelPosY(double aValue)
VECTOR2< T > RelPos(const VECTOR2< T > &aVec)
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)
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 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
void ParseBoard(BOARD *aBoard, const VECTOR2D &aOrigin, std::map< wxString, std::unique_ptr< FOOTPRINT > > &aFootprintMap, wxArrayString aShapes)
void ParseToBoardItemContainer(BOARD_ITEM_CONTAINER *aContainer, BOARD *aParent, std::map< wxString, wxString > paramMap, std::map< wxString, std::unique_ptr< FOOTPRINT > > &aFootprintMap, wxArrayString shapes)
PCB_EASYEDA_PARSER(PROGRESS_REPORTER *aProgressReporter)
PCB_LAYER_ID LayerToKi(const wxString &aLayer)
double ScaleSize(double aValue) override
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)
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_180
static constexpr EDA_ANGLE & ANGLE_0
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:
LSET FlipLayerMask(LSET aMask, int aCopperLayersCount)
Calculate the mask layer when flipping a footprint.
std::optional< V > get_opt(const std::map< wxString, V > &aMap, const wxString &aKey)
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)
Class to handle a set of BOARD_ITEMs.
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
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
VECTOR2< double > VECTOR2D