From 1fb63c097e477e25425a2a5c3e954e537e7381bd Mon Sep 17 00:00:00 2001 From: balazs-bamer Date: Thu, 1 Jan 2015 19:18:59 +0100 Subject: [PATCH] Refactor and cleanup: FeatureBezSurf Refactored and cleaned up code for FeatureBezSurf and created a new common ancestor class for this and FeatureBSplineSurf. --- src/Mod/Surface/App/CMakeLists.txt | 2 + src/Mod/Surface/App/FeatureBSplineSurf.cpp | 10 +- src/Mod/Surface/App/FeatureBSurf.cpp | 103 ++++++++++++ src/Mod/Surface/App/FeatureBSurf.h | 53 ++++++ src/Mod/Surface/App/FeatureBezSurf.cpp | 181 ++++++--------------- src/Mod/Surface/App/FeatureBezSurf.h | 16 +- src/Mod/Surface/Gui/Command.cpp | 2 +- 7 files changed, 215 insertions(+), 152 deletions(-) create mode 100644 src/Mod/Surface/App/FeatureBSurf.cpp create mode 100644 src/Mod/Surface/App/FeatureBSurf.h diff --git a/src/Mod/Surface/App/CMakeLists.txt b/src/Mod/Surface/App/CMakeLists.txt index ff5d1290ef..8e6f0d43f0 100644 --- a/src/Mod/Surface/App/CMakeLists.txt +++ b/src/Mod/Surface/App/CMakeLists.txt @@ -23,6 +23,8 @@ SET(Surface_SRCS AppSurfacePy.cpp PreCompiled.cpp PreCompiled.h + FeatureBSurf.h + FeatureBSurf.cpp FeatureFilling.h FeatureFilling.cpp FeatureSewing.h diff --git a/src/Mod/Surface/App/FeatureBSplineSurf.cpp b/src/Mod/Surface/App/FeatureBSplineSurf.cpp index 2b409705a8..6d24a860b0 100644 --- a/src/Mod/Surface/App/FeatureBSplineSurf.cpp +++ b/src/Mod/Surface/App/FeatureBSplineSurf.cpp @@ -30,20 +30,20 @@ #include #include #include -#endif - -#include "FeatureBSplineSurf.h" -#include "FillType.h" #include #include #include #include #include -#include #include #include #include #include +#endif + +#include "FeatureBSplineSurf.h" +#include "FillType.h" + using namespace Surface; diff --git a/src/Mod/Surface/App/FeatureBSurf.cpp b/src/Mod/Surface/App/FeatureBSurf.cpp new file mode 100644 index 0000000000..9f0fcacd3f --- /dev/null +++ b/src/Mod/Surface/App/FeatureBSurf.cpp @@ -0,0 +1,103 @@ + +/*************************************************************************** + * Copyright (c) 2014 Balázs Bámer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#include "PreCompiled.h" + +#ifndef _PreComp_ +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +#include "FeatureBSurf.h" + +using namespace Surface; + +//Check if any components of the surface have been modified +short BSurf::mustExecute() const +{ + if (aBList.isTouched() || + filltype.isTouched()) + return 1; + return 0; +} + +void BSurf::getWire(TopoDS_Wire& aWire) +{ + Handle(ShapeFix_Wire) aShFW = new ShapeFix_Wire; + Handle(ShapeExtend_WireData) aWD = new ShapeExtend_WireData; + + if(aBList.getSize()>4){Standard_Failure::Raise("Only 2-4 continuous Bezier Curves are allowed");return;} + if(aBList.getSize()<2){Standard_Failure::Raise("Only 2-4 continuous Bezier Curves are allowed");return;} + + for(int i=0; igetTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { + + ts = static_cast(set.obj)->Shape.getShape(); + + //we want only the subshape which is linked + sub = ts.getSubShape(set.sub); + // make a copy of the shape and the underlying geometry to avoid to affect the input shapes + BRepBuilderAPI_Copy copy(sub); + sub = copy.Shape(); + + if(sub.ShapeType() == TopAbs_EDGE) { //Check Shape type and assign edge + etmp = TopoDS::Edge(sub); + } + else { + Standard_Failure::Raise("Curves must be type TopoDS_Edge"); + return; //Raise exception + } + aWD->Add(etmp); + + } + else{Standard_Failure::Raise("Curve not from Part::Feature");return;} + + } + + //Reorder the curves and fix the wire if required + + aShFW->Load(aWD); //Load in the wire + aShFW->FixReorder(); //Fix the order of the edges if required + aShFW->ClosedWireMode() = Standard_True; //Enables closed wire mode + aShFW->FixConnected(); //Fix connection between wires + aShFW->FixSelfIntersection(); //Fix Self Intersection + aShFW->Perform(); //Perform the fixes + + aWire = aShFW->Wire(); //Healed Wire + + if(aWire.IsNull()){Standard_Failure::Raise("Wire unable to be constructed");return;} +} diff --git a/src/Mod/Surface/App/FeatureBSurf.h b/src/Mod/Surface/App/FeatureBSurf.h new file mode 100644 index 0000000000..719b55e031 --- /dev/null +++ b/src/Mod/Surface/App/FeatureBSurf.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * Copyright (c) 2014 Balázs Bámer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#ifndef FEATUREBSURF_H +#define FEATUREBSURF_H + +#include +#include +#include +#include "Mod/Part/App/PartFeature.h" + +namespace Surface +{ + +enum filltype_t +{ +StretchStyle = 1, CoonsStyle, CurvedStyle +}; + +class BSurf : public Part::Feature +{ +public: + App::PropertyLinkSubList aBList; //curves to be turned into a face (2-4 curves allowed). + App::PropertyInteger filltype; //Fill method (1, 2, or 3 for Stretch, Coons, and Curved) + + short mustExecute() const; + +protected: + void getWire(TopoDS_Wire& aWire); +}; + +} + +#endif // FEATUREBSURF_H diff --git a/src/Mod/Surface/App/FeatureBezSurf.cpp b/src/Mod/Surface/App/FeatureBezSurf.cpp index 8ea4d9a5fb..83af828cc0 100644 --- a/src/Mod/Surface/App/FeatureBezSurf.cpp +++ b/src/Mod/Surface/App/FeatureBezSurf.cpp @@ -23,7 +23,6 @@ #include "PreCompiled.h" #ifndef _PreComp_ -#include #include #include #include @@ -32,20 +31,18 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include #endif #include "FeatureBezSurf.h" -#include "FillType.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include + using namespace Surface; @@ -55,7 +52,7 @@ PROPERTY_SOURCE(Surface::BezSurf, Part::Feature) BezSurf::BezSurf() { - ADD_PROPERTY(aBezList,(0,"Geom_BezierCurve")); + ADD_PROPERTY(aBList,(0,"Geom_BezierCurve")); ADD_PROPERTY(filltype,(1)); } @@ -73,19 +70,6 @@ struct crvs{ //Functions -void getCurves(GeomFill_BezierCurves& aBuilder,TopoDS_Wire& aWire, const App::PropertyLinkSubList& anEdge, GeomFill_FillingStyle fstyle); -//bool orderCurves(crvs& Cs, int size); - -//Check if any components of the surface have been modified - -short BezSurf::mustExecute() const -{ - if (aBezList.isTouched() || - filltype.isTouched()) - return 1; - return 0; -} - App::DocumentObjectExecReturn *BezSurf::execute(void) { @@ -99,7 +83,6 @@ App::DocumentObjectExecReturn *BezSurf::execute(void) //Identify filling style GeomFill_FillingStyle fstyle; - if(ftype==StretchStyle) {fstyle = GeomFill_StretchStyle;} else if(ftype==CoonsStyle) {fstyle = GeomFill_CoonsStyle;} else if(ftype==CurvedStyle) {fstyle = GeomFill_CurvedStyle;} @@ -108,20 +91,49 @@ App::DocumentObjectExecReturn *BezSurf::execute(void) //Create Bezier Surface GeomFill_BezierCurves aSurfBuilder; //Create Surface Builder -// BRepBuilderAPI_MakeWire aWireBuilder; //Create Wire Builder TopoDS_Wire aWire; //Create empty wire - //Get Bezier Curves from edges and initialize the builder + //Gets the healed wire + getWire(aWire); - getCurves(aSurfBuilder,aWire,aBezList,fstyle); + //Create Bezier Surface builder + crvs bcrv; + Standard_Real u0;// contains output + Standard_Real u1;// contains output + TopExp_Explorer anExp (aWire, TopAbs_EDGE); + int it = 0; + 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,u0,u1); //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 + if(it==0){bcrv.C1 = b_geom;} + else if(it==1){bcrv.C2 = b_geom;} + else if(it==2){bcrv.C3 = b_geom;} + else if(it==3){bcrv.C4 = b_geom;} + } + else { + Standard_Failure::Raise("Curve not a Bezier Curve"); + } + it++; + } + + int ncrv = aBList.getSize(); + if(ncrv==2){aSurfBuilder.Init(bcrv.C1,bcrv.C2,fstyle);} + else if(ncrv==3){aSurfBuilder.Init(bcrv.C1,bcrv.C2,bcrv.C3,fstyle);} + else if(ncrv==4){aSurfBuilder.Init(bcrv.C1,bcrv.C2,bcrv.C3,bcrv.C4,fstyle);} //Create the surface - const Handle_Geom_BezierSurface aSurface = aSurfBuilder.Surface(); BRepBuilderAPI_MakeFace aFaceBuilder;//(aSurface,aWire,Standard_True); //Create Face Builder - Standard_Real u0 = 0.; - Standard_Real u1 = 1.; + u0 = 0.; + u1 = 1.; Standard_Real v0 = 0.; Standard_Real v1 = 1.; aFaceBuilder.Init(aSurface,u0,u1,v0,v1,Precision::Confusion()); @@ -137,6 +149,10 @@ App::DocumentObjectExecReturn *BezSurf::execute(void) return App::DocumentObject::StdReturn; } //End Try + 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()); @@ -144,103 +160,4 @@ App::DocumentObjectExecReturn *BezSurf::execute(void) } //End execute -void getCurves(GeomFill_BezierCurves& aBuilder,TopoDS_Wire& aWire, const App::PropertyLinkSubList& anEdge, GeomFill_FillingStyle fstyle){ -//void getCurves(TopoDS_Wire& aWire, const App::PropertyLinkSubList& anEdge){ - crvs bcrv; - - Standard_Real u0;// contains output - Standard_Real u1;// contains output - - Handle(ShapeFix_Wire) aShFW = new ShapeFix_Wire; - Handle(ShapeExtend_WireData) aWD = new ShapeExtend_WireData; - - if(anEdge.getSize()>4){Standard_Failure::Raise("Only 2-4 continuous Bezier Curves are allowed");return;} - if(anEdge.getSize()<2){Standard_Failure::Raise("Only 2-4 continuous Bezier Curves are allowed");return;} - - for(int i=0; igetTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { - - ts = static_cast(set.obj)->Shape.getShape(); - - //we want only the subshape which is linked - sub = ts.getSubShape(set.sub); - // make a copy of the shape and the underlying geometry to avoid to affect the input shapes - BRepBuilderAPI_Copy copy(sub); - sub = copy.Shape(); - - if(sub.ShapeType() == TopAbs_EDGE) { //Check Shape type and assign edge - etmp = TopoDS::Edge(sub); - } - else { - Standard_Failure::Raise("Curves must be type TopoDS_Edge"); - return; //Raise exception - } - - aWD->Add(etmp); - - } - - else{Standard_Failure::Raise("Curve not from Part::Feature");return;} - - } - - //Reorder the curves and fix the wire if required - - aShFW->Load(aWD); //Load in the wire - aShFW->FixReorder(); //Fix the order of the edges if required - aShFW->ClosedWireMode() = Standard_True; //Enables closed wire mode - aShFW->FixConnected(); //Fix connection between wires - aShFW->FixSelfIntersection(); //Fix Self Intersection - aShFW->Perform(); //Perform the fixes - - aWire = aShFW->Wire(); //Healed Wire - - if(aWire.IsNull()){Standard_Failure::Raise("Wire unable to be constructed");return;} - - //Create Bezier Surface - - TopExp_Explorer anExp (aWire, TopAbs_EDGE); - int it = 0; - for (; anExp.More(); anExp.Next()) { - printf("it: %i",it); - 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,u0,u1); //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 - if(it==0){bcrv.C1 = b_geom;} - else if(it==1){bcrv.C2 = b_geom;} - else if(it==2){bcrv.C3 = b_geom;} - else if(it==3){bcrv.C4 = b_geom;} - - } - else { - Standard_Failure::Raise("Curve not a Bezier Curve"); - return; - } - - it++; - } - - int ncrv = anEdge.getSize(); - - if(ncrv==2){aBuilder.Init(bcrv.C1,bcrv.C2,fstyle);} - else if(ncrv==3){aBuilder.Init(bcrv.C1,bcrv.C2,bcrv.C3,fstyle);} - else if(ncrv==4){aBuilder.Init(bcrv.C1,bcrv.C2,bcrv.C3,bcrv.C4,fstyle);} - - return; -} diff --git a/src/Mod/Surface/App/FeatureBezSurf.h b/src/Mod/Surface/App/FeatureBezSurf.h index a85b7faaf9..9ff8e2ca4e 100644 --- a/src/Mod/Surface/App/FeatureBezSurf.h +++ b/src/Mod/Surface/App/FeatureBezSurf.h @@ -23,32 +23,20 @@ #ifndef SURFACE_FEATUREBEZSURF_H #define SURFACE_FEATUREBEZSURF_H -#include -#include -#include -#include "Mod/Part/App/PartFeature.h" +#include "FeatureBSurf.h" namespace Surface { -class SurfaceExport BezSurf : public Part::Feature +class SurfaceExport BezSurf : public BSurf { PROPERTY_HEADER(Surface::BezSurf); public: BezSurf(); - App::PropertyLinkSubList aBezList; //Bezier curves to be turned into a face (2-4 curves allowed). - App::PropertyInteger filltype; //Fill method (1, 2, or 3 for Stretch, Coons, and Curved) - // recalculate the feature App::DocumentObjectExecReturn *execute(void); - short mustExecute() const; - /// returns the type name of the view provider -// const char* getViewProviderName(void) const { -// return "PartGui::ViewProviderCut"; -// } - }; }//Namespace Surface #endif diff --git a/src/Mod/Surface/Gui/Command.cpp b/src/Mod/Surface/Gui/Command.cpp index 35987ef7e6..3ca9a7b7fd 100644 --- a/src/Mod/Surface/Gui/Command.cpp +++ b/src/Mod/Surface/Gui/Command.cpp @@ -178,7 +178,7 @@ void CmdSurfaceBezier::activated(int iMsg) std::string FeatName = getUniqueObjectName("BezierSurface"); std::stringstream bezListCmd; // std::vector tempSelNames; - bezListCmd << "FreeCAD.ActiveDocument.ActiveObject.aBezList = ["; + bezListCmd << "FreeCAD.ActiveDocument.ActiveObject.aBList = ["; for (std::vector::iterator it = Sel.begin(); it != Sel.end(); ++it) { App::DocumentObject* obj = it->getObject(); // TODO check object types