From 8296b1d669d8fe46d585e2170415d548a1c7d81e Mon Sep 17 00:00:00 2001 From: Roberto Fernandez Bautista Date: Sun, 6 Sep 2020 22:20:32 +0100 Subject: [PATCH] CADSTAR PCB Archive Importer: Load GROUPs --- .../cadstar/cadstar_pcb_archive_loader.cpp | 205 ++++++++++++++---- .../cadstar/cadstar_pcb_archive_loader.h | 79 ++++--- .../cadstar/cadstar_pcb_archive_parser.cpp | 2 + .../cadstar/cadstar_pcb_archive_parser.h | 1 + 4 files changed, 220 insertions(+), 67 deletions(-) diff --git a/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.cpp b/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.cpp index e0979b130f..895ab5367d 100644 --- a/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.cpp +++ b/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.cpp @@ -78,6 +78,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::Load( ::BOARD* aBoard ) loadBoardStackup(); loadDesignRules(); loadComponentLibrary(); + loadGroups(); loadBoards(); loadFigures(); loadTexts(); @@ -621,16 +622,66 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadLibraryPads( const SYMDEF& aComponent, MODU } +void CADSTAR_PCB_ARCHIVE_LOADER::loadGroups() +{ + for( std::pair groupPair : Layout.Groups ) + { + GROUP& csGroup = groupPair.second; + + PCB_GROUP* kiGroup = new PCB_GROUP( mBoard ); + + mBoard->Add( kiGroup ); + kiGroup->SetName( csGroup.Name ); + kiGroup->SetLocked( csGroup.Fixed ); + + mGroupMap.insert( { csGroup.ID, kiGroup } ); + } + + //now add any groups to their parent group + for( std::pair groupPair : Layout.Groups ) + { + GROUP& csGroup = groupPair.second; + + if( !csGroup.GroupID.IsEmpty() ) + { + if( mGroupMap.find( csGroup.ID ) == mGroupMap.end() ) + THROW_IO_ERROR( wxString::Format( + _( "The file appears to be corrupt. Unable to find group ID %s " + "in the group definitions." ), + csGroup.ID ) ); + + else if( mGroupMap.find( csGroup.ID ) == mGroupMap.end() ) + THROW_IO_ERROR( wxString::Format( + _( "The file appears to be corrupt. Unable to find sub group %s " + "in the group map (parent group ID=%s, Name=%s)." ), + csGroup.GroupID, csGroup.ID, csGroup.Name ) ); + + else + { + PCB_GROUP* kiCadGroup = mGroupMap.at( csGroup.ID ); + PCB_GROUP* parentGroup = mGroupMap.at( csGroup.GroupID ); + parentGroup->AddItem( kiCadGroup ); + } + } + } +} + + void CADSTAR_PCB_ARCHIVE_LOADER::loadBoards() { for( std::pair boardPair : Layout.Boards ) { BOARD& board = boardPair.second; + GROUP_ID boardGroup = createUniqueGroupID( wxT( "Board" ) ); drawCadstarShape( board.Shape, PCB_LAYER_ID::Edge_Cuts, board.LineCodeID, - wxString::Format( "BOARD %s", board.ID ), mBoard ); + wxString::Format( "BOARD %s", board.ID ), mBoard, boardGroup ); - //TODO process board attributes - //TODO process addition to a group + if( !board.GroupID.IsEmpty() ) + { + addToGroup( board.GroupID, getKiCadGroup( boardGroup ) ); + } + + //TODO process board attributes when KiCad supports them } } @@ -641,10 +692,9 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadFigures() { FIGURE& fig = figPair.second; drawCadstarShape( fig.Shape, getKiCadLayer( fig.LayerID ), fig.LineCodeID, - wxString::Format( "FIGURE %s", fig.ID ), mBoard ); + wxString::Format( "FIGURE %s", fig.ID ), mBoard, fig.GroupID ); - //TODO process addition to a group - //TODO process "swaprule" + //TODO process "swaprule" (doesn't seem to apply to Layout Figures?) //TODO process re-use block when KiCad Supports it //TODO process attributes when KiCad Supports attributes in figures } @@ -765,6 +815,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadDocumentationSymbols() { DOCUMENTATION_SYMBOL& docSymInstance = docPair.second; + auto docSymIter = Library.ComponentDefinitions.find( docSymInstance.SymdefID ); if( docSymIter == Library.ComponentDefinitions.end() ) @@ -783,6 +834,14 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadDocumentationSymbols() wxPoint centreOfTransform = getKiCadPoint( docSymDefinition.Origin ); bool mirrorInvert = docSymInstance.Mirror; + //create a group to store the items in + wxString groupName = docSymDefinition.ReferenceName; + + if( !docSymDefinition.Alternate.IsEmpty() ) + groupName += wxT( " (" ) + docSymDefinition.Alternate + wxT( ")" ); + + GROUP_ID groupID = createUniqueGroupID( groupName ); + LSEQ layers = getKiCadLayerSet( docSymInstance.LayerID ).Seq(); for( PCB_LAYER_ID layer : layers ) @@ -793,7 +852,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadDocumentationSymbols() drawCadstarShape( fig.Shape, layer, fig.LineCodeID, wxString::Format( "DOCUMENTATION SYMBOL %s, FIGURE %s", docSymDefinition.ReferenceName, fig.ID ), - mBoard, moveVector, rotationAngle, scalingFactor, centreOfTransform, + mBoard, groupID, moveVector, rotationAngle, scalingFactor, centreOfTransform, mirrorInvert ); } } @@ -801,7 +860,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadDocumentationSymbols() for( std::pair textPair : docSymDefinition.Texts ) { TEXT txt = textPair.second; - drawCadstarText( txt, mBoard, docSymInstance.LayerID, moveVector, rotationAngle, + drawCadstarText( txt, mBoard, groupID, docSymInstance.LayerID, moveVector, rotationAngle, scalingFactor, centreOfTransform, mirrorInvert ); } } @@ -1151,7 +1210,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadNetTracks( dsVector.push_back( ds ); prevEnd = v.Vertex.End; } - + //Todo add real netcode to the tracks std::vector tracks = makeTracksFromDrawsegments( dsVector, mBoard, getKiCadNet( aCadstarNetID ) ); @@ -1216,9 +1275,10 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadNetVia( void CADSTAR_PCB_ARCHIVE_LOADER::drawCadstarText( const TEXT& aCadstarText, - BOARD_ITEM_CONTAINER* aContainer, const LAYER_ID& aCadstarLayerOverride, - const wxPoint& aMoveVector, const double& aRotationAngle, const double& aScalingFactor, - const wxPoint& aTransformCentre, const bool& aMirrorInvert ) + BOARD_ITEM_CONTAINER* aContainer, const GROUP_ID& aCadstarGroupID, + const LAYER_ID& aCadstarLayerOverride, const wxPoint& aMoveVector, + const double& aRotationAngle, const double& aScalingFactor, const wxPoint& aTransformCentre, + const bool& aMirrorInvert ) { TEXTE_PCB* txt = new TEXTE_PCB( aContainer ); aContainer->Add( txt ); @@ -1226,14 +1286,16 @@ void CADSTAR_PCB_ARCHIVE_LOADER::drawCadstarText( const TEXT& aCadstarText, wxPoint rotatedTextPos = getKiCadPoint( aCadstarText.Position ); RotatePoint( &rotatedTextPos, aTransformCentre, aRotationAngle ); - rotatedTextPos.x = KiROUND( (double) ( rotatedTextPos.x - aTransformCentre.x ) * aScalingFactor ); - rotatedTextPos.y = KiROUND( (double) ( rotatedTextPos.y - aTransformCentre.y ) * aScalingFactor ); + rotatedTextPos.x = + KiROUND( (double) ( rotatedTextPos.x - aTransformCentre.x ) * aScalingFactor ); + rotatedTextPos.y = + KiROUND( (double) ( rotatedTextPos.y - aTransformCentre.y ) * aScalingFactor ); rotatedTextPos += aTransformCentre; txt->SetTextPos( rotatedTextPos ); txt->SetPosition( rotatedTextPos ); txt->SetTextAngle( getAngleTenthDegree( aCadstarText.OrientAngle ) + aRotationAngle ); - txt->SetMirrored( aCadstarText.Mirror ); + txt->SetMirrored( aCadstarText.Mirror ); TEXTCODE tc = getTextCode( aCadstarText.TextCodeID ); @@ -1300,7 +1362,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::drawCadstarText( const TEXT& aCadstarText, { txt->Flip( aTransformCentre, true ); } - + //scale it after flipping: if( aScalingFactor != 1.0 ) { @@ -1331,23 +1393,30 @@ void CADSTAR_PCB_ARCHIVE_LOADER::drawCadstarText( const TEXT& aCadstarText, txt->SetLayer( layer ); newtxt = new TEXTE_PCB( *txt ); mBoard->Add( newtxt, ADD_MODE::APPEND ); + + if( !aCadstarGroupID.IsEmpty() ) + addToGroup( aCadstarGroupID, newtxt ); } mBoard->Remove( txt ); delete txt; } else + { txt->SetLayer( getKiCadLayer( layersToDrawOn ) ); - + + if( !aCadstarGroupID.IsEmpty() ) + addToGroup( aCadstarGroupID, txt ); + } //TODO Handle different font types when KiCad can support it. } void CADSTAR_PCB_ARCHIVE_LOADER::drawCadstarShape( const SHAPE& aCadstarShape, const PCB_LAYER_ID& aKiCadLayer, const LINECODE_ID& aCadstarLinecodeID, - const wxString& aShapeName, BOARD_ITEM_CONTAINER* aContainer, const wxPoint& aMoveVector, - const double& aRotationAngle, const double& aScalingFactor, const wxPoint& aTransformCentre, - const bool& aMirrorInvert ) + const wxString& aShapeName, BOARD_ITEM_CONTAINER* aContainer, + const GROUP_ID& aCadstarGroupID, const wxPoint& aMoveVector, const double& aRotationAngle, + const double& aScalingFactor, const wxPoint& aTransformCentre, const bool& aMirrorInvert ) { int lineThickness = getLineThickness( aCadstarLinecodeID ); @@ -1357,10 +1426,11 @@ void CADSTAR_PCB_ARCHIVE_LOADER::drawCadstarShape( const SHAPE& aCadstarShape, case SHAPE_TYPE::OUTLINE: ///TODO update this when Polygons in KiCad can be defined with no fill drawCadstarVerticesAsSegments( aCadstarShape.Vertices, aKiCadLayer, lineThickness, - aContainer, aMoveVector, aRotationAngle, aScalingFactor, aTransformCentre, - aMirrorInvert ); + aContainer, aCadstarGroupID, aMoveVector, aRotationAngle, aScalingFactor, + aTransformCentre, aMirrorInvert ); drawCadstarCutoutsAsSegments( aCadstarShape.Cutouts, aKiCadLayer, lineThickness, aContainer, - aMoveVector, aRotationAngle, aScalingFactor, aTransformCentre, aMirrorInvert ); + aCadstarGroupID, aMoveVector, aRotationAngle, aScalingFactor, aTransformCentre, + aMirrorInvert ); break; case SHAPE_TYPE::HATCHED: @@ -1387,6 +1457,9 @@ void CADSTAR_PCB_ARCHIVE_LOADER::drawCadstarShape( const SHAPE& aCadstarShape, ds->SetWidth( lineThickness ); ds->SetLayer( aKiCadLayer ); aContainer->Add( ds, ADD_MODE::APPEND ); + + if( !aCadstarGroupID.IsEmpty() ) + addToGroup( aCadstarGroupID, ds ); } break; } @@ -1395,26 +1468,28 @@ void CADSTAR_PCB_ARCHIVE_LOADER::drawCadstarShape( const SHAPE& aCadstarShape, void CADSTAR_PCB_ARCHIVE_LOADER::drawCadstarCutoutsAsSegments( const std::vector& aCutouts, const PCB_LAYER_ID& aKiCadLayer, const int& aLineThickness, - BOARD_ITEM_CONTAINER* aContainer, const wxPoint& aMoveVector, const double& aRotationAngle, - const double& aScalingFactor, const wxPoint& aTransformCentre, const bool& aMirrorInvert ) + BOARD_ITEM_CONTAINER* aContainer, const GROUP_ID& aCadstarGroupID, + const wxPoint& aMoveVector, const double& aRotationAngle, const double& aScalingFactor, + const wxPoint& aTransformCentre, const bool& aMirrorInvert ) { for( CUTOUT cutout : aCutouts ) { drawCadstarVerticesAsSegments( cutout.Vertices, aKiCadLayer, aLineThickness, aContainer, - aMoveVector, aRotationAngle, aScalingFactor, aTransformCentre, aMirrorInvert ); + aCadstarGroupID, aMoveVector, aRotationAngle, aScalingFactor, aTransformCentre, + aMirrorInvert ); } } void CADSTAR_PCB_ARCHIVE_LOADER::drawCadstarVerticesAsSegments( const std::vector& aCadstarVertices, const PCB_LAYER_ID& aKiCadLayer, - const int& aLineThickness, BOARD_ITEM_CONTAINER* aContainer, const wxPoint& aMoveVector, - const double& aRotationAngle, const double& aScalingFactor, const wxPoint& aTransformCentre, - const bool& aMirrorInvert ) + const int& aLineThickness, BOARD_ITEM_CONTAINER* aContainer, + const GROUP_ID& aCadstarGroupID, const wxPoint& aMoveVector, const double& aRotationAngle, + const double& aScalingFactor, const wxPoint& aTransformCentre, const bool& aMirrorInvert ) { std::vector drawSegments = - getDrawSegmentsFromVertices( aCadstarVertices, aContainer, aMoveVector, aRotationAngle, - aScalingFactor, aTransformCentre, aMirrorInvert ); + getDrawSegmentsFromVertices( aCadstarVertices, aContainer, aCadstarGroupID, aMoveVector, + aRotationAngle, aScalingFactor, aTransformCentre, aMirrorInvert ); for( DRAWSEGMENT* ds : drawSegments ) { @@ -1428,8 +1503,8 @@ void CADSTAR_PCB_ARCHIVE_LOADER::drawCadstarVerticesAsSegments( std::vector CADSTAR_PCB_ARCHIVE_LOADER::getDrawSegmentsFromVertices( const std::vector& aCadstarVertices, BOARD_ITEM_CONTAINER* aContainer, - const wxPoint& aMoveVector, const double& aRotationAngle, const double& aScalingFactor, - const wxPoint& aTransformCentre, const bool& aMirrorInvert ) + const GROUP_ID& aCadstarGroupID, const wxPoint& aMoveVector, const double& aRotationAngle, + const double& aScalingFactor, const wxPoint& aTransformCentre, const bool& aMirrorInvert ) { std::vector drawSegments; @@ -1443,8 +1518,9 @@ std::vector CADSTAR_PCB_ARCHIVE_LOADER::getDrawSegmentsFromVertice for( size_t i = 1; i < aCadstarVertices.size(); i++ ) { cur = &aCadstarVertices.at( i ); - drawSegments.push_back( getDrawSegmentFromVertex( prev->End, *cur, aContainer, aMoveVector, - aRotationAngle, aScalingFactor, aTransformCentre, aMirrorInvert ) ); + drawSegments.push_back( + getDrawSegmentFromVertex( prev->End, *cur, aContainer, aCadstarGroupID, aMoveVector, + aRotationAngle, aScalingFactor, aTransformCentre, aMirrorInvert ) ); prev = cur; } @@ -1453,9 +1529,9 @@ std::vector CADSTAR_PCB_ARCHIVE_LOADER::getDrawSegmentsFromVertice DRAWSEGMENT* CADSTAR_PCB_ARCHIVE_LOADER::getDrawSegmentFromVertex( const POINT& aCadstarStartPoint, - const VERTEX& aCadstarVertex, BOARD_ITEM_CONTAINER* aContainer, const wxPoint& aMoveVector, - const double& aRotationAngle, const double& aScalingFactor, const wxPoint& aTransformCentre, - const bool& aMirrorInvert ) + const VERTEX& aCadstarVertex, BOARD_ITEM_CONTAINER* aContainer, + const GROUP_ID& aCadstarGroupID, const wxPoint& aMoveVector, const double& aRotationAngle, + const double& aScalingFactor, const wxPoint& aTransformCentre, const bool& aMirrorInvert ) { DRAWSEGMENT* ds = nullptr; bool cw = false; @@ -1521,7 +1597,7 @@ DRAWSEGMENT* CADSTAR_PCB_ARCHIVE_LOADER::getDrawSegmentFromVertex( const POINT& //Apply transforms if( aMirrorInvert ) ds->Flip( aTransformCentre, true ); - + if( aScalingFactor != 1.0 ) { ds->Move( -aTransformCentre ); @@ -1538,6 +1614,9 @@ DRAWSEGMENT* CADSTAR_PCB_ARCHIVE_LOADER::getDrawSegmentFromVertex( const POINT& if( isModule( aContainer ) && ds != nullptr ) ( (EDGE_MODULE*) ds )->SetLocalCoord(); + if( !aCadstarGroupID.IsEmpty() ) + addToGroup( aCadstarGroupID, ds ); + return ds; } @@ -1573,8 +1652,10 @@ SHAPE_POLY_SET CADSTAR_PCB_ARCHIVE_LOADER::getPolySetFromCadstarShape( const SHA const double& aRotationAngle, const double& aScalingFactor, const wxPoint& aTransformCentre, const bool& aMirrorInvert ) { + GROUP_ID noGroup = wxEmptyString; + std::vector outlineSegments = - getDrawSegmentsFromVertices( aCadstarShape.Vertices, aContainer, aMoveVector, + getDrawSegmentsFromVertices( aCadstarShape.Vertices, aContainer, noGroup, aMoveVector, aRotationAngle, aScalingFactor, aTransformCentre, aMirrorInvert ); SHAPE_POLY_SET polySet( getLineChainFromDrawsegments( outlineSegments ) ); @@ -1588,8 +1669,9 @@ SHAPE_POLY_SET CADSTAR_PCB_ARCHIVE_LOADER::getPolySetFromCadstarShape( const SHA for( CUTOUT cutout : aCadstarShape.Cutouts ) { - std::vector cutoutSeg = getDrawSegmentsFromVertices( cutout.Vertices, - aContainer, aMoveVector, aRotationAngle, aScalingFactor, aTransformCentre ); + std::vector cutoutSeg = + getDrawSegmentsFromVertices( cutout.Vertices, aContainer, noGroup, aMoveVector, + aRotationAngle, aScalingFactor, aTransformCentre, aMirrorInvert ); polySet.AddHole( getLineChainFromDrawsegments( cutoutSeg ) ); @@ -2011,6 +2093,14 @@ int CADSTAR_PCB_ARCHIVE_LOADER::getKiCadHatchCodeGap( const HATCHCODE_ID& aCadst } +PCB_GROUP* CADSTAR_PCB_ARCHIVE_LOADER::getKiCadGroup( const GROUP_ID& aCadstarGroupID ) +{ + wxCHECK( mGroupMap.find( aCadstarGroupID ) != mGroupMap.end(), nullptr ); + + return mGroupMap.at( aCadstarGroupID ); +} + + void CADSTAR_PCB_ARCHIVE_LOADER::checkAndLogHatchCode( const HATCHCODE_ID& aCadstarHatchcodeID ) { if( mHatchcodesTested.find( aCadstarHatchcodeID ) != mHatchcodesTested.end() ) @@ -2288,3 +2378,34 @@ LSET CADSTAR_PCB_ARCHIVE_LOADER::getKiCadLayerSet( const LAYER_ID& aCadstarLayer return LSET( getKiCadLayer( aCadstarLayerID ) ); } } + + +void CADSTAR_PCB_ARCHIVE_LOADER::addToGroup( + const GROUP_ID& aCadstarGroupID, BOARD_ITEM* aKiCadItem ) +{ + wxCHECK( mGroupMap.find( aCadstarGroupID ) != mGroupMap.end() ); + + PCB_GROUP* parentGroup = mGroupMap.at( aCadstarGroupID ); + parentGroup->AddItem( aKiCadItem ); +} + + +CADSTAR_PCB_ARCHIVE_LOADER::GROUP_ID CADSTAR_PCB_ARCHIVE_LOADER::createUniqueGroupID( + const wxString& aName ) +{ + wxString groupName = aName; + int num = 0; + + while( mGroupMap.find( groupName ) != mGroupMap.end() ) + { + groupName = aName + wxT( "_" ) + wxString::Format( "%i", ++num ); + } + + PCB_GROUP* docSymGroup = new PCB_GROUP( mBoard ); + mBoard->Add( docSymGroup ); + docSymGroup->SetName( groupName ); + GROUP_ID groupID( groupName ); + mGroupMap.insert( { groupID, docSymGroup } ); + + return groupID; +} diff --git a/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.h b/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.h index f7802f974f..aa077a6172 100644 --- a/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.h +++ b/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.h @@ -74,6 +74,10 @@ private: ///< components in the library. Populated ///< by loadComponentLibrary(). Owns the ///< MODULE objects. + std::map mGroupMap; ///< Map between Cadstar and KiCad + ///< groups. Does NOT ownthe PCB_GROUP + ///< objects (these should have been + ///< loaded to mBoard). std::map mComponentMap; ///< Map between Cadstar and KiCad ///< components on the board. Does NOT own ///< the MODULE objects (these should have @@ -103,6 +107,7 @@ private: void loadBoardStackup(); void loadDesignRules(); void loadComponentLibrary(); + void loadGroups(); void loadBoards(); void loadFigures(); void loadTexts(); @@ -124,10 +129,12 @@ private: void checkAndLogHatchCode( const HATCHCODE_ID& aCadstarHatchcodeID ); //Helper functions for drawing /loading objects onto screen: + /** * @brief * @param aCadstarText * @param aContainer to draw on (e.g. mBoard) + * @param aCadstarGroupID to add the text to * @param aCadstarLayerOverride if not empty, overrides the LayerID in aCadstarText * @param aMoveVector move draw segment by this amount (in KiCad coordinates) * @param aRotationAngle rotate draw segment by this amount (in tenth degrees) @@ -136,6 +143,7 @@ private: * @param aMirrorInvert if true, it inverts the Mirror status of aCadstarText */ void drawCadstarText( const TEXT& aCadstarText, BOARD_ITEM_CONTAINER* aContainer, + const GROUP_ID& aCadstarGroupID = wxEmptyString, const LAYER_ID& aCadstarLayerOverride = wxEmptyString, const wxPoint& aMoveVector = { 0, 0 }, const double& aRotationAngle = 0.0, const double& aScalingFactor = 1.0, const wxPoint& aTransformCentre = { 0, 0 }, @@ -148,17 +156,19 @@ private: * @param aCadstarLinecodeID Thickness of line to draw with * @param aShapeName for reporting warnings/errors to the user * @param aContainer to draw on (e.g. mBoard) + * @param aCadstarGroupID to add the shape to * @param aMoveVector move draw segment by this amount (in KiCad coordinates) * @param aRotationAngle rotate draw segment by this amount (in tenth degrees) * @param aScalingFactor scale draw segment by this amount * @param aTransformCentre around which all transforms are applied (KiCad coordinates) - * @param aMirrorInvert if true, it inverts the Mirror status of aCadstarText + * @param aMirrorInvert if true, mirrors the shape */ void drawCadstarShape( const SHAPE& aCadstarShape, const PCB_LAYER_ID& aKiCadLayer, const LINECODE_ID& aCadstarLinecodeID, const wxString& aShapeName, - BOARD_ITEM_CONTAINER* aContainer, const wxPoint& aMoveVector = { 0, 0 }, - const double& aRotationAngle = 0.0, const double& aScalingFactor = 1.0, - const wxPoint& aTransformCentre = { 0, 0 }, const bool& aMirrorInvert = false ); + BOARD_ITEM_CONTAINER* aContainer, const GROUP_ID& aCadstarGroupID = wxEmptyString, + const wxPoint& aMoveVector = { 0, 0 }, const double& aRotationAngle = 0.0, + const double& aScalingFactor = 1.0, const wxPoint& aTransformCentre = { 0, 0 }, + const bool& aMirrorInvert = false ); /** * @brief Uses DRAWSEGMENT to draw the cutouts on mBoard object @@ -166,17 +176,19 @@ private: * @param aKiCadLayer KiCad layer to draw on * @param aLineThickness Thickness of line to draw with * @param aContainer to draw on (e.g. mBoard) + * @param aCadstarGroupID to add the shape to * @param aMoveVector move draw segment by this amount (in KiCad coordinates) * @param aRotationAngle rotate draw segment by this amount (in tenth degrees) * @param aScalingFactor scale draw segment by this amount * @param aTransformCentre around which all transforms are applied (KiCad coordinates) - * @param aMirrorInvert if true, it inverts the Mirror status of aCadstarText + * @param aMirrorInvert if true, mirrors the drawsegments */ void drawCadstarCutoutsAsSegments( const std::vector& aCutouts, const PCB_LAYER_ID& aKiCadLayer, const int& aLineThickness, - BOARD_ITEM_CONTAINER* aContainer, const wxPoint& aMoveVector = { 0, 0 }, - const double& aRotationAngle = 0.0, const double& aScalingFactor = 1.0, - const wxPoint& aTransformCentre = { 0, 0 }, const bool& aMirrorInvert = false ); + BOARD_ITEM_CONTAINER* aContainer, const GROUP_ID& aCadstarGroupID = wxEmptyString, + const wxPoint& aMoveVector = { 0, 0 }, const double& aRotationAngle = 0.0, + const double& aScalingFactor = 1.0, const wxPoint& aTransformCentre = { 0, 0 }, + const bool& aMirrorInvert = false ); /** * @brief Uses DRAWSEGMENT to draw the vertices on mBoard object @@ -184,52 +196,57 @@ private: * @param aKiCadLayer KiCad layer to draw on * @param aLineThickness Thickness of line to draw with * @param aContainer to draw on (e.g. mBoard) + * @param aCadstarGroupID to add the shape to * @param aMoveVector move draw segment by this amount (in KiCad coordinates) * @param aRotationAngle rotate draw segment by this amount (in tenth degrees) * @param aScalingFactor scale draw segment by this amount * @param aTransformCentre around which all transforms are applied (KiCad coordinates) - * @param aMirrorInvert if true, it inverts the Mirror status of aCadstarText + * @param aMirrorInvert if true, mirrors the drawsegment + * @param aCadstarGroupID to add the shape to */ void drawCadstarVerticesAsSegments( const std::vector& aCadstarVertices, const PCB_LAYER_ID& aKiCadLayer, const int& aLineThickness, - BOARD_ITEM_CONTAINER* aContainer, const wxPoint& aMoveVector = { 0, 0 }, - const double& aRotationAngle = 0.0, const double& aScalingFactor = 1.0, - const wxPoint& aTransformCentre = { 0, 0 }, const bool& aMirrorInvert = false ); + BOARD_ITEM_CONTAINER* aContainer, const GROUP_ID& aCadstarGroupID = wxEmptyString, + const wxPoint& aMoveVector = { 0, 0 }, const double& aRotationAngle = 0.0, + const double& aScalingFactor = 1.0, const wxPoint& aTransformCentre = { 0, 0 }, + const bool& aMirrorInvert = false ); /** * @brief Returns a vector of pointers to DRAWSEGMENT objects. Caller owns the objects. * @param aCadstarVertices * @param aContainer to draw on (e.g. mBoard). Can be nullptr. + * @param aCadstarGroupID to add the shape to * @param aMoveVector move draw segment by this amount (in KiCad coordinates) * @param aRotationAngle rotate draw segment by this amount (in tenth degrees) * @param aScalingFactor scale draw segment by this amount * @param aTransformCentre around which all transforms are applied (KiCad coordinates) - * @param aMirrorInvert if true, it inverts the Mirror status of aCadstarText + * @param aMirrorInvert if true, mirrors the drawsegment * @return */ std::vector getDrawSegmentsFromVertices( const std::vector& aCadstarVertices, BOARD_ITEM_CONTAINER* aContainer = nullptr, - const wxPoint& aMoveVector = { 0, 0 }, const double& aRotationAngle = 0.0, - const double& aScalingFactor = 1.0, const wxPoint& aTransformCentre = { 0, 0 }, - const bool& aMirrorInvert = false ); + const GROUP_ID& aCadstarGroupID = wxEmptyString, const wxPoint& aMoveVector = { 0, 0 }, + const double& aRotationAngle = 0.0, const double& aScalingFactor = 1.0, + const wxPoint& aTransformCentre = { 0, 0 }, const bool& aMirrorInvert = false ); /** * @brief Returns a pointer to a DRAWSEGMENT object. Caller owns the object. * @param aCadstarStartPoint * @param aCadstarVertex * @param aContainer to draw on (e.g. mBoard). Can be nullptr. + * @param aCadstarGroupID to add the shape to * @param aMoveVector move draw segment by this amount (in KiCad coordinates) * @param aRotationAngle rotate draw segment by this amount (in tenth degrees) * @param aScalingFactor scale draw segment by this amount * @param aTransformCentre around which all transforms are applied (KiCad coordinates) - * @param aMirrorInvert if true, it inverts the Mirror status of aCadstarText + * @param aMirrorInvert if true, mirrors the drawsegment * @return */ DRAWSEGMENT* getDrawSegmentFromVertex( const POINT& aCadstarStartPoint, const VERTEX& aCadstarVertex, BOARD_ITEM_CONTAINER* aContainer = nullptr, - const wxPoint& aMoveVector = { 0, 0 }, const double& aRotationAngle = 0.0, - const double& aScalingFactor = 1.0, const wxPoint& aTransformCentre = { 0, 0 }, - const bool& aMirrorInvert = false ); + const GROUP_ID& aCadstarGroupID = wxEmptyString, const wxPoint& aMoveVector = { 0, 0 }, + const double& aRotationAngle = 0.0, const double& aScalingFactor = 1.0, + const wxPoint& aTransformCentre = { 0, 0 }, const bool& aMirrorInvert = false ); /** * @brief @@ -249,7 +266,7 @@ private: * @param aRotationAngle rotate draw segment by this amount (in tenth degrees) * @param aScalingFactor scale draw segment by this amount * @param aTransformCentre around which all transforms are applied (KiCad coordinates) - * @param aMirrorInvert if true, it inverts the Mirror status of aCadstarText + * @param aMirrorInvert if true, mirrors the shape * @return */ SHAPE_POLY_SET getPolySetFromCadstarShape( const SHAPE& aCadstarShape, @@ -307,10 +324,11 @@ private: const std::map& aCadstarAttributeMap ); // Helper Functions for obtaining individual elements as KiCad elements: - double getHatchCodeAngleDegrees( const HATCHCODE_ID& aCadstarHatchcodeID ); - MODULE* getModuleFromCadstarID( const COMPONENT_ID& aCadstarComponentID ); - int getKiCadHatchCodeThickness( const HATCHCODE_ID& aCadstarHatchcodeID ); - int getKiCadHatchCodeGap( const HATCHCODE_ID& aCadstarHatchcodeID ); + double getHatchCodeAngleDegrees( const HATCHCODE_ID& aCadstarHatchcodeID ); + MODULE* getModuleFromCadstarID( const COMPONENT_ID& aCadstarComponentID ); + int getKiCadHatchCodeThickness( const HATCHCODE_ID& aCadstarHatchcodeID ); + int getKiCadHatchCodeGap( const HATCHCODE_ID& aCadstarHatchcodeID ); + PCB_GROUP* getKiCadGroup( const GROUP_ID& aCadstarGroupID ); /** * @brief Scales, offsets and inverts y axis to make the point usable directly in KiCad @@ -397,6 +415,17 @@ private: { return aContainer && aContainer->GetClass() == wxT( "MODULE" ); } + + + void addToGroup( const GROUP_ID& aCadstarGroupID, BOARD_ITEM* aKiCadItem ); + + /** + * @brief Adds a new PCB_GROUP* to mGroupMap + * @param aName Name to give the group. If name already exists, append "_1", "_2", etc. + * to the end to ensure it is unique + * @return + */ + GROUP_ID createUniqueGroupID( const wxString& aName ); }; diff --git a/pcbnew/plugins/cadstar/cadstar_pcb_archive_parser.cpp b/pcbnew/plugins/cadstar/cadstar_pcb_archive_parser.cpp index d61bce5461..6cfea7c07e 100644 --- a/pcbnew/plugins/cadstar/cadstar_pcb_archive_parser.cpp +++ b/pcbnew/plugins/cadstar/cadstar_pcb_archive_parser.cpp @@ -1520,6 +1520,8 @@ void CADSTAR_PCB_ARCHIVE_PARSER::FIGURE::Parse( XNODE* aNode ) { SwapRule = ParseSwapRule( cNode ); } + else if( cNodeName == wxT( "FIX" ) ) + Fixed = true; else if( cNodeName == wxT( "GROUPREF" ) ) GroupID = GetXmlAttributeIDString( cNode, 0 ); else if( cNodeName == wxT( "REUSEBLOCKREF" ) ) diff --git a/pcbnew/plugins/cadstar/cadstar_pcb_archive_parser.h b/pcbnew/plugins/cadstar/cadstar_pcb_archive_parser.h index 01630c4173..b9adeb4b38 100644 --- a/pcbnew/plugins/cadstar/cadstar_pcb_archive_parser.h +++ b/pcbnew/plugins/cadstar/cadstar_pcb_archive_parser.h @@ -975,6 +975,7 @@ public: GROUP_ID GroupID = wxEmptyString; ///< If not empty, this FIGURE is part of a group REUSEBLOCKREF ReuseBlockRef; SWAP_RULE SwapRule = SWAP_RULE::BOTH; ///< Only applicable to Figures in Components + bool Fixed = false; std::map AttributeValues; void Parse( XNODE* aNode );