45#include <wx/mstream.h>
57 "BOM_Manufacturer Part",
83 if( !aValue.ToCDouble( &value ) )
84 THROW_IO_ERROR( wxString::Format(
_(
"Failed to parse value: '%s'" ), aValue ) );
100 else if( aStyle == 1 )
102 else if( aStyle == 2 )
104 else if( aStyle == 3 )
113 T&
text,
const wxString& styleStr )
115 auto it = fontStyles.find( styleStr );
117 if( it == fontStyles.end() )
120 nlohmann::json style = it->second;
122 if( !style.is_array() )
125 if( style.size() < 12 )
128 if( style.at( 3 ).is_string() )
134 if( style.at( 4 ).is_string() )
136 wxString fontname = ( style.at( 4 ) );
138 if( !fontname.IsSameAs( wxS(
"default" ),
false ) )
142 if( style.at( 5 ).is_number() )
144 double size = style.at( 5 ).get<
double>() * 0.5;
148 if( style.at( 10 ).is_number() )
150 int valign = style.at( 10 );
152 if( !
text->GetText().Contains( wxS(
"\n" ) ) )
156 else if( valign == 1 )
158 else if( valign == 2 )
172 if( style.at( 11 ).is_number() )
174 int halign = style.at( 11 );
178 else if( halign == 1 )
180 else if( halign == 2 )
192 T& shape,
const wxString& styleStr )
194 auto it = lineStyles.find( styleStr );
196 if( it == lineStyles.end() )
199 nlohmann::json style = it->second;
201 if( !style.is_array() )
204 if( style.size() < 6 )
209 if( style.at( 2 ).is_string() )
211 wxString colorStr = style.at( 2 ).get<wxString>();
213 if( !colorStr.empty() && colorStr.starts_with( wxS(
"#" ) ) )
220 if( style.at( 3 ).is_number() )
222 int dashStyle = style.at( 3 );
226 if( style.at( 5 ).is_number() )
228 double thickness = style.at( 5 );
232 shape->SetStroke( stroke );
237 const wxString aInput,
const std::map<wxString, wxString>& aDeviceAttributes )
239 wxString inputText = aInput;
240 wxString resolvedText;
241 int variableCount = 0;
247 if( !inputText.StartsWith( wxS(
"={" ) ) )
250 resolvedText.Clear();
253 for(
size_t i = 1; i < inputText.size(); )
255 wxUniChar c = inputText[i++];
260 bool endFound =
false;
262 while( i < inputText.size() )
279 get_def( aDeviceAttributes, varName, wxString::Format(
"{%s!}", varName ) );
281 resolvedText << varValue;
289 inputText = resolvedText;
291 }
while( variableCount > 0 );
300 bool aIsSym,
bool aToSym,
301 const std::map<wxString, wxString>& aDeviceAttributes,
323 auto parent = aParent;
326 int orient =
static_cast<SCH_SYMBOL*
>( parent )->GetOrientation();
404 const std::map<wxString, wxString>& aDeviceAttributes )
408 std::unique_ptr<LIB_SYMBOL> ksymbolPtr = std::make_unique<LIB_SYMBOL>( wxEmptyString );
411 std::map<wxString, nlohmann::json> lineStyles;
412 std::map<wxString, nlohmann::json> fontStyles;
413 std::map<wxString, int> partUnits;
415 std::map<int, std::map<wxString, EASYEDAPRO::SCH_ATTR>> unitAttributes;
416 std::map<int, std::map<wxString, std::vector<nlohmann::json>>> unitParentedLines;
420 for(
const nlohmann::json& line : aLines )
422 wxString type = line.at( 0 );
424 if( type == wxS(
"LINESTYLE" ) )
425 lineStyles[line.at( 1 )] = line;
426 else if( type == wxS(
"FONTSTYLE" ) )
427 fontStyles[line.at( 1 )] = line;
428 else if( type == wxS(
"PART" ) )
429 partUnits[line.at( 1 )] = ++totalUnits;
437 for(
const nlohmann::json& line : aLines )
439 wxString type = line.at( 0 );
441 if( type == wxS(
"PART" ) )
443 currentUnit = partUnits.at( line.at( 1 ) );
445 else if( type == wxS(
"RECT" ) )
447 VECTOR2D start( line.at( 2 ), line.at( 3 ) );
449 wxString styleStr = line.at( 9 );
451 auto rect = std::make_unique<SCH_SHAPE>( SHAPE_T::RECTANGLE,
LAYER_DEVICE );
456 rect->SetUnit( currentUnit );
461 else if( type == wxS(
"CIRCLE" ) )
464 double radius = line.at( 4 );
465 wxString styleStr = line.at( 5 );
472 circle->SetUnit( currentUnit );
477 else if( type == wxS(
"ARC" ) )
479 VECTOR2D start( line.at( 2 ), line.at( 3 ) );
480 VECTOR2D mid( line.at( 4 ), line.at( 5 ) );
482 wxString styleStr = line.at( 8 );
488 auto shape = std::make_unique<SCH_SHAPE>( SHAPE_T::ARC,
LAYER_DEVICE );
490 shape->SetArcGeometry( kstart, kmid, kend );
492 shape->SetUnit( currentUnit );
497 else if( type == wxS(
"BEZIER" ) )
499 std::vector<double> points = line.at( 2 );
500 wxString styleStr = line.at( 3 );
502 std::unique_ptr<SCH_SHAPE> shape =
503 std::make_unique<SCH_SHAPE>( SHAPE_T::BEZIER,
LAYER_DEVICE );
505 for(
size_t i = 1; i < points.size(); i += 2 )
511 case 1: shape->SetStart( pt );
break;
512 case 3: shape->SetBezierC1( pt );
break;
513 case 5: shape->SetBezierC2( pt );
break;
514 case 7: shape->SetEnd( pt );
break;
518 shape->SetUnit( currentUnit );
523 else if( type == wxS(
"POLY" ) )
525 std::vector<double> points = line.at( 2 );
526 wxString styleStr = line.at( 4 );
528 auto shape = std::make_unique<SCH_SHAPE>( SHAPE_T::POLY,
LAYER_DEVICE );
530 for(
size_t i = 1; i < points.size(); i += 2 )
533 shape->SetUnit( currentUnit );
538 else if( type == wxS(
"TEXT" ) )
540 VECTOR2D pos( line.at( 2 ), line.at( 3 ) );
541 double angle = line.at( 4 ).is_number() ? line.at( 4 ).get<
double>() : 0.0;
542 wxString textStr = line.at( 5 );
543 wxString fontStyleStr = line.at( 6 );
550 text->SetTextAngleDegrees( angle );
552 text->SetUnit( currentUnit );
557 else if( type == wxS(
"OBJ" ) )
560 wxString mimeType, data;
564 if( line.at( 3 ).is_number() )
566 start =
VECTOR2D( line.at( 3 ), line.at( 4 ) );
567 size =
VECTOR2D( line.at( 5 ), line.at( 6 ) );
569 upsideDown = line.at( 8 );
571 wxString imageUrl = line.at( 9 );
573 if( imageUrl.BeforeFirst(
':' ) == wxS(
"data" ) )
575 wxArrayString paramsArr =
576 wxSplit( imageUrl.AfterFirst(
':' ).BeforeFirst(
',' ),
';',
'\0' );
578 data = imageUrl.AfterFirst(
',' );
580 if( paramsArr.size() > 0 )
582 mimeType = paramsArr[0];
586 else if( line.at( 3 ).is_string() )
588 mimeType = line.at( 3 ).get<wxString>().BeforeFirst(
';' );
590 start =
VECTOR2D( line.at( 4 ), line.at( 5 ) );
591 size =
VECTOR2D( line.at( 6 ), line.at( 7 ) );
593 data = line.at( 9 ).get<wxString>();
596 if( mimeType.empty() || data.empty() )
599 wxMemoryBuffer buf = wxBase64Decode( data );
601 if( mimeType == wxS(
"image/svg+xml" ) )
620 libsymImporter.
SetScale( pixelScale );
629 for( std::unique_ptr<EDA_ITEM>& item : libsymImporter.
GetItems() )
634 wxMemoryInputStream memis( buf.GetData(), buf.GetDataLen() );
636 wxImage::SetDefaultLoadFlags( wxImage::GetDefaultLoadFlags()
637 & ~wxImage::Load_Verbose );
639 if( img.LoadFile( memis, mimeType ) )
641 int dimMul = img.GetWidth() * img.GetHeight();
642 double maxPixels = 30000;
644 if( dimMul > maxPixels )
646 double scale = sqrt( maxPixels / dimMul );
647 img.Rescale( img.GetWidth() *
scale, img.GetHeight() *
scale );
658 else if( type == wxS(
"HEAD" ) )
662 else if( type == wxS(
"PIN" ) )
664 wxString pinId = line.at( 1 );
665 unitParentedLines[currentUnit][pinId].push_back( line );
667 else if( type == wxS(
"ATTR" ) )
669 wxString parentId = line.at( 2 );
671 if( parentId.empty() )
674 unitAttributes[currentUnit].emplace( attr.
key, attr );
678 unitParentedLines[currentUnit][parentId].push_back( line );
693 if(
auto globalNetAttr =
get_opt( unitAttributes[1], wxS(
"Global Net Name" ) ) )
697 wxString globalNetname = globalNetAttr->value;
699 if( !globalNetname.empty() )
702 _(
"Power symbol creates a global label with name '%s'" ),
709 auto designatorAttr =
get_opt( unitAttributes[1], wxS(
"Designator" ) );
711 if( designatorAttr && !designatorAttr->value.empty() )
713 wxString symbolPrefix = designatorAttr->value;
715 if( symbolPrefix.EndsWith( wxS(
"?" ) ) )
716 symbolPrefix.RemoveLast();
723 if(
auto valOpt =
get_opt( aDeviceAttributes, attrName ) )
725 if( valOpt->empty() )
732 fd =
new SCH_FIELD( ksymbol, FIELD_T::USER, attrName );
736 wxString value = *valOpt;
738 value.Replace( wxS(
"\u2103" ), wxS(
"\u00B0C" ),
true );
746 for(
auto& [unitId, parentedLines] : unitParentedLines )
748 for(
auto& [pinId, lines] : parentedLines )
750 std::optional<EASYEDAPRO::SYM_PIN> epin;
751 std::map<wxString, EASYEDAPRO::SCH_ATTR> pinAttributes;
753 for(
const nlohmann::json& line : lines )
755 wxString type = line.at( 0 );
757 if( type == wxS(
"ATTR" ) )
760 pinAttributes.emplace( attr.
key, attr );
762 else if( type == wxS(
"PIN" ) )
774 std::unique_ptr<SCH_PIN>
pin = std::make_unique<SCH_PIN>( ksymbol );
776 pin->SetUnit( unitId );
783 if( epin->rotation == 0 )
784 orient = PIN_ORIENTATION::PIN_RIGHT;
785 if( epin->rotation == 90 )
786 orient = PIN_ORIENTATION::PIN_UP;
787 if( epin->rotation == 180 )
788 orient = PIN_ORIENTATION::PIN_LEFT;
789 if( epin->rotation == 270 )
790 orient = PIN_ORIENTATION::PIN_DOWN;
792 pin->SetOrientation( orient );
799 else if(
auto pinNameAttr =
get_opt( pinAttributes,
"NAME" ) )
801 pin->SetName( pinNameAttr->value );
802 pinInfo.
name = pinNameAttr->value;
804 if( !pinNameAttr->valVisible )
808 if(
auto pinNumAttr =
get_opt( pinAttributes,
"NUMBER" ) )
810 pin->SetNumber( pinNumAttr->value );
811 pinInfo.
number = pinNumAttr->value;
813 if( !pinNumAttr->valVisible )
819 pin->SetType( ELECTRICAL_PINTYPE::PT_POWER_IN );
821 else if(
auto pinTypeAttr =
get_opt( pinAttributes,
"Pin Type" ) )
823 if( pinTypeAttr->value == wxS(
"IN" ) )
824 pin->SetType( ELECTRICAL_PINTYPE::PT_INPUT );
825 if( pinTypeAttr->value == wxS(
"OUT" ) )
826 pin->SetType( ELECTRICAL_PINTYPE::PT_OUTPUT );
827 if( pinTypeAttr->value == wxS(
"BI" ) )
828 pin->SetType( ELECTRICAL_PINTYPE::PT_BIDI );
831 if(
get_opt( pinAttributes,
"NO_CONNECT" ) )
832 pin->SetType( ELECTRICAL_PINTYPE::PT_NC );
834 if(
pin->GetNumberTextSize() *
int(
pin->GetNumber().size() ) >
pin->GetLength() )
835 pin->SetNumberTextSize(
pin->GetLength() /
pin->GetNumber().size() );
837 symInfo.
pins.push_back( pinInfo );
855 symInfo.
libSymbol = std::move( ksymbolPtr );
862 const nlohmann::json& aProject,
863 std::map<wxString, EASYEDAPRO::SYM_INFO>& aSymbolMap,
864 const std::map<wxString, EASYEDAPRO::BLOB>& aBlobMap,
865 const std::vector<nlohmann::json>& aLines,
866 const wxString& aLibName )
868 std::vector<std::unique_ptr<SCH_ITEM>> createdItems;
870 std::map<wxString, std::vector<nlohmann::json>> parentedLines;
871 std::map<wxString, std::vector<nlohmann::json>> ruleLines;
873 std::map<wxString, nlohmann::json> lineStyles;
874 std::map<wxString, nlohmann::json> fontStyles;
876 for(
const nlohmann::json& line : aLines )
878 wxString type = line.at( 0 );
880 if( type == wxS(
"LINESTYLE" ) )
881 lineStyles[line.at( 1 )] = line;
882 else if( type == wxS(
"FONTSTYLE" ) )
883 fontStyles[line.at( 1 )] = line;
886 for(
const nlohmann::json& line : aLines )
888 wxString type = line.at( 0 );
890 if( type == wxS(
"RECT" ) )
892 VECTOR2D start( line.at( 2 ), line.at( 3 ) );
894 wxString styleStr = line.at( 9 );
896 std::unique_ptr<SCH_SHAPE> rect = std::make_unique<SCH_SHAPE>( SHAPE_T::RECTANGLE );
898 rect->SetStart(
ScalePos( start ) );
903 createdItems.push_back( std::move( rect ) );
905 else if( type == wxS(
"CIRCLE" ) )
908 double radius = line.at( 4 );
909 wxString styleStr = line.at( 5 );
911 std::unique_ptr<SCH_SHAPE>
circle = std::make_unique<SCH_SHAPE>( SHAPE_T::CIRCLE );
918 createdItems.push_back( std::move(
circle ) );
920 else if( type == wxS(
"POLY" ) )
922 std::vector<double> points = line.at( 2 );
923 wxString styleStr = line.at( 4 );
927 for(
size_t i = 1; i < points.size(); i += 2 )
934 std::unique_ptr<SCH_LINE> schLine =
936 schLine->SetEndPoint( seg.
B );
940 createdItems.push_back( std::move( schLine ) );
943 else if( type == wxS(
"TEXT" ) )
945 VECTOR2D pos( line.at( 2 ), line.at( 3 ) );
946 double angle = line.at( 4 ).is_number() ? line.at( 4 ).get<
double>() : 0.0;
947 wxString textStr = line.at( 5 );
948 wxString fontStyleStr = line.at( 6 );
950 std::unique_ptr<SCH_TEXT>
text =
956 text->SetTextAngleDegrees( angle );
960 createdItems.push_back( std::move(
text ) );
962 else if( type == wxS(
"OBJ" ) )
965 wxString mimeType, base64Data;
969 if( line.at( 3 ).is_number() )
971 start =
VECTOR2D( line.at( 3 ), line.at( 4 ) );
972 size =
VECTOR2D( line.at( 5 ), line.at( 6 ) );
973 angle = line.at( 7 );
974 flipped = line.at( 8 );
976 wxString imageUrl = line.at( 9 );
978 if( imageUrl.BeforeFirst(
':' ) == wxS(
"data" ) )
980 wxArrayString paramsArr =
981 wxSplit( imageUrl.AfterFirst(
':' ).BeforeFirst(
',' ),
';',
'\0' );
983 base64Data = imageUrl.AfterFirst(
',' );
985 if( paramsArr.size() > 0 )
986 mimeType = paramsArr[0];
988 else if( imageUrl.BeforeFirst(
':' ) == wxS(
"blob" ) )
990 wxString objectId = imageUrl.AfterLast(
':' );
992 if(
auto blob =
get_opt( aBlobMap, objectId ) )
994 wxString blobUrl = blob->url;
996 if( blobUrl.BeforeFirst(
':' ) == wxS(
"data" ) )
998 wxArrayString paramsArr = wxSplit(
999 blobUrl.AfterFirst(
':' ).BeforeFirst(
',' ),
';',
'\0' );
1001 base64Data = blobUrl.AfterFirst(
',' );
1003 if( paramsArr.size() > 0 )
1004 mimeType = paramsArr[0];
1009 else if( line.at( 3 ).is_string() )
1011 mimeType = line.at( 3 ).get<wxString>().BeforeFirst(
';' );
1013 start =
VECTOR2D( line.at( 4 ), line.at( 5 ) );
1014 size =
VECTOR2D( line.at( 6 ), line.at( 7 ) );
1015 angle = line.at( 8 );
1016 base64Data = line.at( 9 ).get<wxString>();
1022 if( mimeType.empty() || base64Data.empty() )
1025 wxMemoryBuffer buf = wxBase64Decode( base64Data );
1027 if( mimeType == wxS(
"image/svg+xml" ) )
1041 schImporter.
SetScale( pixelScale );
1047 svgImportPlugin.
Import();
1049 for( std::unique_ptr<EDA_ITEM>& item : schImporter.
GetItems() )
1053 for(
double i = angle; i > 0; i -= 90 )
1059 schItem->
Rotate( kstart,
false );
1063 schItem->
Rotate( kstart,
false );
1068 schItem->
Rotate( kstart,
false );
1084 createdItems.emplace_back( schItem );
1089 std::unique_ptr<SCH_BITMAP> bitmap = std::make_unique<SCH_BITMAP>();
1092 wxImage::SetDefaultLoadFlags( wxImage::GetDefaultLoadFlags()
1093 & ~wxImage::Load_Verbose );
1097 VECTOR2D kcenter = kstart + ksize / 2;
1101 bitmap->SetPosition( kcenter );
1103 for(
double i = angle; i > 0; i -= 90 )
1104 bitmap->Rotate( kstart,
false );
1107 bitmap->MirrorHorizontally( kstart.
x );
1109 createdItems.push_back( std::move( bitmap ) );
1113 if( type == wxS(
"WIRE" ) )
1115 wxString wireId = line.at( 1 );
1116 parentedLines[wireId].push_back( line );
1118 else if( type == wxS(
"COMPONENT" ) )
1120 wxString compId = line.at( 1 );
1121 parentedLines[compId].push_back( line );
1123 else if( type == wxS(
"ATTR" ) )
1125 wxString compId = line.at( 2 );
1126 parentedLines[compId].push_back( line );
1130 for(
auto& [parentId, lines] : parentedLines )
1132 std::optional<EASYEDAPRO::SCH_COMPONENT> component;
1133 std::optional<EASYEDAPRO::SCH_WIRE> wire;
1134 std::map<wxString, EASYEDAPRO::SCH_ATTR> attributes;
1136 for(
const nlohmann::json& line : lines )
1138 if( line.at( 0 ) ==
"COMPONENT" )
1142 else if( line.at( 0 ) ==
"WIRE" )
1146 else if( line.at( 0 ) ==
"ATTR" )
1149 attributes.emplace( attr.
key, attr );
1155 auto deviceAttr =
get_opt( attributes,
"Device" );
1156 auto symbolAttr =
get_opt( attributes,
"Symbol" );
1162 aProject.at(
"devices" ).at( deviceAttr->value ).at(
"attributes" ) );
1166 if( symbolAttr && !symbolAttr->value.IsEmpty() )
1167 symbolId = symbolAttr->value;
1169 symbolId = compAttrs.at(
"Symbol" );
1171 auto it = aSymbolMap.find( symbolId );
1172 if( it == aSymbolMap.end() )
1174 wxLogError(
"Symbol of '%s' with uuid '%s' not found.", component->name, symbolId );
1181 wxString unitName = component->name;
1186 auto schSym = std::make_unique<SCH_SYMBOL>( newLibSymbol, libId,
1190 schSym->SetFootprintFieldText( newLibSymbol.
GetFootprint() );
1192 for(
double i = component->rotation; i > 0; i -= 90 )
1193 schSym->Rotate(
VECTOR2I(),
true );
1195 if( component->mirror )
1196 schSym->MirrorHorizontally( 0 );
1198 schSym->SetPosition(
ScalePos( component->position ) );
1202 if(
auto globalNetAttr =
get_opt( attributes,
"Global Net Name" ) )
1205 *globalNetAttr,
false,
true, compAttrs, schSym.get() );
1207 for(
SCH_PIN*
pin : schSym->GetAllLibPins() )
1208 pin->SetName( globalNetAttr->value );
1210 else if(
auto nameAttr =
get_opt( attributes,
"Name" ) )
1213 *nameAttr,
false,
true, compAttrs, schSym.get() );
1215 for(
SCH_PIN*
pin : schSym->GetAllLibPins() )
1216 pin->SetName( nameAttr->value );
1220 SCH_FIELD* valueField = schSym->GetField( FIELD_T::VALUE );
1224 schSym->SetRef( &aSchematic->
CurrentSheet(), wxS(
"#PWR?" ) );
1225 schSym->GetField( FIELD_T::REFERENCE )->SetVisible(
false );
1229 auto nameAttr =
get_opt( attributes,
"Name" );
1233 if( nameAttr && !nameAttr->value.IsEmpty() )
1234 netName = nameAttr->value;
1236 netName = compAttrs.at(
"Name" );
1238 std::unique_ptr<SCH_GLOBALLABEL> label = std::make_unique<SCH_GLOBALLABEL>(
1239 ScalePos( component->position ), netName );
1241 std::vector<SCH_PIN*> pins = schSym->GetPins( &aSchematic->
CurrentSheet() );
1243 if( pins.size() > 0 )
1245 switch( pins[0]->GetType() )
1247 case ELECTRICAL_PINTYPE::PT_INPUT:
1248 label->SetShape( LABEL_FLAG_SHAPE::L_INPUT );
1250 case ELECTRICAL_PINTYPE::PT_OUTPUT:
1251 label->SetShape( LABEL_FLAG_SHAPE::L_OUTPUT );
1253 case ELECTRICAL_PINTYPE::PT_BIDI:
1254 label->SetShape( LABEL_FLAG_SHAPE::L_BIDI );
1260 BOX2I bbox = schSym->GetBodyAndPinsBoundingBox();
1261 bbox.
Offset( -schSym->GetPosition() );
1268 if( bboxCenter.
x >= 0 )
1275 if( bboxCenter.
y >= 0 )
1281 label->SetSpinStyle( spin );
1285 nlohmann::json style = fontStyles[nameAttr->fontStyle];
1287 if( !style.is_null() && style.at( 5 ).is_number() )
1289 double size = style.at( 5 ).get<
double>() * 0.5;
1294 createdItems.push_back( std::move( label ) );
1302 if(
auto valOpt =
get_opt( compAttrs, attrKey ) )
1304 if( valOpt->empty() )
1307 SCH_FIELD*
text = schSym->FindFieldCaseInsensitive( attrKey );
1311 text =
new SCH_FIELD( schSym.get(), FIELD_T::USER, attrKey );
1312 schSym->AddField(
text );
1315 wxString value = *valOpt;
1317 value.Replace( wxS(
"\u2103" ), wxS(
"\u00B0C" ),
true );
1319 text->SetText( value );
1320 text->SetVisible(
false );
1324 auto nameAttr =
get_opt( attributes,
"Name" );
1325 auto valueAttr =
get_opt( attributes,
"Value" );
1327 if( valueAttr && valueAttr->value.empty() )
1328 valueAttr->value =
get_def( compAttrs,
"Value", wxString() );
1330 if( nameAttr && nameAttr->value.empty() )
1331 nameAttr->value =
get_def( compAttrs,
"Name", wxString() );
1333 std::optional<EASYEDAPRO::SCH_ATTR> targetValueAttr;
1335 if( valueAttr && !valueAttr->value.empty() && valueAttr->valVisible )
1336 targetValueAttr = valueAttr;
1337 else if( nameAttr && !nameAttr->value.empty() && nameAttr->valVisible )
1338 targetValueAttr = nameAttr;
1339 else if( valueAttr && !valueAttr->value.empty() )
1340 targetValueAttr = valueAttr;
1341 else if( nameAttr && !nameAttr->value.empty() )
1342 targetValueAttr = nameAttr;
1344 if( targetValueAttr )
1347 *targetValueAttr,
false,
true, compAttrs, schSym.get() );
1350 if(
auto descrAttr =
get_opt( attributes,
"Description" ) )
1353 *descrAttr,
false,
true, compAttrs, schSym.get() );
1356 if(
auto designatorAttr =
get_opt( attributes,
"Designator" ) )
1359 *designatorAttr,
false,
true, compAttrs, schSym.get() );
1361 schSym->SetRef( &aSchematic->
CurrentSheet(), designatorAttr->value );
1364 for(
auto& [attrKey, attr] : attributes )
1366 if( attrKey == wxS(
"Name" ) || attrKey == wxS(
"Value" )
1367 || attrKey == wxS(
"Global Net Name" ) || attrKey == wxS(
"Designator" )
1368 || attrKey == wxS(
"Description" ) || attrKey == wxS(
"Device" )
1369 || attrKey == wxS(
"Footprint" ) || attrKey == wxS(
"Symbol" )
1370 || attrKey == wxS(
"Unique ID" ) )
1375 if( attr.value.IsEmpty() )
1378 SCH_FIELD*
text = schSym->FindFieldCaseInsensitive( attrKey );
1382 text =
new SCH_FIELD( schSym.get(), FIELD_T::USER, attrKey );
1383 schSym->AddField(
text );
1386 text->SetPosition( schSym->GetPosition() );
1395 wxString pinKey = parentId + pinInfo.
pin.
id;
1396 auto pinLines =
get_opt( parentedLines, pinKey );
1401 for(
const nlohmann::json& pinLine : *pinLines )
1403 if( pinLine.at( 0 ) !=
"ATTR" )
1408 if( attr.
key != wxS(
"NO_CONNECT" ) )
1413 VECTOR2I pos = schSym->GetPinPhysicalPosition( schPin->GetLibPin() );
1415 std::unique_ptr<SCH_NO_CONNECT> noConn =
1416 std::make_unique<SCH_NO_CONNECT>( pos );
1418 createdItems.push_back( std::move( noConn ) );
1423 createdItems.push_back( std::move( schSym ) );
1427 std::vector<SHAPE_LINE_CHAIN> wireLines;
1431 for(
const std::vector<double>& ptArr : wire->geometry )
1435 for(
size_t i = 1; i < ptArr.size(); i += 2 )
1441 wireLines.push_back(
chain );
1447 std::unique_ptr<SCH_LINE> schLine =
1449 schLine->SetEndPoint( seg.
B );
1451 createdItems.push_back( std::move( schLine ) );
1456 auto netAttr =
get_opt( attributes,
"NET" );
1460 if( !netAttr->valVisible || netAttr->value.IsEmpty() )
1470 SEG::ecoord dist_sq = ( nearestPt - kpos ).SquaredEuclideanNorm();
1472 if( dist_sq < min_dist_sq )
1474 min_dist_sq = dist_sq;
1475 nearestPos = nearestPt;
1479 std::unique_ptr<SCH_LABEL> label = std::make_unique<SCH_LABEL>();
1484 for(
double i = netAttr->rotation; i > 0; i -= 90 )
1485 label->Rotate90(
true );
1487 label->SetPosition( nearestPos );
1488 label->SetText( netAttr->value );
1492 createdItems.push_back( std::move( label ) );
1500 for( std::unique_ptr<SCH_ITEM>& ptr : createdItems )
1505 sheetBBox.
Merge( ptr->GetBoundingBox() );
1514 offset.
x =
KiROUND( offset.
x / alignGrid ) * alignGrid;
1515 offset.
y =
KiROUND( offset.
y / alignGrid ) * alignGrid;
1522 for( std::unique_ptr<SCH_ITEM>& ptr : createdItems )
1524 ptr->Move( offset );
1525 screen->
Append( ptr.release() );
constexpr EDA_IU_SCALE schIUScale
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
constexpr size_type GetWidth() 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 size_type GetHeight() const
constexpr coord_type GetLeft() const
constexpr coord_type GetTop() const
constexpr void Offset(coord_type dx, coord_type dy)
void SetFlags(EDA_ITEM_FLAGS aMask)
KICAD_T Type() const
Returns the type of object.
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
virtual const wxString & GetText() const
Return the string associated with the text object.
virtual void SetVisible(bool aVisible)
void SetImportOffsetMM(const VECTOR2D &aOffset)
Set the offset in millimeters to add to coordinates when importing graphic items.
void SetScale(const VECTOR2D &aScale)
Set the scale factor affecting the imported shapes.
std::list< std::unique_ptr< EDA_ITEM > > & GetItems()
Return the list of objects representing the imported shapes.
virtual void SetImporter(GRAPHICS_IMPORTER *aImporter)
Set the receiver of the imported shapes.
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false, const std::vector< wxString > *aEmbeddedFiles=nullptr, bool aForDrawingSheet=false)
A color representation with 4 components: red, green, blue, alpha.
A logical library item identifier and consists of various portions much like a URI.
const UTF8 & GetLibItemName() const
Define a library symbol object.
const LIB_ID & GetLibId() const override
void SetUnitCount(int aCount, bool aDuplicateDrawItems=true)
Set the units per symbol count.
wxString GetFootprint() override
For items with footprint fields.
SCH_FIELD * FindFieldCaseInsensitive(const wxString &aFieldName)
wxString GetName() const override
void SetDescription(const wxString &aDescription)
Gets the Description field text value */.
void SetKeyWords(const wxString &aKeyWords)
SCH_FIELD & GetValueField()
Return reference to the value field.
void AddField(SCH_FIELD *aField)
Add a field.
void AddDrawItem(SCH_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
SCH_FIELD & GetReferenceField()
Return reference to the reference designator field.
Describe the page size and margins of a paper page on which to eventually print or plot.
void SetHeightMils(double aHeightInMils)
void SetWidthMils(double aWidthInMils)
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...
bool ReadImageFile(const wxString &aFullFilename)
Read and store an image file.
void SetImageScale(double aScale)
Set the image "zoom" value.
Holds all the data relating to one schematic.
SCH_SHEET_PATH & CurrentSheet() const
static double Convert(wxString aValue)
static VECTOR2< T > ScalePos(VECTOR2< T > aValue)
double SizeToKi(wxString units)
static T ScaleSize(T aValue)
void ApplyFontStyle(const std::map< wxString, nlohmann::json > &fontStyles, T &text, const wxString &styleStr)
static VECTOR2< T > ScalePosSym(VECTOR2< T > aValue)
SCH_EASYEDAPRO_PARSER(SCHEMATIC *aSchematic, PROGRESS_REPORTER *aProgressReporter)
EASYEDAPRO::SYM_INFO ParseSymbol(const std::vector< nlohmann::json > &aLines, const std::map< wxString, wxString > &aDeviceAttributes)
void ApplyAttrToField(const std::map< wxString, nlohmann::json > &fontStyles, T *text, const EASYEDAPRO::SCH_ATTR &aAttr, bool aIsSym, bool aToSym, const std::map< wxString, wxString > &aDeviceAttributes={}, SCH_SYMBOL *aParent=nullptr)
void ParseSchematic(SCHEMATIC *aSchematic, SCH_SHEET *aRootSheet, const nlohmann::json &aProject, std::map< wxString, EASYEDAPRO::SYM_INFO > &aSymbolMap, const std::map< wxString, EASYEDAPRO::BLOB > &aBlobMap, const std::vector< nlohmann::json > &aLines, const wxString &aLibName)
wxString ResolveFieldVariables(const wxString aInput, const std::map< wxString, wxString > &aDeviceAttributes)
void ApplyLineStyle(const std::map< wxString, nlohmann::json > &lineStyles, T &shape, const wxString &styleStr)
void SetText(const wxString &aText) override
Base class for any item which can be embedded within the SCHEMATIC container class,...
virtual void MirrorHorizontally(int aCenter)
Mirror item horizontally about aCenter.
virtual void Rotate(const VECTOR2I &aCenter, bool aRotateCCW)
Rotate the item around aCenter 90 degrees in the clockwise direction.
const PAGE_INFO & GetPageSettings() const
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
void SetPageSettings(const PAGE_INFO &aPageSettings)
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
SCH_SCREEN * GetScreen() const
BOX2I GetBodyAndPinsBoundingBox() const override
Return a bounding box for the symbol body and pins but not the fields.
VECTOR2I::extended_type ecoord
const VECTOR2I GetCenter() const
void SetCenter(const VECTOR2I &aCenter)
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
int PointCount() const
Return the number of points (vertices) in this line chain.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const VECTOR2I NearestPoint(const VECTOR2I &aP, bool aAllowInternalShapePoints=true) const
Find a point on the line chain that is closest to point aP.
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.
Simple container to manage line stroke parameters.
void SetLineStyle(LINE_STYLE aLineStyle)
void SetWidth(int aWidth)
void SetColor(const KIGFX::COLOR4D &aColor)
bool Import() override
Actually imports the file.
virtual double GetImageWidth() const override
Return image width from original imported file.
bool LoadFromMemory(const wxMemoryBuffer &aMemBuffer) override
Set memory buffer with content for import.
virtual double GetImageHeight() const override
Return image height from original imported file.
virtual void SetShowPinNumbers(bool aShow)
Set or clear the pin number visibility flag.
virtual void SetShowPinNames(bool aShow)
Set or clear the pin name visibility flag.
static constexpr extended_type ECOORD_MAX
static constexpr EDA_ANGLE ANGLE_VERTICAL
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
#define ENDPOINT
ends. (Used to support dragging.)
#define STARTPOINT
When a line is selected, these flags indicate which.
void ConvertImageToLibShapes(LIB_SYMBOL *aSymbol, int unit, wxImage img, VECTOR2D pixelScale, VECTOR2D offset)
#define THROW_IO_ERROR(msg)
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)
LIB_ID ToKiCadLibID(const wxString &aLibName, const wxString &aLibReference)
std::map< wxString, wxString > AnyMapToStringMap(const std::map< wxString, nlohmann::json > &aInput)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
PIN_ORIENTATION
The symbol library pin object orientations.
static const std::vector< wxString > c_attributesWhitelist
static LINE_STYLE ConvertStrokeStyle(const wxString &aStyle)
static const std::vector< wxString > c_attributesWhitelist
static LINE_STYLE ConvertStrokeStyle(int aStyle)
wxString UnescapeHTML(const wxString &aString)
Return a new wxString unescaped from HTML format.
LINE_STYLE
Dashed line types.
std::optional< VECTOR2D > position
std::unique_ptr< LIB_SYMBOL > libSymbol
std::vector< PIN_INFO > pins
std::optional< EASYEDAPRO::SCH_ATTR > symbolAttr
std::map< wxString, int > partUnits
EASYEDAPRO::SYM_HEAD head
constexpr double IUTomm(int iu) const
constexpr int IUToMils(int iu) const
constexpr int MilsToIU(int mils) const
const SHAPE_LINE_CHAIN chain
SHAPE_CIRCLE circle(c.m_circle_center, c.m_circle_radius)
GR_TEXT_H_ALIGN_T
This is API surface mapped to common.types.HorizontalAlignment.
GR_TEXT_V_ALIGN_T
This is API surface mapped to common.types.VertialAlignment.
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D