esign/App/FeatureRevolution.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2010 Juergen Riegel <FreeCAD@juergen-riegel.net>        *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 
00024 #include "PreCompiled.h"
00025 #ifndef _PreComp_
00026 # include <BRep_Builder.hxx>
00027 # include <BRepBndLib.hxx>
00028 # include <BRepPrimAPI_MakeRevol.hxx>
00029 # include <BRepBuilderAPI_Copy.hxx>
00030 # include <BRepBuilderAPI_MakeFace.hxx>
00031 # include <TopoDS.hxx>
00032 # include <TopoDS_Face.hxx>
00033 # include <TopoDS_Wire.hxx>
00034 # include <TopExp_Explorer.hxx>
00035 # include <BRepAlgoAPI_Fuse.hxx>
00036 #endif
00037 
00038 #include <Base/Placement.h>
00039 #include <Base/Tools.h>
00040 #include <Mod/Part/App/Part2DObject.h>
00041 
00042 #include "FeatureRevolution.h"
00043 
00044 
00045 using namespace PartDesign;
00046 
00047 namespace PartDesign {
00048 
00049 
00050 PROPERTY_SOURCE(PartDesign::Revolution, PartDesign::SketchBased)
00051 
00052 Revolution::Revolution()
00053 {
00054     ADD_PROPERTY(Base,(Base::Vector3f(0.0f,0.0f,0.0f)));
00055     ADD_PROPERTY(Axis,(Base::Vector3f(0.0f,1.0f,0.0f)));
00056     ADD_PROPERTY(Angle,(360.0));
00057 }
00058 
00059 short Revolution::mustExecute() const
00060 {
00061     if (Sketch.isTouched() ||
00062         Axis.isTouched() ||
00063         Base.isTouched() ||
00064         Angle.isTouched())
00065         return 1;
00066     return 0;
00067 }
00068 
00069 App::DocumentObjectExecReturn *Revolution::execute(void)
00070 {
00071     App::DocumentObject* link = Sketch.getValue();
00072     if (!link)
00073         return new App::DocumentObjectExecReturn("No sketch linked");
00074     if (!link->getTypeId().isDerivedFrom(Part::Part2DObject::getClassTypeId()))
00075         return new App::DocumentObjectExecReturn("Linked object is not a Sketch or Part2DObject");
00076     TopoDS_Shape shape = static_cast<Part::Part2DObject*>(link)->Shape.getShape()._Shape;
00077     if (shape.IsNull())
00078         return new App::DocumentObjectExecReturn("Linked shape object is empty");
00079 
00080     // this is a workaround for an obscure OCC bug which leads to empty tessellations
00081     // for some faces. Making an explicit copy of the linked shape seems to fix it.
00082     // The error only happens when re-computing the shape.
00083     if (!this->Shape.getValue().IsNull()) {
00084         BRepBuilderAPI_Copy copy(shape);
00085         shape = copy.Shape();
00086         if (shape.IsNull())
00087             return new App::DocumentObjectExecReturn("Linked shape object is empty");
00088     }
00089 
00090     TopExp_Explorer ex;
00091     std::vector<TopoDS_Wire> wires;
00092     for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) {
00093         wires.push_back(TopoDS::Wire(ex.Current()));
00094     }
00095     if (wires.empty()) // there can be several wires
00096         return new App::DocumentObjectExecReturn("Linked shape object is not a wire");
00097 #if 0
00098     App::DocumentObject* support = sketch->Support.getValue();
00099     Base::Placement placement = sketch->Placement.getValue();
00100     Base::Vector3d axis(0,1,0);
00101     placement.getRotation().multVec(axis, axis);
00102     Base::BoundBox3d bbox = sketch->Shape.getBoundingBox();
00103     bbox.Enlarge(0.1);
00104     Base::Vector3d base(bbox.MaxX, bbox.MaxY, bbox.MaxZ);
00105 #endif
00106     // get the Sketch plane
00107     Base::Placement SketchPos = static_cast<Part::Part2DObject*>(link)->Placement.getValue();
00108     Base::Rotation SketchOrientation = SketchPos.getRotation();
00109     // get rvolve axis
00110     Base::Vector3f v = Axis.getValue();
00111     Base::Vector3d SketchOrientationVector(v.x,v.y,v.z);
00112     SketchOrientation.multVec(SketchOrientationVector,SketchOrientationVector);
00113 
00114 
00115     Base::Vector3f b = Base.getValue();
00116     gp_Pnt pnt(b.x,b.y,b.z);
00117     gp_Dir dir(SketchOrientationVector.x,SketchOrientationVector.y,SketchOrientationVector.z);
00118 
00119     // get the support of the Sketch if any
00120     App::DocumentObject* SupportLink = static_cast<Part::Part2DObject*>(link)->Support.getValue();
00121     Part::Feature *SupportObject = 0;
00122     if (SupportLink && SupportLink->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
00123         SupportObject = static_cast<Part::Feature*>(SupportLink);
00124 
00125     TopoDS_Shape aFace = makeFace(wires);
00126     if (aFace.IsNull())
00127         return new App::DocumentObjectExecReturn("Creating a face from sketch failed");
00128 
00129     // revolve the face to a solid
00130     BRepPrimAPI_MakeRevol RevolMaker(aFace,gp_Ax1(pnt, dir), Base::toRadians<double>(Angle.getValue()));
00131 
00132     if (RevolMaker.IsDone()) {
00133         TopoDS_Shape result = RevolMaker.Shape();
00134         // if the sketch has a support fuse them to get one result object (PAD!)
00135         if (SupportObject) {
00136             const TopoDS_Shape& support = SupportObject->Shape.getValue();
00137             if (!support.IsNull() && support.ShapeType() == TopAbs_SOLID) {
00138                 // Let's call algorithm computing a fuse operation:
00139                 BRepAlgoAPI_Fuse mkFuse(support, result);
00140                 // Let's check if the fusion has been successful
00141                 if (!mkFuse.IsDone()) 
00142                     throw Base::Exception("Fusion with support failed");
00143                 result = mkFuse.Shape();
00144             }
00145         }
00146 
00147         this->Shape.setValue(result);
00148     }
00149     else
00150         return new App::DocumentObjectExecReturn("Could not revolve the sketch!");
00151 
00152     return App::DocumentObject::StdReturn;
00153 }
00154 
00155 }

Generated on Wed Nov 23 19:00:13 2011 for FreeCAD by  doxygen 1.6.1