266 bool aClosed,
bool aInFill )
const
268 std::vector<std::unique_ptr<PCB_SHAPE>> results;
271 for(
int i = 0; i < (int) polyData.size(); i++ )
273 nlohmann::json val = polyData.at( i );
275 if( val.is_string() )
278 if( str == wxS(
"CIRCLE" ) )
281 center.x = ( polyData.at( ++i ) );
282 center.y = ( polyData.at( ++i ) );
283 double r = ( polyData.at( ++i ) );
285 std::unique_ptr<PCB_SHAPE> shape =
290 shape->SetFilled( aClosed );
292 results.emplace_back( std::move( shape ) );
294 else if( str == wxS(
"R" ) )
297 start.
x = ( polyData.at( ++i ) );
298 start.
y = ( polyData.at( ++i ) );
299 size.
x = ( polyData.at( ++i ) );
300 size.
y = -( polyData.at( ++i ).get<double>() );
301 double angle = polyData.at( ++i );
302 double cr = ( i + 1 ) < (
int) polyData.size() ? polyData.at( ++i ).get<
double>() : 0;
306 std::unique_ptr<PCB_SHAPE> shape =
309 shape->SetStart(
ScalePos( start ) );
310 shape->SetEnd(
ScalePos( start + size ) );
311 shape->SetFilled( aClosed );
314 results.emplace_back( std::move( shape ) );
322 std::unique_ptr<PCB_SHAPE> shape =
325 shape->SetStart(
ScalePos( aStart ) );
327 shape->SetFilled( aClosed );
330 results.emplace_back( std::move( shape ) );
335 std::unique_ptr<PCB_SHAPE> shape =
336 std::make_unique<PCB_SHAPE>( aContainer,
SHAPE_T::ARC );
338 shape->SetStart(
ScalePos( aStart ) );
341 shape->SetFilled( aClosed );
344 results.emplace_back( std::move( shape ) );
352 addArc( {
end.x - cr, start.
y }, {
end.x, start.
y - cr },
353 {
end.x - cr, start.
y - cr } );
356 {
end.x - cr,
end.y + cr } );
358 addArc( { start.
x + cr,
end.y }, { start.
x,
end.y + cr },
359 { start.
x + cr,
end.y + cr } );
361 addArc( { start.
x, start.
y - cr }, { start.
x + cr, start.
y },
362 { start.
x + cr, start.
y - cr } );
365 else if( str == wxS(
"ARC" ) || str == wxS(
"CARC" ) )
368 double angle = polyData.at( ++i ).get<
double>() / ( aInFill ? 10 : 1 );
369 end.x = ( polyData.at( ++i ) );
370 end.y = ( polyData.at( ++i ) );
372 std::unique_ptr<PCB_SHAPE> shape =
373 std::make_unique<PCB_SHAPE>( aContainer,
SHAPE_T::ARC );
377 shape->SetStart(
ScalePos( prevPt ) );
383 shape->SetEnd(
ScalePos( prevPt ) );
389 double ha = angle / 2;
390 double hd =
delta.EuclideanNorm() / 2;
391 double cdist = hd / tan(
DEG2RAD( ha ) );
395 shape->SetFilled( aClosed );
397 results.emplace_back( std::move( shape ) );
401 else if( str == wxS(
"L" ) )
406 while( i < (
int) polyData.size() - 2 && polyData.at( i + 1 ).is_number() )
409 pt.
x = ( polyData.at( ++i ) );
410 pt.
y = ( polyData.at( ++i ) );
419 std::unique_ptr<PCB_SHAPE> shape =
422 wxASSERT(
chain.PointCount() > 2 );
424 if(
chain.PointCount() > 2 )
426 chain.SetClosed(
true );
427 shape->SetFilled(
true );
428 shape->SetPolyShape(
chain );
430 results.emplace_back( std::move( shape ) );
435 for(
int s = 0; s <
chain.SegmentCount(); s++ )
439 std::unique_ptr<PCB_SHAPE> shape =
442 shape->SetStart( seg.
A );
443 shape->SetEnd( seg.
B );
445 results.emplace_back( std::move( shape ) );
450 else if( val.is_number() )
452 prevPt.
x = ( polyData.at( i ) );
453 prevPt.
y = ( polyData.at( ++i ) );
761 const wxString& aFpUuid,
762 const std::vector<nlohmann::json>& aLines )
764 std::unique_ptr<FOOTPRINT> footprintPtr = std::make_unique<FOOTPRINT>(
m_board );
765 FOOTPRINT* footprint = footprintPtr.get();
768 const int defaultTextThickness(
pcbIUScale.mmToIU( 0.15 ) );
772 field->SetTextSize( defaultTextSize );
773 field->SetTextThickness( defaultTextThickness );
776 for(
const nlohmann::json& line : aLines )
778 if( line.size() == 0 )
781 wxString type = line.at( 0 );
783 if( type == wxS(
"POLY" ) || type == wxS(
"PAD" ) || type == wxS(
"FILL" )
784 || type == wxS(
"ATTR" ) )
786 wxString uuid = line.at( 1 );
793 wxString netname = line.at( 3 );
794 int layer = line.at( 4 ).get<
int>();
797 if( type == wxS(
"POLY" ) )
799 double thickness = ( line.at( 5 ) );
800 nlohmann::json polyData = line.at( 6 );
802 std::vector<std::unique_ptr<PCB_SHAPE>> results =
803 ParsePoly( footprint, polyData,
false,
false );
805 for(
auto& shape : results )
807 shape->SetLayer( klayer );
808 shape->SetWidth(
ScaleSize( thickness ) );
813 else if( type == wxS(
"PAD" ) )
815 std::unique_ptr<PAD>
pad =
createPAD( footprint, line );
819 else if( type == wxS(
"FILL" ) )
821 int fillLayer = line.at( 4 ).get<
int>();
824 nlohmann::json polyDataList = line.at( 7 );
826 if( !polyDataList.is_null() && !polyDataList.empty() )
828 if( !polyDataList.at( 0 ).is_array() )
829 polyDataList = nlohmann::json::array( { polyDataList } );
831 std::vector<SHAPE_LINE_CHAIN> contours;
832 for( nlohmann::json& polyData : polyDataList )
837 contours.push_back( contour );
847 std::unique_ptr<PCB_GROUP>
group;
850 group = std::make_unique<PCB_GROUP>( footprint );
854 std::unique_ptr<PCB_SHAPE> shape =
857 shape->SetFilled(
true );
858 shape->SetPolyShape( poly );
859 shape->SetLayer( fillKlayer );
860 shape->SetWidth( 0 );
863 group->AddItem( shape.get() );
872 else if( type == wxS(
"ATTR" ) )
876 if( attr.
key == wxS(
"Designator" ) )
880 else if( type == wxS(
"REGION" ) )
882 wxString uuid = line.at( 1 );
889 int layer = line.at( 3 ).get<
int>();
892 std::set<int> flags = line.at( 5 );
893 nlohmann::json polyDataList = line.at( 6 );
895 for( nlohmann::json& polyData : polyDataList )
899 std::vector<std::unique_ptr<PCB_SHAPE>> results =
900 ParsePoly(
nullptr, polyData,
true,
false );
902 for(
auto& shape : results )
904 shape->SetFilled(
true );
911 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( footprint );
913 zone->SetIsRuleArea(
true );
914 zone->SetDoNotAllowFootprints( !!flags.count( 2 ) );
915 zone->SetDoNotAllowZoneFills( !!flags.count( 7 ) || !!flags.count( 6 )
916 || !!flags.count( 8 ) );
917 zone->SetDoNotAllowPads( !!flags.count( 7 ) );
918 zone->SetDoNotAllowTracks( !!flags.count( 7 ) || !!flags.count( 5 ) );
919 zone->SetDoNotAllowVias( !!flags.count( 7 ) );
921 zone->SetLayer( klayer );
922 zone->Outline()->Append( polySet );
929 if( aProject.is_object() && aProject.contains(
"devices" ) )
931 std::map<wxString, EASYEDAPRO::PRJ_DEVICE> devicesMap = aProject.at(
"devices" );
932 std::map<wxString, wxString> compAttrs;
934 for(
auto& [devUuid, devData] : devicesMap )
936 if(
auto fp =
get_opt( devData.attributes,
"Footprint" ) )
940 compAttrs = devData.attributes;
946 wxString modelUuid, modelTitle, modelTransform;
948 modelUuid =
get_def( compAttrs,
"3D Model",
"" );
949 modelTitle =
get_def( compAttrs,
"3D Model Title", modelUuid );
950 modelTransform =
get_def( compAttrs,
"3D Model Transform",
"" );
956 std::vector<PCB_SHAPE*> edgeShapes;
961 edgeShapes.push_back(
static_cast<PCB_SHAPE*
>( item ) );
972 std::unique_ptr<PCB_SHAPE> shape =
978 shape->SetEnd( bbox.
GetEnd() );
983 bool hasFabRef =
false;
989 if(
static_cast<PCB_TEXT*
>( item )->GetText() == wxT(
"${REFERENCE}" ) )
1000 int c_refTextSize =
pcbIUScale.mmToIU( 0.5 );
1001 int c_refTextThickness =
pcbIUScale.mmToIU( 0.1 );
1002 std::unique_ptr<PCB_TEXT> refText = std::make_unique<PCB_TEXT>( footprint );
1004 refText->SetLayer(
F_Fab );
1005 refText->SetTextSize(
VECTOR2I( c_refTextSize, c_refTextSize ) );
1006 refText->SetTextThickness( c_refTextThickness );
1007 refText->SetText( wxT(
"${REFERENCE}" ) );
1012 return footprintPtr.release();
1017 BOARD* aBoard,
const nlohmann::json& aProject,
1018 std::map<wxString, std::unique_ptr<FOOTPRINT>>& aFootprintMap,
1019 const std::map<wxString, EASYEDAPRO::BLOB>& aBlobMap,
1020 const std::multimap<wxString, EASYEDAPRO::POURED>& aPouredMap,
1021 const std::vector<nlohmann::json>& aLines,
const wxString& aFpLibName )
1023 std::map<wxString, std::vector<nlohmann::json>> componentLines;
1024 std::map<wxString, std::vector<nlohmann::json>> ruleLines;
1026 std::multimap<wxString, EASYEDAPRO::POURED> boardPouredMap = aPouredMap;
1027 std::map<wxString, ZONE*> poursToFill;
1031 for(
const nlohmann::json& line : aLines )
1033 if( line.size() == 0 )
1036 wxString type = line.at( 0 );
1038 if( type == wxS(
"LAYER" ) )
1040 int layer = line.at( 1 );
1043 wxString layerType = line.at( 2 );
1044 wxString layerName = line.at( 3 );
1045 int layerFlag = line.at( 4 );
1047 if( layerFlag != 0 )
1050 blayers.
set( klayer );
1055 else if( type == wxS(
"NET" ) )
1057 wxString netname = line.at( 1 );
1062 else if( type == wxS(
"RULE" ) )
1064 wxString ruleType = line.at( 1 );
1065 wxString ruleName = line.at( 2 );
1066 int isDefault = line.at( 3 );
1067 nlohmann::json ruleData = line.at( 4 );
1069 if( ruleType == wxS(
"3" ) && isDefault )
1071 wxString units = ruleData.at( 0 );
1073 if( ruleData.at( 1 ).is_number() )
1076 double minVal = ruleData.at( 1 );
1085 nlohmann::json
table = ruleData.at( 1 );
1087 for(
auto& [key, arr] :
table.items() )
1089 double minVal = arr.at( 0 );
1097 else if( ruleType == wxS(
"1" ) && isDefault )
1099 wxString units = ruleData.at( 0 );
1100 nlohmann::json
table = ruleData.at( 1 );
1101 int minVal = INT_MAX;
1106 for(
const auto& arr :
table )
1108 for(
int val : arr )
1110 if( val != 0 && val < minVal )
1115 else if(
table.is_object() )
1119 for(
auto& [key, arr] :
table.items() )
1121 for(
const auto& subarr : arr )
1123 for(
int val : subarr )
1125 if( val != 0 && val < minVal )
1135 ruleLines[ruleType].push_back( line );
1137 else if( type == wxS(
"POURED" ) )
1139 if( !line.at( 2 ).is_string() )
1143 boardPouredMap.emplace( poured.
parentId, poured );
1145 else if( type == wxS(
"VIA" ) || type == wxS(
"LINE" ) || type == wxS(
"ARC" )
1146 || type == wxS(
"POLY" ) || type == wxS(
"FILL" ) || type == wxS(
"POUR" ) )
1148 wxString uuid = line.at( 1 );
1155 wxString netname = line.at( 3 );
1157 if( type == wxS(
"VIA" ) )
1163 double drill = line.at( 7 );
1164 double dia = line.at( 8 );
1166 std::unique_ptr<PCB_VIA>
via = std::make_unique<PCB_VIA>( aBoard );
1172 via->SetNet(
getNet( aBoard, netname ) );
1176 else if( type == wxS(
"LINE" ) )
1178 int layer = line.at( 4 ).get<
int>();
1182 start.
x = line.at( 5 );
1183 start.
y = line.at( 6 );
1186 end.x = line.at( 7 );
1187 end.y = line.at( 8 );
1189 double width = line.at( 9 );
1191 std::unique_ptr<PCB_TRACK> track = std::make_unique<PCB_TRACK>( aBoard );
1193 track->SetLayer( klayer );
1194 track->SetStart(
ScalePos( start ) );
1198 track->SetNet(
getNet( aBoard, netname ) );
1202 else if( type == wxS(
"ARC" ) )
1204 int layer = line.at( 4 ).get<
int>();
1208 start.
x = line.at( 5 );
1209 start.
y = line.at( 6 );
1212 end.x = line.at( 7 );
1213 end.y = line.at( 8 );
1215 double angle = line.at( 9 );
1216 double width = line.at( 10 );
1221 double ha = angle / 2;
1222 double hd =
delta.EuclideanNorm() / 2;
1223 double cdist = hd / tan(
DEG2RAD( ha ) );
1230 std::unique_ptr<PCB_ARC> arc = std::make_unique<PCB_ARC>( aBoard, &sarc );
1233 arc->SetLayer( klayer );
1234 arc->SetNet(
getNet( aBoard, netname ) );
1238 else if( type == wxS(
"FILL" ) )
1240 int layer = line.at( 4 ).get<
int>();
1243 nlohmann::json polyDataList = line.at( 7 );
1245 if( !polyDataList.at( 0 ).is_array() )
1246 polyDataList = nlohmann::json::array( { polyDataList } );
1248 std::vector<SHAPE_LINE_CHAIN> contours;
1249 for( nlohmann::json& polyData : polyDataList )
1254 contours.push_back( contour );
1265 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aBoard );
1267 zone->SetNet(
getNet( aBoard, netname ) );
1268 zone->SetLayer( klayer );
1270 zone->SetFilledPolysList( klayer, zoneFillPoly );
1271 zone->SetAssignedPriority( 500 );
1272 zone->SetIsFilled(
true );
1273 zone->SetNeedRefill(
false );
1280 else if( type == wxS(
"POLY" ) )
1282 int layer = line.at( 4 );
1285 double thickness = line.at( 5 );
1286 nlohmann::json polyData = line.at( 6 );
1288 std::vector<std::unique_ptr<PCB_SHAPE>> results =
1289 ParsePoly( aBoard, polyData,
false,
false );
1291 for(
auto& shape : results )
1293 shape->SetLayer( klayer );
1294 shape->SetWidth(
ScaleSize( thickness ) );
1299 else if( type == wxS(
"POUR" ) )
1301 int layer = line.at( 4 ).get<
int>();
1304 wxString pourname = line.at( 6 );
1305 int fillOrder = line.at( 7 ).get<
int>();
1306 nlohmann::json polyDataList = line.at( 8 );
1308 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aBoard );
1310 zone->SetNet(
getNet( aBoard, netname ) );
1311 zone->SetLayer( klayer );
1312 zone->SetAssignedPriority( 500 - fillOrder );
1316 for( nlohmann::json& polyData : polyDataList )
1321 zone->Outline()->Append( contour );
1324 wxASSERT( zone->Outline()->OutlineCount() == 1 );
1326 poursToFill.emplace( uuid, zone.get() );
1331 else if( type == wxS(
"TEARDROP" ) )
1333 wxString uuid = line.at( 1 );
1334 wxString netname = line.at( 2 );
1335 int layer = line.at( 3 ).get<
int>();
1338 nlohmann::json polyData = line.at( 4 );
1343 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aBoard );
1345 zone->SetNet(
getNet( aBoard, netname ) );
1346 zone->SetLayer( klayer );
1347 zone->Outline()->Append( contour );
1348 zone->SetFilledPolysList( klayer, contour );
1349 zone->SetNeedRefill(
false );
1350 zone->SetIsFilled(
true );
1352 zone->SetAssignedPriority( 600 );
1353 zone->SetLocalClearance( 0 );
1354 zone->SetMinThickness( 0 );
1359 else if( type == wxS(
"REGION" ) )
1361 wxString uuid = line.at( 1 );
1368 int layer = line.at( 3 ).get<
int>();
1371 std::set<int> flags = line.at( 5 );
1372 nlohmann::json polyDataList = line.at( 6 );
1374 for( nlohmann::json& polyData : polyDataList )
1379 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aBoard );
1381 zone->SetIsRuleArea(
true );
1382 zone->SetDoNotAllowFootprints( !!flags.count( 2 ) );
1383 zone->SetDoNotAllowZoneFills( !!flags.count( 7 ) || !!flags.count( 6 )
1384 || !!flags.count( 8 ) );
1385 zone->SetDoNotAllowPads( !!flags.count( 7 ) );
1386 zone->SetDoNotAllowTracks( !!flags.count( 7 ) || !!flags.count( 5 ) );
1387 zone->SetDoNotAllowVias( !!flags.count( 7 ) );
1389 zone->SetLayer( klayer );
1390 zone->Outline()->Append( contour );
1395 else if( type == wxS(
"PAD" ) )
1397 wxString netname = line.at( 3 );
1399 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>( aBoard );
1400 std::unique_ptr<PAD>
pad =
createPAD( footprint.get(), line );
1402 pad->SetNet(
getNet( aBoard, netname ) );
1411 footprint->SetPosition( pos );
1412 footprint->SetOrientation( orient );
1414 wxString fpName = wxS(
"Pad_" ) + line.at( 1 ).get<wxString>();
1417 footprint->SetFPID( fpID );
1418 footprint->Reference().SetVisible(
true );
1419 footprint->Value().SetVisible(
true );
1420 footprint->AutoPositionFields();
1424 else if( type == wxS(
"IMAGE" ) )
1426 wxString uuid = line.at( 1 );
1433 int layer = line.at( 3 ).get<
int>();
1436 VECTOR2D start( line.at( 4 ), line.at( 5 ) );
1437 VECTOR2D size( line.at( 6 ), line.at( 7 ) );
1439 double angle = line.at( 8 );
1440 int mirror = line.at( 9 );
1441 nlohmann::json polyDataList = line.at( 10 );
1444 std::vector<SHAPE_LINE_CHAIN> contours;
1445 for( nlohmann::json& polyData : polyDataList )
1450 contours.push_back( contour );
1462 for(
int i = 0; i < contour.PointCount(); i++ )
1473 std::unique_ptr<PCB_GROUP>
group;
1476 group = std::make_unique<PCB_GROUP>( aBoard );
1482 std::unique_ptr<PCB_SHAPE> shape =
1485 shape->SetFilled(
true );
1486 shape->SetPolyShape( poly );
1487 shape->SetLayer( klayer );
1488 shape->SetWidth( 0 );
1498 shape->Mirror(
ScalePos( start ), flipDirection );
1502 group->AddItem( shape.get() );
1510 else if( type == wxS(
"OBJ" ) )
1513 wxString mimeType, base64Data;
1517 if( !line.at( 3 ).is_number() )
1520 int layer = line.at( 3 ).get<
int>();
1523 start =
VECTOR2D( line.at( 5 ), line.at( 6 ) );
1524 size =
VECTOR2D( line.at( 7 ), line.at( 8 ) );
1525 angle = line.at( 9 );
1526 flipped = line.at( 10 );
1528 wxString imageUrl = line.at( 11 );
1530 if( imageUrl.BeforeFirst(
':' ) == wxS(
"blob" ) )
1532 wxString objectId = imageUrl.AfterLast(
':' );
1534 if(
auto blob =
get_opt( aBlobMap, objectId ) )
1536 wxString blobUrl = blob->url;
1538 if( blobUrl.BeforeFirst(
':' ) == wxS(
"data" ) )
1540 wxArrayString paramsArr =
1541 wxSplit( blobUrl.AfterFirst(
':' ).BeforeFirst(
',' ),
';',
'\0' );
1543 base64Data = blobUrl.AfterFirst(
',' );
1545 if( paramsArr.size() > 0 )
1546 mimeType = paramsArr[0];
1554 if( mimeType.empty() || base64Data.empty() )
1557 wxMemoryBuffer buf = wxBase64Decode( base64Data );
1559 if( mimeType == wxS(
"image/svg+xml" ) )
1565 VECTOR2D kcenter = kstart + ksize / 2;
1567 std::unique_ptr<PCB_REFERENCE_IMAGE> bitmap =
1568 std::make_unique<PCB_REFERENCE_IMAGE>( aBoard, kcenter, klayer );
1571 wxImage::SetDefaultLoadFlags( wxImage::GetDefaultLoadFlags()
1572 & ~wxImage::Load_Verbose );
1584 int x = bitmap->GetPosition().x;
1595 else if( type == wxS(
"STRING" ) )
1597 wxString uuid = line.at( 1 );
1604 int layer = line.at( 3 ).get<
int>();
1608 wxString
string = line.at( 6 );
1609 wxString font = line.at( 7 );
1611 double height = line.at( 8 );
1612 double strokew = line.at( 9 );
1614 int align = line.at( 12 );
1615 double angle = line.at( 13 );
1616 int inverted = line.at( 14 );
1617 int mirror = line.at( 16 );
1621 text->SetText(
string );
1622 text->SetLayer( klayer );
1624 text->SetIsKnockout( inverted );
1628 if( font != wxS(
"default" ) )
1641 text->SetMirrored(
true );
1642 text->SetTextAngleDegrees( -angle );
1646 text->SetTextAngleDegrees( angle );
1651 else if( type == wxS(
"COMPONENT" ) )
1653 wxString compId = line.at( 1 );
1654 componentLines[compId].push_back( line );
1656 else if( type == wxS(
"ATTR" ) )
1658 wxString compId = line.at( 3 );
1659 componentLines[compId].push_back( line );
1661 else if( type == wxS(
"PAD_NET" ) )
1663 wxString compId = line.at( 1 );
1664 componentLines[compId].push_back( line );
1668 for(
auto const& [compId, lines] : componentLines )
1671 wxString fpIdOverride;
1672 wxString fpDesignator;
1673 std::map<wxString, wxString> localCompAttribs;
1675 for(
auto& line : lines )
1677 if( line.size() == 0 )
1680 wxString type = line.at( 0 );
1682 if( type == wxS(
"COMPONENT" ) )
1684 localCompAttribs = line.at( 7 );
1686 else if( type == wxS(
"ATTR" ) )
1690 if( attr.
key == wxS(
"Device" ) )
1691 deviceId = attr.
value;
1693 else if( attr.
key == wxS(
"Footprint" ) )
1694 fpIdOverride = attr.
value;
1696 else if( attr.
key == wxS(
"Designator" ) )
1697 fpDesignator = attr.
value;
1701 if( deviceId.empty() )
1704 nlohmann::json compAttrs = aProject.at(
"devices" ).at( deviceId ).at(
"attributes" );
1708 if( !fpIdOverride.IsEmpty() )
1709 fpId = fpIdOverride;
1711 fpId = compAttrs.at(
"Footprint" ).get<wxString>();
1713 auto it = aFootprintMap.find( fpId );
1714 if( it == aFootprintMap.end() )
1716 wxLogError(
"Footprint of '%s' with uuid '%s' not found.", fpDesignator, fpId );
1720 std::unique_ptr<FOOTPRINT>& footprintOrig = it->second;
1721 std::unique_ptr<FOOTPRINT> footprint(
static_cast<FOOTPRINT*
>( footprintOrig->Clone() ) );
1723 wxString modelUuid, modelTitle, modelTransform;
1725 if(
auto val =
get_opt( localCompAttribs,
"3D Model" ) )
1728 modelUuid = compAttrs.value<wxString>(
"3D Model",
"" );
1730 if(
auto val =
get_opt( localCompAttribs,
"3D Model Title" ) )
1731 modelTitle = val->Trim();
1733 modelTitle = compAttrs.value<wxString>(
"3D Model Title", modelUuid ).Trim();
1735 if(
auto val =
get_opt( localCompAttribs,
"3D Model Transform" ) )
1736 modelTransform = *val;
1738 modelTransform = compAttrs.value<wxString>(
"3D Model Transform",
"" );
1742 footprint->SetParent( aBoard );
1744 for(
auto& line : lines )
1746 if( line.size() == 0 )
1749 wxString type = line.at( 0 );
1751 if( type == wxS(
"COMPONENT" ) )
1753 int layer = line.at( 3 );
1758 double orient = line.at( 6 );
1761 if( klayer ==
B_Cu )
1764 footprint->SetOrientationDegrees( orient );
1767 else if( type == wxS(
"ATTR" ) )
1775 if( attr.
key == wxS(
"Designator" ) )
1777 if( attr.
key == wxS(
"Designator" ) )
1787 if( attr.
fontName != wxS(
"default" ) )
1816 else if( type == wxS(
"PAD_NET" ) )
1818 wxString padNumber = line.at( 2 );
1819 wxString padNet = line.at( 3 );
1821 PAD*
pad = footprint->FindPadByNumber( padNumber );
1824 pad->SetNet(
getNet( aBoard, padNet ) );
1839 for(
auto& [uuid, zone] : poursToFill )
1844 auto range = boardPouredMap.equal_range( uuid );
1845 for(
auto& it = range.first; it != range.second; ++it )
1851 for(
int dataId = 0; dataId < (int) poured.
polyData.size(); dataId++ )
1853 const nlohmann::json& fillData = poured.
polyData[dataId];
1854 const double ptScale = 10;
1859 for(
int i = 0; i < contour.
PointCount(); i++ )
1872 thisPoly.
Append( simple );
1881 const int thermalWidth =
pcbIUScale.mmToIU( 0.2 );
1883 for(
int segId = 0; segId < contour.
SegmentCount(); segId++ )
1893 fillPolySet.
Append( thisPoly );
1900 const int strokeWidth =
pcbIUScale.MilsToIU( 8 );
1909 zone->SetFilledPolysList( zone->GetFirstLayer(), fillPolySet );
1910 zone->SetNeedRefill(
false );
1911 zone->SetIsFilled(
true );
1917 std::vector<PCB_SHAPE*> shapes;
1925 shapes.push_back(
static_cast<PCB_SHAPE*
>( item ) );
1940 offset.
x =
KiROUND( offset.
x / alignGrid ) * alignGrid;
1941 offset.
y =
KiROUND( offset.
y / alignGrid ) * alignGrid;
1943 aBoard->
Move( offset );