diff --git a/common/plugins/altium/altium_parser_utils.cpp b/common/plugins/altium/altium_parser_utils.cpp index be09de90e2..e13f1c0e0f 100644 --- a/common/plugins/altium/altium_parser_utils.cpp +++ b/common/plugins/altium/altium_parser_utils.cpp @@ -26,7 +26,8 @@ #include #include - +#include +#include LIB_ID AltiumToKiCadLibID( const wxString& aLibName, const wxString& aLibReference ) { @@ -141,3 +142,76 @@ wxString AltiumSpecialStringsToKiCadVariables( const wxString& return result; } + +wxString AltiumPinNamesToKiCad( wxString& aString ) +{ + wxString output; + wxString tempString; + bool hasPrev = false; + wxUniChar prev; + + + for( wxString::const_iterator it = aString.begin(); it != aString.end(); ++it ) + { + char ch = 0; + + if( (*it).GetAsChar( &ch ) ) + { + if( ch == '\\' ) + { + if( hasPrev ) + { + tempString += prev; + hasPrev = false; + } + + continue; // Backslash is ignored and not added to the output + } + } + + if( hasPrev ) // Two letters in a row with no backslash + { + if( !tempString.empty() ) + { + output += "~{" + tempString + "}"; + tempString.Clear(); + } + + output += prev; + } + + prev = *it; + hasPrev = true; + } + + // Append any leftover escaped string + if( !tempString.IsEmpty() ) + { + output += "~{" + tempString + "}"; + } + + if( hasPrev ) + { + output += prev; + } + + return output; +} + +VECTOR2I AltiumGetEllipticalPos( double aMajor, double aMinor, double aAngleRadians ) +{ + if( aMajor == 0 || aMinor == 0 ) + return VECTOR2I( 0, 0 ); + + double numerator = aMajor * aMinor; + double majorTerm = aMajor * sin( aAngleRadians ); + double minorTerm = aMinor * cos( aAngleRadians ); + double denominator = sqrt( majorTerm * majorTerm + minorTerm * minorTerm ); + + double radius = numerator / denominator; + + VECTOR2I retval( KiROUND( radius * cos( aAngleRadians ) ), KiROUND( radius * sin( aAngleRadians ) ) ); + + return retval; + +} \ No newline at end of file diff --git a/common/plugins/altium/altium_parser_utils.h b/common/plugins/altium/altium_parser_utils.h index 5bfabd5062..fad555ac3d 100644 --- a/common/plugins/altium/altium_parser_utils.h +++ b/common/plugins/altium/altium_parser_utils.h @@ -31,6 +31,7 @@ #include #include +#include LIB_ID AltiumToKiCadLibID( const wxString& aLibName, const wxString& aLibReference ); @@ -39,4 +40,6 @@ wxString AltiumPropertyToKiCadString( const wxString& aString ); wxString AltiumSpecialStringsToKiCadVariables( const wxString& aString, const std::map& aOverrides ); +wxString AltiumPinNamesToKiCad( wxString& aString ); +VECTOR2I AltiumGetEllipticalPos( double aMajor, double aMinor, double aAngleRadians ); #endif //ALTIUM_PARSER_UTILS_H diff --git a/eeschema/sch_plugins/altium/altium_parser_sch.cpp b/eeschema/sch_plugins/altium/altium_parser_sch.cpp index b4b537b4f2..f7dc3daf78 100644 --- a/eeschema/sch_plugins/altium/altium_parser_sch.cpp +++ b/eeschema/sch_plugins/altium/altium_parser_sch.cpp @@ -141,14 +141,12 @@ ASCH_SYMBOL::ASCH_SYMBOL( const std::map& aProps ) } -ASCH_PIN::ASCH_PIN( const std::map& aProps ) +ASCH_PIN::ASCH_PIN( const std::map& aProps ) : + ASCH_OWNER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::PIN ); isKiCadLibPin = ALTIUM_PARSER::ReadBool( aProps, "ISKICADLIBPIN", false ); - - ownerindex = ReadOwnerIndex( aProps ); - ownerpartid = ReadOwnerPartId( aProps ); ownerpartdisplaymode = ALTIUM_PARSER::ReadInt( aProps, "OWNERPARTDISPLAYMODE", 0 ); name = ALTIUM_PARSER::ReadString( aProps, "NAME", "" ); @@ -176,7 +174,9 @@ ASCH_PIN::ASCH_PIN( const std::map& aProps ) hidden = ( pinconglomerate & 0x04 ) != 0; showPinName = ( pinconglomerate & 0x08 ) != 0; showDesignator = ( pinconglomerate & 0x10 ) != 0; - // graphically locked pins are in bit 0x40, but we don't care about that + // 0x20 is unknown + locked = ( pinconglomerate & 0x40 ) != 0; + int x = ALTIUM_PARSER::ReadInt( aProps, "LOCATION.X", 0 ); int xfrac = ALTIUM_PARSER::ReadInt( aProps, "LOCATION.X_FRAC", 0 ); @@ -235,6 +235,15 @@ ASCH_PIN::ASCH_PIN( const std::map& aProps ) } +ASCH_OWNER_INTERFACE::ASCH_OWNER_INTERFACE( const std::map& aProps ) +{ + ownerindex = ReadOwnerIndex( aProps ); + ownerpartid = ReadOwnerPartId( aProps ); + ownerpartdisplaymode = ALTIUM_PARSER::ReadInt( aProps, "OWNERPARTDISPLAYMODE", 0 ); + indexinsheet = ALTIUM_PARSER::ReadInt( aProps, "INDEXINSHEET", 0 ); +} + + ASCH_FILL_INTERFACE::ASCH_FILL_INTERFACE( const std::map& aProps ) { AreaColor = ALTIUM_PARSER::ReadInt( aProps, "AREACOLOR", 0 ); @@ -255,22 +264,12 @@ ASCH_BORDER_INTERFACE::ASCH_BORDER_INTERFACE( const std::map Color = ALTIUM_PARSER::ReadInt( aProps, "COLOR", 0 ); } -ASCH_SHAPE_INTERFACE::ASCH_SHAPE_INTERFACE( const std::map& aProps ) -{ - OwnerIndex = ReadOwnerIndex( aProps ); - OwnerPartID = ReadOwnerPartId( aProps ); - IndexInSheet = ALTIUM_PARSER::ReadInt( aProps, "INDEXINSHEET", 0 ); - OwnerPartDisplayMode = ALTIUM_PARSER::ReadInt( aProps, "OWNERPARTDISPLAYMODE", 0 ); -} - -ASCH_LABEL::ASCH_LABEL( const std::map& aProps ) +ASCH_LABEL::ASCH_LABEL( const std::map& aProps ) : + ASCH_OWNER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::LABEL ); - ownerindex = ReadOwnerIndex( aProps ); - ownerpartid = ReadOwnerPartId( aProps ); - location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ), -ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) ); @@ -287,7 +286,8 @@ ASCH_LABEL::ASCH_LABEL( const std::map& aProps ) } -ASCH_TEXT_FRAME::ASCH_TEXT_FRAME( const std::map& aProps ) +ASCH_TEXT_FRAME::ASCH_TEXT_FRAME( const std::map& aProps ) : + ASCH_OWNER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::NOTE || ReadRecord( aProps ) == ALTIUM_SCH_RECORD::TEXT_FRAME ); @@ -334,7 +334,7 @@ ASCH_NOTE::ASCH_NOTE( const std::map& aProperties ) : ASCH_BEZIER::ASCH_BEZIER( const std::map& aProps ) : - ASCH_SHAPE_INTERFACE( aProps ), + ASCH_OWNER_INTERFACE( aProps ), ASCH_BORDER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::BEZIER ); @@ -351,7 +351,7 @@ ASCH_BEZIER::ASCH_BEZIER( const std::map& aProps ) : ASCH_POLYLINE::ASCH_POLYLINE( const std::map& aProps ) : - ASCH_SHAPE_INTERFACE( aProps ), + ASCH_OWNER_INTERFACE( aProps ), ASCH_BORDER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::POLYLINE ); @@ -376,7 +376,7 @@ ASCH_POLYLINE::ASCH_POLYLINE( const std::map& aProps ) : ASCH_POLYGON::ASCH_POLYGON( const std::map& aProps ) : - ASCH_SHAPE_INTERFACE( aProps ), + ASCH_OWNER_INTERFACE( aProps ), ASCH_FILL_INTERFACE( aProps ), ASCH_BORDER_INTERFACE( aProps ) { @@ -394,7 +394,7 @@ ASCH_POLYGON::ASCH_POLYGON( const std::map& aProps ) : ASCH_ROUND_RECTANGLE::ASCH_ROUND_RECTANGLE( const std::map& aProps ) : - ASCH_SHAPE_INTERFACE( aProps ), + ASCH_OWNER_INTERFACE( aProps ), ASCH_FILL_INTERFACE( aProps ), ASCH_BORDER_INTERFACE( aProps ) { @@ -411,7 +411,7 @@ ASCH_ROUND_RECTANGLE::ASCH_ROUND_RECTANGLE( const std::map& ASCH_ARC::ASCH_ARC( const std::map& aProps ) : - ASCH_SHAPE_INTERFACE( aProps ), + ASCH_OWNER_INTERFACE( aProps ), ASCH_BORDER_INTERFACE( aProps ) { m_IsElliptical = ReadRecord( aProps ) == ALTIUM_SCH_RECORD::ELLIPTICAL_ARC; @@ -431,7 +431,7 @@ ASCH_ARC::ASCH_ARC( const std::map& aProps ) : ASCH_ELLIPSE::ASCH_ELLIPSE( const std::map& aProps ) : - ASCH_SHAPE_INTERFACE( aProps ), + ASCH_OWNER_INTERFACE( aProps ), ASCH_FILL_INTERFACE( aProps ), ASCH_BORDER_INTERFACE( aProps ) { @@ -448,7 +448,7 @@ ASCH_ELLIPSE::ASCH_ELLIPSE( const std::map& aProps ) : ASCH_LINE::ASCH_LINE( const std::map& aProps ) : - ASCH_SHAPE_INTERFACE( aProps ), + ASCH_OWNER_INTERFACE( aProps ), ASCH_BORDER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::LINE ); @@ -460,11 +460,11 @@ ASCH_LINE::ASCH_LINE( const std::map& aProps ) : } -ASCH_SIGNAL_HARNESS::ASCH_SIGNAL_HARNESS( const std::map& aProps ) +ASCH_SIGNAL_HARNESS::ASCH_SIGNAL_HARNESS( const std::map& aProps ) : + ASCH_OWNER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::SIGNAL_HARNESS ); - OwnerPartID = ReadOwnerPartId( aProps ); int locationCount = ALTIUM_PARSER::ReadInt( aProps, "LOCATIONCOUNT", 0 ); @@ -475,18 +475,18 @@ ASCH_SIGNAL_HARNESS::ASCH_SIGNAL_HARNESS( const std::map& aP -ReadKiCadUnitFrac( aProps, "Y" + si ) ); } - IndexInSheet = ALTIUM_PARSER::ReadInt( aProps, "INDEXINSHEET", 0 ); + indexinsheet = ALTIUM_PARSER::ReadInt( aProps, "INDEXINSHEET", 0 ); Color = ALTIUM_PARSER::ReadInt( aProps, "COLOR", 0 ); LineWidth = ReadKiCadUnitFrac( aProps, "LINEWIDTH" ); } -ASCH_HARNESS_CONNECTOR::ASCH_HARNESS_CONNECTOR( const std::map& aProps ) +ASCH_HARNESS_CONNECTOR::ASCH_HARNESS_CONNECTOR( const std::map& aProps ) : + ASCH_OWNER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::HARNESS_CONNECTOR ); - OwnerPartID = ReadOwnerPartId( aProps ); Location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ), -ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) ); @@ -495,13 +495,14 @@ ASCH_HARNESS_CONNECTOR::ASCH_HARNESS_CONNECTOR( const std::map& aProps ) +ASCH_HARNESS_ENTRY::ASCH_HARNESS_ENTRY( const std::map& aProps ) : + ASCH_OWNER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::HARNESS_ENTRY ); @@ -509,9 +510,8 @@ ASCH_HARNESS_ENTRY::ASCH_HARNESS_ENTRY( const std::map& aPro // does not exist in altium file! // ownerindex = ReadOwnerIndex( aProps ); - OwnerPartID = ReadOwnerPartId( aProps ); - IndexInSheet = ALTIUM_PARSER::ReadInt( aProps, "INDEXINSHEET", 0 ); + indexinsheet = ALTIUM_PARSER::ReadInt( aProps, "INDEXINSHEET", 0 ); DistanceFromTop = ReadKiCadUnitFrac1( aProps, "DISTANCEFROMTOP" ); @@ -529,12 +529,12 @@ ASCH_HARNESS_ENTRY::ASCH_HARNESS_ENTRY( const std::map& aPro } -ASCH_HARNESS_TYPE::ASCH_HARNESS_TYPE( const std::map& aProps ) +ASCH_HARNESS_TYPE::ASCH_HARNESS_TYPE( const std::map& aProps ) : + ASCH_OWNER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::HARNESS_TYPE ); //ownerindex = ReadOwnerIndex( aProps ); // use SCH_ALTIUM_PLUGIN::m_harnessEntryParent instead! - OwnerPartID = ReadOwnerPartId( aProps ); Text = ALTIUM_PARSER::ReadString( aProps, "TEXT", "" ); @@ -544,14 +544,14 @@ ASCH_HARNESS_TYPE::ASCH_HARNESS_TYPE( const std::map& aProps IsHidden = ALTIUM_PARSER::ReadBool( aProps, "ISHIDDEN", false ); OwnerIndexAdditionalList = ALTIUM_PARSER::ReadBool( aProps, "OWNERINDEXADDITIONALLIST", true ); - IndexInSheet = ALTIUM_PARSER::ReadInt( aProps, "INDEXINSHEET", 0 ); + indexinsheet = ALTIUM_PARSER::ReadInt( aProps, "INDEXINSHEET", 0 ); Color = ALTIUM_PARSER::ReadInt( aProps, "COLOR", 0 ); FontID = ALTIUM_PARSER::ReadInt( aProps, "TEXTFONTID", 0 ); } ASCH_RECTANGLE::ASCH_RECTANGLE( const std::map& aProps ) : - ASCH_SHAPE_INTERFACE( aProps ), + ASCH_OWNER_INTERFACE( aProps ), ASCH_FILL_INTERFACE( aProps ), ASCH_BORDER_INTERFACE( aProps ) { @@ -565,7 +565,8 @@ ASCH_RECTANGLE::ASCH_RECTANGLE( const std::map& aProps ) : } -ASCH_SHEET_SYMBOL::ASCH_SHEET_SYMBOL( const std::map& aProps ) +ASCH_SHEET_SYMBOL::ASCH_SHEET_SYMBOL( const std::map& aProps ) : + ASCH_OWNER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::SHEET_SYMBOL ); @@ -581,13 +582,11 @@ ASCH_SHEET_SYMBOL::ASCH_SHEET_SYMBOL( const std::map& aProps } -ASCH_SHEET_ENTRY::ASCH_SHEET_ENTRY( const std::map& aProps ) +ASCH_SHEET_ENTRY::ASCH_SHEET_ENTRY( const std::map& aProps ) : + ASCH_OWNER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::SHEET_ENTRY ); - ownerindex = ReadOwnerIndex( aProps ); - ownerpartid = ReadOwnerPartId( aProps ); - // some magic, because it stores those infos in a different unit?? distanceFromTop = ReadKiCadUnitFrac1( aProps, "DISTANCEFROMTOP" ); @@ -600,11 +599,11 @@ ASCH_SHEET_ENTRY::ASCH_SHEET_ENTRY( const std::map& aProps ) } -ASCH_POWER_PORT::ASCH_POWER_PORT( const std::map& aProps ) +ASCH_POWER_PORT::ASCH_POWER_PORT( const std::map& aProps ) : + ASCH_OWNER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::POWER_PORT ); - ownerpartid = ReadOwnerPartId( aProps ); location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ), -ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) ); @@ -620,11 +619,11 @@ ASCH_POWER_PORT::ASCH_POWER_PORT( const std::map& aProps ) } -ASCH_PORT::ASCH_PORT( const std::map& aProps ) +ASCH_PORT::ASCH_PORT( const std::map& aProps ) : + ASCH_OWNER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::PORT ); - OwnerPartID = ReadOwnerPartId( aProps ); Location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ), -ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) ); @@ -660,7 +659,8 @@ ASCH_NO_ERC::ASCH_NO_ERC( const std::map& aProps ) } -ASCH_NET_LABEL::ASCH_NET_LABEL( const std::map& aProps ) +ASCH_NET_LABEL::ASCH_NET_LABEL( const std::map& aProps ) : + ASCH_OWNER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::NET_LABEL ); @@ -677,7 +677,8 @@ ASCH_NET_LABEL::ASCH_NET_LABEL( const std::map& aProps ) } -ASCH_BUS::ASCH_BUS( const std::map& aProps ) +ASCH_BUS::ASCH_BUS( const std::map& aProps ) : + ASCH_OWNER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::BUS ); @@ -696,7 +697,8 @@ ASCH_BUS::ASCH_BUS( const std::map& aProps ) } -ASCH_WIRE::ASCH_WIRE( const std::map& aProps ) +ASCH_WIRE::ASCH_WIRE( const std::map& aProps ) : + ASCH_OWNER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::WIRE ); @@ -715,11 +717,11 @@ ASCH_WIRE::ASCH_WIRE( const std::map& aProps ) } -ASCH_JUNCTION::ASCH_JUNCTION( const std::map& aProps ) +ASCH_JUNCTION::ASCH_JUNCTION( const std::map& aProps ) : + ASCH_OWNER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::JUNCTION ); - ownerpartid = ReadOwnerPartId( aProps ); location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ), -ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) ); @@ -727,7 +729,7 @@ ASCH_JUNCTION::ASCH_JUNCTION( const std::map& aProps ) ASCH_IMAGE::ASCH_IMAGE( const std::map& aProps ) : - ASCH_SHAPE_INTERFACE( aProps ), + ASCH_OWNER_INTERFACE( aProps ), ASCH_BORDER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::IMAGE ); @@ -744,7 +746,8 @@ ASCH_IMAGE::ASCH_IMAGE( const std::map& aProps ) : } -ASCH_SHEET_FONT::ASCH_SHEET_FONT( const std::map& aProps, int aId ) +ASCH_SHEET_FONT::ASCH_SHEET_FONT( const std::map& aProps, int aId ) : + ASCH_OWNER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::SHEET ); @@ -791,7 +794,8 @@ VECTOR2I ASchSheetGetSize( ASCH_SHEET_SIZE aSheetSize ) } -ASCH_SHEET::ASCH_SHEET( const std::map& aProps ) +ASCH_SHEET::ASCH_SHEET( const std::map& aProps ) : + ASCH_OWNER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::SHEET ); @@ -806,13 +810,11 @@ ASCH_SHEET::ASCH_SHEET( const std::map& aProps ) } -ASCH_SHEET_NAME::ASCH_SHEET_NAME( const std::map& aProps ) +ASCH_SHEET_NAME::ASCH_SHEET_NAME( const std::map& aProps ) : + ASCH_OWNER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::SHEET_NAME ); - ownerindex = ReadOwnerIndex( aProps ); - ownerpartid = ReadOwnerPartId( aProps ); - text = ALTIUM_PARSER::ReadString( aProps, "TEXT", "" ); orientation = ReadEnum( aProps, "ORIENTATION", 0, 3, @@ -825,13 +827,11 @@ ASCH_SHEET_NAME::ASCH_SHEET_NAME( const std::map& aProps ) } -ASCH_FILE_NAME::ASCH_FILE_NAME( const std::map& aProps ) +ASCH_FILE_NAME::ASCH_FILE_NAME( const std::map& aProps ) : + ASCH_OWNER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::FILE_NAME ); - ownerindex = ReadOwnerIndex( aProps ); - ownerpartid = ReadOwnerPartId( aProps ); - text = ALTIUM_PARSER::ReadString( aProps, "TEXT", "" ); orientation = ReadEnum( aProps, "ORIENTATION", 0, 3, @@ -844,13 +844,11 @@ ASCH_FILE_NAME::ASCH_FILE_NAME( const std::map& aProps ) } -ASCH_DESIGNATOR::ASCH_DESIGNATOR( const std::map& aProps ) +ASCH_DESIGNATOR::ASCH_DESIGNATOR( const std::map& aProps ) : + ASCH_OWNER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::DESIGNATOR ); - ownerindex = ReadOwnerIndex( aProps ); - ownerpartid = ReadOwnerPartId( aProps ); - name = ALTIUM_PARSER::ReadString( aProps, "NAME", "" ); text = ALTIUM_PARSER::ReadString( aProps, "TEXT", "" ); @@ -865,7 +863,8 @@ ASCH_DESIGNATOR::ASCH_DESIGNATOR( const std::map& aProps ) } -ASCH_IMPLEMENTATION::ASCH_IMPLEMENTATION( const std::map& aProps ) +ASCH_IMPLEMENTATION::ASCH_IMPLEMENTATION( const std::map& aProps ) : + ASCH_OWNER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::IMPLEMENTATION ); @@ -877,15 +876,15 @@ ASCH_IMPLEMENTATION::ASCH_IMPLEMENTATION( const std::map& aP } -ASCH_IMPLEMENTATION_LIST::ASCH_IMPLEMENTATION_LIST( const std::map& aProps ) +ASCH_IMPLEMENTATION_LIST::ASCH_IMPLEMENTATION_LIST( const std::map& aProps ) : + ASCH_OWNER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::IMPLEMENTATION_LIST ); - - ownerindex = ReadOwnerIndex( aProps ); } -ASCH_BUS_ENTRY::ASCH_BUS_ENTRY( const std::map& aProps ) +ASCH_BUS_ENTRY::ASCH_BUS_ENTRY( const std::map& aProps ) : + ASCH_OWNER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::BUS_ENTRY ); @@ -896,13 +895,11 @@ ASCH_BUS_ENTRY::ASCH_BUS_ENTRY( const std::map& aProps ) } -ASCH_PARAMETER::ASCH_PARAMETER( const std::map& aProps ) +ASCH_PARAMETER::ASCH_PARAMETER( const std::map& aProps ) : + ASCH_OWNER_INTERFACE( aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::PARAMETER ); - ownerindex = ReadOwnerIndex( aProps ); - ownerpartid = ReadOwnerPartId( aProps ); - location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ), -ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) ); diff --git a/eeschema/sch_plugins/altium/altium_parser_sch.h b/eeschema/sch_plugins/altium/altium_parser_sch.h index 761aac01e5..5376c53dfa 100644 --- a/eeschema/sch_plugins/altium/altium_parser_sch.h +++ b/eeschema/sch_plugins/altium/altium_parser_sch.h @@ -94,9 +94,9 @@ enum class ALTIUM_SCH_RECORD PARAMETER_SET = 43, IMPLEMENTATION_LIST = 44, IMPLEMENTATION = 45, - RECORD_46 = 46, - RECORD_47 = 47, - RECORD_48 = 48, + MAP_DEFINER_LIST = 46, + MAP_DEFINER = 47, + IMPL_PARAMS = 48, NOTE = 209, COMPILE_MASK = 211, HARNESS_CONNECTOR = 215, @@ -117,14 +117,14 @@ enum class ASCH_RECORD_ORIENTATION }; -struct ASCH_SHAPE_INTERFACE +struct ASCH_OWNER_INTERFACE { - int OwnerIndex; - int OwnerPartID; - int OwnerPartDisplayMode; - int IndexInSheet; + int ownerindex; + int ownerpartid; + int ownerpartdisplaymode; + int indexinsheet; - explicit ASCH_SHAPE_INTERFACE( const std::map& aProps ); + explicit ASCH_OWNER_INTERFACE( const std::map& aProps ); }; struct ASCH_FILL_INTERFACE @@ -302,12 +302,8 @@ enum class ASCH_PIN_ELECTRICAL }; -struct ASCH_PIN +struct ASCH_PIN : ASCH_OWNER_INTERFACE { - int ownerindex; - int ownerpartid; - int ownerpartdisplaymode; - wxString name; wxString text; wxString designator; @@ -329,6 +325,7 @@ struct ASCH_PIN bool showPinName; bool showDesignator; bool hidden; + bool locked; bool isKiCadLibPin; // Tracking variable to handle LibEdit nuance @@ -360,11 +357,8 @@ enum class ASCH_TEXT_FRAME_ALIGNMENT }; -struct ASCH_LABEL +struct ASCH_LABEL : ASCH_OWNER_INTERFACE { - int ownerindex; - int ownerpartid; - VECTOR2I location; wxString text; @@ -387,7 +381,7 @@ struct ASCH_HYPERLINK : ASCH_LABEL }; -struct ASCH_TEXT_FRAME +struct ASCH_TEXT_FRAME : ASCH_OWNER_INTERFACE { VECTOR2I Location; wxSize Size; @@ -423,7 +417,7 @@ struct ASCH_NOTE : ASCH_TEXT_FRAME }; -struct ASCH_BEZIER : ASCH_SHAPE_INTERFACE, ASCH_BORDER_INTERFACE +struct ASCH_BEZIER : ASCH_OWNER_INTERFACE, ASCH_BORDER_INTERFACE { std::vector points; @@ -449,7 +443,7 @@ enum class ASCH_SHEET_ENTRY_SIDE }; -struct ASCH_POLYLINE : ASCH_SHAPE_INTERFACE, ASCH_BORDER_INTERFACE +struct ASCH_POLYLINE : ASCH_OWNER_INTERFACE, ASCH_BORDER_INTERFACE { std::vector Points; @@ -459,7 +453,7 @@ struct ASCH_POLYLINE : ASCH_SHAPE_INTERFACE, ASCH_BORDER_INTERFACE }; -struct ASCH_POLYGON : ASCH_SHAPE_INTERFACE, ASCH_FILL_INTERFACE, ASCH_BORDER_INTERFACE +struct ASCH_POLYGON : ASCH_OWNER_INTERFACE, ASCH_FILL_INTERFACE, ASCH_BORDER_INTERFACE { std::vector points; @@ -467,7 +461,7 @@ struct ASCH_POLYGON : ASCH_SHAPE_INTERFACE, ASCH_FILL_INTERFACE, ASCH_BORDER_INT }; -struct ASCH_ROUND_RECTANGLE : ASCH_SHAPE_INTERFACE, ASCH_FILL_INTERFACE, ASCH_BORDER_INTERFACE +struct ASCH_ROUND_RECTANGLE : ASCH_OWNER_INTERFACE, ASCH_FILL_INTERFACE, ASCH_BORDER_INTERFACE { VECTOR2I BottomLeft; VECTOR2I TopRight; @@ -480,7 +474,7 @@ struct ASCH_ROUND_RECTANGLE : ASCH_SHAPE_INTERFACE, ASCH_FILL_INTERFACE, ASCH_BO }; -struct ASCH_ARC : ASCH_SHAPE_INTERFACE, ASCH_BORDER_INTERFACE +struct ASCH_ARC : ASCH_OWNER_INTERFACE, ASCH_BORDER_INTERFACE { bool m_IsElliptical; VECTOR2I m_Center; @@ -493,7 +487,7 @@ struct ASCH_ARC : ASCH_SHAPE_INTERFACE, ASCH_BORDER_INTERFACE }; -struct ASCH_ELLIPSE : ASCH_SHAPE_INTERFACE, ASCH_FILL_INTERFACE, ASCH_BORDER_INTERFACE +struct ASCH_ELLIPSE : ASCH_OWNER_INTERFACE, ASCH_FILL_INTERFACE, ASCH_BORDER_INTERFACE { VECTOR2I Center; int Radius; @@ -505,7 +499,7 @@ struct ASCH_ELLIPSE : ASCH_SHAPE_INTERFACE, ASCH_FILL_INTERFACE, ASCH_BORDER_INT }; -struct ASCH_LINE : ASCH_SHAPE_INTERFACE, ASCH_BORDER_INTERFACE +struct ASCH_LINE : ASCH_OWNER_INTERFACE, ASCH_BORDER_INTERFACE { VECTOR2I point1; VECTOR2I point2; @@ -514,33 +508,28 @@ struct ASCH_LINE : ASCH_SHAPE_INTERFACE, ASCH_BORDER_INTERFACE }; -struct ASCH_SIGNAL_HARNESS +struct ASCH_SIGNAL_HARNESS : ASCH_OWNER_INTERFACE { - int OwnerPartID; // always -1, can be safely ignored I think - VECTOR2I Point1; VECTOR2I Point2; std::vector Points; int Color; - int IndexInSheet; + int indexinsheet; int LineWidth; explicit ASCH_SIGNAL_HARNESS( const std::map& aProps ); }; -struct ASCH_HARNESS_CONNECTOR +struct ASCH_HARNESS_CONNECTOR : ASCH_OWNER_INTERFACE { - int OwnerPartID; // always -1, can be safely ignored I think - VECTOR2I Location; VECTOR2I Size; int AreaColor; int Color; - int IndexInSheet; // Keeps increasing nicely int LineWidth; //int locationX; // keep just in case //int locationY; @@ -552,17 +541,12 @@ struct ASCH_HARNESS_CONNECTOR }; -struct ASCH_HARNESS_ENTRY +struct ASCH_HARNESS_ENTRY : ASCH_OWNER_INTERFACE { - // Completely random, mostly this entry exists, but not always, should not be used! - // int ownerindex; - - int OwnerPartID; // always -1, can be safely ignored I think - int AreaColor; int Color; int DistanceFromTop; - int IndexInSheet; + int indexinsheet; int TextColor; int TextFontID; int TextStyle; @@ -576,13 +560,10 @@ struct ASCH_HARNESS_ENTRY }; -struct ASCH_HARNESS_TYPE +struct ASCH_HARNESS_TYPE : ASCH_OWNER_INTERFACE { - //int ownerindex; // use SCH_ALTIUM_PLUGIN::m_harnessEntryParent instead! - int OwnerPartID; // Always -1, presumably safe to remuve - int Color; - int IndexInSheet; + int indexinsheet; int FontID; bool IsHidden; @@ -596,7 +577,7 @@ struct ASCH_HARNESS_TYPE }; -struct ASCH_RECTANGLE : ASCH_SHAPE_INTERFACE, ASCH_FILL_INTERFACE, ASCH_BORDER_INTERFACE +struct ASCH_RECTANGLE : ASCH_OWNER_INTERFACE, ASCH_FILL_INTERFACE, ASCH_BORDER_INTERFACE { VECTOR2I BottomLeft; VECTOR2I TopRight; @@ -607,7 +588,7 @@ struct ASCH_RECTANGLE : ASCH_SHAPE_INTERFACE, ASCH_FILL_INTERFACE, ASCH_BORDER_I }; -struct ASCH_SHEET_SYMBOL +struct ASCH_SHEET_SYMBOL : ASCH_OWNER_INTERFACE { VECTOR2I location; VECTOR2I size; @@ -643,11 +624,8 @@ enum class ASCH_PORT_STYLE }; -struct ASCH_SHEET_ENTRY +struct ASCH_SHEET_ENTRY : ASCH_OWNER_INTERFACE { - int ownerindex; - int ownerpartid; - int distanceFromTop; ASCH_SHEET_ENTRY_SIDE side; @@ -678,10 +656,8 @@ enum class ASCH_POWER_PORT_STYLE }; -struct ASCH_POWER_PORT +struct ASCH_POWER_PORT : ASCH_OWNER_INTERFACE { - int ownerpartid; - wxString text; bool showNetName; @@ -693,10 +669,8 @@ struct ASCH_POWER_PORT }; -struct ASCH_PORT +struct ASCH_PORT : ASCH_OWNER_INTERFACE { - int OwnerPartID; - wxString Name; wxString HarnessType; @@ -728,7 +702,7 @@ struct ASCH_NO_ERC }; -struct ASCH_NET_LABEL +struct ASCH_NET_LABEL : ASCH_OWNER_INTERFACE { wxString text; @@ -741,9 +715,8 @@ struct ASCH_NET_LABEL }; -struct ASCH_BUS +struct ASCH_BUS : ASCH_OWNER_INTERFACE { - int indexinsheet; int lineWidth; std::vector points; @@ -752,9 +725,8 @@ struct ASCH_BUS }; -struct ASCH_WIRE +struct ASCH_WIRE : ASCH_OWNER_INTERFACE { - int indexinsheet; int lineWidth; std::vector points; @@ -763,17 +735,15 @@ struct ASCH_WIRE }; -struct ASCH_JUNCTION +struct ASCH_JUNCTION : ASCH_OWNER_INTERFACE { - int ownerpartid; - VECTOR2I location; explicit ASCH_JUNCTION( const std::map& aProps ); }; -struct ASCH_IMAGE : ASCH_SHAPE_INTERFACE, ASCH_BORDER_INTERFACE +struct ASCH_IMAGE : ASCH_OWNER_INTERFACE, ASCH_BORDER_INTERFACE { wxString filename; VECTOR2I location; @@ -786,7 +756,7 @@ struct ASCH_IMAGE : ASCH_SHAPE_INTERFACE, ASCH_BORDER_INTERFACE }; -struct ASCH_SHEET_FONT +struct ASCH_SHEET_FONT : ASCH_OWNER_INTERFACE { wxString FontName; @@ -836,7 +806,7 @@ enum class ASCH_SHEET_WORKSPACEORIENTATION }; -struct ASCH_SHEET +struct ASCH_SHEET : ASCH_OWNER_INTERFACE { std::vector fonts; @@ -847,11 +817,8 @@ struct ASCH_SHEET }; -struct ASCH_SHEET_NAME +struct ASCH_SHEET_NAME : ASCH_OWNER_INTERFACE { - int ownerindex; - int ownerpartid; - wxString text; ASCH_RECORD_ORIENTATION orientation; @@ -863,11 +830,8 @@ struct ASCH_SHEET_NAME }; -struct ASCH_FILE_NAME +struct ASCH_FILE_NAME : ASCH_OWNER_INTERFACE { - int ownerindex; - int ownerpartid; - wxString text; ASCH_RECORD_ORIENTATION orientation; @@ -879,11 +843,8 @@ struct ASCH_FILE_NAME }; -struct ASCH_DESIGNATOR +struct ASCH_DESIGNATOR : ASCH_OWNER_INTERFACE { - int ownerindex; - int ownerpartid; - wxString name; wxString text; @@ -895,10 +856,8 @@ struct ASCH_DESIGNATOR }; -struct ASCH_IMPLEMENTATION +struct ASCH_IMPLEMENTATION : ASCH_OWNER_INTERFACE { - int ownerindex; - wxString name; wxString type; wxString libname; @@ -909,14 +868,13 @@ struct ASCH_IMPLEMENTATION }; -struct ASCH_IMPLEMENTATION_LIST +struct ASCH_IMPLEMENTATION_LIST : ASCH_OWNER_INTERFACE { - int ownerindex; explicit ASCH_IMPLEMENTATION_LIST( const std::map& aProps ); }; -struct ASCH_BUS_ENTRY +struct ASCH_BUS_ENTRY : ASCH_OWNER_INTERFACE { VECTOR2I location; VECTOR2I corner; @@ -925,11 +883,8 @@ struct ASCH_BUS_ENTRY }; -struct ASCH_PARAMETER +struct ASCH_PARAMETER : ASCH_OWNER_INTERFACE { - int ownerindex; - int ownerpartid; - VECTOR2I location; ASCH_LABEL_JUSTIFICATION justification; ASCH_RECORD_ORIENTATION orientation; diff --git a/eeschema/sch_plugins/altium/sch_altium_plugin.cpp b/eeschema/sch_plugins/altium/sch_altium_plugin.cpp index 85680fccbb..11e7201218 100644 --- a/eeschema/sch_plugins/altium/sch_altium_plugin.cpp +++ b/eeschema/sch_plugins/altium/sch_altium_plugin.cpp @@ -134,6 +134,7 @@ static void SetLibShapeLine( const ASCH_BORDER_INTERFACE& elem, LIB_SHAPE* shape { COLOR4D color = GetColorFromInt( elem.Color ); COLOR4D default_color; + COLOR4D alt_default_color; STROKE_PARAMS stroke; switch( aType ) @@ -155,6 +156,9 @@ static void SetLibShapeLine( const ASCH_BORDER_INTERFACE& elem, LIB_SHAPE* shape break; case ALTIUM_SCH_RECORD::POLYLINE: default_color = COLOR4D( BLACK ); + alt_default_color = COLOR4D( PUREBLUE ); // POLYLINEs get two default colors because they are + // often used for drawing wires in polygons, so we will + // want them the same color break; case ALTIUM_SCH_RECORD::RECTANGLE: default_color = COLOR4D( 0.5, 0, 0, 1.0 ); @@ -167,7 +171,7 @@ static void SetLibShapeLine( const ASCH_BORDER_INTERFACE& elem, LIB_SHAPE* shape break; } - if( color == default_color ) + if( color == default_color || color == alt_default_color ) color = COLOR4D::UNSPECIFIED; shape->SetStroke( STROKE_PARAMS( elem.LineWidth, PLOT_DASH_TYPE::SOLID, color ) ); @@ -765,13 +769,13 @@ void SCH_ALTIUM_PLUGIN::ParseFileHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchF ParseImplementation( properties ); break; - case ALTIUM_SCH_RECORD::RECORD_46: + case ALTIUM_SCH_RECORD::MAP_DEFINER_LIST: break; - case ALTIUM_SCH_RECORD::RECORD_47: + case ALTIUM_SCH_RECORD::MAP_DEFINER: break; - case ALTIUM_SCH_RECORD::RECORD_48: + case ALTIUM_SCH_RECORD::IMPL_PARAMS: break; case ALTIUM_SCH_RECORD::NOTE: @@ -933,14 +937,16 @@ void SCH_ALTIUM_PLUGIN::ParseComponent( int aIndex, -void SCH_ALTIUM_PLUGIN::ParsePin( const std::map& aProperties, LIB_SYMBOL* aSymbol ) +void SCH_ALTIUM_PLUGIN::ParsePin( const std::map& aProperties, std::vector& aSymbol ) { ASCH_PIN elem( aProperties ); - LIB_SYMBOL* symbol = aSymbol; + LIB_SYMBOL* symbol = static_cast( aSymbol.size() ) <= elem.ownerpartdisplaymode + ? nullptr + : aSymbol[elem.ownerpartdisplaymode]; SCH_SYMBOL* schSymbol = nullptr; - if( !aSymbol ) + if( !symbol ) { const auto& libSymbolIt = m_libSymbols.find( elem.ownerindex ); @@ -961,11 +967,17 @@ void SCH_ALTIUM_PLUGIN::ParsePin( const std::map& aPropertie } LIB_PIN* pin = new LIB_PIN( symbol ); + + // Make sure that these are visible when initializing the symbol + // This may be overriden by the file data but not by the pin defaults + pin->SetNameTextSize( schIUScale.MilsToIU( DEFAULT_PINNAME_SIZE ) ); + pin->SetNumberTextSize( schIUScale.MilsToIU( DEFAULT_PINNUM_SIZE ) ); + symbol->AddDrawItem( pin, false ); pin->SetUnit( std::max( 0, elem.ownerpartid ) ); - pin->SetName( elem.name ); + pin->SetName( AltiumPinNamesToKiCad( elem.name ) ); pin->SetNumber( elem.designator ); pin->SetLength( elem.pinlength ); @@ -1184,11 +1196,11 @@ void SetTextPositioning( EDA_TEXT* text, ASCH_LABEL_JUSTIFICATION justification, } -void SCH_ALTIUM_PLUGIN::ParseLabel( const std::map& aProperties, LIB_SYMBOL* aSymbol ) +void SCH_ALTIUM_PLUGIN::ParseLabel( const std::map& aProperties, std::vector& aSymbol ) { ASCH_LABEL elem( aProperties ); - if( !aSymbol && elem.ownerpartid == ALTIUM_COMPONENT_NONE ) + if( aSymbol.empty() && elem.ownerpartid == ALTIUM_COMPONENT_NONE ) { std::map variableMap = { { "APPLICATION_BUILDNUMBER", "KICAD_VERSION" }, @@ -1227,7 +1239,9 @@ void SCH_ALTIUM_PLUGIN::ParseLabel( const std::map& aPropert } else { - LIB_SYMBOL* symbol = aSymbol; + LIB_SYMBOL* symbol = static_cast( aSymbol.size() ) <= elem.ownerpartdisplaymode + ? nullptr + : aSymbol[elem.ownerpartdisplaymode]; SCH_SYMBOL* schsym = nullptr; if( !symbol ) @@ -1251,7 +1265,7 @@ void SCH_ALTIUM_PLUGIN::ParseLabel( const std::map& aPropert symbol->AddDrawItem( textItem, false ); /// Handle labels that are in a library symbol, not on schematic - if( aSymbol ) + if( !schsym ) textItem->SetPosition( GetLibEditPosition(elem.location ) ); else textItem->SetPosition( GetRelativePosition( elem.location + m_sheetOffset, schsym ) ); @@ -1273,14 +1287,14 @@ void SCH_ALTIUM_PLUGIN::ParseLabel( const std::map& aPropert } -void SCH_ALTIUM_PLUGIN::ParseTextFrame( const std::map& aProperties, LIB_SYMBOL* aSymbol ) +void SCH_ALTIUM_PLUGIN::ParseTextFrame( const std::map& aProperties, std::vector& aSymbol ) { ASCH_TEXT_FRAME elem( aProperties ); - if( aSymbol ) - AddLibTextBox( &elem, aSymbol ); - else + if( aSymbol.empty() ) AddTextBox( &elem ); + else + AddLibTextBox( &elem, aSymbol ); } @@ -1356,9 +1370,13 @@ void SCH_ALTIUM_PLUGIN::AddTextBox(const ASCH_TEXT_FRAME *aElem ) } -void SCH_ALTIUM_PLUGIN::AddLibTextBox(const ASCH_TEXT_FRAME *aElem, LIB_SYMBOL *aSymbol ) +void SCH_ALTIUM_PLUGIN::AddLibTextBox(const ASCH_TEXT_FRAME *aElem, std::vector& aSymbol ) { - LIB_TEXTBOX* textBox = new LIB_TEXTBOX( aSymbol ); + if( aElem->ownerpartdisplaymode >= static_cast( aSymbol.size() ) ) + return; + + LIB_SYMBOL* symbol = aSymbol[aElem->ownerpartdisplaymode]; + LIB_TEXTBOX* textBox = new LIB_TEXTBOX( symbol ); VECTOR2I sheetTopRight = GetLibEditPosition( aElem->TopRight ); VECTOR2I sheetBottomLeft = GetLibEditPosition( aElem->BottomLeft ); @@ -1395,13 +1413,13 @@ void SCH_ALTIUM_PLUGIN::AddLibTextBox(const ASCH_TEXT_FRAME *aElem, LIB_SYMBOL * break; } - aSymbol->AddDrawItem( textBox, false ); + symbol->AddDrawItem( textBox, false ); } void SCH_ALTIUM_PLUGIN::ParseBezier( const std::map& aProperties, - LIB_SYMBOL* aSymbol ) + std::vector& aSymbol ) { ASCH_BEZIER elem( aProperties ); @@ -1414,7 +1432,7 @@ void SCH_ALTIUM_PLUGIN::ParseBezier( const std::map& aProper return; } - if( !aSymbol && elem.OwnerPartID == ALTIUM_COMPONENT_NONE ) + if( aSymbol.empty() && elem.ownerpartid == ALTIUM_COMPONENT_NONE ) { SCH_SCREEN* currentScreen = getCurrentScreen(); wxCHECK( currentScreen, /* void */ ); @@ -1462,18 +1480,20 @@ void SCH_ALTIUM_PLUGIN::ParseBezier( const std::map& aProper } else { - LIB_SYMBOL* symbol = aSymbol; + LIB_SYMBOL* symbol = static_cast( aSymbol.size() ) <= elem.ownerpartdisplaymode + ? nullptr + : aSymbol[elem.ownerpartdisplaymode]; SCH_SYMBOL* schsym = nullptr; if( !symbol ) { - const auto& libSymbolIt = m_libSymbols.find( elem.OwnerIndex ); + const auto& libSymbolIt = m_libSymbols.find( elem.ownerindex ); if( libSymbolIt == m_libSymbols.end() ) { // TODO: e.g. can depend on Template (RECORD=39 m_reporter->Report( wxString::Format( wxT( "Bezier's owner (%d) not found." ), - elem.OwnerIndex ), + elem.ownerindex ), RPT_SEVERITY_DEBUG ); return; } @@ -1482,7 +1502,7 @@ void SCH_ALTIUM_PLUGIN::ParseBezier( const std::map& aProper schsym = m_symbols.at( libSymbolIt->first ); } - if( !aSymbol && !IsComponentPartVisible( elem.OwnerIndex, elem.OwnerPartDisplayMode ) ) + if( !symbol && !IsComponentPartVisible( elem.ownerindex, elem.ownerpartdisplaymode ) ) return; for( size_t i = 0; i + 1 < elem.points.size(); i += 3 ) @@ -1493,7 +1513,7 @@ void SCH_ALTIUM_PLUGIN::ParseBezier( const std::map& aProper LIB_SHAPE* line = new LIB_SHAPE( symbol, SHAPE_T::POLY ); symbol->AddDrawItem( line, false ); - line->SetUnit( std::max( 0, elem.OwnerPartID ) ); + line->SetUnit( std::max( 0, elem.ownerpartid ) ); for( size_t j = i; j < elem.points.size() && j < i + 2; j++ ) { @@ -1515,7 +1535,7 @@ void SCH_ALTIUM_PLUGIN::ParseBezier( const std::map& aProper LIB_SHAPE* line = new LIB_SHAPE( symbol, SHAPE_T::POLY ); symbol->AddDrawItem( line, false ); - line->SetUnit( std::max( 0, elem.OwnerPartID ) ); + line->SetUnit( std::max( 0, elem.ownerpartid ) ); for( size_t j = i; j < elem.points.size() && j < i + 2; j++ ) { @@ -1534,7 +1554,7 @@ void SCH_ALTIUM_PLUGIN::ParseBezier( const std::map& aProper LIB_SHAPE* bezier = new LIB_SHAPE( symbol, SHAPE_T::BEZIER ); symbol->AddDrawItem( bezier, false ); - bezier->SetUnit( std::max( 0, elem.OwnerPartID ) ); + bezier->SetUnit( std::max( 0, elem.ownerpartid ) ); for( size_t j = i; j < elem.points.size() && j < i + 4; j++ ) { @@ -1563,11 +1583,11 @@ void SCH_ALTIUM_PLUGIN::ParseBezier( const std::map& aProper void SCH_ALTIUM_PLUGIN::ParsePolyline( const std::map& aProperties, - LIB_SYMBOL* aSymbol ) + std::vector& aSymbol ) { ASCH_POLYLINE elem( aProperties ); - if( !aSymbol && elem.OwnerPartID == ALTIUM_COMPONENT_NONE ) + if( aSymbol.empty() && elem.ownerpartid == ALTIUM_COMPONENT_NONE ) { SCH_SCREEN* screen = getCurrentScreen(); wxCHECK( screen, /* void */ ); @@ -1585,18 +1605,20 @@ void SCH_ALTIUM_PLUGIN::ParsePolyline( const std::map& aProp } else { - LIB_SYMBOL* symbol = aSymbol; + LIB_SYMBOL* symbol = static_cast( aSymbol.size() ) <= elem.ownerpartdisplaymode + ? nullptr + : aSymbol[elem.ownerpartdisplaymode]; SCH_SYMBOL* schsym = nullptr; - if( !aSymbol ) + if( !symbol ) { - const auto& libSymbolIt = m_libSymbols.find( elem.OwnerIndex ); + const auto& libSymbolIt = m_libSymbols.find( elem.ownerindex ); if( libSymbolIt == m_libSymbols.end() ) { // TODO: e.g. can depend on Template (RECORD=39 m_reporter->Report( wxString::Format( wxT( "Polyline's owner (%d) not found." ), - elem.OwnerIndex ), + elem.ownerindex ), RPT_SEVERITY_DEBUG ); return; } @@ -1605,13 +1627,13 @@ void SCH_ALTIUM_PLUGIN::ParsePolyline( const std::map& aProp schsym = m_symbols.at( libSymbolIt->first ); } - if( !aSymbol && !IsComponentPartVisible( elem.OwnerIndex, elem.OwnerPartDisplayMode ) ) + if( !symbol && !IsComponentPartVisible( elem.ownerindex, elem.ownerpartdisplaymode ) ) return; LIB_SHAPE* line = new LIB_SHAPE( symbol, SHAPE_T::POLY ); symbol->AddDrawItem( line, false ); - line->SetUnit( elem.OwnerPartID ); + line->SetUnit( elem.ownerpartid ); for( VECTOR2I& point : elem.Points ) { @@ -1631,11 +1653,11 @@ void SCH_ALTIUM_PLUGIN::ParsePolyline( const std::map& aProp void SCH_ALTIUM_PLUGIN::ParsePolygon( const std::map& aProperties, - LIB_SYMBOL* aSymbol ) + std::vector& aSymbol ) { ASCH_POLYGON elem( aProperties ); - if( !aSymbol && elem.OwnerPartID == ALTIUM_COMPONENT_NONE ) + if( aSymbol.empty() && elem.ownerpartid == ALTIUM_COMPONENT_NONE ) { SCH_SCREEN* screen = getCurrentScreen(); wxCHECK( screen, /* void */ ); @@ -1654,18 +1676,20 @@ void SCH_ALTIUM_PLUGIN::ParsePolygon( const std::map& aPrope } else { - LIB_SYMBOL* symbol = aSymbol; + LIB_SYMBOL* symbol = static_cast( aSymbol.size() ) <= elem.ownerpartdisplaymode + ? nullptr + : aSymbol[elem.ownerpartdisplaymode]; SCH_SYMBOL* schsym = nullptr; - if( !aSymbol ) + if( !symbol ) { - const auto& libSymbolIt = m_libSymbols.find( elem.OwnerIndex ); + const auto& libSymbolIt = m_libSymbols.find( elem.ownerindex ); if( libSymbolIt == m_libSymbols.end() ) { // TODO: e.g. can depend on Template (RECORD=39 m_reporter->Report( wxString::Format( wxT( "Polygon's owner (%d) not found." ), - elem.OwnerIndex ), + elem.ownerindex ), RPT_SEVERITY_DEBUG ); return; } @@ -1674,13 +1698,13 @@ void SCH_ALTIUM_PLUGIN::ParsePolygon( const std::map& aPrope schsym = m_symbols.at( libSymbolIt->first ); } - if( !aSymbol && !IsComponentPartVisible( elem.OwnerIndex, elem.OwnerPartDisplayMode ) ) + if( !symbol && !IsComponentPartVisible( elem.ownerindex, elem.ownerpartdisplaymode ) ) return; LIB_SHAPE* line = new LIB_SHAPE( symbol, SHAPE_T::POLY ); symbol->AddDrawItem( line, false ); - line->SetUnit( elem.OwnerPartID ); + line->SetUnit( elem.ownerpartid ); for( VECTOR2I& point : elem.points ) { @@ -1709,14 +1733,14 @@ void SCH_ALTIUM_PLUGIN::ParsePolygon( const std::map& aPrope void SCH_ALTIUM_PLUGIN::ParseRoundRectangle( const std::map& aProperties, - LIB_SYMBOL* aSymbol ) + std::vector& aSymbol ) { ASCH_ROUND_RECTANGLE elem( aProperties ); VECTOR2I sheetTopRight = elem.TopRight + m_sheetOffset; VECTOR2I sheetBottomLeft = elem.BottomLeft + m_sheetOffset; - if( !aSymbol && elem.OwnerPartID == ALTIUM_COMPONENT_NONE ) + if( aSymbol.empty() && elem.ownerpartid == ALTIUM_COMPONENT_NONE ) { SCH_SCREEN* screen = getCurrentScreen(); wxCHECK( screen, /* void */ ); @@ -1734,19 +1758,21 @@ void SCH_ALTIUM_PLUGIN::ParseRoundRectangle( const std::map& } else { - LIB_SYMBOL* symbol = aSymbol; + LIB_SYMBOL* symbol = static_cast( aSymbol.size() ) <= elem.ownerpartdisplaymode + ? nullptr + : aSymbol[elem.ownerpartdisplaymode]; SCH_SYMBOL* schsym = nullptr; - if( !aSymbol ) + if( !symbol ) { - const auto& libSymbolIt = m_libSymbols.find( elem.OwnerIndex ); + const auto& libSymbolIt = m_libSymbols.find( elem.ownerindex ); if( libSymbolIt == m_libSymbols.end() ) { // TODO: e.g. can depend on Template (RECORD=39 m_reporter->Report( wxString::Format( wxT( "Rounded rectangle's owner (%d) not " "found." ), - elem.OwnerIndex ), + elem.ownerindex ), RPT_SEVERITY_DEBUG ); return; } @@ -1755,17 +1781,22 @@ void SCH_ALTIUM_PLUGIN::ParseRoundRectangle( const std::map& schsym = m_symbols.at( libSymbolIt->first ); } - if( !aSymbol && !IsComponentPartVisible( elem.OwnerIndex, elem.OwnerPartDisplayMode ) ) + if( !symbol && !IsComponentPartVisible( elem.ownerindex, elem.ownerpartdisplaymode ) ) return; LIB_SHAPE* rect = nullptr; // If it is a circle, make it a circle - if( elem.CornerRadius.GetX() >= std::abs( elem.TopRight.x - elem.BottomLeft.x ) / 2 - && elem.CornerRadius.GetY() >= std::abs( elem.TopRight.y - elem.BottomLeft.y ) / 2 ) + if( std::abs( elem.CornerRadius.GetX() ) + >= std::abs( elem.TopRight.x - elem.BottomLeft.x ) / 2 + && std::abs( elem.CornerRadius.GetY() ) + >= std::abs( elem.TopRight.y - elem.BottomLeft.y ) / 2 ) { rect = new LIB_SHAPE( symbol, SHAPE_T::CIRCLE ); rect->SetPosition( GetLibEditPosition( ( sheetTopRight + sheetBottomLeft ) / 2 ) ); + rect->SetEnd( VECTOR2I( rect->GetPosition().x + std::abs( elem.CornerRadius.GetX() ), + rect->GetPosition().y ) ); + } else { @@ -1789,12 +1820,12 @@ void SCH_ALTIUM_PLUGIN::ParseRoundRectangle( const std::map& SetLibShapeFillAndColor( elem, rect, ALTIUM_SCH_RECORD::ROUND_RECTANGLE, elem.Color ); symbol->AddDrawItem( rect, false ); - rect->SetUnit( elem.OwnerPartID ); + rect->SetUnit( elem.ownerpartid ); } } -void SCH_ALTIUM_PLUGIN::ParseArc( const std::map& aProperties, LIB_SYMBOL* aSymbol ) +void SCH_ALTIUM_PLUGIN::ParseArc( const std::map& aProperties, std::vector& aSymbol ) { // The Arc can be ALTIUM_SCH_RECORD::ELLIPTICAL_ARC or ALTIUM_SCH_RECORD::ARC // Elliptical arcs are not handled in KiCad. So use an arc instead @@ -1809,7 +1840,7 @@ void SCH_ALTIUM_PLUGIN::ParseArc( const std::map& aPropertie if( elem.m_IsElliptical ) arc_radius = std::max( elem.m_Radius, elem.m_SecondaryRadius ); - if( !aSymbol && elem.OwnerPartID == ALTIUM_COMPONENT_NONE ) + if( aSymbol.empty() && elem.ownerpartid == ALTIUM_COMPONENT_NONE ) { SCH_SCREEN* currentScreen = getCurrentScreen(); wxCHECK( currentScreen, /* void */ ); @@ -1843,18 +1874,20 @@ void SCH_ALTIUM_PLUGIN::ParseArc( const std::map& aPropertie } else { - LIB_SYMBOL* symbol = aSymbol; + LIB_SYMBOL* symbol = static_cast( aSymbol.size() ) <= elem.ownerpartdisplaymode + ? nullptr + : aSymbol[elem.ownerpartdisplaymode]; SCH_SYMBOL* schsym = nullptr; - if( !aSymbol ) + if( !symbol ) { - const auto& libSymbolIt = m_libSymbols.find( elem.OwnerIndex ); + const auto& libSymbolIt = m_libSymbols.find( elem.ownerindex ); if( libSymbolIt == m_libSymbols.end() ) { // TODO: e.g. can depend on Template (RECORD=39 m_reporter->Report( wxString::Format( wxT( "Arc's owner (%d) not found." ), - elem.OwnerIndex ), + elem.ownerindex ), RPT_SEVERITY_DEBUG ); return; } @@ -1863,7 +1896,7 @@ void SCH_ALTIUM_PLUGIN::ParseArc( const std::map& aPropertie schsym = m_symbols.at( libSymbolIt->first ); } - if( !aSymbol && !IsComponentPartVisible( elem.OwnerIndex, elem.OwnerPartDisplayMode ) ) + if( !symbol && !IsComponentPartVisible( elem.ownerindex, elem.ownerpartdisplaymode ) ) return; if( elem.m_StartAngle == 0 && ( elem.m_EndAngle == 0 || elem.m_EndAngle == 360 ) ) @@ -1871,7 +1904,7 @@ void SCH_ALTIUM_PLUGIN::ParseArc( const std::map& aPropertie LIB_SHAPE* circle = new LIB_SHAPE( symbol, SHAPE_T::CIRCLE ); symbol->AddDrawItem( circle, false ); - circle->SetUnit( std::max( 0, elem.OwnerPartID ) ); + circle->SetUnit( std::max( 0, elem.ownerpartid ) ); if( !schsym ) circle->SetPosition( GetLibEditPosition( elem.m_Center ) ); @@ -1885,22 +1918,35 @@ void SCH_ALTIUM_PLUGIN::ParseArc( const std::map& aPropertie { LIB_SHAPE* arc = new LIB_SHAPE( symbol, SHAPE_T::ARC ); symbol->AddDrawItem( arc, false ); - arc->SetUnit( std::max( 0, elem.OwnerPartID ) ); + arc->SetUnit( std::max( 0, elem.ownerpartid ) ); if( !schsym ) arc->SetCenter( GetLibEditPosition( elem.m_Center ) ); else arc->SetCenter( GetRelativePosition( elem.m_Center + m_sheetOffset, schsym ) ); - VECTOR2I arcStart( arc_radius, 0 ); - RotatePoint( arcStart, -EDA_ANGLE( elem.m_StartAngle, DEGREES_T ) ); + VECTOR2I arcStart = AltiumGetEllipticalPos( + elem.m_Radius, elem.m_SecondaryRadius, + -EDA_ANGLE( elem.m_StartAngle, DEGREES_T ).AsRadians() ); arcStart += arc->GetCenter(); - arc->SetStart( arcStart ); - VECTOR2I arcEnd( arc_radius, 0 ); - RotatePoint( arcEnd, -EDA_ANGLE( elem.m_EndAngle, DEGREES_T ) ); + VECTOR2I arcEnd = AltiumGetEllipticalPos( + elem.m_Radius, elem.m_SecondaryRadius, + -EDA_ANGLE( elem.m_EndAngle, DEGREES_T ).AsRadians() ); arcEnd += arc->GetCenter(); - arc->SetEnd( arcEnd ); + + double end_angle = elem.m_EndAngle; + + if( elem.m_EndAngle < elem.m_StartAngle ) + end_angle += 360; + + double mid_angle = std::fmod( ( elem.m_StartAngle + end_angle ) / 2, 360 ); + VECTOR2I arcMid = AltiumGetEllipticalPos( + elem.m_Radius, elem.m_SecondaryRadius, + -EDA_ANGLE( mid_angle, DEGREES_T ).AsRadians() ); + arcMid += arc->GetCenter(); + + arc->SetArcGeometry( arcStart, arcMid, arcEnd ); SetLibShapeLine( elem, arc, ALTIUM_SCH_RECORD::ARC ); } @@ -1908,7 +1954,7 @@ void SCH_ALTIUM_PLUGIN::ParseArc( const std::map& aPropertie } -void SCH_ALTIUM_PLUGIN::ParseEllipse( const std::map& aProperties, LIB_SYMBOL* aSymbol ) +void SCH_ALTIUM_PLUGIN::ParseEllipse( const std::map& aProperties, std::vector& aSymbol ) { ASCH_ELLIPSE elem( aProperties ); @@ -1924,7 +1970,7 @@ void SCH_ALTIUM_PLUGIN::ParseEllipse( const std::map& aPrope return; } - if( !aSymbol && elem.OwnerPartID == ALTIUM_COMPONENT_NONE ) + if( aSymbol.empty() && elem.ownerpartid == ALTIUM_COMPONENT_NONE ) { SCH_SCREEN* screen = getCurrentScreen(); wxCHECK( screen, /* void */ ); @@ -1957,18 +2003,20 @@ void SCH_ALTIUM_PLUGIN::ParseEllipse( const std::map& aPrope } else { - LIB_SYMBOL* symbol = aSymbol; + LIB_SYMBOL* symbol = static_cast( aSymbol.size() ) <= elem.ownerpartdisplaymode + ? nullptr + : aSymbol[elem.ownerpartdisplaymode]; SCH_SYMBOL* schsym = nullptr; - if( !aSymbol ) + if( !symbol ) { - const auto& libSymbolIt = m_libSymbols.find( elem.OwnerIndex ); + const auto& libSymbolIt = m_libSymbols.find( elem.ownerindex ); if( libSymbolIt == m_libSymbols.end() ) { // TODO: e.g. can depend on Template (RECORD=39 m_reporter->Report( wxString::Format( wxT( "Ellipse's owner (%d) not found." ), - elem.OwnerIndex ), + elem.ownerindex ), RPT_SEVERITY_DEBUG ); return; } @@ -1983,8 +2031,8 @@ void SCH_ALTIUM_PLUGIN::ParseEllipse( const std::map& aPrope symbol->AddDrawItem( arc1, false ); symbol->AddDrawItem( arc2, false ); - arc1->SetUnit( elem.OwnerPartID ); - arc2->SetUnit( elem.OwnerPartID ); + arc1->SetUnit( elem.ownerpartid ); + arc2->SetUnit( elem.ownerpartid ); if( !schsym ) { @@ -2017,11 +2065,11 @@ void SCH_ALTIUM_PLUGIN::ParseEllipse( const std::map& aPrope } -void SCH_ALTIUM_PLUGIN::ParseCircle( const std::map& aProperties, LIB_SYMBOL* aSymbol ) +void SCH_ALTIUM_PLUGIN::ParseCircle( const std::map& aProperties, std::vector& aSymbol ) { ASCH_ELLIPSE elem( aProperties ); - if( !aSymbol && elem.OwnerPartID == ALTIUM_COMPONENT_NONE ) + if( aSymbol.empty() && elem.ownerpartid == ALTIUM_COMPONENT_NONE ) { SCH_SCREEN* screen = getCurrentScreen(); wxCHECK( screen, /* void */ ); @@ -2043,18 +2091,20 @@ void SCH_ALTIUM_PLUGIN::ParseCircle( const std::map& aProper } else { - LIB_SYMBOL* symbol = aSymbol; + LIB_SYMBOL* symbol = static_cast( aSymbol.size() ) <= elem.ownerpartdisplaymode + ? nullptr + : aSymbol[elem.ownerpartdisplaymode]; SCH_SYMBOL* schsym = nullptr; - if( !aSymbol ) + if( !symbol ) { - const auto& libSymbolIt = m_libSymbols.find( elem.OwnerIndex ); + const auto& libSymbolIt = m_libSymbols.find( elem.ownerindex ); if( libSymbolIt == m_libSymbols.end() ) { // TODO: e.g. can depend on Template (RECORD=39 m_reporter->Report( wxString::Format( wxT( "Ellipse's owner (%d) not found." ), - elem.OwnerIndex ), + elem.ownerindex ), RPT_SEVERITY_DEBUG ); return; } @@ -2066,7 +2116,7 @@ void SCH_ALTIUM_PLUGIN::ParseCircle( const std::map& aProper LIB_SHAPE* circle = new LIB_SHAPE( symbol, SHAPE_T::CIRCLE ); symbol->AddDrawItem( circle, false ); - circle->SetUnit( elem.OwnerPartID ); + circle->SetUnit( elem.ownerpartid ); if( !schsym ) circle->SetPosition( GetLibEditPosition( elem.Center ) ); @@ -2081,11 +2131,11 @@ void SCH_ALTIUM_PLUGIN::ParseCircle( const std::map& aProper } -void SCH_ALTIUM_PLUGIN::ParseLine( const std::map& aProperties, LIB_SYMBOL* aSymbol ) +void SCH_ALTIUM_PLUGIN::ParseLine( const std::map& aProperties, std::vector& aSymbol ) { ASCH_LINE elem( aProperties ); - if( !aSymbol && elem.OwnerPartID == ALTIUM_COMPONENT_NONE ) + if( aSymbol.empty() && elem.ownerpartid == ALTIUM_COMPONENT_NONE ) { SCH_SCREEN* screen = getCurrentScreen(); @@ -2101,18 +2151,20 @@ void SCH_ALTIUM_PLUGIN::ParseLine( const std::map& aProperti } else { - LIB_SYMBOL* symbol = aSymbol; + LIB_SYMBOL* symbol = static_cast( aSymbol.size() ) <= elem.ownerpartdisplaymode + ? nullptr + : aSymbol[elem.ownerpartdisplaymode]; SCH_SYMBOL* schsym = nullptr; - if( !aSymbol ) + if( !symbol ) { - const auto& libSymbolIt = m_libSymbols.find( elem.OwnerIndex ); + const auto& libSymbolIt = m_libSymbols.find( elem.ownerindex ); if( libSymbolIt == m_libSymbols.end() ) { // TODO: e.g. can depend on Template (RECORD=39 m_reporter->Report( wxString::Format( wxT( "Line's owner (%d) not found." ), - elem.OwnerIndex ), + elem.ownerindex ), RPT_SEVERITY_DEBUG ); return; } @@ -2121,13 +2173,13 @@ void SCH_ALTIUM_PLUGIN::ParseLine( const std::map& aProperti schsym = m_symbols.at( libSymbolIt->first ); } - if( !aSymbol && !IsComponentPartVisible( elem.OwnerIndex, elem.OwnerPartDisplayMode ) ) + if( !symbol && !IsComponentPartVisible( elem.ownerindex, elem.ownerpartdisplaymode ) ) return; LIB_SHAPE* line = new LIB_SHAPE( symbol, SHAPE_T::POLY ); symbol->AddDrawItem( line, false ); - line->SetUnit( std::max( 0, elem.OwnerPartID ) ); + line->SetUnit( std::max( 0, elem.ownerpartid ) ); if( !schsym ) { @@ -2149,7 +2201,7 @@ void SCH_ALTIUM_PLUGIN::ParseSignalHarness( const std::map& { ASCH_SIGNAL_HARNESS elem( aProperties ); - if( elem.OwnerPartID == ALTIUM_COMPONENT_NONE ) + if( elem.ownerpartid == ALTIUM_COMPONENT_NONE ) { SCH_SCREEN* screen = getCurrentScreen(); wxCHECK( screen, /* void */ ); @@ -2179,7 +2231,7 @@ void SCH_ALTIUM_PLUGIN::ParseHarnessConnector( int aIndex, const std::map& aP void SCH_ALTIUM_PLUGIN::ParseRectangle( const std::map& aProperties, - LIB_SYMBOL* aSymbol ) + std::vector& aSymbol ) { ASCH_RECTANGLE elem( aProperties ); VECTOR2I sheetTopRight = elem.TopRight + m_sheetOffset; VECTOR2I sheetBottomLeft = elem.BottomLeft + m_sheetOffset; - if( elem.OwnerPartID == ALTIUM_COMPONENT_NONE ) + if( elem.ownerpartid == ALTIUM_COMPONENT_NONE ) { SCH_SCREEN* screen = getCurrentScreen(); wxCHECK( screen, /* void */ ); @@ -2332,18 +2384,20 @@ void SCH_ALTIUM_PLUGIN::ParseRectangle( const std::map& aPro } else { - LIB_SYMBOL* symbol = aSymbol; + LIB_SYMBOL* symbol = static_cast( aSymbol.size() ) <= elem.ownerpartdisplaymode + ? nullptr + : aSymbol[elem.ownerpartdisplaymode]; SCH_SYMBOL* schsym = nullptr; - if( !aSymbol ) + if( !symbol ) { - const auto& libSymbolIt = m_libSymbols.find( elem.OwnerIndex ); + const auto& libSymbolIt = m_libSymbols.find( elem.ownerindex ); if( libSymbolIt == m_libSymbols.end() ) { // TODO: e.g. can depend on Template (RECORD=39 m_reporter->Report( wxString::Format( wxT( "Rectangle's owner (%d) not found." ), - elem.OwnerIndex ), + elem.ownerindex ), RPT_SEVERITY_DEBUG ); return; } @@ -2352,13 +2406,13 @@ void SCH_ALTIUM_PLUGIN::ParseRectangle( const std::map& aPro schsym = m_symbols.at( libSymbolIt->first ); } - if( !aSymbol && !IsComponentPartVisible( elem.OwnerIndex, elem.OwnerPartDisplayMode ) ) + if( !symbol && !IsComponentPartVisible( elem.ownerindex, elem.ownerpartdisplaymode ) ) return; LIB_SHAPE* rect = new LIB_SHAPE( symbol, SHAPE_T::RECTANGLE ); symbol->AddDrawItem( rect, false ); - rect->SetUnit( elem.OwnerPartID ); + rect->SetUnit( elem.ownerpartid ); if( !schsym ) { @@ -3088,11 +3142,11 @@ void SCH_ALTIUM_PLUGIN::ParseImage( const std::map& aPropert { ASCH_IMAGE elem( aProperties ); - const auto& component = m_altiumComponents.find( elem.OwnerIndex ); + const auto& component = m_altiumComponents.find( elem.ownerindex ); //Hide the image if it is owned by a component but the part id do not match if( component != m_altiumComponents.end() - && component->second.currentpartid != elem.OwnerPartID ) + && component->second.currentpartid != elem.ownerpartid ) return; VECTOR2I center = ( elem.location + elem.corner ) / 2 + m_sheetOffset; @@ -3250,14 +3304,18 @@ void SCH_ALTIUM_PLUGIN::ParseFileName( const std::map& aProp void SCH_ALTIUM_PLUGIN::ParseDesignator( const std::map& aProperties, - LIB_SYMBOL* aSymbol ) + std::vector& aSymbol ) { ASCH_DESIGNATOR elem( aProperties ); - if( aSymbol ) + if( !aSymbol.empty() ) { + wxCHECK_RET( static_cast( aSymbol.size() ) > elem.ownerpartdisplaymode, wxT( "Invalid ownerpartdisplaymode" ) ); + + LIB_SYMBOL* symbol = aSymbol[elem.ownerpartdisplaymode]; + bool emptyRef = elem.text.IsEmpty(); - LIB_FIELD& refField = aSymbol->GetReferenceField(); + LIB_FIELD& refField = symbol->GetReferenceField(); if( emptyRef ) refField.SetText( wxT( "X?" ) ); @@ -3323,7 +3381,7 @@ void SCH_ALTIUM_PLUGIN::ParseBusEntry( const std::map& aProp void SCH_ALTIUM_PLUGIN::ParseParameter( const std::map& aProperties, - LIB_SYMBOL* aSymbol ) + std::vector& aSymbol ) { ASCH_PARAMETER elem( aProperties ); @@ -3333,7 +3391,7 @@ void SCH_ALTIUM_PLUGIN::ParseParameter( const std::map& aPro { "VALUE", "ALTIUM_VALUE" }, }; - if( !aSymbol && elem.ownerindex <= 0 && elem.ownerpartid == ALTIUM_COMPONENT_NONE ) + if( aSymbol.empty() && elem.ownerindex <= 0 && elem.ownerpartid == ALTIUM_COMPONENT_NONE ) { // This is some sheet parameter if( elem.text == "*" ) @@ -3368,10 +3426,12 @@ void SCH_ALTIUM_PLUGIN::ParseParameter( const std::map& aPro } else { - LIB_SYMBOL* libSymbol = aSymbol; + wxCHECK_RET( static_cast( aSymbol.size() ) > elem.ownerpartdisplaymode, wxT( "Invalid ownerpartdisplaymode" ) ); + + LIB_SYMBOL* libSymbol = aSymbol[elem.ownerpartdisplaymode]; SCH_SYMBOL* symbol = nullptr; - if( !aSymbol ) + if( !symbol ) { const auto& libSymbolIt = m_libSymbols.find( elem.ownerindex ); @@ -3511,33 +3571,45 @@ void SCH_ALTIUM_PLUGIN::ParseImplementation( const std::map& -LIB_SYMBOL* SCH_ALTIUM_PLUGIN::ParseLibComponent( const std::map& aProperties ) +std::vector SCH_ALTIUM_PLUGIN::ParseLibComponent( const std::map& aProperties ) { ASCH_SYMBOL elem( aProperties ); - LIB_ID libId = AltiumToKiCadLibID( getLibName(), elem.libreference ); + std::vector symbols; - LIB_SYMBOL* ksymbol = new LIB_SYMBOL( wxEmptyString ); - ksymbol->SetName( elem.libreference ); - ksymbol->SetDescription( elem.componentdescription ); - ksymbol->SetLibId( libId ); - ksymbol->SetUnitCount( elem.partcount - 1 ); + symbols.reserve( elem.displaymodecount ); - return ksymbol; + for( int i = 0; i < elem.displaymodecount; i++ ) + { + LIB_SYMBOL* symbol = new LIB_SYMBOL( wxEmptyString ); + + if( elem.displaymodecount > 1 ) + symbol->SetName( wxString::Format( "%s (Altium Display %d)", elem.libreference, i + 1 ) ); + else + symbol->SetName( elem.libreference ); + + LIB_ID libId = AltiumToKiCadLibID( getLibName(), symbol->GetName() ); + symbol->SetDescription( elem.componentdescription ); + symbol->SetLibId( libId ); + symbol->SetUnitCount( elem.partcount - 1 ); + symbols.push_back( symbol ); + } + + return symbols; } -std::map SCH_ALTIUM_PLUGIN::ParseLibFile( const ALTIUM_COMPOUND_FILE& aAltiumSchFile ) +std::map SCH_ALTIUM_PLUGIN::ParseLibFile( const ALTIUM_COMPOUND_FILE& aAltiumLibFile ) { std::map ret; { - const CFB::COMPOUND_FILE_ENTRY* file = aAltiumSchFile.FindStream( { "FileHeader" } ); + const CFB::COMPOUND_FILE_ENTRY* file = aAltiumLibFile.FindStream( { "FileHeader" } ); if( file == nullptr ) THROW_IO_ERROR( "FileHeader not found" ); - ALTIUM_PARSER reader( aAltiumSchFile, file ); + ALTIUM_PARSER reader( aAltiumLibFile, file ); if( reader.GetRemainingBytes() <= 0 ) { @@ -3545,12 +3617,12 @@ std::map SCH_ALTIUM_PLUGIN::ParseLibFile( const ALTIUM_COM } } - std::map syms = aAltiumSchFile.GetLibSymbols( nullptr ); + std::map syms = aAltiumLibFile.GetLibSymbols( nullptr ); for( auto& [name, entry] : syms ) { - ALTIUM_PARSER reader( aAltiumSchFile, entry ); - LIB_SYMBOL* symbol = nullptr; + ALTIUM_PARSER reader( aAltiumLibFile, entry ); + std::vector symbols; if( reader.GetRemainingBytes() <= 0 ) { @@ -3565,7 +3637,7 @@ std::map SCH_ALTIUM_PLUGIN::ParseLibFile( const ALTIUM_COM if( record != ALTIUM_SCH_RECORD::COMPONENT ) THROW_IO_ERROR( "LibSymbol does not start with COMPONENT record" ); - symbol = ParseLibComponent( properties ); + symbols = ParseLibComponent( properties ); } auto handleBinaryDataLambda = @@ -3601,6 +3673,7 @@ std::map SCH_ALTIUM_PLUGIN::ParseLibFile( const ALTIUM_COM result["DESIGNATOR"] = binreader.ReadPascalString(); result["SWAPIDGROUP"] = binreader.ReadPascalString(); + std::string partSeq = binreader.ReadPascalString(); // This is 'part|&|seq' std::vector partSeqSplit = split( partSeq, "|" ); @@ -3628,40 +3701,51 @@ std::map SCH_ALTIUM_PLUGIN::ParseLibFile( const ALTIUM_COM switch( record ) { - case ALTIUM_SCH_RECORD::PIN: ParsePin( properties, symbol ); break; + case ALTIUM_SCH_RECORD::PIN: ParsePin( properties, symbols ); break; - case ALTIUM_SCH_RECORD::LABEL: ParseLabel( properties, symbol ); break; + case ALTIUM_SCH_RECORD::LABEL: ParseLabel( properties, symbols ); break; - case ALTIUM_SCH_RECORD::BEZIER: ParseBezier( properties, symbol ); break; + case ALTIUM_SCH_RECORD::BEZIER: ParseBezier( properties, symbols ); break; - case ALTIUM_SCH_RECORD::POLYLINE: ParsePolyline( properties, symbol ); break; + case ALTIUM_SCH_RECORD::POLYLINE: ParsePolyline( properties, symbols ); break; - case ALTIUM_SCH_RECORD::POLYGON: ParsePolygon( properties, symbol ); break; + case ALTIUM_SCH_RECORD::POLYGON: ParsePolygon( properties, symbols ); break; - case ALTIUM_SCH_RECORD::ELLIPSE: ParseEllipse( properties, symbol ); break; + case ALTIUM_SCH_RECORD::ELLIPSE: ParseEllipse( properties, symbols ); break; - case ALTIUM_SCH_RECORD::ROUND_RECTANGLE: ParseRoundRectangle( properties, symbol ); break; + case ALTIUM_SCH_RECORD::ROUND_RECTANGLE: ParseRoundRectangle( properties, symbols ); break; case ALTIUM_SCH_RECORD::ELLIPTICAL_ARC: - case ALTIUM_SCH_RECORD::ARC: ParseArc( properties, symbol ); break; + case ALTIUM_SCH_RECORD::ARC: ParseArc( properties, symbols ); break; - case ALTIUM_SCH_RECORD::LINE: ParseLine( properties, symbol ); break; + case ALTIUM_SCH_RECORD::LINE: ParseLine( properties, symbols ); break; - case ALTIUM_SCH_RECORD::RECTANGLE: ParseRectangle( properties, symbol ); break; + case ALTIUM_SCH_RECORD::RECTANGLE: ParseRectangle( properties, symbols ); break; - case ALTIUM_SCH_RECORD::DESIGNATOR: ParseDesignator( properties, symbol ); break; + case ALTIUM_SCH_RECORD::DESIGNATOR: ParseDesignator( properties, symbols ); break; - case ALTIUM_SCH_RECORD::PARAMETER: ParseParameter( properties, symbol ); break; + case ALTIUM_SCH_RECORD::PARAMETER: ParseParameter( properties, symbols ); break; - case ALTIUM_SCH_RECORD::TEXT_FRAME: ParseTextFrame( properties, symbol ); break; + case ALTIUM_SCH_RECORD::TEXT_FRAME: ParseTextFrame( properties, symbols ); break; // Nothing for now. TODO: Figure out how implementation lists are generted in libs case ALTIUM_SCH_RECORD::IMPLEMENTATION_LIST: break; + case ALTIUM_SCH_RECORD::IMPLEMENTATION: break; + case ALTIUM_SCH_RECORD::IMPL_PARAMS: break; + + case ALTIUM_SCH_RECORD::MAP_DEFINER_LIST: break; + case ALTIUM_SCH_RECORD::MAP_DEFINER: break; + + // TODO: add support for these. They are just drawn symbols, so we can probably hardcode + case ALTIUM_SCH_RECORD::IEEE_SYMBOL: break; + + // TODO: Hanlde images once libedit supports them + case ALTIUM_SCH_RECORD::IMAGE: break; default: m_reporter->Report( wxString::Format( _( "Unknown or unexpected record id %d found " - "inside \"Data\" section." ), - recordId ), + "in %s." ), + recordId, symbols[0]->GetName() ), RPT_SEVERITY_ERROR ); break; } @@ -3673,7 +3757,15 @@ std::map SCH_ALTIUM_PLUGIN::ParseLibFile( const ALTIUM_COM if( reader.GetRemainingBytes() != 0 ) THROW_IO_ERROR( "stream is not fully parsed" ); - ret[name] = symbol; + for( size_t ii = 0; ii < symbols.size(); ii++ ) + { + LIB_SYMBOL* symbol = symbols[ii]; + + if( symbols.size() == 1 ) + ret[name] = symbol; + else + ret[wxString::Format( "%s (Altium Display %zd)", name, ii + 1 )] = symbol; + } } return ret; @@ -3739,23 +3831,49 @@ void SCH_ALTIUM_PLUGIN::ParseLibHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFi { THROW_IO_ERROR( "FileHeader does not contain any data" ); } - else + + std::map properties = reader.ReadProperties(); + + wxString libtype = ALTIUM_PARSER::ReadString( properties, "HEADER", "" ); + + if( libtype.CmpNoCase( "Protel for Windows - Schematic Library Editor Binary File Version 5.0" ) ) + THROW_IO_ERROR( _( "Expected Altium Schematic Library file version 5.0" ) ); + + for( auto& [key, value] : properties ) { - std::map properties = reader.ReadProperties(); + wxString upperKey = key.Upper(); + wxString* remaining = nullptr; - wxString libtype = ALTIUM_PARSER::ReadString( properties, "HEADER", "" ); - - if( libtype != "Protel for Windows - Schematic Library Editor Binary File Version 5.0" ) - THROW_IO_ERROR( _( "Expected Altium Schematic Library file version 5.0" ) ); - - for( auto& [key, value] : properties ) + if( upperKey.StartsWith( "LIBREF" ) ) { - if( key.StartsWith( "LibRef" ) ) + aSymbolNameList.Add( value ); + } + else if( upperKey.StartsWith( "SIZE", remaining ) ) + { + if( remaining ) { - aSymbolNameList.Add( value ); + int ind = wxAtoi( *remaining ); + + if( static_cast( m_fonts.size() ) <= ind ) + m_fonts.resize( ind + 1 ); + + m_fonts[ind].second = wxAtoi( value ); + } + } + else if( upperKey.StartsWith( "FONTNAME", remaining ) ) + { + if( remaining ) + { + int ind = wxAtoi( *remaining ); + + if( static_cast( m_fonts.size() ) <= ind ) + m_fonts.resize( ind + 1 ); + + m_fonts[ind].first = value; } } } + } @@ -3763,7 +3881,16 @@ void SCH_ALTIUM_PLUGIN::EnumerateSymbolLib( wxArrayString& aSymbolNameLi const wxString& aLibraryPath, const STRING_UTF8_MAP* aProperties ) { - ParseLibHeader( aLibraryPath, aSymbolNameList ); + ensureLoadedLibrary( aLibraryPath, aProperties ); + + auto it = m_libCache.find( aLibraryPath ); + + if( it != m_libCache.end() ) + { + for( auto& [libnameStr, libSymbol] : it->second ) + aSymbolNameList.Add( libnameStr ); + } + } diff --git a/eeschema/sch_plugins/altium/sch_altium_plugin.h b/eeschema/sch_plugins/altium/sch_altium_plugin.h index 0cd859f1b9..70c531ab1e 100644 --- a/eeschema/sch_plugins/altium/sch_altium_plugin.h +++ b/eeschema/sch_plugins/altium/sch_altium_plugin.h @@ -26,6 +26,7 @@ #define _SCH_ALTIUM_PLUGIN_H_ #include +#include #include #include #include @@ -45,6 +46,9 @@ class ALTIUM_COMPOUND_FILE; * * As with all SCH_PLUGINs there is no UI dependencies i.e. windowing calls allowed. */ + +static std::vector nullsym; + class SCH_ALTIUM_PLUGIN : public SCH_PLUGIN { public: @@ -126,28 +130,28 @@ private: bool IsComponentPartVisible( int aOwnerindex, int aOwnerpartdisplaymode ) const; const ASCH_STORAGE_FILE* GetFileFromStorage( const wxString& aFilename ) const; void AddTextBox( const ASCH_TEXT_FRAME* aElem ); - void AddLibTextBox( const ASCH_TEXT_FRAME* aElem, LIB_SYMBOL* aLibSymbol = nullptr ); + void AddLibTextBox( const ASCH_TEXT_FRAME* aElem, std::vector& aSymbol = nullsym); void ParseComponent( int aIndex, const std::map& aProperties ); - void ParsePin( const std::map& aProperties, LIB_SYMBOL* aLibSymbol = nullptr ); - void ParseLabel( const std::map& aProperties, LIB_SYMBOL* aLibSymbol = nullptr ); - void ParseTextFrame( const std::map& aProperties, LIB_SYMBOL* aLibSymbol = nullptr ); + void ParsePin( const std::map& aProperties, std::vector& aSymbol = nullsym); + void ParseLabel( const std::map& aProperties, std::vector& aSymbol = nullsym); + void ParseTextFrame( const std::map& aProperties, std::vector& aSymbol = nullsym); void ParseNote( const std::map& aProperties ); - void ParseBezier( const std::map& aProperties, LIB_SYMBOL* aLibSymbol = nullptr ); - void ParsePolyline( const std::map& aProperties, LIB_SYMBOL* aLibSymbol = nullptr ); - void ParsePolygon( const std::map& aProperties, LIB_SYMBOL* aLibSymbol = nullptr ); - void ParseRoundRectangle( const std::map& aProperties, LIB_SYMBOL* aLibSymbol = nullptr ); - void ParseArc( const std::map& aProperties, LIB_SYMBOL* aLibSymbol = nullptr ); - void ParseEllipse( const std::map& aProperties, LIB_SYMBOL* aLibSymbol = nullptr ); - void ParseCircle( const std::map& aProperties, LIB_SYMBOL* aLibSymbol = nullptr ); - void ParseLine( const std::map& aProperties, LIB_SYMBOL* aLibSymbol = nullptr ); + void ParseBezier( const std::map& aProperties, std::vector& aSymbol = nullsym); + void ParsePolyline( const std::map& aProperties, std::vector& aSymbol = nullsym); + void ParsePolygon( const std::map& aProperties, std::vector& aSymbol = nullsym); + void ParseRoundRectangle( const std::map& aProperties, std::vector& aSymbol = nullsym); + void ParseArc( const std::map& aProperties, std::vector& aSymbol = nullsym); + void ParseEllipse( const std::map& aProperties, std::vector& aSymbol = nullsym); + void ParseCircle( const std::map& aProperties, std::vector& aSymbol = nullsym); + void ParseLine( const std::map& aProperties, std::vector& aSymbol = nullsym); void ParseSignalHarness( const std::map& aProperties ); void ParseHarnessConnector( int aIndex, const std::map& aProperties ); void ParseHarnessEntry( const std::map& aProperties ); void ParseHarnessType( const std::map& aProperties ); void ParseHarnessPort( const ASCH_PORT& aElem ); - void ParseHyperlink( const std::map& aProperties, LIB_SYMBOL* aLibSymbol = nullptr ); - void ParseRectangle( const std::map& aProperties, LIB_SYMBOL* aLibSymbol = nullptr ); + void ParseHyperlink( const std::map& aProperties, std::vector& aSymbol = nullsym); + void ParseRectangle( const std::map& aProperties, std::vector& aSymbol = nullsym); void ParseSheetSymbol( int aIndex, const std::map& aProperties ); void ParseSheetEntry( const std::map& aProperties ); void ParsePowerPort( const std::map& aProperties ); @@ -161,15 +165,15 @@ private: void ParseSheet( const std::map& aProperties ); void ParseSheetName( const std::map& aProperties ); void ParseFileName( const std::map& aProperties ); - void ParseDesignator( const std::map& aProperties, LIB_SYMBOL* aLibSymbol = nullptr ); + void ParseDesignator( const std::map& aProperties, std::vector& aSymbol = nullsym); void ParseBusEntry( const std::map& aProperties ); - void ParseParameter( const std::map& aProperties, LIB_SYMBOL* aLibSymbol = nullptr ); + void ParseParameter( const std::map& aProperties, std::vector& aSymbol = nullsym); void ParseImplementationList( int aIndex, const std::map& aProperties ); void ParseImplementation( const std::map& aProperties ); void ParseLibHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile, wxArrayString& aLibNames ); std::map ParseLibFile( const ALTIUM_COMPOUND_FILE& aAltiumSchFile ); - LIB_SYMBOL* ParseLibComponent( const std::map& aProperties ); + std::vector ParseLibComponent( const std::map& aProperties ); private: REPORTER* m_reporter; // current reporter for warnings/errors @@ -212,6 +216,9 @@ private: std::map m_timestamps; std::map> m_libCache; + + // List of available fonts with font name and font size in pt + std::vector> m_fonts; }; #endif // _SCH_ALTIUM_PLUGIN_H_