diff --git a/common/eda_shape.cpp b/common/eda_shape.cpp index 22879140e3..4cda3ab5b5 100644 --- a/common/eda_shape.cpp +++ b/common/eda_shape.cpp @@ -494,10 +494,10 @@ void EDA_SHAPE::SetArcGeometry( const VECTOR2I& aStart, const VECTOR2I& aMid, co m_arcCenter = CalcArcCenter( aStart, aMid, aEnd ); m_endsSwapped = false; - /** - * If the input winding doesn't match our internal winding, the calculated midpoint will end up - * on the other side of the arc. In this case, we need to flip the start/end points and flag this - * change for the system + /* + * If the input winding doesn't match our internal winding, the calculated midpoint will end + * up on the other side of the arc. In this case, we need to flip the start/end points and + * flag this change for the system. */ VECTOR2I new_mid = GetArcMid(); VECTOR2D dist( new_mid - aMid ); diff --git a/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp b/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp index 80a558ab94..904ed7dfa2 100644 --- a/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp +++ b/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp @@ -984,16 +984,29 @@ LIB_SHAPE* SCH_SEXPR_PARSER::parseArc() if( hasMidPoint ) { 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 ) { arc->SetCenter( center ); - /** - * This accounts for an oddity in the old library format, where the symbol is overdefined. - * 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. + /* + * Older versions stored start-end with an implied winding, but the winding was different + * between LibEdit and PCBNew. Since we now use a common class (EDA_SHAPE) for both we + * need to flip one of them. LibEdit drew the short straw. */ VECTOR2I temp = arc->GetStart(); arc->SetStart( arc->GetEnd() ); @@ -2822,13 +2835,8 @@ SCH_SHAPE* SCH_SEXPR_PARSER::parseSchArc() VECTOR2I startPoint; VECTOR2I midPoint; VECTOR2I endPoint; - VECTOR2I pos; - EDA_ANGLE startAngle; - EDA_ANGLE endAngle; STROKE_PARAMS stroke( Mils2iu( DEFAULT_LINE_WIDTH_MILS ), PLOT_DASH_TYPE::DEFAULT ); FILL_PARAMS fill; - bool hasMidPoint = false; - bool hasAngles = false; std::unique_ptr arc = std::make_unique( SHAPE_T::ARC ); for( token = NextTok(); token != T_RIGHT; token = NextTok() ) @@ -2848,7 +2856,6 @@ SCH_SHAPE* SCH_SEXPR_PARSER::parseSchArc() case T_mid: midPoint = parseXY(); NeedRIGHT(); - hasMidPoint = true; break; case T_end: @@ -2856,44 +2863,6 @@ SCH_SHAPE* SCH_SEXPR_PARSER::parseSchArc() NeedRIGHT(); 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: parseStroke( stroke ); arc->SetStroke( stroke ); @@ -2912,38 +2881,29 @@ SCH_SHAPE* SCH_SEXPR_PARSER::parseSchArc() break; default: - Expecting( "start, mid, end, radius, stroke, fill or uuid" ); + Expecting( "start, mid, end, stroke, fill or uuid" ); } } arc->SetStart( startPoint ); arc->SetEnd( endPoint ); + arc->SetCenter( CalcArcCenter( arc->GetStart(), midPoint, arc->GetEnd() ) ); - if( hasMidPoint ) - { - VECTOR2I center = 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. (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 ); - } - else if( hasAngles ) + if( start > end ) { - arc->SetCenter( pos ); - /** - * This accounts for an oddity in the old library format, where the symbol is overdefined. - * 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 ); - } + 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(); }