36#include <wx/mstream.h>
87 nlohmann::json holeObj = aRow.
inner.value(
"hole", nlohmann::json() );
88 nlohmann::json padDef = aRow.
inner.value(
"defaultPad", nlohmann::json() );
90 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
92 pad->SetNumber( padNumber );
94 pad->SetOrientationDegrees( orientation );
99 if( holeObj.is_object() )
101 wxString holeType =
V3GetString( holeObj,
"holeType", wxS(
"ROUND" ) );
103 if( holeType == wxS(
"RECT" ) )
104 holeType = wxS(
"SLOT" );
106 if( holeType != wxS(
"ROUND" ) && holeType != wxS(
"SLOT" ) )
107 holeType = wxS(
"ROUND" );
113 if( drill.
x > 0 || drill.
y > 0 )
122 std::swap( drill.
x, drill.
y );
124 if( holeType == wxS(
"SLOT" ) )
137 else if( klayer ==
B_Cu )
144 if( padDef.is_object() )
146 wxString padType =
V3GetString( padDef,
"padType", wxS(
"RECT" ) );
148 if( padType == wxS(
"RECT" ) )
154 double radiusRatio = std::clamp(
radius, 0.0, 100.0 ) / 100 / 2;
159 if( radiusRatio == 0 )
167 else if( padType == wxS(
"ELLIPSE" ) )
178 else if( padType == wxS(
"OVAL" ) )
188 else if( padType == wxS(
"POLY" ) || padType == wxS(
"POLYGON" ) )
194 nlohmann::json polyData = padDef.value(
"path", nlohmann::json() );
196 std::vector<std::unique_ptr<PCB_SHAPE>> results =
197 m_v2Parser.ParsePoly( aFootprint, polyData,
true,
false );
199 for(
auto& shape : results )
201 shape->SetLayer( klayer );
202 shape->SetWidth( 0 );
203 shape->Move( -
pad->GetPosition() );
237 wxString originStr =
V3GetString( aRow.
inner,
"origin", wxS(
"LEFT_BOTTOM" ) );
245 text->SetText(
string );
246 text->SetLayer( klayer );
248 text->SetIsKnockout( inverted );
253 if( font != wxS(
"default" ) )
260 text->SetMirrored(
true );
261 text->SetTextAngleDegrees( -angle );
265 text->SetTextAngleDegrees( angle );
275 std::unique_ptr<FOOTPRINT> footprintPtr = std::make_unique<FOOTPRINT>(
m_board );
276 FOOTPRINT* footprint = footprintPtr.get();
279 const int defaultTextThickness(
pcbIUScale.mmToIU( 0.15 ) );
283 field->SetTextSize( defaultTextSize );
284 field->SetTextThickness( defaultTextThickness );
289 if( row.
type == wxS(
"POLY" ) )
295 nlohmann::json polyData = row.
inner.value(
"path", nlohmann::json::array() );
297 std::vector<std::unique_ptr<PCB_SHAPE>> results =
298 m_v2Parser.ParsePoly( footprint, polyData,
false,
false );
300 for(
auto& shape : results )
302 shape->SetLayer( klayer );
307 else if( row.
type == wxS(
"PAD" ) )
312 else if( row.
type == wxS(
"FILL" ) )
317 nlohmann::json polyDataList = row.
inner.value(
"path", nlohmann::json::array() );
319 if( !polyDataList.is_null() && !polyDataList.empty() )
321 if( !polyDataList.at( 0 ).is_array() )
322 polyDataList = nlohmann::json::array( { polyDataList } );
324 std::vector<SHAPE_LINE_CHAIN> contours;
326 for( nlohmann::json& polyData : polyDataList )
330 contours.push_back( contour );
340 std::unique_ptr<PCB_GROUP>
group;
343 group = std::make_unique<PCB_GROUP>( footprint );
347 std::unique_ptr<PCB_SHAPE> shape =
350 shape->SetFilled(
true );
351 shape->SetPolyShape( poly );
352 shape->SetLayer( klayer );
353 shape->SetWidth( 0 );
356 group->AddItem( shape.get() );
365 else if( row.
type == wxS(
"ATTR" ) )
370 if( key == wxS(
"Designator" ) )
373 else if( row.
type == wxS(
"REGION" ) )
378 nlohmann::json polyDataList = row.
inner.value(
"path", nlohmann::json::array() );
379 nlohmann::json prohibitTypes = row.
inner.value(
"prohibitType", nlohmann::json::array() );
383 if( prohibitTypes.is_array() )
385 for(
const auto& pt : prohibitTypes )
390 ptStr = pt.get<std::string>();
392 if( ptStr == wxS(
"COMPONENT" ) )
394 else if( ptStr == wxS(
"TRACK" ) )
396 else if( ptStr == wxS(
"COPPER" ) )
398 else if( ptStr == wxS(
"VIA" ) )
400 else if( ptStr == wxS(
"FILL" ) || ptStr == wxS(
"PLANE" ) )
405 for( nlohmann::json& polyData : polyDataList )
409 std::vector<std::unique_ptr<PCB_SHAPE>> results =
410 m_v2Parser.ParsePoly(
nullptr, polyData,
true,
false );
412 for(
auto& shape : results )
414 shape->SetFilled(
true );
415 shape->TransformShapeToPolygon( polySet, klayer, 0,
ARC_HIGH_DEF,
421 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( footprint );
423 zone->SetIsRuleArea(
true );
424 zone->SetDoNotAllowFootprints( !!flags.count( 2 ) );
425 zone->SetDoNotAllowZoneFills( !!flags.count( 7 ) || !!flags.count( 6 )
426 || !!flags.count( 8 ) );
427 zone->SetDoNotAllowPads( !!flags.count( 7 ) );
428 zone->SetDoNotAllowTracks( !!flags.count( 7 ) || !!flags.count( 5 ) );
429 zone->SetDoNotAllowVias( !!flags.count( 7 ) );
431 zone->SetLayer( klayer );
432 zone->Outline()->Append( polySet );
437 else if( row.
type == wxS(
"IMAGE" ) )
452 nlohmann::json polyDataList = row.
inner.value(
"path", nlohmann::json::array() );
455 std::vector<SHAPE_LINE_CHAIN> contours;
456 for( nlohmann::json& polyData : polyDataList )
461 contours.push_back( contour );
476 for(
int i = 0; i < contour.PointCount(); i++ )
487 std::unique_ptr<PCB_GROUP>
group;
490 group = std::make_unique<PCB_GROUP>( footprint );
496 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>( footprint,
SHAPE_T::POLY );
498 shape->SetFilled(
true );
499 shape->SetPolyShape( poly );
500 shape->SetLayer( klayer );
501 shape->SetWidth( 0 );
513 group->AddItem( shape.get() );
521 else if( row.
type == wxS(
"OBJ" ) )
538 if( imageUrl.empty() )
541 wxString mimeType, base64Data;
543 if( imageUrl.BeforeFirst(
':' ) == wxS(
"blob" ) )
545 wxString objectId = imageUrl.AfterLast(
':' );
547 if(
auto blob =
get_opt( aBlobMap, objectId ) )
549 wxString blobUrl = blob->url;
551 if( blobUrl.BeforeFirst(
':' ) == wxS(
"data" ) )
553 wxArrayString paramsArr =
554 wxSplit( blobUrl.AfterFirst(
':' ).BeforeFirst(
',' ),
';',
'\0' );
556 base64Data = blobUrl.AfterFirst(
',' );
558 if( paramsArr.size() > 0 )
559 mimeType = paramsArr[0];
567 if( mimeType.empty() || base64Data.empty() )
570 wxMemoryBuffer buf = wxBase64Decode( base64Data );
572 if( mimeType == wxS(
"image/svg+xml" ) )
578 VECTOR2D kcenter = kstart + ksize / 2;
580 std::unique_ptr<PCB_REFERENCE_IMAGE> bitmap =
581 std::make_unique<PCB_REFERENCE_IMAGE>( footprint, kcenter, klayer );
584 wxImage::SetDefaultLoadFlags( wxImage::GetDefaultLoadFlags()
585 & ~wxImage::Load_Verbose );
597 int x = bitmap->GetPosition().x;
608 else if( row.
type == wxS(
"STRING" ) )
619 std::vector<PCB_SHAPE*> edgeShapes;
624 edgeShapes.push_back(
static_cast<PCB_SHAPE*
>( item ) );
635 std::unique_ptr<PCB_SHAPE> shape =
641 shape->SetEnd( bbox.
GetEnd() );
647 bool hasFabRef =
false;
653 if(
static_cast<PCB_TEXT*
>( item )->GetText() == wxT(
"${REFERENCE}" ) )
664 int c_refTextThickness =
pcbIUScale.mmToIU( 0.1 );
665 std::unique_ptr<PCB_TEXT> refText = std::make_unique<PCB_TEXT>( footprint );
667 refText->SetLayer(
F_Fab );
668 refText->SetTextSize(
VECTOR2I( c_refTextSize, c_refTextSize ) );
669 refText->SetTextThickness( c_refTextThickness );
670 refText->SetText( wxT(
"${REFERENCE}" ) );
675 return footprintPtr.release();
725 if( aAlign == wxS(
"LEFT_TOP" ) )
727 if( aAlign == wxS(
"LEFT_CENTER" ) || aAlign == wxS(
"LEFT_MIDDLE" ) )
729 if( aAlign == wxS(
"LEFT_BOTTOM" ) )
731 if( aAlign == wxS(
"CENTER_TOP" ) )
733 if( aAlign == wxS(
"CENTER_MIDDLE" ) || aAlign == wxS(
"CENTER_CENTER" ) )
735 if( aAlign == wxS(
"CENTER_BOTTOM" ) )
737 if( aAlign == wxS(
"RIGHT_TOP" ) )
739 if( aAlign == wxS(
"RIGHT_CENTER" ) || aAlign == wxS(
"RIGHT_MIDDLE" ) )
741 if( aAlign == wxS(
"RIGHT_BOTTOM" ) )
749 BOARD* aBoard,
const nlohmann::json& aProject,
750 std::map<wxString, std::unique_ptr<FOOTPRINT>>& aFootprintMap,
751 const std::map<wxString, EASYEDAPRO::BLOB>& aBlobMap,
752 const std::multimap<wxString, EASYEDAPRO::POURED>& aPouredMap,
753 const V3_DOC_RAW& aDoc,
const wxString& aFpLibName )
761 std::map<wxString, wxString> attrs;
773 bool keyVisible =
false;
774 bool valVisible =
false;
776 double fontSize = 45.0;
777 double strokeWidth = 6.0;
791 std::map<wxString, COMP_DATA> componentMap;
792 std::multimap<wxString, ATTR_DATA> attrMap;
793 std::multimap<wxString, PAD_NET_DATA> padNetMap;
795 std::multimap<wxString, EASYEDAPRO::POURED> boardPouredMap = aPouredMap;
796 std::map<wxString, ZONE*> poursToFill;
802 if( row.
type == wxS(
"LAYER" ) )
813 blayers.
set( klayer );
816 if( !layerName.IsEmpty() )
820 else if( row.
type == wxS(
"NET" ) )
825 if( idArr.is_array() && idArr.size() > 1 )
828 if( !netname.IsEmpty() )
835 else if( row.
type == wxS(
"RULE" ) )
839 if( !idArr.is_array() || idArr.size() < 3 )
845 nlohmann::json context = row.
inner.value(
"ruleContext", nlohmann::json() );
847 if( ruleType == wxS(
"TRACK" ) && isDefault )
849 nlohmann::json track = context.value(
"track", nlohmann::json() );
850 nlohmann::json content = track.value(
"content", nlohmann::json::array() );
852 if( content.is_array() && !content.empty() )
854 double minVal =
V3GetDouble( content[0],
"stroMin" );
858 else if( ruleType == wxS(
"SAFE" ) && isDefault )
860 nlohmann::json safeSpacing = context.value(
"safeSpacing",
861 nlohmann::json::array() );
863 if( safeSpacing.is_array() && !safeSpacing.empty() )
865 nlohmann::json content = safeSpacing[0].value(
"content",
866 nlohmann::json::array() );
868 int minVal = INT_MAX;
870 for(
const auto& arr : content )
874 for(
const auto& val : arr )
876 int v = val.is_number() ? val.get<
int>() : 0;
883 if( minVal != INT_MAX )
888 else if( row.
type == wxS(
"VIA" ) )
898 std::unique_ptr<PCB_VIA>
via = std::make_unique<PCB_VIA>( aBoard );
908 else if( row.
type == wxS(
"LINE" ) )
924 std::unique_ptr<PCB_TRACK> track = std::make_unique<PCB_TRACK>( aBoard );
926 track->SetLayer( klayer );
930 track->SetNet( aBoard->
FindNet( netname ) );
934 else if( row.
type == wxS(
"ARC" ) )
954 double ha = angle / 2;
955 double hd =
delta.EuclideanNorm() / 2;
956 double cdist = hd / tan(
DEG2RAD( ha ) );
965 std::unique_ptr<PCB_ARC> arc = std::make_unique<PCB_ARC>( aBoard, &sarc );
967 arc->SetLayer( klayer );
968 arc->SetNet( aBoard->
FindNet( netname ) );
972 else if( row.
type == wxS(
"POLY" ) )
978 nlohmann::json polyData = row.
inner.value(
"path", nlohmann::json::array() );
980 std::vector<std::unique_ptr<PCB_SHAPE>> results =
981 m_v2Parser.ParsePoly( aBoard, polyData,
false,
false );
983 for(
auto& shape : results )
985 shape->SetLayer( klayer );
991 else if( row.
type == wxS(
"FILL" ) )
998 nlohmann::json polyDataList = row.
inner.value(
"path", nlohmann::json::array() );
1000 if( polyDataList.is_null() || polyDataList.empty() )
1003 if( !polyDataList.at( 0 ).is_array() )
1004 polyDataList = nlohmann::json::array( { polyDataList } );
1006 std::vector<SHAPE_LINE_CHAIN> contours;
1008 for( nlohmann::json& polyData : polyDataList )
1012 contours.push_back( contour );
1023 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aBoard );
1025 zone->SetNet( aBoard->
FindNet( netname ) );
1026 zone->SetLayer( klayer );
1028 zone->SetFilledPolysList( klayer, zoneFillPoly );
1029 zone->SetAssignedPriority( 500 );
1030 zone->SetIsFilled(
true );
1031 zone->SetNeedRefill(
false );
1038 else if( row.
type == wxS(
"POUR" ) )
1046 nlohmann::json polyDataList = row.
inner.value(
"path", nlohmann::json::array() );
1048 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aBoard );
1050 zone->SetNet( aBoard->
FindNet( netname ) );
1051 zone->SetLayer( klayer );
1052 zone->SetAssignedPriority( 500 - fillOrder );
1056 for( nlohmann::json& polyData : polyDataList )
1060 zone->Outline()->Append( contour );
1063 wxASSERT( zone->Outline()->OutlineCount() == 1 );
1065 poursToFill.emplace( row.
id, zone.get() );
1069 else if( row.
type == wxS(
"POURED" ) )
1074 if( idArr.is_array() && idArr.size() > 1 )
1077 nlohmann::json fills = row.
inner.value(
"pourFill", nlohmann::json::array() );
1079 if( !fills.is_array() )
1082 for(
const nlohmann::json& fill : fills )
1086 nlohmann::json( row.
id ) ) );
1090 poured.
polyData = fill.value(
"path", nlohmann::json::array() );
1092 boardPouredMap.emplace( poured.
parentId, poured );
1095 else if( row.
type == wxS(
"REGION" ) )
1100 nlohmann::json polyDataList = row.
inner.value(
"path", nlohmann::json::array() );
1101 nlohmann::json prohibitTypes = row.
inner.value(
"prohibitType",
1102 nlohmann::json::array() );
1104 std::set<int> flags;
1106 if( prohibitTypes.is_array() )
1108 for(
const auto& pt : prohibitTypes )
1112 if( pt.is_string() )
1113 ptStr = pt.get<std::string>();
1115 if( ptStr == wxS(
"COMPONENT" ) )
1117 else if( ptStr == wxS(
"TRACK" ) )
1119 else if( ptStr == wxS(
"COPPER" ) )
1121 else if( ptStr == wxS(
"VIA" ) )
1123 else if( ptStr == wxS(
"FILL" ) || ptStr == wxS(
"PLANE" ) )
1128 for( nlohmann::json& polyData : polyDataList )
1133 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aBoard );
1135 zone->SetIsRuleArea(
true );
1136 zone->SetDoNotAllowFootprints( !!flags.count( 2 ) );
1137 zone->SetDoNotAllowZoneFills( !!flags.count( 7 ) || !!flags.count( 6 )
1138 || !!flags.count( 8 ) );
1139 zone->SetDoNotAllowPads( !!flags.count( 7 ) );
1140 zone->SetDoNotAllowTracks( !!flags.count( 7 ) || !!flags.count( 5 ) );
1141 zone->SetDoNotAllowVias( !!flags.count( 7 ) );
1143 zone->SetLayer( klayer );
1144 zone->Outline()->Append( contour );
1149 else if( row.
type == wxS(
"STRING" ) )
1153 else if( row.
type == wxS(
"COMPONENT" ) )
1161 nlohmann::json attrsObj = row.
inner.value(
"attrs", nlohmann::json::object() );
1163 if( attrsObj.is_object() )
1165 for(
auto& [k, v] : attrsObj.items() )
1169 componentMap[row.
id] =
comp;
1171 else if( row.
type == wxS(
"ATTR" ) )
1196 attrMap.emplace( attr.parentId, attr );
1198 else if( row.
type == wxS(
"PAD_NET" ) )
1203 pn.compId = idArr.is_array() && idArr.size() > 1
1206 pn.padNumber = idArr.is_array() && idArr.size() > 2
1211 if( !pn.compId.IsEmpty() )
1212 padNetMap.emplace( pn.compId, pn );
1214 else if( row.
type == wxS(
"PAD" ) )
1218 std::unique_ptr<FOOTPRINT> footprint =
1219 std::make_unique<FOOTPRINT>( aBoard );
1231 footprint->SetPosition( pos );
1232 footprint->SetOrientation( orient );
1234 wxString fpName = wxS(
"Pad_" ) + row.
id;
1237 footprint->SetFPID( fpID );
1238 footprint->Reference().SetVisible(
true );
1239 footprint->Value().SetVisible(
true );
1240 footprint->AutoPositionFields();
1244 else if( row.
type == wxS(
"IMAGE" ) )
1259 nlohmann::json polyDataList = row.
inner.value(
"path", nlohmann::json::array() );
1262 std::vector<SHAPE_LINE_CHAIN> contours;
1263 for( nlohmann::json& polyData : polyDataList )
1268 contours.push_back( contour );
1283 for(
int i = 0; i < contour.PointCount(); i++ )
1294 std::unique_ptr<PCB_GROUP>
group;
1297 group = std::make_unique<PCB_GROUP>( aBoard );
1303 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>( aBoard,
SHAPE_T::POLY );
1305 shape->SetFilled(
true );
1306 shape->SetPolyShape( poly );
1307 shape->SetLayer( klayer );
1308 shape->SetWidth( 0 );
1320 group->AddItem( shape.get() );
1328 else if( row.
type == wxS(
"OBJ" ) )
1345 if( imageUrl.empty() )
1348 wxString mimeType, base64Data;
1350 if( imageUrl.BeforeFirst(
':' ) == wxS(
"blob" ) )
1352 wxString objectId = imageUrl.AfterLast(
':' );
1354 if(
auto blob =
get_opt( aBlobMap, objectId ) )
1356 wxString blobUrl = blob->url;
1358 if( blobUrl.BeforeFirst(
':' ) == wxS(
"data" ) )
1360 wxArrayString paramsArr =
1361 wxSplit( blobUrl.AfterFirst(
':' ).BeforeFirst(
',' ),
';',
'\0' );
1363 base64Data = blobUrl.AfterFirst(
',' );
1365 if( paramsArr.size() > 0 )
1366 mimeType = paramsArr[0];
1374 if( mimeType.empty() || base64Data.empty() )
1377 wxMemoryBuffer buf = wxBase64Decode( base64Data );
1379 if( mimeType == wxS(
"image/svg+xml" ) )
1385 VECTOR2D kcenter = kstart + ksize / 2;
1387 std::unique_ptr<PCB_REFERENCE_IMAGE> bitmap =
1388 std::make_unique<PCB_REFERENCE_IMAGE>( aBoard, kcenter, klayer );
1391 wxImage::SetDefaultLoadFlags( wxImage::GetDefaultLoadFlags()
1392 & ~wxImage::Load_Verbose );
1404 int x = bitmap->GetPosition().x;
1418 for(
auto const& [compId,
comp] : componentMap )
1421 wxString fpIdOverride;
1422 wxString fpDesignator;
1425 auto attrRange = attrMap.equal_range( compId );
1427 for(
auto it = attrRange.first; it != attrRange.second; ++it )
1429 const ATTR_DATA& attr = it->second;
1431 if( attr.key == wxS(
"Device" ) )
1432 deviceId = attr.value;
1433 else if( attr.key == wxS(
"Footprint" ) )
1434 fpIdOverride = attr.value;
1435 else if( attr.key == wxS(
"Designator" ) )
1436 fpDesignator = attr.value;
1441 const std::map<wxString, wxString>& deviceAttrs = deviceData.
attributes;
1443 wxString fpId = fpIdOverride;
1446 fpId =
get_def( deviceAttrs, wxS(
"Footprint" ), wxEmptyString );
1450 wxLogTrace(
traceEasyEdaIo, wxT(
"EasyEDA Pro v3 component '%s' (%s): no footprint mapping, skipping." ),
1451 compId, fpDesignator );
1455 auto it = aFootprintMap.find( fpId );
1457 if( it == aFootprintMap.end() )
1459 wxLogTrace(
traceEasyEdaIo,
"Footprint of '%s' with uuid '%s' not found.", fpDesignator, fpId );
1463 std::unique_ptr<FOOTPRINT>& footprintOrig = it->second;
1464 std::unique_ptr<FOOTPRINT> footprint(
1465 static_cast<FOOTPRINT*
>( footprintOrig->Clone() ) );
1467 footprint->SetParent( aBoard );
1471 wxString libItemName = footprint->GetFPID().GetLibItemName();
1473 if( libItemName.empty() )
1476 footprint->SetFPID(
ToKiCadLibID( aFpLibName, libItemName ) );
1478 wxString modelUuid =
get_def( deviceAttrs, wxS(
"3D Model" ), wxEmptyString );
1479 wxString modelTitle =
get_def( deviceAttrs, wxS(
"3D Model Title" ), modelUuid ).Trim();
1480 wxString modelTransform =
get_def( deviceAttrs, wxS(
"3D Model Transform" ), wxEmptyString );
1482 m_v2Parser.FillFootprintModelInfo( footprint.get(), modelUuid, modelTitle, modelTransform );
1486 if( !valueText.empty() )
1487 footprint->SetValue( valueText );
1491 if( description.empty() )
1492 description =
get_def( deviceAttrs, wxS(
"Description" ), wxEmptyString );
1494 if( !description.empty() )
1502 [&](
const wxString& attrKey,
const wxString& value )
1506 if( attrKey == wxS(
"Datasheet" ) )
1509 field = footprint->GetField( attrKey );
1524 if( klayer ==
B_Cu )
1527 footprint->SetOrientationDegrees(
comp.angle );
1531 for(
auto attrIt = attrRange.first; attrIt != attrRange.second; ++attrIt )
1533 const ATTR_DATA& attr = attrIt->second;
1535 if( attr.key == wxS(
"Designator" ) )
1539 if( attr.fontName != wxS(
"default" ) )
1542 if( attr.valVisible && attr.keyVisible )
1543 field->
SetText( attr.key +
':' + attr.value );
1544 else if( attr.keyVisible )
1549 field->
SetVisible( attr.keyVisible || attr.valVisible );
1576 auto padNetRange = padNetMap.equal_range( compId );
1578 for(
auto pnIt = padNetRange.first; pnIt != padNetRange.second; ++pnIt )
1580 const PAD_NET_DATA& pn = pnIt->second;
1582 PAD*
pad = footprint->FindPadByNumber( pn.padNumber );
1594 for(
auto& [uuid, zone] : poursToFill )
1599 auto range = boardPouredMap.equal_range( uuid );
1601 for(
auto& pIt = range.first; pIt != range.second; ++pIt )
1607 for(
int dataId = 0;
1608 dataId < static_cast<int>( poured.
polyData.size() ); dataId++ )
1610 const nlohmann::json& fillData = poured.
polyData[dataId];
1611 const double ptScale = 10;
1617 for(
int i = 0; i < contour.
PointCount(); i++ )
1630 thisPoly.
Append( simple );
1639 const int thermalWidth =
pcbIUScale.mmToIU( 0.2 );
1641 for(
int segId = 0; segId < contour.
SegmentCount(); segId++ )
1652 fillPolySet.
Append( thisPoly );
1659 const int strokeWidth =
pcbIUScale.MilsToIU( 8 );
1661 fillPolySet.
Inflate( strokeWidth / 2,
1668 zone->SetFilledPolysList( zone->GetFirstLayer(), fillPolySet );
1669 zone->SetNeedRefill(
false );
1670 zone->SetIsFilled(
true );
1676 std::vector<PCB_SHAPE*> shapes;
1684 shapes.push_back(
static_cast<PCB_SHAPE*
>( item ) );
1699 offset.
x =
KiROUND( offset.
x / alignGrid ) * alignGrid;
1700 offset.
y =
KiROUND( offset.
y / alignGrid ) * alignGrid;
1702 aBoard->
Move( offset );
constexpr int ARC_HIGH_DEF
constexpr EDA_IU_SCALE pcbIUScale
#define DEFAULT_COURTYARD_WIDTH
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
BASE_SET & set(size_t pos)
void Mirror(FLIP_DIRECTION aFlipDirection)
Mirror image vertically (i.e.
Container for design settings for a BOARD object.
void SetAuxOrigin(const VECTOR2I &aOrigin)
Abstract interface for BOARD_ITEMs capable of storing other items inside.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual void SetIsKnockout(bool aKnockout)
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.
const PAGE_INFO & GetPageSettings() const
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
bool SetLayerName(PCB_LAYER_ID aLayer, const wxString &aLayerName)
Changes the name of the layer given by aLayer.
void Move(const VECTOR2I &aMoveVector) override
Move this object.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
const LSET & GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
BOX2I ComputeBoundingBox(bool aBoardEdgesOnly=false, bool aPhysicalLayersOnly=false) const
Calculate the bounding box containing all board items (or board edge segments).
unsigned GetNetCount() const
void SetEnabledLayers(const LSET &aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings.
const DRAWINGS & Drawings() const
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
constexpr const Vec GetEnd() const
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
constexpr const Vec GetCenter() const
constexpr const Vec & GetOrigin() const
constexpr const SizeVec & GetSize() const
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
virtual void SetVisible(bool aVisible)
void SetTextAngleDegrees(double aOrientation)
void SetKeepUpright(bool aKeepUpright)
virtual void SetText(const wxString &aText)
void SetFont(KIFONT::FONT *aFont)
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.
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 SMDMask()
layer set for a SMD pad on Front layer
Describe the page size and margins of a paper page on which to eventually print or plot.
double GetHeightMils() const
double GetWidthMils() const
static T ScaleSize(T aValue)
static VECTOR2< T > ScalePos(VECTOR2< T > aValue)
void ParseBoard(BOARD *aBoard, const nlohmann::json &aProject, std::map< wxString, std::unique_ptr< FOOTPRINT > > &aFootprintMap, const std::map< wxString, EASYEDAPRO::BLOB > &aBlobMap, const std::multimap< wxString, EASYEDAPRO::POURED > &aPouredMap, const EASYEDAPRO::V3_DOC_RAW &aDoc, const wxString &aFpLibName)
PCB_IO_EASYEDAPRO_V3_PARSER(BOARD *aBoard, PROGRESS_REPORTER *aProgressReporter)
PCB_IO_EASYEDAPRO_PARSER m_v2Parser
FOOTPRINT * ParseFootprint(const std::map< wxString, EASYEDAPRO::BLOB > &aBlobMap, const EASYEDAPRO::V3_DOC_RAW &aDoc)
std::unique_ptr< PAD > createV3PAD(FOOTPRINT *aFootprint, const EASYEDAPRO::V3_ROW &aRow)
PCB_TEXT * createV3Text(BOARD_ITEM_CONTAINER *aContainer, const EASYEDAPRO::V3_ROW &aRow)
void SetTextThickness(int aWidth) override
The TextThickness is that set by the user.
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true) override
virtual void SetPosition(const VECTOR2I &aPos) override
A progress reporter interface for use in multi-threaded environments.
A REFERENCE_IMAGE is a wrapper around a BITMAP_IMAGE that is displayed in an editor as a reference fo...
BITMAP_BASE & MutableImage() const
Only use this if you really need to modify the underlying image.
bool ReadImageFile(const wxString &aFullFilename)
Read and store an image file.
void SetImageScale(double aScale)
Set the image "zoom" value.
SHAPE_ARC & ConstructFromStartEndCenter(const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aCenter, bool aClockwise=false, double aWidth=0)
Constructs this arc from the given start, end and center.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
virtual const VECTOR2I GetPoint(int aIndex) const override
void SetPoint(int aIndex, const VECTOR2I &aPos)
Move a point to a specific location.
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
int PointCount() const
Return the number of points (vertices) in this 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.
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
Represent a set of closed polygons.
void BooleanAdd(const SHAPE_POLY_SET &b)
Perform boolean polyset union.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
bool IsEmpty() const
Return true if the set is empty (no polygons at all)
void Inflate(int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError, bool aSimplify=false)
Perform outline inflation/deflation.
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)
void Simplify()
Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections)
std::vector< SHAPE_LINE_CHAIN > POLYGON
represents a single polygon outline with holes.
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.
void Fracture(bool aSimplify=true)
Convert a set of polygons with holes to a single outline with "slits"/"fractures" connecting the oute...
void BooleanSubtract(const SHAPE_POLY_SET &b)
Perform boolean polyset difference.
const std::vector< POLYGON > & CPolygons() const
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
const SHAPE_LINE_CHAIN Outline() const
void TransformOvalToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aWidth, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a oblong shape to a polygon, using multiple segments.
@ ROUND_ALL_CORNERS
All angles are rounded.
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_90
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
void ConnectBoardShapes(std::vector< PCB_SHAPE * > &aShapeList, int aChainingEpsilon)
Connects shapes to each other, making continious contours (adjacent shapes will have a common vertex)...
const wxChar *const traceEasyEdaIo
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a back layer.
PCB_LAYER_ID
A quick note on layer IDs:
wxString get_def(const std::map< wxString, wxString > &aMap, const char *aKey, const char *aDefval="")
std::optional< V > get_opt(const std::map< wxString, V > &aMap, const wxString &aKey)
constexpr void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
@ LEFT_RIGHT
Flip left to right (around the Y axis)
@ TOP_BOTTOM
Flip top to bottom (around the X axis)
LIB_ID ToKiCadLibID(const wxString &aLibName, const wxString &aLibReference)
bool V3GetBool(const nlohmann::json &aObj, const char *aKey, bool aDefault)
void ForEachImportedDeviceField(const std::map< wxString, wxString > &aDeviceAttributes, bool aIncludeValue, const std::function< void(const wxString &aKey, const wxString &aValue)> &aCallback)
Invoke aCallback for each non-empty whitelisted Device field (resolved + normalized).
wxString ResolveDeviceFieldVariables(const wxString &aInput, const std::map< wxString, wxString > &aDeviceAttributes)
Resolve EasyEDA ={Var} / ={A}text{B} field expressions against device attributes.
wxString NormalizeEasyEDAText(wxString aText)
Replace EasyEDA temperature glyph (℃) with °C.
V3_DEVICE_DATA GetV3DeviceData(const nlohmann::json &aProject, const wxString &aDeviceUuid)
static const bool IMPORT_POURED
nlohmann::json V3ParseIdArray(const wxString &aId)
bool V3IsNullOrMissing(const nlohmann::json &aObj, const char *aKey)
double V3GetDouble(const nlohmann::json &aObj, const char *aKey, double aDefault)
wxString V3JsonToString(const nlohmann::json &aValue, const wxString &aDefault)
wxString ResolveV3DeviceValueText(const std::map< wxString, wxString > &aDeviceAttributes)
Preferred Value text: Value attribute, else Name, with variables resolved.
int V3GetInt(const nlohmann::json &aObj, const char *aKey, int aDefault)
wxString V3GetString(const nlohmann::json &aObj, const char *aKey, const wxString &aDefault)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
@ SMD
Smd pad, appears on the solder paste layer (default)
@ PTH
Plated through hole pad.
Class to handle a set of BOARD_ITEMs.
static const int SHAPE_JOIN_DISTANCE
static int V3AlignToOriginCode(const wxString &aAlign)
static void V3AlignText(EDA_TEXT *text, int align)
std::map< wxString, wxString > attributes
Raw parsed document from an EasyEDA Pro v3 .epru stream.
std::vector< V3_ROW > rows
One parsed row from an EasyEDA Pro v3 .epru document stream.
@ USER
The field ID hasn't been set yet; field is invalid.
@ DESCRIPTION
Field Description of part, i.e. "1/4W 1% Metal Film Resistor".
@ DATASHEET
name of datasheet
@ REFERENCE
Field Reference of part, i.e. "IC21".
wxLogTrace helper definitions.
double DEG2RAD(double deg)
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D