Maybe, just maybe, fix LibEdit arc parsing.
Fixes https://gitlab.com/kicad/code/kicad/issues/10455
This commit is contained in:
parent
af20d46d06
commit
3ba89f50ef
|
@ -494,10 +494,10 @@ void EDA_SHAPE::SetArcGeometry( const VECTOR2I& aStart, const VECTOR2I& aMid, co
|
||||||
m_arcCenter = CalcArcCenter( aStart, aMid, aEnd );
|
m_arcCenter = CalcArcCenter( aStart, aMid, aEnd );
|
||||||
m_endsSwapped = false;
|
m_endsSwapped = false;
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* If the input winding doesn't match our internal winding, the calculated midpoint will end up
|
* If the input winding doesn't match our internal winding, the calculated midpoint will end
|
||||||
* on the other side of the arc. In this case, we need to flip the start/end points and flag this
|
* up on the other side of the arc. In this case, we need to flip the start/end points and
|
||||||
* change for the system
|
* flag this change for the system.
|
||||||
*/
|
*/
|
||||||
VECTOR2I new_mid = GetArcMid();
|
VECTOR2I new_mid = GetArcMid();
|
||||||
VECTOR2D dist( new_mid - aMid );
|
VECTOR2D dist( new_mid - aMid );
|
||||||
|
|
|
@ -984,16 +984,29 @@ LIB_SHAPE* SCH_SEXPR_PARSER::parseArc()
|
||||||
if( hasMidPoint )
|
if( hasMidPoint )
|
||||||
{
|
{
|
||||||
arc->SetCenter( CalcArcCenter( arc->GetStart(), midPoint, arc->GetEnd() ) );
|
arc->SetCenter( CalcArcCenter( arc->GetStart(), midPoint, arc->GetEnd() ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current file format stores start-mid-end and so doesn't care about winding. We
|
||||||
|
* store start-end with an implied winding internally though, so we need to swap the
|
||||||
|
* ends if they don't match what we're expecting.
|
||||||
|
*/
|
||||||
|
EDA_ANGLE start, end;
|
||||||
|
arc->CalcArcAngles( start, end );
|
||||||
|
|
||||||
|
if( start < end )
|
||||||
|
{
|
||||||
|
VECTOR2I temp = arc->GetStart();
|
||||||
|
arc->SetStart( arc->GetEnd() );
|
||||||
|
arc->SetEnd( temp );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( hasAngles )
|
else if( hasAngles )
|
||||||
{
|
{
|
||||||
arc->SetCenter( center );
|
arc->SetCenter( center );
|
||||||
/**
|
/*
|
||||||
* This accounts for an oddity in the old library format, where the symbol is overdefined.
|
* Older versions stored start-end with an implied winding, but the winding was different
|
||||||
* The previous draw (based on wxwidgets) used start point and end point and always drew
|
* between LibEdit and PCBNew. Since we now use a common class (EDA_SHAPE) for both we
|
||||||
* counter-clockwise. The new GAL draw takes center, radius and start/end angles. All of
|
* need to flip one of them. LibEdit drew the short straw.
|
||||||
* these points were stored in the file, so we need to mimic the swapping of start/end
|
|
||||||
* points rather than using the stored angles in order to properly map edge cases.
|
|
||||||
*/
|
*/
|
||||||
VECTOR2I temp = arc->GetStart();
|
VECTOR2I temp = arc->GetStart();
|
||||||
arc->SetStart( arc->GetEnd() );
|
arc->SetStart( arc->GetEnd() );
|
||||||
|
@ -2822,13 +2835,8 @@ SCH_SHAPE* SCH_SEXPR_PARSER::parseSchArc()
|
||||||
VECTOR2I startPoint;
|
VECTOR2I startPoint;
|
||||||
VECTOR2I midPoint;
|
VECTOR2I midPoint;
|
||||||
VECTOR2I endPoint;
|
VECTOR2I endPoint;
|
||||||
VECTOR2I pos;
|
|
||||||
EDA_ANGLE startAngle;
|
|
||||||
EDA_ANGLE endAngle;
|
|
||||||
STROKE_PARAMS stroke( Mils2iu( DEFAULT_LINE_WIDTH_MILS ), PLOT_DASH_TYPE::DEFAULT );
|
STROKE_PARAMS stroke( Mils2iu( DEFAULT_LINE_WIDTH_MILS ), PLOT_DASH_TYPE::DEFAULT );
|
||||||
FILL_PARAMS fill;
|
FILL_PARAMS fill;
|
||||||
bool hasMidPoint = false;
|
|
||||||
bool hasAngles = false;
|
|
||||||
std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>( SHAPE_T::ARC );
|
std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>( SHAPE_T::ARC );
|
||||||
|
|
||||||
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
|
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
|
||||||
|
@ -2848,7 +2856,6 @@ SCH_SHAPE* SCH_SEXPR_PARSER::parseSchArc()
|
||||||
case T_mid:
|
case T_mid:
|
||||||
midPoint = parseXY();
|
midPoint = parseXY();
|
||||||
NeedRIGHT();
|
NeedRIGHT();
|
||||||
hasMidPoint = true;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_end:
|
case T_end:
|
||||||
|
@ -2856,44 +2863,6 @@ SCH_SHAPE* SCH_SEXPR_PARSER::parseSchArc()
|
||||||
NeedRIGHT();
|
NeedRIGHT();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_radius:
|
|
||||||
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
|
|
||||||
{
|
|
||||||
if( token != T_LEFT )
|
|
||||||
Expecting( T_LEFT );
|
|
||||||
|
|
||||||
token = NextTok();
|
|
||||||
|
|
||||||
switch( token )
|
|
||||||
{
|
|
||||||
case T_at:
|
|
||||||
pos = parseXY();
|
|
||||||
NeedRIGHT();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case T_length:
|
|
||||||
parseInternalUnits( "radius length" );
|
|
||||||
NeedRIGHT();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case T_angles:
|
|
||||||
{
|
|
||||||
startAngle = EDA_ANGLE( parseDouble( "start radius angle" ), DEGREES_T );
|
|
||||||
endAngle = EDA_ANGLE( parseDouble( "end radius angle" ), DEGREES_T );
|
|
||||||
startAngle.Normalize();
|
|
||||||
endAngle.Normalize();
|
|
||||||
NeedRIGHT();
|
|
||||||
hasAngles = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
Expecting( "at, length, or angle" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case T_stroke:
|
case T_stroke:
|
||||||
parseStroke( stroke );
|
parseStroke( stroke );
|
||||||
arc->SetStroke( stroke );
|
arc->SetStroke( stroke );
|
||||||
|
@ -2912,38 +2881,29 @@ SCH_SHAPE* SCH_SEXPR_PARSER::parseSchArc()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Expecting( "start, mid, end, radius, stroke, fill or uuid" );
|
Expecting( "start, mid, end, stroke, fill or uuid" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
arc->SetStart( startPoint );
|
arc->SetStart( startPoint );
|
||||||
arc->SetEnd( endPoint );
|
arc->SetEnd( endPoint );
|
||||||
|
arc->SetCenter( CalcArcCenter( arc->GetStart(), midPoint, arc->GetEnd() ) );
|
||||||
|
|
||||||
if( hasMidPoint )
|
/**
|
||||||
{
|
* Current file format stores start-mid-end and so doesn't care about winding. We store
|
||||||
VECTOR2I center = CalcArcCenter( arc->GetStart(), midPoint, arc->GetEnd() );
|
* start-end with an implied winding internally though, so we need to swap the ends if they
|
||||||
|
* don't match what we're expecting. (Note that what we're expecting is backwards from the
|
||||||
|
* LIB_SHAPE case because LibEdit has an upside-down coordinate system.)
|
||||||
|
*/
|
||||||
|
EDA_ANGLE start, end;
|
||||||
|
arc->CalcArcAngles( start, end );
|
||||||
|
|
||||||
arc->SetCenter( center );
|
if( start > end )
|
||||||
}
|
|
||||||
else if( hasAngles )
|
|
||||||
{
|
{
|
||||||
arc->SetCenter( pos );
|
VECTOR2I temp = arc->GetStart();
|
||||||
/**
|
arc->SetStart( arc->GetEnd() );
|
||||||
* This accounts for an oddity in the old library format, where the symbol is overdefined.
|
arc->SetEnd( temp );
|
||||||
* The previous draw (based on wxwidgets) used start point and end point and always drew
|
|
||||||
* counter-clockwise. The new GAL draw takes center, radius and start/end angles. All of
|
|
||||||
* these points were stored in the file, so we need to mimic the swapping of start/end
|
|
||||||
* points rather than using the stored angles in order to properly map edge cases.
|
|
||||||
*/
|
|
||||||
if( !TRANSFORM().MapAngles( &startAngle, &endAngle ) )
|
|
||||||
{
|
|
||||||
VECTOR2I temp = arc->GetStart();
|
|
||||||
arc->SetStart( arc->GetEnd() );
|
|
||||||
arc->SetEnd( temp );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
wxFAIL_MSG( "Setting arc without either midpoint or angles not implemented." );
|
|
||||||
|
|
||||||
return arc.release();
|
return arc.release();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue