diff --git a/src/Mod/Drawing/App/DrawingExport.cpp b/src/Mod/Drawing/App/DrawingExport.cpp index cc3ad8728c..06133ee5de 100644 --- a/src/Mod/Drawing/App/DrawingExport.cpp +++ b/src/Mod/Drawing/App/DrawingExport.cpp @@ -359,17 +359,18 @@ void SVGOutput::printBSpline(const BRepAdaptor_Curve& c, int id, std::ostream& o { try { std::stringstream str; - Handle(Geom_BSplineCurve) spline = c.BSpline(); - if (spline->Degree() > 3 || spline->IsRational()) { - Standard_Real tol3D = 0.001; - Standard_Integer maxDegree = 3, maxSegment = 100; - Handle(BRepAdaptor_HCurve) hCurve = new BRepAdaptor_HCurve(c); - // approximate the curve using a tolerance - Approx_Curve3d approx(hCurve,tol3D,GeomAbs_C0,maxSegment,maxDegree); - if (approx.IsDone() && approx.HasResult()) { - // have the result - spline = approx.Curve(); - } + Handle(Geom_BSplineCurve) spline; + Standard_Real tol3D = 0.001; + Standard_Integer maxDegree = 3, maxSegment = 100; + Handle(BRepAdaptor_HCurve) hCurve = new BRepAdaptor_HCurve(c); + // approximate the curve using a tolerance + Approx_Curve3d approx(hCurve,tol3D,GeomAbs_C0,maxSegment,maxDegree); + if (approx.IsDone() && approx.HasResult()) { + // have the result + spline = approx.Curve(); + } else { + printGeneric(c, id, out); + return; } GeomConvert_BSplineCurveToBezierCurve crt(spline); @@ -659,17 +660,18 @@ void DXFOutput::printBSpline(const BRepAdaptor_Curve& c, int id, std::ostream& o { try { std::stringstream str; - Handle(Geom_BSplineCurve) spline = c.BSpline(); - if (spline->Degree() > 3 || spline->IsRational()) { - Standard_Real tol3D = 0.001; - Standard_Integer maxDegree = 3, maxSegment = 50; - Handle(BRepAdaptor_HCurve) hCurve = new BRepAdaptor_HCurve(c); - // approximate the curve using a tolerance - Approx_Curve3d approx(hCurve,tol3D,GeomAbs_C0,maxSegment,maxDegree); - if (approx.IsDone() && approx.HasResult()) { - // have the result - spline = approx.Curve(); - } + Handle(Geom_BSplineCurve) spline; + Standard_Real tol3D = 0.001; + Standard_Integer maxDegree = 3, maxSegment = 50; + Handle(BRepAdaptor_HCurve) hCurve = new BRepAdaptor_HCurve(c); + // approximate the curve using a tolerance + Approx_Curve3d approx(hCurve,tol3D,GeomAbs_C0,maxSegment,maxDegree); + if (approx.IsDone() && approx.HasResult()) { + // have the result + spline = approx.Curve(); + } else { + printGeneric(c, id, out); + return; } //GeomConvert_BSplineCurveToBezierCurve crt(spline); diff --git a/src/Mod/TechDraw/App/Geometry.cpp b/src/Mod/TechDraw/App/Geometry.cpp index c835ddce56..793d8a1837 100644 --- a/src/Mod/TechDraw/App/Geometry.cpp +++ b/src/Mod/TechDraw/App/Geometry.cpp @@ -42,12 +42,15 @@ #include #include #include +#include #include #include #include #include #include #include +#include + #include #endif // #ifndef _PreComp_ @@ -429,64 +432,52 @@ BSpline::BSpline(const TopoDS_Edge &e) geomType = BSPLINE; BRepAdaptor_Curve c(e); occEdge = e; - Handle(Geom_BSplineCurve) spline = c.BSpline(); - bool fail = false; + Handle(Geom_BSplineCurve) spline; double f,l; - gp_Pnt s,m,ePt; + gp_Pnt s,ePt; - if (spline->Degree() > 3 || spline->IsRational()) { //if spline is too complex, approximate it - Standard_Real tol3D = 0.001; //1/1000 of a mm? screen can't resolve this - Standard_Integer maxDegree = 3, maxSegment = 100; - Handle(BRepAdaptor_HCurve) hCurve = new BRepAdaptor_HCurve(c); - // approximate the curve using a tolerance - //Approx_Curve3d approx(hCurve, tol3D, GeomAbs_C2, maxSegment, maxDegree); //gives degree == 5 ==> too many poles ==> buffer overrun - Approx_Curve3d approx(hCurve, tol3D, GeomAbs_C0, maxSegment, maxDegree); - if (approx.IsDone() && approx.HasResult()) { + Standard_Real tol3D = 0.001; //1/1000 of a mm? screen can't resolve this + Standard_Integer maxDegree = 3, maxSegment = 100; + Handle(BRepAdaptor_HCurve) hCurve = new BRepAdaptor_HCurve(c); + // approximate the curve using a tolerance + //Approx_Curve3d approx(hCurve, tol3D, GeomAbs_C2, maxSegment, maxDegree); //gives degree == 5 ==> too many poles ==> buffer overrun + Approx_Curve3d approx(hCurve, tol3D, GeomAbs_C0, maxSegment, maxDegree); + if (approx.IsDone() && approx.HasResult()) { + spline = approx.Curve(); + } else { + if (approx.HasResult()) { //result, but not within tolerance spline = approx.Curve(); + Base::Console().Log("Geometry::BSpline - result not within tolerance\n"); } else { - if (approx.HasResult()) { //result, but not within tolerance - spline = approx.Curve(); - Base::Console().Log("Geometry::BSpline - result not within tolerance\n"); - } else { - fail = true; - f = c.FirstParameter(); - l = c.LastParameter(); - s = c.Value(f); - m = c.Value((l+f)/2.0); - ePt = c.Value(l); - Base::Console().Log("Error - Geometry::BSpline - no result- from:(%.3f,%.3f) to:(%.3f,%.3f) poles: %d\n", - s.X(),s.Y(),ePt.X(),ePt.Y(),spline->NbPoles()); - throw Base::Exception("Geometry::BSpline - could not approximate curve"); - } + f = c.FirstParameter(); + l = c.LastParameter(); + s = c.Value(f); + ePt = c.Value(l); + Base::Console().Log("Error - Geometry::BSpline - no result- from:(%.3f,%.3f) to:(%.3f,%.3f) poles: %d\n", + s.X(),s.Y(),ePt.X(),ePt.Y(),spline->NbPoles()); + TColgp_Array1OfPnt controlPoints(0,1); + controlPoints.SetValue(0,s); + controlPoints.SetValue(1,ePt); + spline = GeomAPI_PointsToBSpline(controlPoints,1).Curve(); } } GeomConvert_BSplineCurveToBezierCurve crt(spline); gp_Pnt controlPoint; - if (fail) { + for (Standard_Integer i = 1; i <= crt.NbArcs(); ++i) { BezierSegment tempSegment; - tempSegment.poles = 3; - tempSegment.degree = 2; - tempSegment.pnts.push_back(Base::Vector2d(s.X(),s.Y())); - tempSegment.pnts.push_back(Base::Vector2d(m.X(),m.Y())); - tempSegment.pnts.push_back(Base::Vector2d(ePt.X(),ePt.Y())); - segments.push_back(tempSegment); - } else { - for (Standard_Integer i = 1; i <= crt.NbArcs(); ++i) { - BezierSegment tempSegment; - Handle(Geom_BezierCurve) bezier = crt.Arc(i); - if (bezier->Degree() > 3) { - Base::Console().Log("Geometry::BSpline - converted curve degree > 3\n"); - } - tempSegment.poles = bezier->NbPoles(); - tempSegment.degree = bezier->Degree(); - for (int pole = 1; pole <= tempSegment.poles; ++pole) { - controlPoint = bezier->Pole(pole); - tempSegment.pnts.push_back(Base::Vector2d(controlPoint.X(), controlPoint.Y())); - } - segments.push_back(tempSegment); + Handle(Geom_BezierCurve) bezier = crt.Arc(i); + if (bezier->Degree() > 3) { + Base::Console().Log("Geometry::BSpline - converted curve degree > 3\n"); } + tempSegment.poles = bezier->NbPoles(); + tempSegment.degree = bezier->Degree(); + for (int pole = 1; pole <= tempSegment.poles; ++pole) { + controlPoint = bezier->Pole(pole); + tempSegment.pnts.push_back(Base::Vector2d(controlPoint.X(), controlPoint.Y())); + } + segments.push_back(tempSegment); } }