/*************************************************************************** * Copyright (c) 2014 Nathan Miller * * 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 "FeatureBezSurf.h" #include "FillType.h" #include #include #include #include #include #include #include #include #include #include using namespace Surface; PROPERTY_SOURCE(Surface::BezSurf, Part::Feature) //Initial values BezSurf::BezSurf() { ADD_PROPERTY(aBezList,(0,"Geom_BezierCurve")); ADD_PROPERTY(filltype,(1)); } //Structures struct crvs{ Handle_Geom_BezierCurve C1; Handle_Geom_BezierCurve C2; Handle_Geom_BezierCurve C3; Handle_Geom_BezierCurve C4; }; //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) { //Set Variables int ftype = filltype.getValue(); //Begin Construction try{ //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;} else {return new App::DocumentObjectExecReturn("Filling style must be 1 (Stretch), 2 (Coons), or 3 (Curved).");} //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 getCurves(aSurfBuilder,aWire,aBezList,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.; Standard_Real v0 = 0.; Standard_Real v1 = 1.; aFaceBuilder.Init(aSurface,u0,u1,v0,v1,Precision::Confusion()); TopoDS_Face aFace = aFaceBuilder.Face(); //Returned Face if(!aFaceBuilder.IsDone()){return new App::DocumentObjectExecReturn("Face unable to be constructed");} if (aFace.IsNull()){ return new App::DocumentObjectExecReturn("Resulting Face is null"); } this->Shape.setValue(aFace); return App::DocumentObject::StdReturn; } //End Try catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); return new App::DocumentObjectExecReturn(e->GetMessageString()); } //End Catch } //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); 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; }