263 bool aClosed,
bool aInFill )
const
265 std::vector<std::unique_ptr<PCB_SHAPE>> results;
268 for(
int i = 0; i < (int) polyData.size(); i++ )
270 nlohmann::json val = polyData.at( i );
272 if( val.is_string() )
275 if( str == wxS(
"CIRCLE" ) )
278 center.x = ( polyData.at( ++i ) );
279 center.y = ( polyData.at( ++i ) );
280 double r = ( polyData.at( ++i ) );
282 std::unique_ptr<PCB_SHAPE> shape =
287 shape->SetFilled( aClosed );
289 results.emplace_back( std::move( shape ) );
291 else if( str == wxS(
"R" ) )
294 start.
x = ( polyData.at( ++i ) );
295 start.
y = ( polyData.at( ++i ) );
296 size.
x = ( polyData.at( ++i ) );
297 size.
y = -( polyData.at( ++i ).get<double>() );
298 double angle = polyData.at( ++i );
299 double cr = ( i + 1 ) < (
int) polyData.size() ? polyData.at( ++i ).get<
double>() : 0;
303 std::unique_ptr<PCB_SHAPE> shape =
306 shape->SetStart(
ScalePos( start ) );
307 shape->SetEnd(
ScalePos( start + size ) );
308 shape->SetFilled( aClosed );
311 results.emplace_back( std::move( shape ) );
319 std::unique_ptr<PCB_SHAPE> shape =
322 shape->SetStart(
ScalePos( aStart ) );
324 shape->SetFilled( aClosed );
327 results.emplace_back( std::move( shape ) );
332 std::unique_ptr<PCB_SHAPE> shape =
333 std::make_unique<PCB_SHAPE>( aContainer,
SHAPE_T::ARC );
335 shape->SetStart(
ScalePos( aStart ) );
338 shape->SetFilled( aClosed );
341 results.emplace_back( std::move( shape ) );
349 addArc( {
end.x - cr, start.
y }, {
end.x, start.
y - cr },
350 {
end.x - cr, start.
y - cr } );
353 {
end.x - cr,
end.y + cr } );
355 addArc( { start.
x + cr,
end.y }, { start.
x,
end.y + cr },
356 { start.
x + cr,
end.y + cr } );
358 addArc( { start.
x, start.
y - cr }, { start.
x + cr, start.
y },
359 { start.
x + cr, start.
y - cr } );
362 else if( str == wxS(
"ARC" ) || str == wxS(
"CARC" ) )
365 double angle = polyData.at( ++i ).get<
double>() / ( aInFill ? 10 : 1 );
366 end.x = ( polyData.at( ++i ) );
367 end.y = ( polyData.at( ++i ) );
369 std::unique_ptr<PCB_SHAPE> shape =
370 std::make_unique<PCB_SHAPE>( aContainer,
SHAPE_T::ARC );
374 shape->SetStart(
ScalePos( prevPt ) );
380 shape->SetEnd(
ScalePos( prevPt ) );
386 double ha = angle / 2;
387 double hd =
delta.EuclideanNorm() / 2;
388 double cdist = hd / tan(
DEG2RAD( ha ) );
392 shape->SetFilled( aClosed );
394 results.emplace_back( std::move( shape ) );
398 else if( str == wxS(
"L" ) )
403 while( i < (
int) polyData.size() - 2 && polyData.at( i + 1 ).is_number() )
406 pt.
x = ( polyData.at( ++i ) );
407 pt.
y = ( polyData.at( ++i ) );
416 if(
chain.PointCount() > 2 )
418 std::unique_ptr<PCB_SHAPE> shape =
421 chain.SetClosed(
true );
422 shape->SetFilled(
true );
423 shape->SetPolyShape(
chain );
425 results.emplace_back( std::move( shape ) );
430 for(
int s = 0; s <
chain.SegmentCount(); s++ )
434 std::unique_ptr<PCB_SHAPE> shape =
437 shape->SetStart( seg.
A );
438 shape->SetEnd( seg.
B );
440 results.emplace_back( std::move( shape ) );
445 else if( val.is_number() )
447 prevPt.
x = ( polyData.at( i ) );
448 prevPt.
y = ( polyData.at( ++i ) );
756 const wxString& aFpUuid,
757 const std::vector<nlohmann::json>& aLines )
759 std::unique_ptr<FOOTPRINT> footprintPtr = std::make_unique<FOOTPRINT>(
m_board );
760 FOOTPRINT* footprint = footprintPtr.get();
763 const int defaultTextThickness(
pcbIUScale.mmToIU( 0.15 ) );
767 field->SetTextSize( defaultTextSize );
768 field->SetTextThickness( defaultTextThickness );
771 for(
const nlohmann::json& line : aLines )
773 if( line.size() == 0 )
776 wxString type = line.at( 0 );
778 if( type == wxS(
"POLY" ) || type == wxS(
"PAD" ) || type == wxS(
"FILL" )
779 || type == wxS(
"ATTR" ) )
781 wxString uuid = line.at( 1 );
788 wxString netname = line.at( 3 );
789 int layer = line.at( 4 ).get<
int>();
792 if( type == wxS(
"POLY" ) )
794 double thickness = ( line.at( 5 ) );
795 nlohmann::json polyData = line.at( 6 );
797 std::vector<std::unique_ptr<PCB_SHAPE>> results =
798 ParsePoly( footprint, polyData,
false,
false );
800 for(
auto& shape : results )
802 shape->SetLayer( klayer );
803 shape->SetWidth(
ScaleSize( thickness ) );
808 else if( type == wxS(
"PAD" ) )
810 std::unique_ptr<PAD>
pad =
createPAD( footprint, line );
814 else if( type == wxS(
"FILL" ) )
816 int fillLayer = line.at( 4 ).get<
int>();
819 nlohmann::json polyDataList = line.at( 7 );
821 if( !polyDataList.is_null() && !polyDataList.empty() )
823 if( !polyDataList.at( 0 ).is_array() )
824 polyDataList = nlohmann::json::array( { polyDataList } );
826 std::vector<SHAPE_LINE_CHAIN> contours;
827 for( nlohmann::json& polyData : polyDataList )
832 contours.push_back( contour );
842 std::unique_ptr<PCB_GROUP>
group;
845 group = std::make_unique<PCB_GROUP>( footprint );
849 std::unique_ptr<PCB_SHAPE> shape =
852 shape->SetFilled(
true );
853 shape->SetPolyShape( poly );
854 shape->SetLayer( fillKlayer );
855 shape->SetWidth( 0 );
858 group->AddItem( shape.get() );
867 else if( type == wxS(
"ATTR" ) )
871 if( attr.
key == wxS(
"Designator" ) )
875 else if( type == wxS(
"REGION" ) )
877 wxString uuid = line.at( 1 );
884 int layer = line.at( 3 ).get<
int>();
887 std::set<int> flags = line.at( 5 );
888 nlohmann::json polyDataList = line.at( 6 );
890 for( nlohmann::json& polyData : polyDataList )
894 std::vector<std::unique_ptr<PCB_SHAPE>> results =
895 ParsePoly(
nullptr, polyData,
true,
false );
897 for(
auto& shape : results )
899 shape->SetFilled(
true );
906 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( footprint );
908 zone->SetIsRuleArea(
true );
909 zone->SetDoNotAllowFootprints( !!flags.count( 2 ) );
910 zone->SetDoNotAllowZoneFills( !!flags.count( 7 ) || !!flags.count( 6 )
911 || !!flags.count( 8 ) );
912 zone->SetDoNotAllowPads( !!flags.count( 7 ) );
913 zone->SetDoNotAllowTracks( !!flags.count( 7 ) || !!flags.count( 5 ) );
914 zone->SetDoNotAllowVias( !!flags.count( 7 ) );
916 zone->SetLayer( klayer );
917 zone->Outline()->Append( polySet );
924 if( aProject.is_object() && aProject.contains(
"devices" ) )
926 std::map<wxString, EASYEDAPRO::PRJ_DEVICE> devicesMap = aProject.at(
"devices" );
927 std::map<wxString, wxString> compAttrs;
929 for(
auto& [devUuid, devData] : devicesMap )
931 if(
auto fp =
get_opt( devData.attributes,
"Footprint" ) )
935 compAttrs = devData.attributes;
941 wxString modelUuid, modelTitle, modelTransform;
943 modelUuid =
get_def( compAttrs,
"3D Model",
"" );
944 modelTitle =
get_def( compAttrs,
"3D Model Title", modelUuid );
945 modelTransform =
get_def( compAttrs,
"3D Model Transform",
"" );
951 std::vector<PCB_SHAPE*> edgeShapes;
956 edgeShapes.push_back(
static_cast<PCB_SHAPE*
>( item ) );
967 std::unique_ptr<PCB_SHAPE> shape =
973 shape->SetEnd( bbox.
GetEnd() );
978 bool hasFabRef =
false;
984 if(
static_cast<PCB_TEXT*
>( item )->GetText() == wxT(
"${REFERENCE}" ) )
996 int c_refTextThickness =
pcbIUScale.mmToIU( 0.1 );
997 std::unique_ptr<PCB_TEXT> refText = std::make_unique<PCB_TEXT>( footprint );
999 refText->SetLayer(
F_Fab );
1000 refText->SetTextSize(
VECTOR2I( c_refTextSize, c_refTextSize ) );
1001 refText->SetTextThickness( c_refTextThickness );
1002 refText->SetText( wxT(
"${REFERENCE}" ) );
1007 return footprintPtr.release();
1012 BOARD* aBoard,
const nlohmann::json& aProject,
1013 std::map<wxString, std::unique_ptr<FOOTPRINT>>& aFootprintMap,
1014 const std::map<wxString, EASYEDAPRO::BLOB>& aBlobMap,
1015 const std::multimap<wxString, EASYEDAPRO::POURED>& aPouredMap,
1016 const std::vector<nlohmann::json>& aLines,
const wxString& aFpLibName )
1018 std::map<wxString, std::vector<nlohmann::json>> componentLines;
1019 std::map<wxString, std::vector<nlohmann::json>> ruleLines;
1021 std::multimap<wxString, EASYEDAPRO::POURED> boardPouredMap = aPouredMap;
1022 std::map<wxString, ZONE*> poursToFill;
1026 for(
const nlohmann::json& line : aLines )
1028 if( line.size() == 0 )
1031 wxString type = line.at( 0 );
1033 if( type == wxS(
"LAYER" ) )
1035 int layer = line.at( 1 );
1038 wxString layerType = line.at( 2 );
1039 wxString layerName = line.at( 3 );
1040 int layerFlag = line.at( 4 );
1042 if( layerFlag != 0 )
1045 blayers.
set( klayer );
1050 else if( type == wxS(
"NET" ) )
1052 wxString netname = line.at( 1 );
1057 else if( type == wxS(
"RULE" ) )
1059 wxString ruleType = line.at( 1 );
1060 wxString ruleName = line.at( 2 );
1061 int isDefault = line.at( 3 );
1062 nlohmann::json ruleData = line.at( 4 );
1064 if( ruleType == wxS(
"3" ) && isDefault )
1066 wxString units = ruleData.at( 0 );
1068 if( ruleData.at( 1 ).is_number() )
1071 double minVal = ruleData.at( 1 );
1080 nlohmann::json
table = ruleData.at( 1 );
1082 for(
auto& [key, arr] :
table.items() )
1084 double minVal = arr.at( 0 );
1092 else if( ruleType == wxS(
"1" ) && isDefault )
1094 wxString units = ruleData.at( 0 );
1095 nlohmann::json
table = ruleData.at( 1 );
1096 int minVal = INT_MAX;
1101 for(
const auto& arr :
table )
1103 for(
int val : arr )
1105 if( val != 0 && val < minVal )
1110 else if(
table.is_object() )
1114 for(
auto& [key, arr] :
table.items() )
1116 for(
const auto& subarr : arr )
1118 for(
int val : subarr )
1120 if( val != 0 && val < minVal )
1130 ruleLines[ruleType].push_back( line );
1132 else if( type == wxS(
"POURED" ) )
1134 if( !line.at( 2 ).is_string() )
1138 boardPouredMap.emplace( poured.
parentId, poured );
1140 else if( type == wxS(
"VIA" ) || type == wxS(
"LINE" ) || type == wxS(
"ARC" )
1141 || type == wxS(
"POLY" ) || type == wxS(
"FILL" ) || type == wxS(
"POUR" ) )
1143 wxString uuid = line.at( 1 );
1150 wxString netname = line.at( 3 );
1152 if( type == wxS(
"VIA" ) )
1158 double drill = line.at( 7 );
1159 double dia = line.at( 8 );
1161 std::unique_ptr<PCB_VIA>
via = std::make_unique<PCB_VIA>( aBoard );
1167 via->SetNet(
getNet( aBoard, netname ) );
1171 else if( type == wxS(
"LINE" ) )
1173 int layer = line.at( 4 ).get<
int>();
1177 start.
x = line.at( 5 );
1178 start.
y = line.at( 6 );
1181 end.x = line.at( 7 );
1182 end.y = line.at( 8 );
1184 double width = line.at( 9 );
1186 std::unique_ptr<PCB_TRACK> track = std::make_unique<PCB_TRACK>( aBoard );
1188 track->SetLayer( klayer );
1189 track->SetStart(
ScalePos( start ) );
1193 track->SetNet(
getNet( aBoard, netname ) );
1197 else if( type == wxS(
"ARC" ) )
1199 int layer = line.at( 4 ).get<
int>();
1203 start.
x = line.at( 5 );
1204 start.
y = line.at( 6 );
1207 end.x = line.at( 7 );
1208 end.y = line.at( 8 );
1210 double angle = line.at( 9 );
1211 double width = line.at( 10 );
1216 double ha = angle / 2;
1217 double hd =
delta.EuclideanNorm() / 2;
1218 double cdist = hd / tan(
DEG2RAD( ha ) );
1225 std::unique_ptr<PCB_ARC> arc = std::make_unique<PCB_ARC>( aBoard, &sarc );
1228 arc->SetLayer( klayer );
1229 arc->SetNet(
getNet( aBoard, netname ) );
1233 else if( type == wxS(
"FILL" ) )
1235 int layer = line.at( 4 ).get<
int>();
1238 nlohmann::json polyDataList = line.at( 7 );
1240 if( !polyDataList.at( 0 ).is_array() )
1241 polyDataList = nlohmann::json::array( { polyDataList } );
1243 std::vector<SHAPE_LINE_CHAIN> contours;
1244 for( nlohmann::json& polyData : polyDataList )
1249 contours.push_back( contour );
1260 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aBoard );
1262 zone->SetNet(
getNet( aBoard, netname ) );
1263 zone->SetLayer( klayer );
1265 zone->SetFilledPolysList( klayer, zoneFillPoly );
1266 zone->SetAssignedPriority( 500 );
1267 zone->SetIsFilled(
true );
1268 zone->SetNeedRefill(
false );
1275 else if( type == wxS(
"POLY" ) )
1277 int layer = line.at( 4 );
1280 double thickness = line.at( 5 );
1281 nlohmann::json polyData = line.at( 6 );
1283 std::vector<std::unique_ptr<PCB_SHAPE>> results =
1284 ParsePoly( aBoard, polyData,
false,
false );
1286 for(
auto& shape : results )
1288 shape->SetLayer( klayer );
1289 shape->SetWidth(
ScaleSize( thickness ) );
1294 else if( type == wxS(
"POUR" ) )
1296 int layer = line.at( 4 ).get<
int>();
1299 wxString pourname = line.at( 6 );
1300 int fillOrder = line.at( 7 ).get<
int>();
1301 nlohmann::json polyDataList = line.at( 8 );
1303 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aBoard );
1305 zone->SetNet(
getNet( aBoard, netname ) );
1306 zone->SetLayer( klayer );
1307 zone->SetAssignedPriority( 500 - fillOrder );
1311 for( nlohmann::json& polyData : polyDataList )
1316 zone->Outline()->Append( contour );
1319 wxASSERT( zone->Outline()->OutlineCount() == 1 );
1321 poursToFill.emplace( uuid, zone.get() );
1326 else if( type == wxS(
"TEARDROP" ) )
1328 wxString uuid = line.at( 1 );
1329 wxString netname = line.at( 2 );
1330 int layer = line.at( 3 ).get<
int>();
1333 nlohmann::json polyData = line.at( 4 );
1338 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aBoard );
1340 zone->SetNet(
getNet( aBoard, netname ) );
1341 zone->SetLayer( klayer );
1342 zone->Outline()->Append( contour );
1343 zone->SetFilledPolysList( klayer, contour );
1344 zone->SetNeedRefill(
false );
1345 zone->SetIsFilled(
true );
1347 zone->SetAssignedPriority( 600 );
1348 zone->SetLocalClearance( 0 );
1349 zone->SetMinThickness( 0 );
1354 else if( type == wxS(
"REGION" ) )
1356 wxString uuid = line.at( 1 );
1363 int layer = line.at( 3 ).get<
int>();
1366 std::set<int> flags = line.at( 5 );
1367 nlohmann::json polyDataList = line.at( 6 );
1369 for( nlohmann::json& polyData : polyDataList )
1374 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aBoard );
1376 zone->SetIsRuleArea(
true );
1377 zone->SetDoNotAllowFootprints( !!flags.count( 2 ) );
1378 zone->SetDoNotAllowZoneFills( !!flags.count( 7 ) || !!flags.count( 6 )
1379 || !!flags.count( 8 ) );
1380 zone->SetDoNotAllowPads( !!flags.count( 7 ) );
1381 zone->SetDoNotAllowTracks( !!flags.count( 7 ) || !!flags.count( 5 ) );
1382 zone->SetDoNotAllowVias( !!flags.count( 7 ) );
1384 zone->SetLayer( klayer );
1385 zone->Outline()->Append( contour );
1390 else if( type == wxS(
"PAD" ) )
1392 wxString netname = line.at( 3 );
1394 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>( aBoard );
1395 std::unique_ptr<PAD>
pad =
createPAD( footprint.get(), line );
1397 pad->SetNet(
getNet( aBoard, netname ) );
1406 footprint->SetPosition( pos );
1407 footprint->SetOrientation( orient );
1409 wxString fpName = wxS(
"Pad_" ) + line.at( 1 ).get<wxString>();
1412 footprint->SetFPID( fpID );
1413 footprint->Reference().SetVisible(
true );
1414 footprint->Value().SetVisible(
true );
1415 footprint->AutoPositionFields();
1419 else if( type == wxS(
"IMAGE" ) )
1421 wxString uuid = line.at( 1 );
1428 int layer = line.at( 3 ).get<
int>();
1431 VECTOR2D start( line.at( 4 ), line.at( 5 ) );
1432 VECTOR2D size( line.at( 6 ), line.at( 7 ) );
1434 double angle = line.at( 8 );
1435 int mirror = line.at( 9 );
1436 nlohmann::json polyDataList = line.at( 10 );
1439 std::vector<SHAPE_LINE_CHAIN> contours;
1440 for( nlohmann::json& polyData : polyDataList )
1445 contours.push_back( contour );
1457 for(
int i = 0; i < contour.PointCount(); i++ )
1468 std::unique_ptr<PCB_GROUP>
group;
1471 group = std::make_unique<PCB_GROUP>( aBoard );
1477 std::unique_ptr<PCB_SHAPE> shape =
1480 shape->SetFilled(
true );
1481 shape->SetPolyShape( poly );
1482 shape->SetLayer( klayer );
1483 shape->SetWidth( 0 );
1493 shape->Mirror(
ScalePos( start ), flipDirection );
1497 group->AddItem( shape.get() );
1505 else if( type == wxS(
"OBJ" ) )
1508 wxString mimeType, base64Data;
1512 if( !line.at( 3 ).is_number() )
1515 int layer = line.at( 3 ).get<
int>();
1518 start =
VECTOR2D( line.at( 5 ), line.at( 6 ) );
1519 size =
VECTOR2D( line.at( 7 ), line.at( 8 ) );
1520 angle = line.at( 9 );
1521 flipped = line.at( 10 );
1523 wxString imageUrl = line.at( 11 );
1525 if( imageUrl.BeforeFirst(
':' ) == wxS(
"blob" ) )
1527 wxString objectId = imageUrl.AfterLast(
':' );
1529 if(
auto blob =
get_opt( aBlobMap, objectId ) )
1531 wxString blobUrl = blob->url;
1533 if( blobUrl.BeforeFirst(
':' ) == wxS(
"data" ) )
1535 wxArrayString paramsArr =
1536 wxSplit( blobUrl.AfterFirst(
':' ).BeforeFirst(
',' ),
';',
'\0' );
1538 base64Data = blobUrl.AfterFirst(
',' );
1540 if( paramsArr.size() > 0 )
1541 mimeType = paramsArr[0];
1549 if( mimeType.empty() || base64Data.empty() )
1552 wxMemoryBuffer buf = wxBase64Decode( base64Data );
1554 if( mimeType == wxS(
"image/svg+xml" ) )
1560 VECTOR2D kcenter = kstart + ksize / 2;
1562 std::unique_ptr<PCB_REFERENCE_IMAGE> bitmap =
1563 std::make_unique<PCB_REFERENCE_IMAGE>( aBoard, kcenter, klayer );
1566 wxImage::SetDefaultLoadFlags( wxImage::GetDefaultLoadFlags()
1567 & ~wxImage::Load_Verbose );
1579 int x = bitmap->GetPosition().x;
1590 else if( type == wxS(
"STRING" ) )
1592 wxString uuid = line.at( 1 );
1599 int layer = line.at( 3 ).get<
int>();
1603 wxString
string = line.at( 6 );
1604 wxString font = line.at( 7 );
1606 double height = line.at( 8 );
1607 double strokew = line.at( 9 );
1609 int align = line.at( 12 );
1610 double angle = line.at( 13 );
1611 int inverted = line.at( 14 );
1612 int mirror = line.at( 16 );
1616 text->SetText(
string );
1617 text->SetLayer( klayer );
1619 text->SetIsKnockout( inverted );
1623 if( font != wxS(
"default" ) )
1636 text->SetMirrored(
true );
1637 text->SetTextAngleDegrees( -angle );
1641 text->SetTextAngleDegrees( angle );
1646 else if( type == wxS(
"COMPONENT" ) )
1648 wxString compId = line.at( 1 );
1649 componentLines[compId].push_back( line );
1651 else if( type == wxS(
"ATTR" ) )
1653 wxString compId = line.at( 3 );
1654 componentLines[compId].push_back( line );
1656 else if( type == wxS(
"PAD_NET" ) )
1658 wxString compId = line.at( 1 );
1659 componentLines[compId].push_back( line );
1663 for(
auto const& [compId, lines] : componentLines )
1666 wxString fpIdOverride;
1667 wxString fpDesignator;
1668 std::map<wxString, wxString> localCompAttribs;
1670 for(
auto& line : lines )
1672 if( line.size() == 0 )
1675 wxString type = line.at( 0 );
1677 if( type == wxS(
"COMPONENT" ) )
1679 localCompAttribs = line.at( 7 );
1681 else if( type == wxS(
"ATTR" ) )
1685 if( attr.
key == wxS(
"Device" ) )
1686 deviceId = attr.
value;
1688 else if( attr.
key == wxS(
"Footprint" ) )
1689 fpIdOverride = attr.
value;
1691 else if( attr.
key == wxS(
"Designator" ) )
1692 fpDesignator = attr.
value;
1696 if( deviceId.empty() )
1699 nlohmann::json compAttrs = aProject.at(
"devices" ).at( deviceId ).at(
"attributes" );
1703 if( !fpIdOverride.IsEmpty() )
1704 fpId = fpIdOverride;
1706 fpId = compAttrs.at(
"Footprint" ).get<wxString>();
1708 auto it = aFootprintMap.find( fpId );
1709 if( it == aFootprintMap.end() )
1711 wxLogTrace(
traceEasyEdaIo,
"Footprint of '%s' with uuid '%s' not found.", fpDesignator, fpId );
1715 std::unique_ptr<FOOTPRINT>& footprintOrig = it->second;
1716 std::unique_ptr<FOOTPRINT> footprint(
static_cast<FOOTPRINT*
>( footprintOrig->Clone() ) );
1718 wxString modelUuid, modelTitle, modelTransform;
1720 if(
auto val =
get_opt( localCompAttribs,
"3D Model" ) )
1723 modelUuid = compAttrs.value<wxString>(
"3D Model",
"" );
1725 if(
auto val =
get_opt( localCompAttribs,
"3D Model Title" ) )
1726 modelTitle = val->Trim();
1728 modelTitle = compAttrs.value<wxString>(
"3D Model Title", modelUuid ).Trim();
1730 if(
auto val =
get_opt( localCompAttribs,
"3D Model Transform" ) )
1731 modelTransform = *val;
1733 modelTransform = compAttrs.value<wxString>(
"3D Model Transform",
"" );
1737 footprint->SetParent( aBoard );
1739 for(
auto& line : lines )
1741 if( line.size() == 0 )
1744 wxString type = line.at( 0 );
1746 if( type == wxS(
"COMPONENT" ) )
1748 int layer = line.at( 3 );
1753 double orient = line.at( 6 );
1756 if( klayer ==
B_Cu )
1759 footprint->SetOrientationDegrees( orient );
1762 else if( type == wxS(
"ATTR" ) )
1770 if( attr.
key == wxS(
"Designator" ) )
1772 if( attr.
key == wxS(
"Designator" ) )
1782 if( attr.
fontName != wxS(
"default" ) )
1811 else if( type == wxS(
"PAD_NET" ) )
1813 wxString padNumber = line.at( 2 );
1814 wxString padNet = line.at( 3 );
1816 PAD*
pad = footprint->FindPadByNumber( padNumber );
1819 pad->SetNet(
getNet( aBoard, padNet ) );
1834 for(
auto& [uuid, zone] : poursToFill )
1839 auto range = boardPouredMap.equal_range( uuid );
1840 for(
auto& it = range.first; it != range.second; ++it )
1846 for(
int dataId = 0; dataId < (int) poured.
polyData.size(); dataId++ )
1848 const nlohmann::json& fillData = poured.
polyData[dataId];
1849 const double ptScale = 10;
1854 for(
int i = 0; i < contour.
PointCount(); i++ )
1867 thisPoly.
Append( simple );
1876 const int thermalWidth =
pcbIUScale.mmToIU( 0.2 );
1878 for(
int segId = 0; segId < contour.
SegmentCount(); segId++ )
1888 fillPolySet.
Append( thisPoly );
1895 const int strokeWidth =
pcbIUScale.MilsToIU( 8 );
1904 zone->SetFilledPolysList( zone->GetFirstLayer(), fillPolySet );
1905 zone->SetNeedRefill(
false );
1906 zone->SetIsFilled(
true );
1912 std::vector<PCB_SHAPE*> shapes;
1920 shapes.push_back(
static_cast<PCB_SHAPE*
>( item ) );
1935 offset.
x =
KiROUND( offset.
x / alignGrid ) * alignGrid;
1936 offset.
y =
KiROUND( offset.
y / alignGrid ) * alignGrid;
1938 aBoard->
Move( offset );