From 38bd612c01b32cf1ec5748c19f4ab521bd0872d4 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Sun, 27 Mar 2022 10:31:21 +0200 Subject: [PATCH] sch_sexpr_parser.cpp: allows reading a polyline descr with more than 2 points In symbols, a polyline descr is already a true polyline / polygon descr. In schematic, a polyline descr was restricted to only 2 points (a line). A true polyline / polygon descr is now allowed in schematic that support already polygons. For compatibility reason, a 2 points polygon (SCH_SHAPE) is converted to a SCH_LINE. --- .../sch_plugins/kicad/sch_sexpr_parser.cpp | 93 +++++++++++++++++++ eeschema/sch_plugins/kicad/sch_sexpr_parser.h | 1 + eeschema/tools/ee_tool_base.h | 2 +- 3 files changed, 95 insertions(+), 1 deletion(-) diff --git a/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp b/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp index 8acab58d33..96e992553d 100644 --- a/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp +++ b/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp @@ -2289,6 +2289,35 @@ void SCH_SEXPR_PARSER::ParseSchematic( SCH_SHEET* aSheet, bool aIsCopyableOnly, break; case T_polyline: + { + // polyline keyword is used in eeschema both for SCH_SHAPE and SCH_LINE items. + // In symbols it describes a polygon, having n corners and can be filled + // In schematic it describes a line (with no fill descr), but could be extended to a + // polygon (for instance when importing files) because the schematic handles all SCH_SHAPE. + // parseSchPolyLine() returns always a SCH_SHAPE, io convert it to a simple SCH_LINE + // For compatibility reasons, keep SCH_SHAPE for a polygon and convert to SCH_LINE + // when the item has only 2 corners, similar to a SCH_LINE + SCH_SHAPE* poly = parseSchPolyLine(); + + if( poly->GetPointCount() > 2 ) + screen->Append( poly ); + else + { + // For SCH_SHAPE having only 2 points, this is a "old" SCH_LINE entity. + // So convert the SCH_SHAPE to a simple SCH_LINE + SCH_LINE* line = new SCH_LINE( VECTOR2I(), LAYER_NOTES ); + SHAPE_LINE_CHAIN& outline = poly->GetPolyShape().Outline(0); + line->SetStartPoint( outline.CPoint(0) ); + line->SetEndPoint( outline.CPoint(1) ); + line->SetStroke( poly->GetStroke() ); + + screen->Append( line ); + + delete poly; + } + } + break; + case T_bus: case T_wire: screen->Append( parseLine() ); @@ -2919,8 +2948,72 @@ SCH_BUS_WIRE_ENTRY* SCH_SEXPR_PARSER::parseBusEntry() } +SCH_SHAPE* SCH_SEXPR_PARSER::parseSchPolyLine() +{ + T token; + STROKE_PARAMS stroke( Mils2iu( DEFAULT_LINE_WIDTH_MILS ), PLOT_DASH_TYPE::DEFAULT ); + FILL_PARAMS fill; + int layer = LAYER_NOTES; + + std::unique_ptr polyline = std::make_unique( SHAPE_T::POLY, layer ); + + for( token = NextTok(); token != T_RIGHT; token = NextTok() ) + { + if( token != T_LEFT ) + Expecting( T_LEFT ); + + token = NextTok(); + + switch( token ) + { + case T_pts: + for( token = NextTok(); token != T_RIGHT; token = NextTok() ) + { + if( token != T_LEFT ) + Expecting( T_LEFT ); + + token = NextTok(); + + if( token != T_xy ) + Expecting( "xy" ); + + polyline->AddPoint( parseXY() ); + + NeedRIGHT(); + } + break; + + case T_stroke: + parseStroke( stroke ); + polyline->SetStroke( stroke ); + break; + + case T_fill: + parseFill( fill ); + polyline->SetFillMode( fill.m_FillType ); + polyline->SetFillColor( fill.m_Color ); + break; + + case T_uuid: + NeedSYMBOL(); + const_cast( polyline->m_Uuid ) = parseKIID(); + NeedRIGHT(); + break; + + default: + Expecting( "pts, uuid, stroke, or fill" ); + } + } + + return polyline.release(); +} + + SCH_LINE* SCH_SEXPR_PARSER::parseLine() { + // Note: T_polyline is deprecated in this code: it is now handled by + // parseSchPolyLine() that can handle true polygons, and not only one segment. + T token; STROKE_PARAMS stroke( Mils2iu( DEFAULT_LINE_WIDTH_MILS ), PLOT_DASH_TYPE::DEFAULT ); int layer; diff --git a/eeschema/sch_plugins/kicad/sch_sexpr_parser.h b/eeschema/sch_plugins/kicad/sch_sexpr_parser.h index 4791db2fa4..6cde8d3012 100644 --- a/eeschema/sch_plugins/kicad/sch_sexpr_parser.h +++ b/eeschema/sch_plugins/kicad/sch_sexpr_parser.h @@ -195,6 +195,7 @@ class SCH_SEXPR_PARSER : public SCHEMATIC_LEXER SCH_NO_CONNECT* parseNoConnect(); SCH_BUS_WIRE_ENTRY* parseBusEntry(); SCH_LINE* parseLine(); + SCH_SHAPE* parseSchPolyLine(); SCH_SHAPE* parseSchArc(); SCH_SHAPE* parseSchCircle(); SCH_SHAPE* parseSchRectangle(); diff --git a/eeschema/tools/ee_tool_base.h b/eeschema/tools/ee_tool_base.h index a5e9518ff6..781f6923ca 100644 --- a/eeschema/tools/ee_tool_base.h +++ b/eeschema/tools/ee_tool_base.h @@ -145,7 +145,7 @@ protected: if( m_isSymbolEditor ) { SYMBOL_EDIT_FRAME* editFrame = dynamic_cast( m_frame ); - wxASSERT( editFrame ); + wxCHECK_RET( editFrame, wxT( "editFrame is null" ) ); editFrame->SaveCopyInUndoList( static_cast( aItem ), aType, aAppend ); }