Browse Source

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
pull/17/head
Maciej Suminski 8 years ago
parent
commit
1541cbdf04
  1. 27
      utils/kicad2step/pcb/oce_utils.cpp

27
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 );

Loading…
Cancel
Save