From 430da6722243e492777978a5ec3e43c9c8ff3cf8 Mon Sep 17 00:00:00 2001 From: Alex Shvartzkop Date: Sat, 22 Jul 2023 22:37:50 +0500 Subject: [PATCH] Altium PCB import: support dashed outlines (Region kind 2) --- pcbnew/plugins/altium/altium_parser_pcb.cpp | 2 +- pcbnew/plugins/altium/altium_parser_pcb.h | 2 +- pcbnew/plugins/altium/altium_pcb.cpp | 68 +++++++++++++++++++++ 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/pcbnew/plugins/altium/altium_parser_pcb.cpp b/pcbnew/plugins/altium/altium_parser_pcb.cpp index 2eec24f7d7..dd6b095a7d 100644 --- a/pcbnew/plugins/altium/altium_parser_pcb.cpp +++ b/pcbnew/plugins/altium/altium_parser_pcb.cpp @@ -1054,7 +1054,7 @@ AREGION6::AREGION6( ALTIUM_PARSER& aReader, bool aExtendedVertices ) kind = ALTIUM_REGION_KIND::POLYGON_CUTOUT; break; case 2: - kind = ALTIUM_REGION_KIND::UNKNOWN_2; // TODO: what kind is this? + kind = ALTIUM_REGION_KIND::DASHED_OUTLINE; break; case 3: kind = ALTIUM_REGION_KIND::UNKNOWN_3; // TODO: what kind is this? diff --git a/pcbnew/plugins/altium/altium_parser_pcb.h b/pcbnew/plugins/altium/altium_parser_pcb.h index 3c78380db5..3adba6df72 100644 --- a/pcbnew/plugins/altium/altium_parser_pcb.h +++ b/pcbnew/plugins/altium/altium_parser_pcb.h @@ -88,7 +88,7 @@ enum class ALTIUM_REGION_KIND COPPER = 0, // KIND=0 POLYGON_CUTOUT = 1, // KIND=1 - UNKNOWN_2 = 2, // KIND=2 + DASHED_OUTLINE = 2, // KIND=2 UNKNOWN_3 = 3, // KIND=3 CAVITY_DEFINITION = 4, // KIND=4 BOARD_CUTOUT = 5, // KIND=0 AND ISBOARDCUTOUT=TRUE diff --git a/pcbnew/plugins/altium/altium_pcb.cpp b/pcbnew/plugins/altium/altium_pcb.cpp index 4c3493da84..f85b17cc1f 100644 --- a/pcbnew/plugins/altium/altium_pcb.cpp +++ b/pcbnew/plugins/altium/altium_pcb.cpp @@ -1958,6 +1958,40 @@ void ALTIUM_PCB::ConvertShapeBasedRegions6ToBoardItem( const AREGION6& aElem ) zone->SetBorderDisplayStyle( ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE, ZONE::GetDefaultHatchPitch(), true ); } + else if( aElem.kind == ALTIUM_REGION_KIND::DASHED_OUTLINE ) + { + PCB_LAYER_ID klayer = GetKicadLayer( aElem.layer ); + + if( klayer == UNDEFINED_LAYER ) + { + wxLogWarning( + _( "Dashed outline found on an Altium layer (%d) with no KiCad equivalent. " + "It has been moved to KiCad layer Eco1_User." ), + aElem.layer ); + klayer = Eco1_User; + } + + SHAPE_LINE_CHAIN linechain; + HelperShapeLineChainFromAltiumVertices( linechain, aElem.outline ); + + if( linechain.PointCount() < 3 ) + { + // We have found multiple Altium files with polygon records containing nothing but + // two coincident vertices. These polygons do not appear when opening the file in + // Altium. https://gitlab.com/kicad/code/kicad/-/issues/8183 + // Also, polygons with less than 3 points are not supported in KiCad. + return; + } + + PCB_SHAPE* shape = new PCB_SHAPE( m_board, SHAPE_T::POLY ); + + shape->SetPolyShape( linechain ); + shape->SetFilled( false ); + shape->SetLayer( klayer ); + shape->SetStroke( STROKE_PARAMS( pcbIUScale.mmToIU( 0.1 ), PLOT_DASH_TYPE::DASH ) ); + + m_board->Add( shape, ADD_MODE::APPEND ); + } else if( aElem.kind == ALTIUM_REGION_KIND::COPPER ) { if( aElem.subpolyindex == ALTIUM_POLYGON_NONE ) @@ -2017,6 +2051,40 @@ void ALTIUM_PCB::ConvertShapeBasedRegions6ToFootprintItem( FOOTPRINT* aFoot aPrimitiveIndex ); } } + else if( aElem.kind == ALTIUM_REGION_KIND::DASHED_OUTLINE ) + { + PCB_LAYER_ID klayer = GetKicadLayer( aElem.layer ); + + if( klayer == UNDEFINED_LAYER ) + { + wxLogWarning( + _( "Dashed outline found on an Altium layer (%d) with no KiCad equivalent. " + "It has been moved to KiCad layer Eco1_User." ), + aElem.layer ); + klayer = Eco1_User; + } + + SHAPE_LINE_CHAIN linechain; + HelperShapeLineChainFromAltiumVertices( linechain, aElem.outline ); + + if( linechain.PointCount() < 3 ) + { + // We have found multiple Altium files with polygon records containing nothing but + // two coincident vertices. These polygons do not appear when opening the file in + // Altium. https://gitlab.com/kicad/code/kicad/-/issues/8183 + // Also, polygons with less than 3 points are not supported in KiCad. + return; + } + + PCB_SHAPE* shape = new PCB_SHAPE( aFootprint, SHAPE_T::POLY ); + + shape->SetPolyShape( linechain ); + shape->SetFilled( false ); + shape->SetLayer( klayer ); + shape->SetStroke( STROKE_PARAMS( pcbIUScale.mmToIU( 0.1 ), PLOT_DASH_TYPE::DASH ) ); + + aFootprint->Add( shape, ADD_MODE::APPEND ); + } else { wxLogError( _( "Ignored polygon shape of kind %d (not yet supported)." ), aElem.kind );