262 bool aClosed,
bool aInFill )
const
264 std::vector<std::unique_ptr<PCB_SHAPE>> results;
267 for(
int i = 0; i < (int) polyData.size(); i++ )
269 nlohmann::json val = polyData.at( i );
271 if( val.is_string() )
274 if( str == wxS(
"CIRCLE" ) )
277 center.x = ( polyData.at( ++i ) );
278 center.y = ( polyData.at( ++i ) );
279 double r = ( polyData.at( ++i ) );
281 std::unique_ptr<PCB_SHAPE> shape =
286 shape->SetFilled( aClosed );
288 results.emplace_back( std::move( shape ) );
290 else if( str == wxS(
"R" ) )
293 start.
x = ( polyData.at( ++i ) );
294 start.
y = ( polyData.at( ++i ) );
295 size.
x = ( polyData.at( ++i ) );
296 size.
y = -( polyData.at( ++i ).get<double>() );
297 double angle = polyData.at( ++i );
298 double cr = ( i + 1 ) < (
int) polyData.size() ? polyData.at( ++i ).get<
double>() : 0;
302 std::unique_ptr<PCB_SHAPE> shape =
305 shape->SetStart(
ScalePos( start ) );
306 shape->SetEnd(
ScalePos( start + size ) );
307 shape->SetFilled( aClosed );
310 results.emplace_back( std::move( shape ) );
318 std::unique_ptr<PCB_SHAPE> shape =
321 shape->SetStart(
ScalePos( aStart ) );
323 shape->SetFilled( aClosed );
326 results.emplace_back( std::move( shape ) );
331 std::unique_ptr<PCB_SHAPE> shape =
332 std::make_unique<PCB_SHAPE>( aContainer,
SHAPE_T::ARC );
334 shape->SetStart(
ScalePos( aStart ) );
337 shape->SetFilled( aClosed );
340 results.emplace_back( std::move( shape ) );
348 addArc( {
end.x - cr, start.
y }, {
end.x, start.
y - cr },
349 {
end.x - cr, start.
y - cr } );
352 {
end.x - cr,
end.y + cr } );
354 addArc( { start.
x + cr,
end.y }, { start.
x,
end.y + cr },
355 { start.
x + cr,
end.y + cr } );
357 addArc( { start.
x, start.
y - cr }, { start.
x + cr, start.
y },
358 { start.
x + cr, start.
y - cr } );
361 else if( str == wxS(
"ARC" ) || str == wxS(
"CARC" ) )
364 double angle = polyData.at( ++i ).get<
double>() / ( aInFill ? 10 : 1 );
365 end.x = ( polyData.at( ++i ) );
366 end.y = ( polyData.at( ++i ) );
368 std::unique_ptr<PCB_SHAPE> shape =
369 std::make_unique<PCB_SHAPE>( aContainer,
SHAPE_T::ARC );
373 shape->SetStart(
ScalePos( prevPt ) );
379 shape->SetEnd(
ScalePos( prevPt ) );
385 double ha = angle / 2;
386 double hd =
delta.EuclideanNorm() / 2;
387 double cdist = hd / tan(
DEG2RAD( ha ) );
391 shape->SetFilled( aClosed );
393 results.emplace_back( std::move( shape ) );
397 else if( str == wxS(
"L" ) )
402 while( i < (
int) polyData.size() - 2 && polyData.at( i + 1 ).is_number() )
405 pt.
x = ( polyData.at( ++i ) );
406 pt.
y = ( polyData.at( ++i ) );
415 std::unique_ptr<PCB_SHAPE> shape =
418 wxASSERT(
chain.PointCount() > 2 );
420 if(
chain.PointCount() > 2 )
422 chain.SetClosed(
true );
423 shape->SetFilled(
true );
424 shape->SetPolyShape(
chain );
426 results.emplace_back( std::move( shape ) );
431 for(
int s = 0; s <
chain.SegmentCount(); s++ )
435 std::unique_ptr<PCB_SHAPE> shape =
438 shape->SetStart( seg.
A );
439 shape->SetEnd( seg.
B );
441 results.emplace_back( std::move( shape ) );
446 else if( val.is_number() )
448 prevPt.
x = ( polyData.at( i ) );
449 prevPt.
y = ( polyData.at( ++i ) );
757 const wxString& aFpUuid,
758 const std::vector<nlohmann::json>& aLines )
760 std::unique_ptr<FOOTPRINT> footprintPtr = std::make_unique<FOOTPRINT>(
m_board );
761 FOOTPRINT* footprint = footprintPtr.get();
764 const int defaultTextThickness(
pcbIUScale.mmToIU( 0.15 ) );
768 field->SetTextSize( defaultTextSize );
769 field->SetTextThickness( defaultTextThickness );
772 for(
const nlohmann::json& line : aLines )
774 if( line.size() == 0 )
777 wxString type = line.at( 0 );
779 if( type == wxS(
"POLY" ) || type == wxS(
"PAD" ) || type == wxS(
"FILL" )
780 || type == wxS(
"ATTR" ) )
782 wxString uuid = line.at( 1 );
789 wxString netname = line.at( 3 );
790 int layer = line.at( 4 ).get<
int>();
793 if( type == wxS(
"POLY" ) )
795 double thickness = ( line.at( 5 ) );
796 nlohmann::json polyData = line.at( 6 );
798 std::vector<std::unique_ptr<PCB_SHAPE>> results =
799 ParsePoly( footprint, polyData,
false,
false );
801 for(
auto& shape : results )
803 shape->SetLayer( klayer );
804 shape->SetWidth(
ScaleSize( thickness ) );
809 else if( type == wxS(
"PAD" ) )
811 std::unique_ptr<PAD>
pad =
createPAD( footprint, line );
815 else if( type == wxS(
"FILL" ) )
817 int fillLayer = line.at( 4 ).get<
int>();
820 nlohmann::json polyDataList = line.at( 7 );
822 if( !polyDataList.is_null() && !polyDataList.empty() )
824 if( !polyDataList.at( 0 ).is_array() )
825 polyDataList = nlohmann::json::array( { polyDataList } );
827 std::vector<SHAPE_LINE_CHAIN> contours;
828 for( nlohmann::json& polyData : polyDataList )
833 contours.push_back( contour );
843 std::unique_ptr<PCB_GROUP>
group;
846 group = std::make_unique<PCB_GROUP>( footprint );
850 std::unique_ptr<PCB_SHAPE> shape =
853 shape->SetFilled(
true );
854 shape->SetPolyShape( poly );
855 shape->SetLayer( fillKlayer );
856 shape->SetWidth( 0 );
859 group->AddItem( shape.get() );
868 else if( type == wxS(
"ATTR" ) )
872 if( attr.
key == wxS(
"Designator" ) )
876 else if( type == wxS(
"REGION" ) )
878 wxString uuid = line.at( 1 );
885 int layer = line.at( 3 ).get<
int>();
888 std::set<int> flags = line.at( 5 );
889 nlohmann::json polyDataList = line.at( 6 );
891 for( nlohmann::json& polyData : polyDataList )
895 std::vector<std::unique_ptr<PCB_SHAPE>> results =
896 ParsePoly(
nullptr, polyData,
true,
false );
898 for(
auto& shape : results )
900 shape->SetFilled(
true );
907 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( footprint );
909 zone->SetIsRuleArea(
true );
910 zone->SetDoNotAllowFootprints( !!flags.count( 2 ) );
911 zone->SetDoNotAllowZoneFills( !!flags.count( 7 ) || !!flags.count( 6 )
912 || !!flags.count( 8 ) );
913 zone->SetDoNotAllowPads( !!flags.count( 7 ) );
914 zone->SetDoNotAllowTracks( !!flags.count( 7 ) || !!flags.count( 5 ) );
915 zone->SetDoNotAllowVias( !!flags.count( 7 ) );
917 zone->SetLayer( klayer );
918 zone->Outline()->Append( polySet );
925 if( aProject.is_object() && aProject.contains(
"devices" ) )
927 std::map<wxString, EASYEDAPRO::PRJ_DEVICE> devicesMap = aProject.at(
"devices" );
928 std::map<wxString, wxString> compAttrs;
930 for(
auto& [devUuid, devData] : devicesMap )
932 if(
auto fp =
get_opt( devData.attributes,
"Footprint" ) )
936 compAttrs = devData.attributes;
942 wxString modelUuid, modelTitle, modelTransform;
944 modelUuid =
get_def( compAttrs,
"3D Model",
"" );
945 modelTitle =
get_def( compAttrs,
"3D Model Title", modelUuid );
946 modelTransform =
get_def( compAttrs,
"3D Model Transform",
"" );
952 std::vector<PCB_SHAPE*> edgeShapes;
957 edgeShapes.push_back(
static_cast<PCB_SHAPE*
>( item ) );
968 std::unique_ptr<PCB_SHAPE> shape =
974 shape->SetEnd( bbox.
GetEnd() );
979 bool hasFabRef =
false;
985 if(
static_cast<PCB_TEXT*
>( item )->GetText() == wxT(
"${REFERENCE}" ) )
997 int c_refTextThickness =
pcbIUScale.mmToIU( 0.1 );
998 std::unique_ptr<PCB_TEXT> refText = std::make_unique<PCB_TEXT>( footprint );
1000 refText->SetLayer(
F_Fab );
1001 refText->SetTextSize(
VECTOR2I( c_refTextSize, c_refTextSize ) );
1002 refText->SetTextThickness( c_refTextThickness );
1003 refText->SetText( wxT(
"${REFERENCE}" ) );
1008 return footprintPtr.release();
1013 BOARD* aBoard,
const nlohmann::json& aProject,
1014 std::map<wxString, std::unique_ptr<FOOTPRINT>>& aFootprintMap,
1015 const std::map<wxString, EASYEDAPRO::BLOB>& aBlobMap,
1016 const std::multimap<wxString, EASYEDAPRO::POURED>& aPouredMap,
1017 const std::vector<nlohmann::json>& aLines,
const wxString& aFpLibName )
1019 std::map<wxString, std::vector<nlohmann::json>> componentLines;
1020 std::map<wxString, std::vector<nlohmann::json>> ruleLines;
1022 std::multimap<wxString, EASYEDAPRO::POURED> boardPouredMap = aPouredMap;
1023 std::map<wxString, ZONE*> poursToFill;
1027 for(
const nlohmann::json& line : aLines )
1029 if( line.size() == 0 )
1032 wxString type = line.at( 0 );
1034 if( type == wxS(
"LAYER" ) )
1036 int layer = line.at( 1 );
1039 wxString layerType = line.at( 2 );
1040 wxString layerName = line.at( 3 );
1041 int layerFlag = line.at( 4 );
1043 if( layerFlag != 0 )
1046 blayers.
set( klayer );
1051 else if( type == wxS(
"NET" ) )
1053 wxString netname = line.at( 1 );
1058 else if( type == wxS(
"RULE" ) )
1060 wxString ruleType = line.at( 1 );
1061 wxString ruleName = line.at( 2 );
1062 int isDefault = line.at( 3 );
1063 nlohmann::json ruleData = line.at( 4 );
1065 if( ruleType == wxS(
"3" ) && isDefault )
1067 wxString units = ruleData.at( 0 );
1069 if( ruleData.at( 1 ).is_number() )
1072 double minVal = ruleData.at( 1 );
1081 nlohmann::json
table = ruleData.at( 1 );
1083 for(
auto& [key, arr] :
table.items() )
1085 double minVal = arr.at( 0 );
1093 else if( ruleType == wxS(
"1" ) && isDefault )
1095 wxString units = ruleData.at( 0 );
1096 nlohmann::json
table = ruleData.at( 1 );
1097 int minVal = INT_MAX;
1102 for(
const auto& arr :
table )
1104 for(
int val : arr )
1106 if( val != 0 && val < minVal )
1111 else if(
table.is_object() )
1115 for(
auto& [key, arr] :
table.items() )
1117 for(
const auto& subarr : arr )
1119 for(
int val : subarr )
1121 if( val != 0 && val < minVal )
1131 ruleLines[ruleType].push_back( line );
1133 else if( type == wxS(
"POURED" ) )
1135 if( !line.at( 2 ).is_string() )
1139 boardPouredMap.emplace( poured.
parentId, poured );
1141 else if( type == wxS(
"VIA" ) || type == wxS(
"LINE" ) || type == wxS(
"ARC" )
1142 || type == wxS(
"POLY" ) || type == wxS(
"FILL" ) || type == wxS(
"POUR" ) )
1144 wxString uuid = line.at( 1 );
1151 wxString netname = line.at( 3 );
1153 if( type == wxS(
"VIA" ) )
1159 double drill = line.at( 7 );
1160 double dia = line.at( 8 );
1162 std::unique_ptr<PCB_VIA>
via = std::make_unique<PCB_VIA>( aBoard );
1168 via->SetNet(
getNet( aBoard, netname ) );
1172 else if( type == wxS(
"LINE" ) )
1174 int layer = line.at( 4 ).get<
int>();
1178 start.
x = line.at( 5 );
1179 start.
y = line.at( 6 );
1182 end.x = line.at( 7 );
1183 end.y = line.at( 8 );
1185 double width = line.at( 9 );
1187 std::unique_ptr<PCB_TRACK> track = std::make_unique<PCB_TRACK>( aBoard );
1189 track->SetLayer( klayer );
1190 track->SetStart(
ScalePos( start ) );
1194 track->SetNet(
getNet( aBoard, netname ) );
1198 else if( type == wxS(
"ARC" ) )
1200 int layer = line.at( 4 ).get<
int>();
1204 start.
x = line.at( 5 );
1205 start.
y = line.at( 6 );
1208 end.x = line.at( 7 );
1209 end.y = line.at( 8 );
1211 double angle = line.at( 9 );
1212 double width = line.at( 10 );
1217 double ha = angle / 2;
1218 double hd =
delta.EuclideanNorm() / 2;
1219 double cdist = hd / tan(
DEG2RAD( ha ) );
1226 std::unique_ptr<PCB_ARC> arc = std::make_unique<PCB_ARC>( aBoard, &sarc );
1229 arc->SetLayer( klayer );
1230 arc->SetNet(
getNet( aBoard, netname ) );
1234 else if( type == wxS(
"FILL" ) )
1236 int layer = line.at( 4 ).get<
int>();
1239 nlohmann::json polyDataList = line.at( 7 );
1241 if( !polyDataList.at( 0 ).is_array() )
1242 polyDataList = nlohmann::json::array( { polyDataList } );
1244 std::vector<SHAPE_LINE_CHAIN> contours;
1245 for( nlohmann::json& polyData : polyDataList )
1250 contours.push_back( contour );
1261 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aBoard );
1263 zone->SetNet(
getNet( aBoard, netname ) );
1264 zone->SetLayer( klayer );
1266 zone->SetFilledPolysList( klayer, zoneFillPoly );
1267 zone->SetAssignedPriority( 500 );
1268 zone->SetIsFilled(
true );
1269 zone->SetNeedRefill(
false );
1276 else if( type == wxS(
"POLY" ) )
1278 int layer = line.at( 4 );
1281 double thickness = line.at( 5 );
1282 nlohmann::json polyData = line.at( 6 );
1284 std::vector<std::unique_ptr<PCB_SHAPE>> results =
1285 ParsePoly( aBoard, polyData,
false,
false );
1287 for(
auto& shape : results )
1289 shape->SetLayer( klayer );
1290 shape->SetWidth(
ScaleSize( thickness ) );
1295 else if( type == wxS(
"POUR" ) )
1297 int layer = line.at( 4 ).get<
int>();
1300 wxString pourname = line.at( 6 );
1301 int fillOrder = line.at( 7 ).get<
int>();
1302 nlohmann::json polyDataList = line.at( 8 );
1304 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aBoard );
1306 zone->SetNet(
getNet( aBoard, netname ) );
1307 zone->SetLayer( klayer );
1308 zone->SetAssignedPriority( 500 - fillOrder );
1312 for( nlohmann::json& polyData : polyDataList )
1317 zone->Outline()->Append( contour );
1320 wxASSERT( zone->Outline()->OutlineCount() == 1 );
1322 poursToFill.emplace( uuid, zone.get() );
1327 else if( type == wxS(
"TEARDROP" ) )
1329 wxString uuid = line.at( 1 );
1330 wxString netname = line.at( 2 );
1331 int layer = line.at( 3 ).get<
int>();
1334 nlohmann::json polyData = line.at( 4 );
1339 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aBoard );
1341 zone->SetNet(
getNet( aBoard, netname ) );
1342 zone->SetLayer( klayer );
1343 zone->Outline()->Append( contour );
1344 zone->SetFilledPolysList( klayer, contour );
1345 zone->SetNeedRefill(
false );
1346 zone->SetIsFilled(
true );
1348 zone->SetAssignedPriority( 600 );
1349 zone->SetLocalClearance( 0 );
1350 zone->SetMinThickness( 0 );
1355 else if( type == wxS(
"REGION" ) )
1357 wxString uuid = line.at( 1 );
1364 int layer = line.at( 3 ).get<
int>();
1367 std::set<int> flags = line.at( 5 );
1368 nlohmann::json polyDataList = line.at( 6 );
1370 for( nlohmann::json& polyData : polyDataList )
1375 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aBoard );
1377 zone->SetIsRuleArea(
true );
1378 zone->SetDoNotAllowFootprints( !!flags.count( 2 ) );
1379 zone->SetDoNotAllowZoneFills( !!flags.count( 7 ) || !!flags.count( 6 )
1380 || !!flags.count( 8 ) );
1381 zone->SetDoNotAllowPads( !!flags.count( 7 ) );
1382 zone->SetDoNotAllowTracks( !!flags.count( 7 ) || !!flags.count( 5 ) );
1383 zone->SetDoNotAllowVias( !!flags.count( 7 ) );
1385 zone->SetLayer( klayer );
1386 zone->Outline()->Append( contour );
1391 else if( type == wxS(
"PAD" ) )
1393 wxString netname = line.at( 3 );
1395 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>( aBoard );
1396 std::unique_ptr<PAD>
pad =
createPAD( footprint.get(), line );
1398 pad->SetNet(
getNet( aBoard, netname ) );
1407 footprint->SetPosition( pos );
1408 footprint->SetOrientation( orient );
1410 wxString fpName = wxS(
"Pad_" ) + line.at( 1 ).get<wxString>();
1413 footprint->SetFPID( fpID );
1414 footprint->Reference().SetVisible(
true );
1415 footprint->Value().SetVisible(
true );
1416 footprint->AutoPositionFields();
1420 else if( type == wxS(
"IMAGE" ) )
1422 wxString uuid = line.at( 1 );
1429 int layer = line.at( 3 ).get<
int>();
1432 VECTOR2D start( line.at( 4 ), line.at( 5 ) );
1433 VECTOR2D size( line.at( 6 ), line.at( 7 ) );
1435 double angle = line.at( 8 );
1436 int mirror = line.at( 9 );
1437 nlohmann::json polyDataList = line.at( 10 );
1440 std::vector<SHAPE_LINE_CHAIN> contours;
1441 for( nlohmann::json& polyData : polyDataList )
1446 contours.push_back( contour );
1458 for(
int i = 0; i < contour.PointCount(); i++ )
1469 std::unique_ptr<PCB_GROUP>
group;
1472 group = std::make_unique<PCB_GROUP>( aBoard );
1478 std::unique_ptr<PCB_SHAPE> shape =
1481 shape->SetFilled(
true );
1482 shape->SetPolyShape( poly );
1483 shape->SetLayer( klayer );
1484 shape->SetWidth( 0 );
1494 shape->Mirror(
ScalePos( start ), flipDirection );
1498 group->AddItem( shape.get() );
1506 else if( type == wxS(
"OBJ" ) )
1509 wxString mimeType, base64Data;
1513 if( !line.at( 3 ).is_number() )
1516 int layer = line.at( 3 ).get<
int>();
1519 start =
VECTOR2D( line.at( 5 ), line.at( 6 ) );
1520 size =
VECTOR2D( line.at( 7 ), line.at( 8 ) );
1521 angle = line.at( 9 );
1522 flipped = line.at( 10 );
1524 wxString imageUrl = line.at( 11 );
1526 if( imageUrl.BeforeFirst(
':' ) == wxS(
"blob" ) )
1528 wxString objectId = imageUrl.AfterLast(
':' );
1530 if(
auto blob =
get_opt( aBlobMap, objectId ) )
1532 wxString blobUrl = blob->url;
1534 if( blobUrl.BeforeFirst(
':' ) == wxS(
"data" ) )
1536 wxArrayString paramsArr =
1537 wxSplit( blobUrl.AfterFirst(
':' ).BeforeFirst(
',' ),
';',
'\0' );
1539 base64Data = blobUrl.AfterFirst(
',' );
1541 if( paramsArr.size() > 0 )
1542 mimeType = paramsArr[0];
1550 if( mimeType.empty() || base64Data.empty() )
1553 wxMemoryBuffer buf = wxBase64Decode( base64Data );
1555 if( mimeType == wxS(
"image/svg+xml" ) )
1561 VECTOR2D kcenter = kstart + ksize / 2;
1563 std::unique_ptr<PCB_REFERENCE_IMAGE> bitmap =
1564 std::make_unique<PCB_REFERENCE_IMAGE>( aBoard, kcenter, klayer );
1567 wxImage::SetDefaultLoadFlags( wxImage::GetDefaultLoadFlags()
1568 & ~wxImage::Load_Verbose );
1580 int x = bitmap->GetPosition().x;
1591 else if( type == wxS(
"STRING" ) )
1593 wxString uuid = line.at( 1 );
1600 int layer = line.at( 3 ).get<
int>();
1604 wxString
string = line.at( 6 );
1605 wxString font = line.at( 7 );
1607 double height = line.at( 8 );
1608 double strokew = line.at( 9 );
1610 int align = line.at( 12 );
1611 double angle = line.at( 13 );
1612 int inverted = line.at( 14 );
1613 int mirror = line.at( 16 );
1617 text->SetText(
string );
1618 text->SetLayer( klayer );
1620 text->SetIsKnockout( inverted );
1624 if( font != wxS(
"default" ) )
1637 text->SetMirrored(
true );
1638 text->SetTextAngleDegrees( -angle );
1642 text->SetTextAngleDegrees( angle );
1647 else if( type == wxS(
"COMPONENT" ) )
1649 wxString compId = line.at( 1 );
1650 componentLines[compId].push_back( line );
1652 else if( type == wxS(
"ATTR" ) )
1654 wxString compId = line.at( 3 );
1655 componentLines[compId].push_back( line );
1657 else if( type == wxS(
"PAD_NET" ) )
1659 wxString compId = line.at( 1 );
1660 componentLines[compId].push_back( line );
1664 for(
auto const& [compId, lines] : componentLines )
1667 wxString fpIdOverride;
1668 wxString fpDesignator;
1669 std::map<wxString, wxString> localCompAttribs;
1671 for(
auto& line : lines )
1673 if( line.size() == 0 )
1676 wxString type = line.at( 0 );
1678 if( type == wxS(
"COMPONENT" ) )
1680 localCompAttribs = line.at( 7 );
1682 else if( type == wxS(
"ATTR" ) )
1686 if( attr.
key == wxS(
"Device" ) )
1687 deviceId = attr.
value;
1689 else if( attr.
key == wxS(
"Footprint" ) )
1690 fpIdOverride = attr.
value;
1692 else if( attr.
key == wxS(
"Designator" ) )
1693 fpDesignator = attr.
value;
1697 if( deviceId.empty() )
1700 nlohmann::json compAttrs = aProject.at(
"devices" ).at( deviceId ).at(
"attributes" );
1704 if( !fpIdOverride.IsEmpty() )
1705 fpId = fpIdOverride;
1707 fpId = compAttrs.at(
"Footprint" ).get<wxString>();
1709 auto it = aFootprintMap.find( fpId );
1710 if( it == aFootprintMap.end() )
1712 wxLogError(
"Footprint of '%s' with uuid '%s' not found.", fpDesignator, fpId );
1716 std::unique_ptr<FOOTPRINT>& footprintOrig = it->second;
1717 std::unique_ptr<FOOTPRINT> footprint(
static_cast<FOOTPRINT*
>( footprintOrig->Clone() ) );
1719 wxString modelUuid, modelTitle, modelTransform;
1721 if(
auto val =
get_opt( localCompAttribs,
"3D Model" ) )
1724 modelUuid = compAttrs.value<wxString>(
"3D Model",
"" );
1726 if(
auto val =
get_opt( localCompAttribs,
"3D Model Title" ) )
1727 modelTitle = val->Trim();
1729 modelTitle = compAttrs.value<wxString>(
"3D Model Title", modelUuid ).Trim();
1731 if(
auto val =
get_opt( localCompAttribs,
"3D Model Transform" ) )
1732 modelTransform = *val;
1734 modelTransform = compAttrs.value<wxString>(
"3D Model Transform",
"" );
1738 footprint->SetParent( aBoard );
1740 for(
auto& line : lines )
1742 if( line.size() == 0 )
1745 wxString type = line.at( 0 );
1747 if( type == wxS(
"COMPONENT" ) )
1749 int layer = line.at( 3 );
1754 double orient = line.at( 6 );
1757 if( klayer ==
B_Cu )
1760 footprint->SetOrientationDegrees( orient );
1763 else if( type == wxS(
"ATTR" ) )
1771 if( attr.
key == wxS(
"Designator" ) )
1773 if( attr.
key == wxS(
"Designator" ) )
1783 if( attr.
fontName != wxS(
"default" ) )
1812 else if( type == wxS(
"PAD_NET" ) )
1814 wxString padNumber = line.at( 2 );
1815 wxString padNet = line.at( 3 );
1817 PAD*
pad = footprint->FindPadByNumber( padNumber );
1820 pad->SetNet(
getNet( aBoard, padNet ) );
1835 for(
auto& [uuid, zone] : poursToFill )
1840 auto range = boardPouredMap.equal_range( uuid );
1841 for(
auto& it = range.first; it != range.second; ++it )
1847 for(
int dataId = 0; dataId < (int) poured.
polyData.size(); dataId++ )
1849 const nlohmann::json& fillData = poured.
polyData[dataId];
1850 const double ptScale = 10;
1855 for(
int i = 0; i < contour.
PointCount(); i++ )
1868 thisPoly.
Append( simple );
1877 const int thermalWidth =
pcbIUScale.mmToIU( 0.2 );
1879 for(
int segId = 0; segId < contour.
SegmentCount(); segId++ )
1889 fillPolySet.
Append( thisPoly );
1896 const int strokeWidth =
pcbIUScale.MilsToIU( 8 );
1905 zone->SetFilledPolysList( zone->GetFirstLayer(), fillPolySet );
1906 zone->SetNeedRefill(
false );
1907 zone->SetIsFilled(
true );
1913 std::vector<PCB_SHAPE*> shapes;
1921 shapes.push_back(
static_cast<PCB_SHAPE*
>( item ) );
1936 offset.
x =
KiROUND( offset.
x / alignGrid ) * alignGrid;
1937 offset.
y =
KiROUND( offset.
y / alignGrid ) * alignGrid;
1939 aBoard->
Move( offset );