From ff34c3eece4d6713947b89aa05a7de963d05daee Mon Sep 17 00:00:00 2001 From: wmayer Date: Sun, 16 Apr 2017 10:40:20 +0200 Subject: [PATCH] move handling of Bezier and BSpline surface creation into a common class to increase flexibility --- src/Mod/Surface/App/FeatureBSplineSurface.cpp | 76 ------ src/Mod/Surface/App/FeatureBSplineSurface.h | 3 - src/Mod/Surface/App/FeatureBezierSurface.cpp | 57 ----- src/Mod/Surface/App/FeatureBezierSurface.h | 3 - src/Mod/Surface/App/FeatureSurface.cpp | 224 +++++++++++++----- src/Mod/Surface/App/FeatureSurface.h | 10 +- src/Mod/Surface/Gui/Command.cpp | 2 +- 7 files changed, 171 insertions(+), 204 deletions(-) diff --git a/src/Mod/Surface/App/FeatureBSplineSurface.cpp b/src/Mod/Surface/App/FeatureBSplineSurface.cpp index aeeea87454..2b5409a223 100644 --- a/src/Mod/Surface/App/FeatureBSplineSurface.cpp +++ b/src/Mod/Surface/App/FeatureBSplineSurface.cpp @@ -54,79 +54,3 @@ PROPERTY_SOURCE(Surface::BSplineSurface, Surface::SurfaceFeature) BSplineSurface::BSplineSurface() : SurfaceFeature() { } - -App::DocumentObjectExecReturn *BSplineSurface::execute(void) -{ - try{ - std::vector crvs; - crvs.reserve(4); - TopoDS_Wire aWire; - - //Gets the healed wire - getWire(aWire); - - Standard_Real u1, u2; // contains output - TopExp_Explorer anExp (aWire, TopAbs_EDGE); - for (; anExp.More(); anExp.Next()) { - const TopoDS_Edge& edge = TopoDS::Edge (anExp.Current()); - TopLoc_Location heloc; // this will be output - Handle_Geom_Curve c_geom = BRep_Tool::Curve(edge, heloc, u1, u2); //The geometric curve - Handle_Geom_BSplineCurve b_geom = Handle_Geom_BSplineCurve::DownCast(c_geom); //Try to get BSpline curve - - if (!b_geom.IsNull()) { - gp_Trsf transf = heloc.Transformation(); - b_geom->Transform(transf); // apply original transformation to control points - //Store Underlying Geometry - crvs.push_back(b_geom); - } - else { - // try to convert it into a b-spline - BRepBuilderAPI_NurbsConvert mkNurbs(edge); - TopoDS_Edge nurbs = TopoDS::Edge(mkNurbs.Shape()); - // avoid copying - TopLoc_Location heloc2; // this will be output - Handle_Geom_Curve c_geom2 = BRep_Tool::Curve(nurbs, heloc2, u1, u2); //The geometric curve - Handle_Geom_BSplineCurve b_geom2 = Handle_Geom_BSplineCurve::DownCast(c_geom2); //Try to get BSpline curve - - if (!b_geom2.IsNull()) { - gp_Trsf transf = heloc2.Transformation(); - b_geom2->Transform(transf); // apply original transformation to control points - //Store Underlying Geometry - crvs.push_back(b_geom2); - } - else { - Standard_Failure::Raise("A curve was not a b-spline and could not be converted into one."); - } - } - } - - GeomFill_FillingStyle fstyle = getFillingStyle(); - GeomFill_BSplineCurves aSurfBuilder; //Create Surface Builder - - std::size_t edgeCount = crvs.size(); - if (edgeCount==2) { - aSurfBuilder.Init(crvs[0], crvs[1], fstyle); - } - else if (edgeCount==3) { - aSurfBuilder.Init(crvs[0], crvs[1], crvs[2], fstyle); - } - else if (edgeCount==4) { - aSurfBuilder.Init(crvs[0], crvs[1], crvs[2], crvs[3], fstyle); - } - - createFace(aSurfBuilder.Surface()); - - return App::DocumentObject::StdReturn; - } - catch (Standard_ConstructionError) { - // message is in a Latin language, show a normal one - return new App::DocumentObjectExecReturn("Curves are disjoint."); - } - catch (StdFail_NotDone) { - return new App::DocumentObjectExecReturn("A curve was not a b-spline and could not be converted into one."); - } - catch (Standard_Failure) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - return new App::DocumentObjectExecReturn(e->GetMessageString()); - } -} diff --git a/src/Mod/Surface/App/FeatureBSplineSurface.h b/src/Mod/Surface/App/FeatureBSplineSurface.h index 06e23f2eb8..b0a190a386 100644 --- a/src/Mod/Surface/App/FeatureBSplineSurface.h +++ b/src/Mod/Surface/App/FeatureBSplineSurface.h @@ -35,9 +35,6 @@ class SurfaceExport BSplineSurface : public SurfaceFeature public: BSplineSurface(); - - // recalculate the feature - virtual App::DocumentObjectExecReturn *execute(void); }; }//Namespace Surface diff --git a/src/Mod/Surface/App/FeatureBezierSurface.cpp b/src/Mod/Surface/App/FeatureBezierSurface.cpp index 482726fd2b..74ee4856f1 100644 --- a/src/Mod/Surface/App/FeatureBezierSurface.cpp +++ b/src/Mod/Surface/App/FeatureBezierSurface.cpp @@ -51,60 +51,3 @@ PROPERTY_SOURCE(Surface::BezierSurface, Surface::SurfaceFeature) BezierSurface::BezierSurface() : SurfaceFeature() { } - -App::DocumentObjectExecReturn *BezierSurface::execute(void) -{ - try { - std::vector crvs; - crvs.reserve(4); - TopoDS_Wire aWire; - - //Gets the healed wire - getWire(aWire); - - Standard_Real u1, u2; // contains output - TopExp_Explorer anExp (aWire, TopAbs_EDGE); - for (; anExp.More(); anExp.Next()) { - const TopoDS_Edge hedge = TopoDS::Edge (anExp.Current()); - TopLoc_Location heloc; // this will be output - Handle_Geom_Curve c_geom = BRep_Tool::Curve(hedge, heloc, u1, u2); //The geometric curve - Handle_Geom_BezierCurve b_geom = Handle_Geom_BezierCurve::DownCast(c_geom); //Try to get Bezier curve - - if (!b_geom.IsNull()) { - gp_Trsf transf = heloc.Transformation(); - b_geom->Transform(transf); // apply original transformation to control points - //Store Underlying Geometry - crvs.push_back(b_geom); - } - else { - Standard_Failure::Raise("Curve not a Bezier Curve"); - } - } - - GeomFill_FillingStyle fstyle = getFillingStyle(); - GeomFill_BezierCurves aSurfBuilder; //Create Surface Builder - - std::size_t edgeCount = crvs.size(); - if (edgeCount == 2) { - aSurfBuilder.Init(crvs[0], crvs[1], fstyle); - } - else if (edgeCount == 3) { - aSurfBuilder.Init(crvs[0], crvs[1], crvs[2], fstyle); - } - else if (edgeCount == 4) { - aSurfBuilder.Init(crvs[0], crvs[1], crvs[2], crvs[3], fstyle); - } - - createFace(aSurfBuilder.Surface()); - - return App::DocumentObject::StdReturn; - } - catch (Standard_ConstructionError) { - // message is in a Latin language, show a normal one - return new App::DocumentObjectExecReturn("Curves are disjoint."); - } - catch (Standard_Failure) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - return new App::DocumentObjectExecReturn(e->GetMessageString()); - } -} diff --git a/src/Mod/Surface/App/FeatureBezierSurface.h b/src/Mod/Surface/App/FeatureBezierSurface.h index f8a25877da..2250a47592 100644 --- a/src/Mod/Surface/App/FeatureBezierSurface.h +++ b/src/Mod/Surface/App/FeatureBezierSurface.h @@ -35,9 +35,6 @@ class SurfaceExport BezierSurface : public SurfaceFeature public: BezierSurface(); - - // recalculate the feature - virtual App::DocumentObjectExecReturn *execute(void); }; }//Namespace Surface diff --git a/src/Mod/Surface/App/FeatureSurface.cpp b/src/Mod/Surface/App/FeatureSurface.cpp index 9775897f67..f493d5bb44 100644 --- a/src/Mod/Surface/App/FeatureSurface.cpp +++ b/src/Mod/Surface/App/FeatureSurface.cpp @@ -24,18 +24,29 @@ #include "PreCompiled.h" #ifndef _PreComp_ -#include -#include +#include +#include #include +#include #include +#include +#include #include #include #include +#include #include +#include +#include #include -#include +#include +#include +#include +#include +#include +#include +#include #include -#include #endif #include @@ -52,7 +63,7 @@ ShapeValidator::ShapeValidator() void ShapeValidator::initValidator(void) { - willBezier = willBSpline = false; + willBezier = true; edgeCount = 0; } @@ -60,7 +71,7 @@ void ShapeValidator::initValidator(void) void ShapeValidator::checkEdge(const TopoDS_Shape& shape) { if (shape.IsNull() || shape.ShapeType() != TopAbs_EDGE) { - Standard_Failure::Raise("Shape is not an edge."); + Standard_Failure::Raise("Shape is not an edge.\n"); } TopoDS_Edge etmp = TopoDS::Edge(shape); //Curve TopoDS_Edge @@ -69,28 +80,10 @@ void ShapeValidator::checkEdge(const TopoDS_Shape& shape) Standard_Real u1;// contains output Handle_Geom_Curve c_geom = BRep_Tool::Curve(etmp,heloc,u0,u1); //The geometric curve Handle_Geom_BezierCurve bez_geom = Handle_Geom_BezierCurve::DownCast(c_geom); //Try to get Bezier curve - Handle_Geom_BSplineCurve bsp_geom = Handle_Geom_BSplineCurve::DownCast(c_geom); //Try to get BSpline curve - if (!bez_geom.IsNull()) { - // this one is a Bezier - if (willBSpline) { - // already found the other type, fail - Standard_Failure::Raise("Mixing Bezier and B-Spline curves is not allowed."); - } - // we will create Bezier surface - willBezier = true; - } - else if (!bsp_geom.IsNull()) { - // this one is Bezier - if (willBezier) { - // already found the other type, fail - Standard_Failure::Raise("Mixing Bezier and B-Spline curves is not allowed."); - } - // we will create B-Spline surface - willBSpline = true; - } - else { - //Standard_Failure::Raise("Neither Bezier nor B-Spline curve."); + // if not a Bezier then try to create a B-spline surface from the edges + if (bez_geom.IsNull()) { + willBezier = false; } edgeCount++; @@ -109,24 +102,6 @@ void ShapeValidator::checkAndAdd(const TopoDS_Shape &shape, Handle(ShapeExtend_W void ShapeValidator::checkAndAdd(const Part::TopoShape &ts, const char *subName, Handle(ShapeExtend_WireData) *aWD) { try { -#if 0 // weird logic! - // unwrap the wire - if ((!ts._Shape.IsNull()) && ts._Shape.ShapeType() == TopAbs_WIRE) { - TopoDS_Wire wire = TopoDS::Wire(ts._Shape); - for (TopExp_Explorer wireExplorer (wire, TopAbs_EDGE); wireExplorer.More(); wireExplorer.Next()) { - checkAndAdd(wireExplorer.Current(), aWD); - } - } - else { - if (subName != NULL && *subName != 0) { - //we want only the subshape which is linked - checkAndAdd(ts.getSubShape(subName), aWD); - } - else { - checkAndAdd(ts._Shape, aWD); - } - } -#else if (subName != NULL && *subName != '\0') { //we want only the subshape which is linked checkAndAdd(ts.getSubShape(subName), aWD); @@ -140,10 +115,9 @@ void ShapeValidator::checkAndAdd(const Part::TopoShape &ts, const char *subName, else { checkAndAdd(ts.getShape(), aWD); } -#endif } - catch(Standard_Failure) { // any OCC exception means an unappropriate shape in the selection - Standard_Failure::Raise("Wrong shape type."); + catch (Standard_Failure) { // any OCC exception means an unappropriate shape in the selection + Standard_Failure::Raise("Wrong shape type.\n"); } } @@ -164,11 +138,38 @@ SurfaceFeature::SurfaceFeature(): Spline() short SurfaceFeature::mustExecute() const { if (BoundaryList.isTouched() || - FillType.isTouched()) - { + FillType.isTouched()) { return 1; } - return 0; + return Spline::mustExecute(); +} + +App::DocumentObjectExecReturn *SurfaceFeature::execute(void) +{ + try { + TopoDS_Wire aWire; + + //Gets the healed wire + if (getWire(aWire)) { + createBezierSurface(aWire); + } + else { + createBSplineSurface(aWire); + } + + return App::DocumentObject::StdReturn; + } + catch (Standard_ConstructionError) { + // message is in a Latin language, show a normal one + return new App::DocumentObjectExecReturn("Curves are disjoint."); + } + catch (StdFail_NotDone) { + return new App::DocumentObjectExecReturn("A curve was not a b-spline and could not be converted into one."); + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + return new App::DocumentObjectExecReturn(e->GetMessageString()); + } } GeomFill_FillingStyle SurfaceFeature::getFillingStyle() @@ -185,15 +186,14 @@ GeomFill_FillingStyle SurfaceFeature::getFillingStyle() } } -void SurfaceFeature::getWire(TopoDS_Wire& aWire) +bool SurfaceFeature::getWire(TopoDS_Wire& aWire) { Handle(ShapeFix_Wire) aShFW = new ShapeFix_Wire; Handle(ShapeExtend_WireData) aWD = new ShapeExtend_WireData; std::vector boundary = BoundaryList.getSubListValues(); - if(boundary.size() > 4) // if too many not even try - { - Standard_Failure::Raise("Only 2-4 curves are allowed"); + if (boundary.size() > 4) {// if too many not even try + Standard_Failure::Raise("Only 2-4 curves are allowed\n"); } ShapeValidator validator; @@ -207,7 +207,7 @@ void SurfaceFeature::getWire(TopoDS_Wire& aWire) } } else { - Standard_Failure::Raise("Curve not from Part::Feature"); + Standard_Failure::Raise("Curve not from Part::Feature\n"); } } @@ -227,8 +227,10 @@ void SurfaceFeature::getWire(TopoDS_Wire& aWire) aWire = aShFW->Wire(); //Healed Wire if (aWire.IsNull()) { - Standard_Failure::Raise("Wire unable to be constructed"); + Standard_Failure::Raise("Wire unable to be constructed\n"); } + + return validator.isBezier(); } void SurfaceFeature::createFace(const Handle_Geom_BoundedSurface &aSurface) @@ -242,10 +244,114 @@ void SurfaceFeature::createFace(const Handle_Geom_BoundedSurface &aSurface) TopoDS_Face aFace = aFaceBuilder.Face(); if (!aFaceBuilder.IsDone()) { - Standard_Failure::Raise("Face unable to be constructed"); + Standard_Failure::Raise("Face unable to be constructed\n"); } if (aFace.IsNull()) { - Standard_Failure::Raise("Resulting Face is null"); + Standard_Failure::Raise("Resulting Face is null\n"); } this->Shape.setValue(aFace); } + +void SurfaceFeature::createBezierSurface(TopoDS_Wire& aWire) +{ + std::vector crvs; + crvs.reserve(4); + + Standard_Real u1, u2; // contains output + TopExp_Explorer anExp (aWire, TopAbs_EDGE); + for (; anExp.More(); anExp.Next()) { + const TopoDS_Edge hedge = TopoDS::Edge (anExp.Current()); + TopLoc_Location heloc; // this will be output + Handle_Geom_Curve c_geom = BRep_Tool::Curve(hedge, heloc, u1, u2); //The geometric curve + Handle_Geom_BezierCurve b_geom = Handle_Geom_BezierCurve::DownCast(c_geom); //Try to get Bezier curve + + if (!b_geom.IsNull()) { + gp_Trsf transf = heloc.Transformation(); + b_geom->Transform(transf); // apply original transformation to control points + //Store Underlying Geometry + crvs.push_back(b_geom); + } + else { + Standard_Failure::Raise("Curve not a Bezier Curve"); + } + } + + GeomFill_FillingStyle fstyle = getFillingStyle(); + GeomFill_BezierCurves aSurfBuilder; //Create Surface Builder + + std::size_t edgeCount = crvs.size(); + if (edgeCount == 2) { + aSurfBuilder.Init(crvs[0], crvs[1], fstyle); + } + else if (edgeCount == 3) { + aSurfBuilder.Init(crvs[0], crvs[1], crvs[2], fstyle); + } + else if (edgeCount == 4) { + aSurfBuilder.Init(crvs[0], crvs[1], crvs[2], crvs[3], fstyle); + } + + createFace(aSurfBuilder.Surface()); +} + +void SurfaceFeature::createBSplineSurface(TopoDS_Wire& aWire) +{ + std::vector crvs; + crvs.reserve(4); + Standard_Real u1, u2; // contains output + TopExp_Explorer anExp (aWire, TopAbs_EDGE); + for (; anExp.More(); anExp.Next()) { + const TopoDS_Edge& edge = TopoDS::Edge (anExp.Current()); + TopLoc_Location heloc; // this will be output + Handle_Geom_Curve c_geom = BRep_Tool::Curve(edge, heloc, u1, u2); //The geometric curve + Handle_Geom_BSplineCurve b_geom = Handle_Geom_BSplineCurve::DownCast(c_geom); //Try to get BSpline curve + + if (!b_geom.IsNull()) { + gp_Trsf transf = heloc.Transformation(); + b_geom->Transform(transf); // apply original transformation to control points + //Store Underlying Geometry + crvs.push_back(b_geom); + } + else { + // try to convert it into a b-spline + BRepBuilderAPI_NurbsConvert mkNurbs(edge); + TopoDS_Edge nurbs = TopoDS::Edge(mkNurbs.Shape()); + // avoid copying + TopLoc_Location heloc2; // this will be output + Handle_Geom_Curve c_geom2 = BRep_Tool::Curve(nurbs, heloc2, u1, u2); //The geometric curve + Handle_Geom_BSplineCurve b_geom2 = Handle_Geom_BSplineCurve::DownCast(c_geom2); //Try to get BSpline curve + + if (!b_geom2.IsNull()) { + gp_Trsf transf = heloc2.Transformation(); + b_geom2->Transform(transf); // apply original transformation to control points + //Store Underlying Geometry + crvs.push_back(b_geom2); + } + else { + // BRepBuilderAPI_NurbsConvert failed, try ShapeConstruct_Curve now + ShapeConstruct_Curve scc; + Handle_Geom_BSplineCurve spline = scc.ConvertToBSpline(c_geom, u1, u2, Precision::Confusion()); + if (spline.IsNull()) + Standard_Failure::Raise("A curve was not a b-spline and could not be converted into one."); + gp_Trsf transf = heloc2.Transformation(); + spline->Transform(transf); // apply original transformation to control points + crvs.push_back(spline); + } + } + } + + GeomFill_FillingStyle fstyle = getFillingStyle(); + GeomFill_BSplineCurves aSurfBuilder; //Create Surface Builder + + std::size_t edgeCount = crvs.size(); + if (edgeCount == 2) { + aSurfBuilder.Init(crvs[0], crvs[1], fstyle); + } + else if (edgeCount == 3) { + aSurfBuilder.Init(crvs[0], crvs[1], crvs[2], fstyle); + } + else if (edgeCount == 4) { + aSurfBuilder.Init(crvs[0], crvs[1], crvs[2], crvs[3], fstyle); + } + + createFace(aSurfBuilder.Surface()); +} diff --git a/src/Mod/Surface/App/FeatureSurface.h b/src/Mod/Surface/App/FeatureSurface.h index e7f8eba1d1..ed0985f2c5 100644 --- a/src/Mod/Surface/App/FeatureSurface.h +++ b/src/Mod/Surface/App/FeatureSurface.h @@ -40,7 +40,6 @@ class SurfaceExport ShapeValidator { protected: bool willBezier; - bool willBSpline; int edgeCount; public: @@ -53,9 +52,6 @@ public: bool isBezier() const { return willBezier; } - bool isBSpline() const { - return willBSpline; - } int numEdges() const { return edgeCount; } @@ -71,6 +67,7 @@ public: App::PropertyEnumeration FillType; //Fill method (1, 2, or 3 for Stretch, Coons, and Curved) short mustExecute() const; + App::DocumentObjectExecReturn *execute(void); /// returns the type name of the view provider const char* getViewProviderName(void) const { @@ -79,8 +76,11 @@ public: protected: GeomFill_FillingStyle getFillingStyle(); - void getWire(TopoDS_Wire& aWire); + /// True means that all edges have Bezier curves + bool getWire(TopoDS_Wire& aWire); void createFace(const Handle_Geom_BoundedSurface &aSurface); + void createBezierSurface(TopoDS_Wire& aWire); + void createBSplineSurface(TopoDS_Wire& aWire); private: static const char* FillTypeEnums[]; diff --git a/src/Mod/Surface/Gui/Command.cpp b/src/Mod/Surface/Gui/Command.cpp index 8e4adea597..3fb70566ee 100644 --- a/src/Mod/Surface/Gui/Command.cpp +++ b/src/Mod/Surface/Gui/Command.cpp @@ -173,7 +173,7 @@ void CmdSurfaceBSurf::activated(int iMsg) std::string FeatName = getUniqueObjectName("Surface"); openCommand("Create surface"); - doCommand(Doc, "App.ActiveDocument.addObject(\"Surface::BSplineSurface\",\"%s\")", FeatName.c_str()); + doCommand(Doc, "App.ActiveDocument.addObject(\"Surface::SurfaceFeature\",\"%s\")", FeatName.c_str()); doCommand(Doc, "Gui.ActiveDocument.setEdit('%s',0)", FeatName.c_str()); }