From 1541cbdf04a471f506f22e133bcfc0db0a5d603e Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 18 Jun 2018 17:25:07 +0200 Subject: [PATCH] kicad2step: Add short segments to fix outline contiguity for arcs STEP exporter keeps outline contiguous by storing the last point coordinates and using them as the starting point for the next segment. It might create a problem for arcs, as one of the arc end points may become translated (changed to the last outline point), while the remaining points (center and the other endpoint) are kept original. For large deltas it renders an arc invalid, as it cannot pass through a modified endpoint anymore. To fix this, short segments are added to link the last outline point with an arc endpoint, but only if the distance between the two is below a certain threshold. This way the outline is kept contiguous and the arc end point is unmodified, warranting its correctness. Fixes: lp:1774351 * https://bugs.launchpad.net/kicad/+bug/1774351 --- utils/kicad2step/pcb/oce_utils.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/utils/kicad2step/pcb/oce_utils.cpp b/utils/kicad2step/pcb/oce_utils.cpp index d5603a6b44..9342ec88c6 100644 --- a/utils/kicad2step/pcb/oce_utils.cpp +++ b/utils/kicad2step/pcb/oce_utils.cpp @@ -1460,6 +1460,33 @@ bool OUTLINE::addEdge( BRepBuilderAPI_MakeWire* aWire, KICADCURVE& aCurve, DOUBL case CURVE_ARC: { + // Arcs are particularly tricky to be used in contiguous outlines. + // If an arc is not precisely aligned with the previous segment end point + // (aLastPoint != aCurve.m_end), then it might be impossible to request an arc + // passing through aLastPoint and the other arc end. To fix this, a small segment + // is added, joining aLastPoint and aCurve.m_end, but only if the distance + // is small. + double dx = aLastPoint.x - aCurve.m_end.x; + double dy = aLastPoint.y - aCurve.m_end.y; + double distance = dx * dx + dy * dy; + + if( distance > 0 && distance < MIN_LENGTH2 ) + { + std::ostringstream ostr; + +#ifdef __WXDEBUG__ + ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; +#endif /* __WXDEBUG */ + ostr << " * added an auxiliary segment from " + << aLastPoint << " to " << aCurve.m_end << "\n"; + wxLogMessage( "%s", ostr.str().c_str() ); + + edge = BRepBuilderAPI_MakeEdge( gp_Pnt( aLastPoint.x, aLastPoint.y, 0.0 ), + gp_Pnt( aCurve.m_end.x, aCurve.m_end.y, 0.0 ) ); + aWire->Add( edge ); + aLastPoint = aCurve.m_end; + } + gp_Circ arc( gp_Ax2( gp_Pnt( aCurve.m_start.x, aCurve.m_start.y, 0.0 ), gp_Dir( 0.0, 0.0, 1.0 ) ), aCurve.m_radius );