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,
319 auto parent = aParent;
322 int orient =
static_cast<SCH_SYMBOL*
>( parent )->GetOrientation();
400 const std::map<wxString, wxString>& aDeviceAttributes )
404 std::unique_ptr<LIB_SYMBOL> ksymbolPtr = std::make_unique<LIB_SYMBOL>( wxEmptyString );
407 std::map<wxString, nlohmann::json> lineStyles;
408 std::map<wxString, nlohmann::json> fontStyles;
409 std::map<wxString, int> partUnits;
411 std::map<int, std::map<wxString, EASYEDAPRO::SCH_ATTR>> unitAttributes;
412 std::map<int, std::map<wxString, std::vector<nlohmann::json>>> unitParentedLines;
416 for(
const nlohmann::json& line : aLines )
418 wxString type = line.at( 0 );
420 if( type == wxS(
"LINESTYLE" ) )
421 lineStyles[line.at( 1 )] = line;
422 else if( type == wxS(
"FONTSTYLE" ) )
423 fontStyles[line.at( 1 )] = line;
424 else if( type == wxS(
"PART" ) )
425 partUnits[line.at( 1 )] = ++totalUnits;
433 for(
const nlohmann::json& line : aLines )
435 wxString type = line.at( 0 );
437 if( type == wxS(
"PART" ) )
439 currentUnit = partUnits.at( line.at( 1 ) );
441 else if( type == wxS(
"RECT" ) )
443 VECTOR2D start( line.at( 2 ), line.at( 3 ) );
444 VECTOR2D end( line.at( 4 ), line.at( 5 ) );
445 wxString styleStr = line.at( 9 );
447 auto rect = std::make_unique<SCH_SHAPE>( SHAPE_T::RECTANGLE,
LAYER_DEVICE );
452 rect->SetUnit( currentUnit );
457 else if( type == wxS(
"CIRCLE" ) )
459 VECTOR2D center( line.at( 2 ), line.at( 3 ) );
460 double radius = line.at( 4 );
461 wxString styleStr = line.at( 5 );
463 auto circle = std::make_unique<SCH_SHAPE>( SHAPE_T::CIRCLE,
LAYER_DEVICE );
468 circle->SetUnit( currentUnit );
473 else if( type == wxS(
"ARC" ) )
475 VECTOR2D start( line.at( 2 ), line.at( 3 ) );
476 VECTOR2D mid( line.at( 4 ), line.at( 5 ) );
477 VECTOR2D end( line.at( 6 ), line.at( 7 ) );
478 wxString styleStr = line.at( 8 );
484 auto shape = std::make_unique<SCH_SHAPE>( SHAPE_T::ARC,
LAYER_DEVICE );
486 shape->SetArcGeometry( kstart, kmid, kend );
488 shape->SetUnit( currentUnit );
493 else if( type == wxS(
"POLY" ) )
495 std::vector<double> points = line.at( 2 );
496 wxString styleStr = line.at( 4 );
498 auto shape = std::make_unique<SCH_SHAPE>( SHAPE_T::POLY,
LAYER_DEVICE );
500 for(
size_t i = 1; i < points.size(); i += 2 )
503 shape->SetUnit( currentUnit );
508 else if( type == wxS(
"TEXT" ) )
510 VECTOR2D pos( line.at( 2 ), line.at( 3 ) );
511 double angle = line.at( 4 );
512 wxString textStr = line.at( 5 );
513 wxString fontStyleStr = line.at( 6 );
520 text->SetTextAngleDegrees( angle );
522 text->SetUnit( currentUnit );
527 else if( type == wxS(
"OBJ" ) )
530 wxString mimeType, data;
534 if( line.at( 3 ).is_number() )
536 start =
VECTOR2D( line.at( 3 ), line.at( 4 ) );
537 size =
VECTOR2D( line.at( 5 ), line.at( 6 ) );
539 upsideDown = line.at( 8 );
541 wxString imageUrl = line.at( 9 );
543 if( imageUrl.BeforeFirst(
':' ) == wxS(
"data" ) )
545 wxArrayString paramsArr =
546 wxSplit( imageUrl.AfterFirst(
':' ).BeforeFirst(
',' ),
';',
'\0' );
548 data = imageUrl.AfterFirst(
',' );
550 if( paramsArr.size() > 0 )
552 mimeType = paramsArr[0];
556 else if( line.at( 3 ).is_string() )
558 mimeType = line.at( 3 ).get<wxString>().BeforeFirst(
';' );
560 start =
VECTOR2D( line.at( 4 ), line.at( 5 ) );
561 size =
VECTOR2D( line.at( 6 ), line.at( 7 ) );
563 data = line.at( 9 ).get<wxString>();
566 if( mimeType.empty() || data.empty() )
569 wxMemoryBuffer buf = wxBase64Decode( data );
571 if( mimeType == wxS(
"image/svg+xml" ) )
590 libsymImporter.
SetScale( pixelScale );
599 for( std::unique_ptr<EDA_ITEM>& item : libsymImporter.
GetItems() )
604 wxMemoryInputStream memis( buf.GetData(), buf.GetDataLen() );
606 wxImage::SetDefaultLoadFlags( wxImage::GetDefaultLoadFlags()
607 & ~wxImage::Load_Verbose );
609 if( img.LoadFile( memis, mimeType ) )
611 int dimMul = img.GetWidth() * img.GetHeight();
612 double maxPixels = 30000;
614 if( dimMul > maxPixels )
616 double scale = sqrt( maxPixels / dimMul );
617 img.Rescale( img.GetWidth() *
scale, img.GetHeight() *
scale );
628 else if( type == wxS(
"HEAD" ) )
632 else if( type == wxS(
"PIN" ) )
634 wxString pinId = line.at( 1 );
635 unitParentedLines[currentUnit][pinId].push_back( line );
637 else if( type == wxS(
"ATTR" ) )
639 wxString parentId = line.at( 2 );
641 if( parentId.empty() )
644 unitAttributes[currentUnit].emplace( attr.
key, attr );
648 unitParentedLines[currentUnit][parentId].push_back( line );
663 if(
auto globalNetAttr =
get_opt( unitAttributes[1], wxS(
"Global Net Name" ) ) )
667 wxString globalNetname = globalNetAttr->value;
669 if( !globalNetname.empty() )
672 _(
"Power symbol creates a global label with name '%s'" ),
679 auto designatorAttr =
get_opt( unitAttributes[1], wxS(
"Designator" ) );
681 if( designatorAttr && !designatorAttr->value.empty() )
683 wxString symbolPrefix = designatorAttr->value;
685 if( symbolPrefix.EndsWith( wxS(
"?" ) ) )
686 symbolPrefix.RemoveLast();
693 if(
auto valOpt =
get_opt( aDeviceAttributes, attrName ) )
695 if( valOpt->empty() )
706 wxString value = *valOpt;
708 value.Replace( wxS(
"\u2103" ), wxS(
"\u00B0C" ),
true );
716 for(
auto& [unitId, parentedLines] : unitParentedLines )
718 for(
auto& [pinId, lines] : parentedLines )
720 std::optional<EASYEDAPRO::SYM_PIN> epin;
721 std::map<wxString, EASYEDAPRO::SCH_ATTR> pinAttributes;
723 for(
const nlohmann::json& line : lines )
725 wxString type = line.at( 0 );
727 if( type == wxS(
"ATTR" ) )
730 pinAttributes.emplace( attr.
key, attr );
732 else if( type == wxS(
"PIN" ) )
744 std::unique_ptr<SCH_PIN>
pin = std::make_unique<SCH_PIN>( ksymbol );
746 pin->SetUnit( unitId );
753 if( epin->rotation == 0 )
754 orient = PIN_ORIENTATION::PIN_RIGHT;
755 if( epin->rotation == 90 )
756 orient = PIN_ORIENTATION::PIN_UP;
757 if( epin->rotation == 180 )
758 orient = PIN_ORIENTATION::PIN_LEFT;
759 if( epin->rotation == 270 )
760 orient = PIN_ORIENTATION::PIN_DOWN;
762 pin->SetOrientation( orient );
769 else if(
auto pinNameAttr =
get_opt( pinAttributes,
"NAME" ) )
771 pin->SetName( pinNameAttr->value );
772 pinInfo.
name = pinNameAttr->value;
774 if( !pinNameAttr->valVisible )
778 if(
auto pinNumAttr =
get_opt( pinAttributes,
"NUMBER" ) )
780 pin->SetNumber( pinNumAttr->value );
781 pinInfo.
number = pinNumAttr->value;
783 if( !pinNumAttr->valVisible )
789 pin->SetType( ELECTRICAL_PINTYPE::PT_POWER_IN );
791 else if(
auto pinTypeAttr =
get_opt( pinAttributes,
"Pin Type" ) )
793 if( pinTypeAttr->value == wxS(
"IN" ) )
794 pin->SetType( ELECTRICAL_PINTYPE::PT_INPUT );
795 if( pinTypeAttr->value == wxS(
"OUT" ) )
796 pin->SetType( ELECTRICAL_PINTYPE::PT_OUTPUT );
797 if( pinTypeAttr->value == wxS(
"BI" ) )
798 pin->SetType( ELECTRICAL_PINTYPE::PT_BIDI );
801 if(
get_opt( pinAttributes,
"NO_CONNECT" ) )
802 pin->SetType( ELECTRICAL_PINTYPE::PT_NC );
804 if(
pin->GetNumberTextSize() *
int(
pin->GetNumber().size() ) >
pin->GetLength() )
805 pin->SetNumberTextSize(
pin->GetLength() /
pin->GetNumber().size() );
807 symInfo.
pins.push_back( pinInfo );
825 symInfo.
libSymbol = std::move( ksymbolPtr );
832 const nlohmann::json& aProject,
833 std::map<wxString, EASYEDAPRO::SYM_INFO>& aSymbolMap,
834 const std::map<wxString, EASYEDAPRO::BLOB>& aBlobMap,
835 const std::vector<nlohmann::json>& aLines,
836 const wxString& aLibName )
838 std::vector<std::unique_ptr<SCH_ITEM>> createdItems;
840 std::map<wxString, std::vector<nlohmann::json>> parentedLines;
841 std::map<wxString, std::vector<nlohmann::json>> ruleLines;
843 std::map<wxString, nlohmann::json> lineStyles;
844 std::map<wxString, nlohmann::json> fontStyles;
846 for(
const nlohmann::json& line : aLines )
848 wxString type = line.at( 0 );
850 if( type == wxS(
"LINESTYLE" ) )
851 lineStyles[line.at( 1 )] = line;
852 else if( type == wxS(
"FONTSTYLE" ) )
853 fontStyles[line.at( 1 )] = line;
856 for(
const nlohmann::json& line : aLines )
858 wxString type = line.at( 0 );
860 if( type == wxS(
"RECT" ) )
862 VECTOR2D start( line.at( 2 ), line.at( 3 ) );
863 VECTOR2D end( line.at( 4 ), line.at( 5 ) );
864 wxString styleStr = line.at( 9 );
866 std::unique_ptr<SCH_SHAPE> rect = std::make_unique<SCH_SHAPE>( SHAPE_T::RECTANGLE );
868 rect->SetStart(
ScalePos( start ) );
873 createdItems.push_back( std::move( rect ) );
875 else if( type == wxS(
"CIRCLE" ) )
877 VECTOR2D center( line.at( 2 ), line.at( 3 ) );
878 double radius = line.at( 4 );
879 wxString styleStr = line.at( 5 );
881 std::unique_ptr<SCH_SHAPE> circle = std::make_unique<SCH_SHAPE>( SHAPE_T::CIRCLE );
883 circle->SetCenter(
ScalePos( center ) );
888 createdItems.push_back( std::move( circle ) );
890 else if( type == wxS(
"POLY" ) )
892 std::vector<double> points = line.at( 2 );
893 wxString styleStr = line.at( 4 );
897 for(
size_t i = 1; i < points.size(); i += 2 )
900 for(
int segId = 0; segId < chain.
SegmentCount(); segId++ )
904 std::unique_ptr<SCH_LINE> schLine =
906 schLine->SetEndPoint( seg.
B );
910 createdItems.push_back( std::move( schLine ) );
913 else if( type == wxS(
"TEXT" ) )
915 VECTOR2D pos( line.at( 2 ), line.at( 3 ) );
916 double angle = line.at( 4 );
917 wxString textStr = line.at( 5 );
918 wxString fontStyleStr = line.at( 6 );
920 std::unique_ptr<SCH_TEXT>
text =
926 text->SetTextAngleDegrees( angle );
930 createdItems.push_back( std::move(
text ) );
932 else if( type == wxS(
"OBJ" ) )
935 wxString mimeType, base64Data;
939 if( line.at( 3 ).is_number() )
941 start =
VECTOR2D( line.at( 3 ), line.at( 4 ) );
942 size =
VECTOR2D( line.at( 5 ), line.at( 6 ) );
943 angle = line.at( 7 );
944 flipped = line.at( 8 );
946 wxString imageUrl = line.at( 9 );
948 if( imageUrl.BeforeFirst(
':' ) == wxS(
"data" ) )
950 wxArrayString paramsArr =
951 wxSplit( imageUrl.AfterFirst(
':' ).BeforeFirst(
',' ),
';',
'\0' );
953 base64Data = imageUrl.AfterFirst(
',' );
955 if( paramsArr.size() > 0 )
956 mimeType = paramsArr[0];
958 else if( imageUrl.BeforeFirst(
':' ) == wxS(
"blob" ) )
960 wxString objectId = imageUrl.AfterLast(
':' );
962 if(
auto blob =
get_opt( aBlobMap, objectId ) )
964 wxString blobUrl = blob->url;
966 if( blobUrl.BeforeFirst(
':' ) == wxS(
"data" ) )
968 wxArrayString paramsArr = wxSplit(
969 blobUrl.AfterFirst(
':' ).BeforeFirst(
',' ),
';',
'\0' );
971 base64Data = blobUrl.AfterFirst(
',' );
973 if( paramsArr.size() > 0 )
974 mimeType = paramsArr[0];
979 else if( line.at( 3 ).is_string() )
981 mimeType = line.at( 3 ).get<wxString>().BeforeFirst(
';' );
983 start =
VECTOR2D( line.at( 4 ), line.at( 5 ) );
984 size =
VECTOR2D( line.at( 6 ), line.at( 7 ) );
985 angle = line.at( 8 );
986 base64Data = line.at( 9 ).get<wxString>();
992 if( mimeType.empty() || base64Data.empty() )
995 wxMemoryBuffer buf = wxBase64Decode( base64Data );
997 if( mimeType == wxS(
"image/svg+xml" ) )
1011 schImporter.
SetScale( pixelScale );
1017 svgImportPlugin.
Import();
1019 for( std::unique_ptr<EDA_ITEM>& item : schImporter.
GetItems() )
1023 for(
double i = angle; i > 0; i -= 90 )
1029 schItem->
Rotate( kstart,
false );
1033 schItem->
Rotate( kstart,
false );
1038 schItem->
Rotate( kstart,
false );
1054 createdItems.emplace_back( schItem );
1059 std::unique_ptr<SCH_BITMAP> bitmap = std::make_unique<SCH_BITMAP>();
1061 wxImage::SetDefaultLoadFlags( wxImage::GetDefaultLoadFlags()
1062 & ~wxImage::Load_Verbose );
1064 if( bitmap->ReadImageFile( buf ) )
1066 VECTOR2D kcenter = kstart + ksize / 2;
1068 double scaleFactor =
ScaleSize( size.
x ) / bitmap->GetSize().x;
1069 bitmap->SetImageScale( scaleFactor );
1070 bitmap->SetPosition( kcenter );
1072 for(
double i = angle; i > 0; i -= 90 )
1073 bitmap->Rotate( kstart,
false );
1076 bitmap->MirrorHorizontally( kstart.
x );
1078 createdItems.push_back( std::move( bitmap ) );
1082 if( type == wxS(
"WIRE" ) )
1084 wxString wireId = line.at( 1 );
1085 parentedLines[wireId].push_back( line );
1087 else if( type == wxS(
"COMPONENT" ) )
1089 wxString compId = line.at( 1 );
1090 parentedLines[compId].push_back( line );
1092 else if( type == wxS(
"ATTR" ) )
1094 wxString compId = line.at( 2 );
1095 parentedLines[compId].push_back( line );
1099 for(
auto& [parentId, lines] : parentedLines )
1101 std::optional<EASYEDAPRO::SCH_COMPONENT> component;
1102 std::optional<EASYEDAPRO::SCH_WIRE> wire;
1103 std::map<wxString, EASYEDAPRO::SCH_ATTR> attributes;
1105 for(
const nlohmann::json& line : lines )
1107 if( line.at( 0 ) ==
"COMPONENT" )
1111 else if( line.at( 0 ) ==
"WIRE" )
1115 else if( line.at( 0 ) ==
"ATTR" )
1118 attributes.emplace( attr.
key, attr );
1124 auto deviceAttr =
get_opt( attributes,
"Device" );
1125 auto symbolAttr =
get_opt( attributes,
"Symbol" );
1130 std::map<wxString, wxString> compAttrs =
1131 aProject.at(
"devices" ).at( deviceAttr->value ).at(
"attributes" );
1135 if( symbolAttr && !symbolAttr->value.IsEmpty() )
1136 symbolId = symbolAttr->value;
1138 symbolId = compAttrs.at(
"Symbol" );
1140 auto it = aSymbolMap.find( symbolId );
1141 if( it == aSymbolMap.end() )
1143 wxLogError(
"Symbol of '%s' with uuid '%s' not found.", component->name, symbolId );
1150 wxString unitName = component->name;
1155 auto schSym = std::make_unique<SCH_SYMBOL>( newLibSymbol, libId,
1161 for(
double i = component->rotation; i > 0; i -= 90 )
1162 schSym->Rotate(
VECTOR2I(),
false );
1164 if( component->mirror )
1165 schSym->MirrorHorizontally( 0 );
1167 schSym->SetPosition(
ScalePos( component->position ) );
1171 if(
auto globalNetAttr =
get_opt( attributes,
"Global Net Name" ) )
1174 false,
true, compAttrs, schSym.get() );
1176 for(
SCH_PIN*
pin : schSym->GetAllLibPins() )
1177 pin->SetName( globalNetAttr->value );
1185 schSym->SetRef( &aSchematic->
CurrentSheet(), wxS(
"#PWR?" ) );
1190 auto nameAttr =
get_opt( attributes,
"Name" );
1194 std::unique_ptr<SCH_GLOBALLABEL> label = std::make_unique<SCH_GLOBALLABEL>(
1195 ScalePos( component->position ), nameAttr->value );
1201 wxString symStr = esymInfo.
symbolAttr->value;
1203 if( symStr == wxS(
"Netport-IN" ) )
1206 label->SetShape( LABEL_FLAG_SHAPE::L_INPUT );
1208 if( symStr == wxS(
"Netport-OUT" ) )
1211 label->SetShape( LABEL_FLAG_SHAPE::L_OUTPUT );
1213 if( symStr == wxS(
"Netport-BI" ) )
1216 label->SetShape( LABEL_FLAG_SHAPE::L_BIDI );
1220 for(
double i = component->rotation; i > 0; i -= 90 )
1223 label->SetSpinStyle( spin );
1225 nlohmann::json style = fontStyles[nameAttr->fontStyle];
1227 if( !style.is_null() && style.at( 5 ).is_number() )
1229 double size = style.at( 5 ).get<
double>() * 0.5;
1233 createdItems.push_back( std::move( label ) );
1242 if(
auto valOpt =
get_opt( compAttrs, attrKey ) )
1244 if( valOpt->empty() )
1251 text = schSym->AddField(
1252 SCH_FIELD( schSym.get(), schSym->GetFieldCount(), attrKey ) );
1255 wxString value = *valOpt;
1257 value.Replace( wxS(
"\u2103" ), wxS(
"\u00B0C" ), true );
1259 text->SetText( value );
1260 text->SetVisible(
false );
1264 auto nameAttr =
get_opt( attributes,
"Name" );
1265 auto valueAttr =
get_opt( attributes,
"Value" );
1267 std::optional<EASYEDAPRO::SCH_ATTR> targetValueAttr;
1269 if( valueAttr && !valueAttr->value.empty() && valueAttr->valVisible )
1270 targetValueAttr = valueAttr;
1271 else if( nameAttr && !nameAttr->value.empty() && nameAttr->valVisible )
1272 targetValueAttr = nameAttr;
1273 else if( valueAttr && !valueAttr->value.empty() )
1274 targetValueAttr = valueAttr;
1275 else if( nameAttr && !nameAttr->value.empty() )
1276 targetValueAttr = nameAttr;
1278 if( targetValueAttr )
1281 false,
true, compAttrs, schSym.get() );
1284 if(
auto descrAttr =
get_opt( attributes,
"Description" ) )
1287 false,
true, compAttrs, schSym.get() );
1290 if(
auto designatorAttr =
get_opt( attributes,
"Designator" ) )
1293 *designatorAttr,
false,
true, compAttrs, schSym.get() );
1295 schSym->SetRef( &aSchematic->
CurrentSheet(), designatorAttr->value );
1298 for(
auto& [attrKey, attr] : attributes )
1300 if( attrKey == wxS(
"Name" ) || attrKey == wxS(
"Value" )
1301 || attrKey == wxS(
"Global Net Name" ) || attrKey == wxS(
"Designator" )
1302 || attrKey == wxS(
"Description" ) || attrKey == wxS(
"Device" )
1303 || attrKey == wxS(
"Footprint" ) || attrKey == wxS(
"Symbol" )
1304 || attrKey == wxS(
"Unique ID" ) )
1309 if( attr.value.IsEmpty() )
1316 text = schSym->AddField(
1317 SCH_FIELD( schSym.get(), schSym->GetFieldCount(), attrKey ) );
1320 text->SetPosition( schSym->GetPosition() );
1329 wxString pinKey = parentId + pinInfo.
pin.
id;
1330 auto pinLines =
get_opt( parentedLines, pinKey );
1335 for(
const nlohmann::json& pinLine : *pinLines )
1337 if( pinLine.at( 0 ) !=
"ATTR" )
1342 if( attr.
key != wxS(
"NO_CONNECT" ) )
1347 VECTOR2I pos = schSym->GetPinPhysicalPosition( schPin->GetLibPin() );
1349 std::unique_ptr<SCH_NO_CONNECT> noConn =
1350 std::make_unique<SCH_NO_CONNECT>( pos );
1352 createdItems.push_back( std::move( noConn ) );
1357 createdItems.push_back( std::move( schSym ) );
1361 std::vector<SHAPE_LINE_CHAIN> wireLines;
1365 for(
const std::vector<double>& ptArr : wire->geometry )
1369 for(
size_t i = 1; i < ptArr.size(); i += 2 )
1375 wireLines.push_back( chain );
1377 for(
int segId = 0; segId < chain.
SegmentCount(); segId++ )
1381 std::unique_ptr<SCH_LINE> schLine =
1383 schLine->SetEndPoint( seg.
B );
1385 createdItems.push_back( std::move( schLine ) );
1390 auto netAttr =
get_opt( attributes,
"NET" );
1394 if( !netAttr->valVisible )
1403 VECTOR2I nearestPt = chain.NearestPoint( kpos,
false );
1404 SEG::ecoord dist_sq = ( nearestPt - kpos ).SquaredEuclideanNorm();
1406 if( dist_sq < min_dist_sq )
1408 min_dist_sq = dist_sq;
1409 nearestPos = nearestPt;
1413 std::unique_ptr<SCH_LABEL> label = std::make_unique<SCH_LABEL>();
1418 for(
double i = netAttr->rotation; i > 0; i -= 90 )
1419 label->Rotate90(
true );
1421 label->SetPosition( nearestPos );
1422 label->SetText( netAttr->value );
1426 createdItems.push_back( std::move( label ) );
1434 for( std::unique_ptr<SCH_ITEM>& ptr : createdItems )
1439 sheetBBox.
Merge( ptr->GetBoundingBox() );
1448 offset.
x =
KiROUND( offset.
x / alignGrid ) * alignGrid;
1449 offset.
y =
KiROUND( offset.
y / alignGrid ) * alignGrid;
1456 for( std::unique_ptr<SCH_ITEM>& ptr : createdItems )
1458 ptr->Move( offset );
1459 screen->
Append( ptr.release() );
constexpr EDA_IU_SCALE schIUScale
size_type GetHeight() const
coord_type GetTop() const
size_type GetWidth() const
coord_type GetLeft() const
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
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.
int GetNextAvailableFieldId() const
SCH_FIELD & GetValueField() const
Return reference to the value field.
SCH_FIELD & GetFootprintField() const
Return reference to the footprint field.
wxString GetName() const override
void SetDescription(const wxString &aDescription)
Gets the Description field text value */.
void SetKeyWords(const wxString &aKeyWords)
SCH_FIELD & GetReferenceField() const
Return reference to the reference designator field.
SCH_FIELD * FindField(const wxString &aFieldName, bool aCaseInsensitive=false)
Find a field within this symbol matching aFieldName and returns it or NULL if not found.
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.
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.
Holds all the data relating to one schematic.
SCH_SHEET_PATH & CurrentSheet() const override
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)
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
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
Return a bounding box for the symbol body and pins but not the fields.
VECTOR2I::extended_type ecoord
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.
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)
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
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
@ DESCRIPTION_FIELD
Field Description of part, i.e. "1/4W 1% Metal Film Resistor".
constexpr ret_type KiROUND(fp_type v, bool aQuiet=false)
Round a floating point number to an integer using "round halfway cases away from zero".
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D