diff --git a/eeschema/sch_plugins/altium/altium_parser_sch.cpp b/eeschema/sch_plugins/altium/altium_parser_sch.cpp index 1fb8316ace..a084f7f903 100644 --- a/eeschema/sch_plugins/altium/altium_parser_sch.cpp +++ b/eeschema/sch_plugins/altium/altium_parser_sch.cpp @@ -44,6 +44,16 @@ constexpr int Altium2KiCadUnit( const int val, const int frac ) } +int PropertiesReadKiCadUnitFrac( + const std::map& aProperties, const wxString& aKey ) +{ + // a unit is stored using two fields, denoting the size in mils and a fraction size + int key = ALTIUM_PARSER::PropertiesReadInt( aProperties, aKey, 0 ); + int keyFrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, aKey + "_FRAC", 0 ); + return Altium2KiCadUnit( key, keyFrac ); +} + + ASCH_COMPONENT::ASCH_COMPONENT( const std::map& aProperties ) { wxASSERT( PropertiesReadRecord( aProperties ) == ALTIUM_SCH_RECORD::COMPONENT ); @@ -68,7 +78,8 @@ ASCH_PIN::ASCH_PIN( const std::map& aProperties ) ownerindex = ALTIUM_PARSER::PropertiesReadInt( aProperties, "OWNERINDEX", ALTIUM_COMPONENT_NONE ); - ownerpartid = ALTIUM_PARSER::PropertiesReadInt( aProperties, "OWNERPARTID", 0 ); + ownerpartid = + ALTIUM_PARSER::PropertiesReadInt( aProperties, "OWNERPARTID", ALTIUM_COMPONENT_NONE ); name = ALTIUM_PARSER::PropertiesReadString( aProperties, "NAME", "" ); text = ALTIUM_PARSER::PropertiesReadString( aProperties, "TEXT", "" ); @@ -114,13 +125,40 @@ ASCH_PIN::ASCH_PIN( const std::map& aProperties ) } +ASCH_POLYGON::ASCH_POLYGON( const std::map& aProperties ) +{ + wxASSERT( PropertiesReadRecord( aProperties ) == ALTIUM_SCH_RECORD::POLYGON ); + + ownerindex = + ALTIUM_PARSER::PropertiesReadInt( aProperties, "OWNERINDEX", ALTIUM_COMPONENT_NONE ); + ownerpartid = + ALTIUM_PARSER::PropertiesReadInt( aProperties, "OWNERPARTID", ALTIUM_COMPONENT_NONE ); + + int locationCount = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LOCATIONCOUNT", 0 ); + for( int i = 1; i <= locationCount; i++ ) + { + const wxString si = std::to_string( i ); + + int x = ALTIUM_PARSER::PropertiesReadInt( aProperties, "X" + si, 0 ); + int xfrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, "X" + si + "_FRAC", 0 ); + int y = ALTIUM_PARSER::PropertiesReadInt( aProperties, "Y" + si, 0 ); + int yfrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, "Y" + si + "_FRAC", 0 ); + points.emplace_back( Altium2KiCadUnit( x, xfrac ), -Altium2KiCadUnit( y, yfrac ) ); + } + + lineWidth = PropertiesReadKiCadUnitFrac( aProperties, "LINEWIDTH" ); + isSolid = ALTIUM_PARSER::PropertiesReadBool( aProperties, "ISSOLID", false ); +} + + ASCH_RECTANGLE::ASCH_RECTANGLE( const std::map& aProperties ) { wxASSERT( PropertiesReadRecord( aProperties ) == ALTIUM_SCH_RECORD::RECTANGLE ); ownerindex = ALTIUM_PARSER::PropertiesReadInt( aProperties, "OWNERINDEX", ALTIUM_COMPONENT_NONE ); - ownerpartid = ALTIUM_PARSER::PropertiesReadInt( aProperties, "OWNERPARTID", 0 ); + ownerpartid = + ALTIUM_PARSER::PropertiesReadInt( aProperties, "OWNERPARTID", ALTIUM_COMPONENT_NONE ); int x = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LOCATION.X", 0 ); int xfrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LOCATION.X_FRAC", 0 ); @@ -134,7 +172,7 @@ ASCH_RECTANGLE::ASCH_RECTANGLE( const std::map& aProperties yfrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, "CORNER.Y_FRAC", 0 ); topRight = wxPoint( Altium2KiCadUnit( x, xfrac ), -Altium2KiCadUnit( y, yfrac ) ); - lineWidth = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LINEWIDTH", 0 ); + lineWidth = PropertiesReadKiCadUnitFrac( aProperties, "LINEWIDTH" ); isSolid = ALTIUM_PARSER::PropertiesReadBool( aProperties, "ISSOLID", false ); isTransparent = ALTIUM_PARSER::PropertiesReadBool( aProperties, "TRANSPARENT", false ); } @@ -160,12 +198,11 @@ ASCH_BUS::ASCH_BUS( const std::map& aProperties ) wxASSERT( PropertiesReadRecord( aProperties ) == ALTIUM_SCH_RECORD::BUS ); indexinsheet = ALTIUM_PARSER::PropertiesReadInt( aProperties, "INDEXINSHEET", 0 ); - linewidth = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LINEWIDTH", 0 ); int locationcount = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LOCATIONCOUNT", 0 ); - for( int i = 0; i < locationcount; i++ ) + for( int i = 1; i <= locationcount; i++ ) { - const wxString si = std::to_string( i + 1 ); + const wxString si = std::to_string( i ); int x = ALTIUM_PARSER::PropertiesReadInt( aProperties, "X" + si, 0 ); int xfrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, "X" + si + "_FRAC", 0 ); @@ -173,6 +210,8 @@ ASCH_BUS::ASCH_BUS( const std::map& aProperties ) int yfrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, "Y" + si + "_FRAC", 0 ); points.emplace_back( Altium2KiCadUnit( x, xfrac ), -Altium2KiCadUnit( y, yfrac ) ); } + + lineWidth = PropertiesReadKiCadUnitFrac( aProperties, "LINEWIDTH" ); } @@ -189,12 +228,11 @@ ASCH_WIRE::ASCH_WIRE( const std::map& aProperties ) }*/ indexinsheet = ALTIUM_PARSER::PropertiesReadInt( aProperties, "INDEXINSHEET", 0 ); - linewidth = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LINEWIDTH", 0 ); int locationcount = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LOCATIONCOUNT", 0 ); - for( int i = 0; i < locationcount; i++ ) + for( int i = 1; i <= locationcount; i++ ) { - const wxString si = std::to_string( i + 1 ); + const wxString si = std::to_string( i ); int x = ALTIUM_PARSER::PropertiesReadInt( aProperties, "X" + si, 0 ); int xfrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, "X" + si + "_FRAC", 0 ); @@ -202,6 +240,8 @@ ASCH_WIRE::ASCH_WIRE( const std::map& aProperties ) int yfrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, "Y" + si + "_FRAC", 0 ); points.emplace_back( Altium2KiCadUnit( x, xfrac ), -Altium2KiCadUnit( y, yfrac ) ); } + + lineWidth = PropertiesReadKiCadUnitFrac( aProperties, "LINEWIDTH" ); } diff --git a/eeschema/sch_plugins/altium/altium_parser_sch.h b/eeschema/sch_plugins/altium/altium_parser_sch.h index 3e93bd46d4..7f8edfb84c 100644 --- a/eeschema/sch_plugins/altium/altium_parser_sch.h +++ b/eeschema/sch_plugins/altium/altium_parser_sch.h @@ -194,6 +194,20 @@ struct ASCH_PIN }; +struct ASCH_POLYGON +{ + int ownerindex; + int ownerpartid; + + std::vector points; + + int lineWidth; + bool isSolid; + + explicit ASCH_POLYGON( const std::map& aProperties ); +}; + + struct ASCH_RECTANGLE { int ownerindex; @@ -223,7 +237,7 @@ struct ASCH_NET_LABEL struct ASCH_BUS { int indexinsheet; - int linewidth; + int lineWidth; std::vector points; @@ -234,7 +248,7 @@ struct ASCH_BUS struct ASCH_WIRE { int indexinsheet; - int linewidth; + int lineWidth; std::vector points; diff --git a/eeschema/sch_plugins/altium/sch_altium_plugin.cpp b/eeschema/sch_plugins/altium/sch_altium_plugin.cpp index 6ac32aa98a..a4a25860ff 100644 --- a/eeschema/sch_plugins/altium/sch_altium_plugin.cpp +++ b/eeschema/sch_plugins/altium/sch_altium_plugin.cpp @@ -312,6 +312,7 @@ void SCH_ALTIUM_PLUGIN::Parse( const CFB::CompoundFileReader& aReader ) case ALTIUM_SCH_RECORD::POLYLINE: break; case ALTIUM_SCH_RECORD::POLYGON: + ParsePolygon( properties ); break; case ALTIUM_SCH_RECORD::ELLIPSE: break; @@ -587,38 +588,122 @@ void SCH_ALTIUM_PLUGIN::ParsePin( const std::map& aPropertie } +void SCH_ALTIUM_PLUGIN::ParsePolygon( const std::map& aProperties ) +{ + ASCH_POLYGON elem( aProperties ); + + if( elem.ownerpartid == ALTIUM_COMPONENT_NONE ) + { + // TODO: we cannot fill this polygon, only draw it for now + for( int i = 0; i < (int) elem.points.size() - 1; i++ ) + { + SCH_LINE* line = new SCH_LINE( elem.points.at( i ), SCH_LAYER_ID::LAYER_NOTES ); + line->SetEndPoint( elem.points.at( i + 1 ) ); + + line->SetFlags( IS_NEW ); + m_currentSheet->GetScreen()->Append( line ); + } + + // close polygon + SCH_LINE* line = new SCH_LINE( elem.points.front(), SCH_LAYER_ID::LAYER_NOTES ); + line->SetEndPoint( elem.points.back() ); + + line->SetFlags( IS_NEW ); + m_currentSheet->GetScreen()->Append( line ); + } + else + { + const auto& symbol = m_symbols.find( elem.ownerindex ); + if( symbol == m_symbols.end() ) + { + // TODO: e.g. can depend on Template (RECORD=39 + wxLogWarning( wxString::Format( + "Rectangle tries to access symbol with ownerindex %d which does not exist", + elem.ownerindex ) ); + return; + } + + const auto& component = m_components.at( symbol->first ); + + LIB_POLYLINE* line = new LIB_POLYLINE( symbol->second ); + symbol->second->AddDrawItem( line ); + + // TODO: we cannot fill this polygon, only draw it for now? + for( wxPoint& point : elem.points ) + { + line->AddPoint( GetRelativePosition( point, component ) ); + } + + line->SetWidth( elem.lineWidth ); + if( elem.isSolid ) + { + line->SetFillMode( FILL_TYPE::FILLED_SHAPE ); + } + } +} + + void SCH_ALTIUM_PLUGIN::ParseRectangle( const std::map& aProperties ) { ASCH_RECTANGLE elem( aProperties ); - const auto& symbol = m_symbols.find( elem.ownerindex ); - if( symbol == m_symbols.end() ) + if( elem.ownerpartid == ALTIUM_COMPONENT_NONE ) { - // TODO: e.g. can depend on Template (RECORD=39 - wxLogWarning( wxString::Format( - "Pin tries to access symbol with ownerindex %d which does not exist", - elem.ownerindex ) ); - return; - } + const wxPoint topLeft = { elem.bottomLeft.x, elem.topRight.y }; + const wxPoint bottomRight = { elem.topRight.x, elem.bottomLeft.y }; - const auto& component = m_components.at( symbol->first ); + // TODO: we cannot fill this rectangle, only draw it for now + SCH_LINE* lineTop = new SCH_LINE( elem.topRight, SCH_LAYER_ID::LAYER_NOTES ); + lineTop->SetEndPoint( topLeft ); + lineTop->SetFlags( IS_NEW ); + m_currentSheet->GetScreen()->Append( lineTop ); - LIB_RECTANGLE* rect = new LIB_RECTANGLE( symbol->second ); - symbol->second->AddDrawItem( rect ); - rect->SetPosition( GetRelativePosition( elem.topRight, component ) ); - rect->SetEnd( GetRelativePosition( elem.bottomLeft, component ) ); - rect->SetWidth( elem.lineWidth ); - if( elem.isTransparent ) - { - rect->SetFillMode( FILL_TYPE::NO_FILL ); - } - else if( elem.isSolid ) - { - rect->SetFillMode( FILL_TYPE::FILLED_SHAPE ); + SCH_LINE* lineBottom = new SCH_LINE( elem.bottomLeft, SCH_LAYER_ID::LAYER_NOTES ); + lineBottom->SetEndPoint( bottomRight ); + lineBottom->SetFlags( IS_NEW ); + m_currentSheet->GetScreen()->Append( lineBottom ); + + SCH_LINE* lineRight = new SCH_LINE( elem.topRight, SCH_LAYER_ID::LAYER_NOTES ); + lineRight->SetEndPoint( bottomRight ); + lineRight->SetFlags( IS_NEW ); + m_currentSheet->GetScreen()->Append( lineRight ); + + SCH_LINE* lineLeft = new SCH_LINE( elem.bottomLeft, SCH_LAYER_ID::LAYER_NOTES ); + lineLeft->SetEndPoint( topLeft ); + lineLeft->SetFlags( IS_NEW ); + m_currentSheet->GetScreen()->Append( lineLeft ); } else { - rect->SetFillMode( FILL_TYPE::FILLED_WITH_BG_BODYCOLOR ); + const auto& symbol = m_symbols.find( elem.ownerindex ); + if( symbol == m_symbols.end() ) + { + // TODO: e.g. can depend on Template (RECORD=39 + wxLogWarning( wxString::Format( + "Rectangle tries to access symbol with ownerindex %d which does not exist", + elem.ownerindex ) ); + return; + } + + const auto& component = m_components.at( symbol->first ); + + LIB_RECTANGLE* rect = new LIB_RECTANGLE( symbol->second ); + symbol->second->AddDrawItem( rect ); + rect->SetPosition( GetRelativePosition( elem.topRight, component ) ); + rect->SetEnd( GetRelativePosition( elem.bottomLeft, component ) ); + rect->SetWidth( elem.lineWidth ); + if( elem.isTransparent ) + { + rect->SetFillMode( FILL_TYPE::NO_FILL ); + } + else if( elem.isSolid ) + { + rect->SetFillMode( FILL_TYPE::FILLED_SHAPE ); + } + else + { + rect->SetFillMode( FILL_TYPE::FILLED_WITH_BG_BODYCOLOR ); + } } } diff --git a/eeschema/sch_plugins/altium/sch_altium_plugin.h b/eeschema/sch_plugins/altium/sch_altium_plugin.h index fad66a3659..f51cdf3ee4 100644 --- a/eeschema/sch_plugins/altium/sch_altium_plugin.h +++ b/eeschema/sch_plugins/altium/sch_altium_plugin.h @@ -100,6 +100,7 @@ public: private: void ParseComponent( int index, const std::map& aProperties ); void ParsePin( const std::map& aProperties ); + void ParsePolygon( const std::map& aProperties ); void ParseRectangle( const std::map& aProperties ); void ParseNetLabel( const std::map& aProperties ); void ParseBus( const std::map& aProperties );