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
This commit is contained in:
Roberto Fernandez Bautista 2023-02-26 18:16:34 +01:00
parent beb177fa79
commit 698d0b7e92
4 changed files with 49 additions and 84 deletions

View File

@ -486,18 +486,28 @@ void CADSTAR_ARCHIVE_PARSER::VERTEX::AppendToChain( SHAPE_LINE_CHAIN* aChainToAp
const std::function<VECTOR2I( const VECTOR2I& )> 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<VECTOR2I( const VECTOR2I& )> 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 );
}

View File

@ -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<VECTOR2I( const VECTOR2I& )> aCadstarToKicadPointCallback,
double aAccuracy ) const;
SHAPE_ARC BuildArc( const VECTOR2I& aPrevPoint,
const std::function<VECTOR2I( const VECTOR2I& )>
aCadstarToKicadPointCallback ) const;
};
/**

View File

@ -40,6 +40,7 @@
#include <sch_junction.h>
#include <sch_line.h>
#include <sch_screen.h>
#include <sch_shape.h>
#include <sch_sheet.h>
#include <sch_sheet_path.h>
#include <sch_sheet_pin.h>
@ -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<VERTEX>& aCadstarVertices,
LINECODE_ID aCadstarLineCodeID,
LAYER_ID aCadstarSheetID,
@ -2073,68 +2044,58 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadShapeVertices( const std::vector<VERTEX>& 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;
SHAPE_ARC tempArc = cur->BuildArc( transformedStartPoint, pointTransform );
if( cw )
arcAngle = arcAngle.Normalize();
else
arcAngle = -arcAngle.Normalize();
SCH_SHAPE* arcShape = new SCH_SHAPE( SHAPE_T::ARC, lineWidth );
arcShape->SetArcGeometry( tempArc.GetP0(), tempArc.GetArcMid(), tempArc.GetP1() );
// TODO: Load as arc...
SHAPE_ARC tempArc( centerPoint, startPoint, arcAngle );
SHAPE_LINE_CHAIN arcSegments = tempArc.ConvertToPolyline( ARC_ACCURACY );
// 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:

View File

@ -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<VERTEX>& aCadstarVertices,
LINECODE_ID aCadstarLineCodeID, LAYER_ID aCadstarSheetID,
SCH_LAYER_ID aKiCadSchLayerID, const VECTOR2I& aMoveVector = { 0, 0 },