From 698d0b7e92bdd396cae5d03f55bcc9b3124c4437 Mon Sep 17 00:00:00 2001 From: Roberto Fernandez Bautista Date: Sun, 26 Feb 2023 18:16:34 +0100 Subject: [PATCH] CADSTAR Sch: Fix loading of graphical arc shapes Correctly load arc shapes as real arcs instead of approximating now that v7 supports graphical arcs in the schematic. Also fix calculation of arc geometry for ccw arcs. Fixes https://gitlab.com/kicad/code/kicad/-/issues/14101 --- .../cadstar/cadstar_archive_parser.cpp | 21 ++-- .../plugins/cadstar/cadstar_archive_parser.h | 5 + .../cadstar/cadstar_sch_archive_loader.cpp | 97 ++++++------------- .../cadstar/cadstar_sch_archive_loader.h | 10 -- 4 files changed, 49 insertions(+), 84 deletions(-) diff --git a/common/plugins/cadstar/cadstar_archive_parser.cpp b/common/plugins/cadstar/cadstar_archive_parser.cpp index 957c35dce5..2f6439503c 100644 --- a/common/plugins/cadstar/cadstar_archive_parser.cpp +++ b/common/plugins/cadstar/cadstar_archive_parser.cpp @@ -486,18 +486,28 @@ void CADSTAR_ARCHIVE_PARSER::VERTEX::AppendToChain( SHAPE_LINE_CHAIN* aChainToAp const std::function aCadstarToKicadPointCallback, double aAccuracy ) const { - VECTOR2I endPoint = aCadstarToKicadPointCallback( End ); - if( Type == VERTEX_TYPE::POINT ) { - aChainToAppendTo->Append( endPoint ); + aChainToAppendTo->Append( aCadstarToKicadPointCallback( End ) ); return; } wxCHECK_MSG( aChainToAppendTo->PointCount() > 0, /*void*/, "Can't append an arc to vertex to an empty chain" ); - VECTOR2I startPoint = aChainToAppendTo->GetPoint( -1 ); + aChainToAppendTo->Append( BuildArc( aChainToAppendTo->GetPoint( -1 ), aCadstarToKicadPointCallback), + aAccuracy ); +} + + +SHAPE_ARC CADSTAR_ARCHIVE_PARSER::VERTEX::BuildArc( const VECTOR2I& aPrevPoint, + const std::function aCadstarToKicadPointCallback ) const +{ + wxCHECK_MSG( Type != VERTEX_TYPE::POINT, SHAPE_ARC(), + "Can't build an arc for a straight segment!" ); + + VECTOR2I startPoint = aPrevPoint; + VECTOR2I endPoint = aCadstarToKicadPointCallback( End ); VECTOR2I centerPoint; if( Type == VERTEX_TYPE::ANTICLOCKWISE_SEMICIRCLE || Type == VERTEX_TYPE::CLOCKWISE_SEMICIRCLE ) @@ -516,9 +526,8 @@ void CADSTAR_ARCHIVE_PARSER::VERTEX::AppendToChain( SHAPE_LINE_CHAIN* aChainToAp clockwise = !clockwise; SHAPE_ARC arc; - arc.ConstructFromStartEndCenter( startPoint, endPoint, centerPoint, clockwise ); - aChainToAppendTo->Append( arc, aAccuracy ); + return arc.ConstructFromStartEndCenter( startPoint, endPoint, centerPoint, clockwise ); } diff --git a/common/plugins/cadstar/cadstar_archive_parser.h b/common/plugins/cadstar/cadstar_archive_parser.h index 533d9b878d..040f4780fb 100644 --- a/common/plugins/cadstar/cadstar_archive_parser.h +++ b/common/plugins/cadstar/cadstar_archive_parser.h @@ -83,6 +83,7 @@ class wxXmlAttribute; class PROGRESS_REPORTER; class SHAPE_LINE_CHAIN; class SHAPE_POLY_SET; +class SHAPE_ARC; /** * @brief Helper functions and common structures for CADSTAR PCB and Schematic archive files. @@ -451,6 +452,10 @@ public: void AppendToChain( SHAPE_LINE_CHAIN* aChainToAppendTo, const std::function aCadstarToKicadPointCallback, double aAccuracy ) const; + + SHAPE_ARC BuildArc( const VECTOR2I& aPrevPoint, + const std::function + aCadstarToKicadPointCallback ) const; }; /** diff --git a/eeschema/sch_plugins/cadstar/cadstar_sch_archive_loader.cpp b/eeschema/sch_plugins/cadstar/cadstar_sch_archive_loader.cpp index 0a63d1d7a7..c7649ee218 100644 --- a/eeschema/sch_plugins/cadstar/cadstar_sch_archive_loader.cpp +++ b/eeschema/sch_plugins/cadstar/cadstar_sch_archive_loader.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -2033,36 +2034,6 @@ wxString CADSTAR_SCH_ARCHIVE_LOADER::getNetName( const NET_SCH& aNet ) } -void CADSTAR_SCH_ARCHIVE_LOADER::loadGraphicStaightSegment( const VECTOR2I& aStartPoint, - const VECTOR2I& aEndPoint, - const LINECODE_ID& aCadstarLineCodeID, - const LAYER_ID& aCadstarSheetID, - const SCH_LAYER_ID& aKiCadSchLayerID, - const VECTOR2I& aMoveVector, - const EDA_ANGLE& aRotation, - const double& aScalingFactor, - const VECTOR2I& aTransformCentre, - const bool& aMirrorInvert ) -{ - SCH_LINE* segment = new SCH_LINE(); - - segment->SetLayer( aKiCadSchLayerID ); - segment->SetLineWidth( KiROUND( getLineThickness( aCadstarLineCodeID ) * aScalingFactor ) ); - segment->SetLineStyle( getLineStyle( aCadstarLineCodeID ) ); - - //Apply transforms - VECTOR2I startPoint = applyTransform( aStartPoint, aMoveVector, aRotation, aScalingFactor, - aTransformCentre, aMirrorInvert ); - VECTOR2I endPoint = applyTransform( aEndPoint, aMoveVector, aRotation, aScalingFactor, - aTransformCentre, aMirrorInvert ); - - segment->SetStartPoint( startPoint ); - segment->SetEndPoint( endPoint ); - - loadItemOntoKiCadSheet( aCadstarSheetID, segment ); -} - - void CADSTAR_SCH_ARCHIVE_LOADER::loadShapeVertices( const std::vector& aCadstarVertices, LINECODE_ID aCadstarLineCodeID, LAYER_ID aCadstarSheetID, @@ -2073,68 +2044,58 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadShapeVertices( const std::vector& a const VECTOR2I& aTransformCentre, const bool& aMirrorInvert ) { + int lineWidth = KiROUND( getLineThickness( aCadstarLineCodeID ) * aScalingFactor ); + PLOT_DASH_TYPE lineStyle = getLineStyle( aCadstarLineCodeID ); + const VERTEX* prev = &aCadstarVertices.at( 0 ); const VERTEX* cur; wxASSERT_MSG( prev->Type == VERTEX_TYPE::POINT, "First vertex should always be a point vertex" ); + auto pointTransform = + [&]( const VECTOR2I& aV ) + { + return applyTransform( getKiCadPoint( aV ), aMoveVector, aRotation, + aScalingFactor, aTransformCentre, aMirrorInvert ); + }; + for( size_t ii = 1; ii < aCadstarVertices.size(); ii++ ) { cur = &aCadstarVertices.at( ii ); - VECTOR2I startPoint = getKiCadPoint( prev->End ); - VECTOR2I endPoint = getKiCadPoint( cur->End ); - VECTOR2I centerPoint = getKiCadPoint( cur->Center ); - bool cw = false; - - if( cur->Type == VERTEX_TYPE::ANTICLOCKWISE_SEMICIRCLE - || cur->Type == VERTEX_TYPE::CLOCKWISE_SEMICIRCLE ) - { - centerPoint = ( startPoint + endPoint ) / 2; - } + VECTOR2I transformedStartPoint = pointTransform( prev->End ); + VECTOR2I transformedEndPoint = pointTransform( cur->End ); switch( cur->Type ) { case VERTEX_TYPE::CLOCKWISE_SEMICIRCLE: case VERTEX_TYPE::CLOCKWISE_ARC: - cw = true; - KI_FALLTHROUGH; case VERTEX_TYPE::ANTICLOCKWISE_SEMICIRCLE: case VERTEX_TYPE::ANTICLOCKWISE_ARC: { - EDA_ANGLE arcStartAngle( startPoint - centerPoint ); - EDA_ANGLE arcEndAngle( endPoint - centerPoint ); - EDA_ANGLE arcAngle = arcEndAngle - arcStartAngle; - - if( cw ) - arcAngle = arcAngle.Normalize(); - else - arcAngle = -arcAngle.Normalize(); - - // TODO: Load as arc... + SHAPE_ARC tempArc = cur->BuildArc( transformedStartPoint, pointTransform ); - SHAPE_ARC tempArc( centerPoint, startPoint, arcAngle ); - SHAPE_LINE_CHAIN arcSegments = tempArc.ConvertToPolyline( ARC_ACCURACY ); + SCH_SHAPE* arcShape = new SCH_SHAPE( SHAPE_T::ARC, lineWidth ); + arcShape->SetArcGeometry( tempArc.GetP0(), tempArc.GetArcMid(), tempArc.GetP1() ); - // Load the arc as a series of piece-wise segments - - for( int jj = 0; jj < arcSegments.SegmentCount(); jj++ ) - { - VECTOR2I segStart = arcSegments.Segment( jj ).A; - VECTOR2I segEnd = arcSegments.Segment( jj ).B; - - loadGraphicStaightSegment( segStart, segEnd, aCadstarLineCodeID, aCadstarSheetID, - aKiCadSchLayerID, aMoveVector, aRotation, aScalingFactor, - aTransformCentre, aMirrorInvert ); - } + loadItemOntoKiCadSheet( aCadstarSheetID, arcShape ); } break; case VERTEX_TYPE::POINT: - loadGraphicStaightSegment( startPoint, endPoint, aCadstarLineCodeID, aCadstarSheetID, - aKiCadSchLayerID, aMoveVector, aRotation, aScalingFactor, - aTransformCentre, aMirrorInvert ); + { + SCH_LINE* segment = new SCH_LINE(); + + segment->SetLayer( aKiCadSchLayerID ); + segment->SetLineWidth( lineWidth ); + segment->SetLineStyle( lineStyle ); + + segment->SetStartPoint( transformedStartPoint ); + segment->SetEndPoint( transformedEndPoint ); + + loadItemOntoKiCadSheet( aCadstarSheetID, segment ); + } break; default: diff --git a/eeschema/sch_plugins/cadstar/cadstar_sch_archive_loader.h b/eeschema/sch_plugins/cadstar/cadstar_sch_archive_loader.h index e071458faf..f6a2db3133 100644 --- a/eeschema/sch_plugins/cadstar/cadstar_sch_archive_loader.h +++ b/eeschema/sch_plugins/cadstar/cadstar_sch_archive_loader.h @@ -165,16 +165,6 @@ private: wxString getNetName( const NET_SCH& aNet ); //Helper functions for loading figures / graphical items - void loadGraphicStaightSegment( const VECTOR2I& aStartPoint, const VECTOR2I& aEndPoint, - const LINECODE_ID& aCadstarLineCodeID, - const LAYER_ID& aCadstarSheetID, - const SCH_LAYER_ID& aKiCadSchLayerID, - const VECTOR2I& aMoveVector = { 0, 0 }, - const EDA_ANGLE& aRotation = ANGLE_0, - const double& aScalingFactor = 1.0, - const VECTOR2I& aTransformCentre = { 0, 0 }, - const bool& aMirrorInvert = false ); - void loadShapeVertices( const std::vector& aCadstarVertices, LINECODE_ID aCadstarLineCodeID, LAYER_ID aCadstarSheetID, SCH_LAYER_ID aKiCadSchLayerID, const VECTOR2I& aMoveVector = { 0, 0 },