PrimitiveFeature.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2007 Werner Mayer <wmayer[at]users.sourceforge.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 <cfloat>
00027 # include <BRepLib.hxx>
00028 # include <BRepPrimAPI_MakeCone.hxx>
00029 # include <BRepPrimAPI_MakeCylinder.hxx>
00030 # include <BRepPrimAPI_MakeRevol.hxx>
00031 # include <BRepPrimAPI_MakeSphere.hxx>
00032 # include <BRepPrimAPI_MakeTorus.hxx>
00033 # include <BRepPrim_Wedge.hxx>
00034 # include <BRepBuilderAPI_MakeEdge.hxx>
00035 # include <BRepBuilderAPI_MakeFace.hxx>
00036 # include <BRepBuilderAPI_MakeVertex.hxx>
00037 # include <BRepBuilderAPI_MakeWire.hxx>
00038 # include <BRepBuilderAPI_MakeSolid.hxx>
00039 # include <BRepBuilderAPI_GTransform.hxx>
00040 # include <gp_Circ.hxx>
00041 # include <gp_GTrsf.hxx>
00042 # include <GCE2d_MakeSegment.hxx>
00043 # include <Geom_Plane.hxx>
00044 # include <Geom_ConicalSurface.hxx>
00045 # include <Geom_CylindricalSurface.hxx>
00046 # include <Geom2d_Line.hxx>
00047 # include <Geom2d_TrimmedCurve.hxx>
00048 # include <Handle_Geom_Plane.hxx>
00049 # include <Handle_Geom_CylindricalSurface.hxx>
00050 # include <Handle_Geom2d_Line.hxx>
00051 # include <Handle_Geom2d_TrimmedCurve.hxx>
00052 # include <Precision.hxx>
00053 # include <Standard_Real.hxx>
00054 # include <TopoDS.hxx>
00055 # include <TopoDS_Solid.hxx>
00056 # include <TopoDS_Vertex.hxx>
00057 #endif
00058 
00059 
00060 #include "PrimitiveFeature.h"
00061 #include <Base/Tools.h>
00062 
00063 #ifndef M_PI
00064 #define M_PI       3.14159265358979323846
00065 #endif
00066 
00067 
00068 namespace Part {
00069     const App::PropertyFloatConstraint::Constraints floatRange  = {0.0f,FLT_MAX,0.1f};
00070     const App::PropertyFloatConstraint::Constraints apexRange   = {0.0f,90.0f,0.1f};
00071     const App::PropertyFloatConstraint::Constraints angleRangeU = {0.0f,360.0f,1.0f};
00072     const App::PropertyFloatConstraint::Constraints angleRangeV = {-90.0f,90.0f,1.0f};
00073     const App::PropertyFloatConstraint::Constraints torusRangeV = {-180.0f,180.0f,1.0f};
00074 }
00075 
00076 using namespace Part;
00077 
00078 
00079 PROPERTY_SOURCE_ABSTRACT(Part::Primitive, Part::Feature)
00080 
00081 Primitive::Primitive(void) 
00082 {
00083     touch();
00084 }
00085 
00086 Primitive::~Primitive()
00087 {
00088 }
00089 
00090 short Primitive::mustExecute(void) const
00091 {
00092     return Feature::mustExecute();
00093 }
00094 
00095 void Primitive::onChanged(const App::Property* prop)
00096 {
00097     if (!isRestoring()) {
00098         // Do not support sphere, ellipsoid and torus because the creation
00099         // takes too long and thus is not feasible
00100         std::string grp = (prop->getGroup() ? prop->getGroup() : "");
00101         if (grp == "Plane" || grp == "Cylinder" || grp == "Cone"){
00102             try {
00103                 App::DocumentObjectExecReturn *ret = recompute();
00104                 delete ret;
00105             }
00106             catch (...) {
00107             }
00108         }
00109     }
00110     Part::Feature::onChanged(prop);
00111 }
00112 
00113 PROPERTY_SOURCE(Part::Vertex, Part::Primitive)
00114 
00115 Vertex::Vertex()
00116 {
00117     ADD_PROPERTY(X,(0.0f));
00118     ADD_PROPERTY(Y,(0.0f));
00119     ADD_PROPERTY(Z,(0.0f));
00120 }
00121 
00122 Vertex::~Vertex()
00123 {
00124 }
00125 
00126 short Vertex::mustExecute() const
00127 {
00128     if (X.isTouched() ||
00129         Y.isTouched() ||
00130         Z.isTouched())
00131         return 1;
00132     return Part::Feature::mustExecute();
00133 }
00134 
00135 App::DocumentObjectExecReturn *Vertex::execute(void)
00136 {
00137     gp_Pnt point;
00138     point.SetX(this->X.getValue());
00139     point.SetY(this->Y.getValue());
00140     point.SetZ(this->Z.getValue());
00141     
00142     BRepBuilderAPI_MakeVertex MakeVertex(point);
00143     const TopoDS_Vertex& vertex = MakeVertex.Vertex();
00144     this->Shape.setValue(vertex);
00145 
00146     return App::DocumentObject::StdReturn;
00147 }
00148 
00149 
00150 void Vertex::onChanged(const App::Property* prop)
00151 {
00152     if (!isRestoring()) {
00153         if (prop == &X || prop == &Y || prop == &Z){
00154             try {
00155                 App::DocumentObjectExecReturn *ret = recompute();
00156                 delete ret;
00157             }
00158             catch (...) {
00159             }
00160         }
00161     }
00162     Part::Feature::onChanged(prop);
00163 }
00164 
00165 PROPERTY_SOURCE(Part::Plane, Part::Primitive)
00166 
00167 Plane::Plane()
00168 {
00169     ADD_PROPERTY_TYPE(Length,(100.0f),"Plane",App::Prop_None,"The length of the plane");
00170     ADD_PROPERTY_TYPE(Width ,(100.0f),"Plane",App::Prop_None,"The width of the plane");
00171 }
00172 
00173 short Plane::mustExecute() const
00174 {
00175     if (Length.isTouched() ||
00176         Width.isTouched() )
00177         return 1;
00178     return Primitive::mustExecute();
00179 }
00180 
00181 App::DocumentObjectExecReturn *Plane::execute(void)
00182 {
00183     double L = this->Length.getValue();
00184     double W = this->Width.getValue();
00185 
00186     if (L < Precision::Confusion())
00187         return new App::DocumentObjectExecReturn("Length of plane too small");
00188     if (W < Precision::Confusion())
00189       return new App::DocumentObjectExecReturn("Width of plane too small");
00190 
00191     gp_Pnt pnt(0.0,0.0,0.0);
00192     gp_Dir dir(0.0,0.0,1.0);
00193     Handle_Geom_Plane aPlane = new Geom_Plane(pnt, dir);
00194     BRepBuilderAPI_MakeFace mkFace(aPlane, 0.0, L, 0.0, W);
00195 
00196     const char *error=0;
00197     switch (mkFace.Error())
00198     {
00199     case BRepBuilderAPI_FaceDone:
00200         break; // ok
00201     case BRepBuilderAPI_NoFace:
00202         error = "no face";
00203         break;
00204     case BRepBuilderAPI_NotPlanar:
00205         error = "not planar";
00206         break;
00207     case BRepBuilderAPI_CurveProjectionFailed:
00208         break;
00209     case BRepBuilderAPI_ParametersOutOfRange:
00210         error = "parameters out of range";
00211         break;
00212 #if OCC_HEX_VERSION < 0x060500
00213     case BRepBuilderAPI_SurfaceNotC2:
00214         error = "surface not C2";
00215         break;
00216 #endif
00217     default:
00218         error = "unknown error";
00219         break;
00220     }
00221     // Error ?
00222     if (error) {
00223         return new App::DocumentObjectExecReturn(error);
00224     }
00225 
00226     TopoDS_Shape ResultShape = mkFace.Shape();
00227     this->Shape.setValue(ResultShape);
00228 
00229     return App::DocumentObject::StdReturn;
00230 }
00231 
00232 PROPERTY_SOURCE(Part::Sphere, Part::Primitive)
00233 
00234 Sphere::Sphere(void)
00235 {
00236     ADD_PROPERTY_TYPE(Radius,(5.0),"Sphere",App::Prop_None,"The radius of the sphere");
00237     Radius.setConstraints(&floatRange);
00238     ADD_PROPERTY_TYPE(Angle1,(-90.0f),"Sphere",App::Prop_None,"The angle of the sphere");
00239     Angle1.setConstraints(&angleRangeV);
00240     ADD_PROPERTY_TYPE(Angle2,(90.0f),"Sphere",App::Prop_None,"The angle of the sphere");
00241     Angle2.setConstraints(&angleRangeV);
00242     ADD_PROPERTY_TYPE(Angle3,(360.0f),"Sphere",App::Prop_None,"The angle of the sphere");
00243     Angle3.setConstraints(&angleRangeU);
00244 }
00245 
00246 short Sphere::mustExecute() const
00247 {
00248     if (Radius.isTouched())
00249         return 1;
00250     if (Angle1.isTouched())
00251         return 1;
00252     if (Angle2.isTouched())
00253         return 1;
00254     if (Angle3.isTouched())
00255         return 1;
00256     return Primitive::mustExecute();
00257 }
00258 
00259 App::DocumentObjectExecReturn *Sphere::execute(void)
00260 {
00261     // Build a sphere
00262     if (Radius.getValue() < Precision::Confusion())
00263         return new App::DocumentObjectExecReturn("Radius of sphere too small");
00264     try {
00265         BRepPrimAPI_MakeSphere mkSphere(Radius.getValue(),
00266                                         Angle1.getValue()/180.0f*Standard_PI,
00267                                         Angle2.getValue()/180.0f*Standard_PI,
00268                                         Angle3.getValue()/180.0f*Standard_PI);
00269         TopoDS_Shape ResultShape = mkSphere.Shape();
00270         this->Shape.setValue(ResultShape);
00271     }
00272     catch (Standard_Failure) {
00273         Handle_Standard_Failure e = Standard_Failure::Caught();
00274         return new App::DocumentObjectExecReturn(e->GetMessageString());
00275     }
00276 
00277     return App::DocumentObject::StdReturn;
00278 }
00279 
00280 PROPERTY_SOURCE(Part::Ellipsoid, Part::Primitive)
00281 
00282 Ellipsoid::Ellipsoid(void)
00283 {
00284     ADD_PROPERTY_TYPE(Radius1,(2.0),"Ellipsoid",App::Prop_None,"The radius of the ellipsoid");
00285     Radius1.setConstraints(&floatRange);
00286     ADD_PROPERTY_TYPE(Radius2,(4.0),"Ellipsoid",App::Prop_None,"The radius of the ellipsoid");
00287     Radius2.setConstraints(&floatRange);
00288     ADD_PROPERTY_TYPE(Angle1,(-90.0f),"Ellipsoid",App::Prop_None,"The angle of the ellipsoid");
00289     Angle1.setConstraints(&angleRangeV);
00290     ADD_PROPERTY_TYPE(Angle2,(90.0f),"Ellipsoid",App::Prop_None,"The angle of the ellipsoid");
00291     Angle2.setConstraints(&angleRangeV);
00292     ADD_PROPERTY_TYPE(Angle3,(360.0f),"Ellipsoid",App::Prop_None,"The angle of the ellipsoid");
00293     Angle3.setConstraints(&angleRangeU);
00294 }
00295 
00296 short Ellipsoid::mustExecute() const
00297 {
00298     if (Radius1.isTouched())
00299         return 1;
00300     if (Radius2.isTouched())
00301         return 1;
00302     if (Angle1.isTouched())
00303         return 1;
00304     if (Angle2.isTouched())
00305         return 1;
00306     if (Angle3.isTouched())
00307         return 1;
00308     return Primitive::mustExecute();
00309 }
00310 
00311 App::DocumentObjectExecReturn *Ellipsoid::execute(void)
00312 {
00313     // Build a sphere
00314     if (Radius1.getValue() < Precision::Confusion())
00315         return new App::DocumentObjectExecReturn("Radius of ellipsoid too small");
00316     if (Radius2.getValue() < Precision::Confusion())
00317         return new App::DocumentObjectExecReturn("Radius of ellipsoid too small");
00318     try {
00319         gp_Pnt pnt(0.0,0.0,0.0);
00320         gp_Dir dir(0.0,0.0,1.0);
00321         gp_Ax2 ax2(pnt,dir);
00322         BRepPrimAPI_MakeSphere mkSphere(ax2,
00323                                         Radius2.getValue(), 
00324                                         Angle1.getValue()/180.0f*Standard_PI,
00325                                         Angle2.getValue()/180.0f*Standard_PI,
00326                                         Angle3.getValue()/180.0f*Standard_PI);
00327         Standard_Real scale = Radius1.getValue()/Radius2.getValue();
00328         gp_Dir xDir = ax2.XDirection();
00329         gp_Dir yDir = ax2.YDirection();
00330         gp_GTrsf mat;
00331         mat.SetValue(1,1,xDir.X());
00332         mat.SetValue(2,1,xDir.Y());
00333         mat.SetValue(3,1,xDir.Z());
00334         mat.SetValue(1,2,yDir.X());
00335         mat.SetValue(2,2,yDir.Y());
00336         mat.SetValue(3,2,yDir.Z());
00337         mat.SetValue(1,3,dir.X()*scale);
00338         mat.SetValue(2,3,dir.Y()*scale);
00339         mat.SetValue(3,3,dir.Z()*scale);
00340         BRepBuilderAPI_GTransform mkTrsf(mkSphere.Shape(), mat);
00341         TopoDS_Shape ResultShape = mkTrsf.Shape();
00342         this->Shape.setValue(ResultShape);
00343     }
00344     catch (Standard_Failure) {
00345         Handle_Standard_Failure e = Standard_Failure::Caught();
00346         return new App::DocumentObjectExecReturn(e->GetMessageString());
00347     }
00348 
00349     return App::DocumentObject::StdReturn;
00350 }
00351 
00352 PROPERTY_SOURCE(Part::Cylinder, Part::Primitive)
00353 
00354 Cylinder::Cylinder(void)
00355 {
00356     ADD_PROPERTY_TYPE(Radius,(2.0),"Cylinder",App::Prop_None,"The radius of the cylinder");
00357     ADD_PROPERTY_TYPE(Height,(10.0f),"Cylinder",App::Prop_None,"The height of the cylinder");
00358     ADD_PROPERTY_TYPE(Angle,(360.0f),"Cylinder",App::Prop_None,"The angle of the cylinder");
00359     Angle.setConstraints(&angleRangeU);
00360 }
00361 
00362 short Cylinder::mustExecute() const
00363 {
00364     if (Radius.isTouched())
00365         return 1;
00366     if (Height.isTouched())
00367         return 1;
00368     if (Angle.isTouched())
00369         return 1;
00370     return Primitive::mustExecute();
00371 }
00372 
00373 App::DocumentObjectExecReturn *Cylinder::execute(void)
00374 {
00375     // Build a cylinder
00376     if (Radius.getValue() < Precision::Confusion())
00377         return new App::DocumentObjectExecReturn("Radius of cylinder too small");
00378     if (Height.getValue() < Precision::Confusion())
00379         return new App::DocumentObjectExecReturn("Height of cylinder too small");
00380     try {
00381         BRepPrimAPI_MakeCylinder mkCylr(Radius.getValue(),
00382                                         Height.getValue(),
00383                                         Angle.getValue()/180.0f*Standard_PI);
00384         TopoDS_Shape ResultShape = mkCylr.Shape();
00385         this->Shape.setValue(ResultShape);
00386     }
00387     catch (Standard_Failure) {
00388         Handle_Standard_Failure e = Standard_Failure::Caught();
00389         return new App::DocumentObjectExecReturn(e->GetMessageString());
00390     }
00391 
00392     return App::DocumentObject::StdReturn;
00393 }
00394 
00395 PROPERTY_SOURCE(Part::Cone, Part::Primitive)
00396 
00397 Cone::Cone(void)
00398 {
00399     ADD_PROPERTY_TYPE(Radius1,(2.0),"Cone",App::Prop_None,"The radius of the cone");
00400     ADD_PROPERTY_TYPE(Radius2,(4.0),"Cone",App::Prop_None,"The radius of the cone");
00401     ADD_PROPERTY_TYPE(Height,(10.0),"Cone",App::Prop_None,"The height of the cone");
00402     ADD_PROPERTY_TYPE(Angle,(360.0),"Cone",App::Prop_None,"The angle of the cone");
00403     Angle.setConstraints(&angleRangeU);
00404 }
00405 
00406 short Cone::mustExecute() const
00407 {
00408     if (Radius1.isTouched())
00409         return 1;
00410     if (Radius2.isTouched())
00411         return 1;
00412     if (Height.isTouched())
00413         return 1;
00414     if (Angle.isTouched())
00415         return 1;
00416     return Primitive::mustExecute();
00417 }
00418 
00419 App::DocumentObjectExecReturn *Cone::execute(void)
00420 {
00421     if (Radius1.getValue() < Precision::Confusion())
00422         return new App::DocumentObjectExecReturn("Radius of cone too small");
00423     if (Radius2.getValue() < Precision::Confusion())
00424         return new App::DocumentObjectExecReturn("Radius of cone too small");
00425     if (Height.getValue() < Precision::Confusion())
00426         return new App::DocumentObjectExecReturn("Height of cone too small");
00427     try {
00428         // Build a cone
00429         BRepPrimAPI_MakeCone mkCone(Radius1.getValue(),
00430                                     Radius2.getValue(),
00431                                     Height.getValue(),
00432                                     Angle.getValue()/180.0f*Standard_PI);
00433         TopoDS_Shape ResultShape = mkCone.Shape();
00434         this->Shape.setValue(ResultShape);
00435     }
00436     catch (Standard_Failure) {
00437         Handle_Standard_Failure e = Standard_Failure::Caught();
00438         return new App::DocumentObjectExecReturn(e->GetMessageString());
00439     }
00440 
00441     return App::DocumentObject::StdReturn;
00442 }
00443 
00444 PROPERTY_SOURCE(Part::Torus, Part::Primitive)
00445 
00446 Torus::Torus(void)
00447 {
00448     ADD_PROPERTY_TYPE(Radius1,(10.0),"Torus",App::Prop_None,"The radius of the torus");
00449     Radius1.setConstraints(&floatRange);
00450     ADD_PROPERTY_TYPE(Radius2,(2.0),"Torus",App::Prop_None,"The radius of the torus");
00451     Radius2.setConstraints(&floatRange);
00452     ADD_PROPERTY_TYPE(Angle1,(-180.0),"Torus",App::Prop_None,"The angle of the torus");
00453     Angle1.setConstraints(&torusRangeV);
00454     ADD_PROPERTY_TYPE(Angle2,(180.0),"Torus",App::Prop_None,"The angle of the torus");
00455     Angle2.setConstraints(&torusRangeV);
00456     ADD_PROPERTY_TYPE(Angle3,(360.0),"Torus",App::Prop_None,"The angle of the torus");
00457     Angle3.setConstraints(&angleRangeU);
00458 }
00459 
00460 short Torus::mustExecute() const
00461 {
00462     if (Radius1.isTouched())
00463         return 1;
00464     if (Radius2.isTouched())
00465         return 1;
00466     if (Angle1.isTouched())
00467         return 1;
00468     if (Angle2.isTouched())
00469         return 1;
00470     if (Angle3.isTouched())
00471         return 1;
00472     return Primitive::mustExecute();
00473 }
00474 
00475 App::DocumentObjectExecReturn *Torus::execute(void)
00476 {
00477     if (Radius1.getValue() < Precision::Confusion())
00478         return new App::DocumentObjectExecReturn("Radius of torus too small");
00479     if (Radius2.getValue() < Precision::Confusion())
00480         return new App::DocumentObjectExecReturn("Radius of torus too small");
00481     try {
00482 #if 1
00483         // Build a torus
00484         gp_Circ circle;
00485         circle.SetRadius(Radius2.getValue());
00486         gp_Pnt pos(Radius1.getValue(),0,0);
00487         gp_Dir dir(0,1,0);
00488         circle.SetAxis(gp_Ax1(pos, dir));
00489 
00490         BRepBuilderAPI_MakeEdge mkEdge(circle, Base::toRadians<double>(Angle1.getValue()+180.0f),
00491                                                Base::toRadians<double>(Angle2.getValue()+180.0f));
00492         BRepBuilderAPI_MakeWire mkWire;
00493         mkWire.Add(mkEdge.Edge());
00494         BRepBuilderAPI_MakeFace mkFace(mkWire.Wire());
00495         BRepPrimAPI_MakeRevol mkRevol(mkFace.Face(), gp_Ax1(gp_Pnt(0,0,0), gp_Dir(0,0,1)),
00496             Base::toRadians<double>(Angle3.getValue()), Standard_True);
00497         TopoDS_Shape ResultShape = mkRevol.Shape();
00498 #else
00499         BRepPrimAPI_MakeTorus mkTorus(Radius1.getValue(),
00500                                       Radius2.getValue(),
00501                                       Angle1.getValue()/180.0f*Standard_PI,
00502                                       Angle2.getValue()/180.0f*Standard_PI,
00503                                       Angle3.getValue()/180.0f*Standard_PI);
00504         const TopoDS_Solid& ResultShape = mkTorus.Solid();
00505 #endif
00506         this->Shape.setValue(ResultShape);
00507     }
00508     catch (Standard_Failure) {
00509         Handle_Standard_Failure e = Standard_Failure::Caught();
00510         return new App::DocumentObjectExecReturn(e->GetMessageString());
00511     }
00512 
00513     return App::DocumentObject::StdReturn;
00514 }
00515 
00516 PROPERTY_SOURCE(Part::Helix, Part::Primitive)
00517 
00518 Helix::Helix(void)
00519 {
00520     ADD_PROPERTY_TYPE(Pitch, (1.0),"Helix",App::Prop_None,"The pitch of the helix");
00521     Pitch.setConstraints(&floatRange);
00522     ADD_PROPERTY_TYPE(Height,(2.0),"Helix",App::Prop_None,"The height of the helix");
00523     Height.setConstraints(&floatRange);
00524     ADD_PROPERTY_TYPE(Radius,(1.0),"Helix",App::Prop_None,"The radius of the helix");
00525     Radius.setConstraints(&floatRange);
00526     ADD_PROPERTY_TYPE(Angle,(0.0),"Helix",App::Prop_None,"If angle is > 0 a conical otherwise a cylindircal surface is used");
00527     Angle.setConstraints(&apexRange);
00528 }
00529 
00530 short Helix::mustExecute() const
00531 {
00532     if (Pitch.isTouched())
00533         return 1;
00534     if (Height.isTouched())
00535         return 1;
00536     if (Radius.isTouched())
00537         return 1;
00538     if (Angle.isTouched())
00539         return 1;
00540     return Primitive::mustExecute();
00541 }
00542 
00543 App::DocumentObjectExecReturn *Helix::execute(void)
00544 {
00545     try {
00546         Standard_Real myPitch  = Pitch.getValue();
00547         Standard_Real myHeight = Height.getValue();
00548         Standard_Real myRadius = Radius.getValue();
00549         Standard_Real myAngle  = Angle.getValue();
00550         TopoShape helix;
00551         this->Shape.setValue(helix.makeHelix(myPitch, myHeight, myRadius, myAngle));
00552     }
00553     catch (Standard_Failure) {
00554         Handle_Standard_Failure e = Standard_Failure::Caught();
00555         return new App::DocumentObjectExecReturn(e->GetMessageString());
00556     }
00557 
00558     return App::DocumentObject::StdReturn;
00559 }
00560 
00561 PROPERTY_SOURCE(Part::Wedge, Part::Primitive)
00562 
00563 Wedge::Wedge()
00564 {
00565     ADD_PROPERTY_TYPE(Xmin,(0.0f),"Wedge",App::Prop_None,"Xmin of the wedge");
00566     ADD_PROPERTY_TYPE(Ymin,(0.0f),"Wedge",App::Prop_None,"Ymin of the wedge");
00567     ADD_PROPERTY_TYPE(Zmin,(0.0f),"Wedge",App::Prop_None,"Zmin of the wedge");
00568     ADD_PROPERTY_TYPE(X2min,(2.0f),"Wedge",App::Prop_None,"X2min of the wedge");
00569     ADD_PROPERTY_TYPE(Z2min,(2.0f),"Wedge",App::Prop_None,"Z2min of the wedge");
00570     ADD_PROPERTY_TYPE(Xmax,(10.0f),"Wedge",App::Prop_None,"Xmax of the wedge");
00571     ADD_PROPERTY_TYPE(Ymax,(10.0f),"Wedge",App::Prop_None,"Ymax of the wedge");
00572     ADD_PROPERTY_TYPE(Zmax,(10.0f),"Wedge",App::Prop_None,"Zmax of the wedge");
00573     ADD_PROPERTY_TYPE(X2max,(8.0f),"Wedge",App::Prop_None,"X2max of the wedge");
00574     ADD_PROPERTY_TYPE(Z2max,(8.0f),"Wedge",App::Prop_None,"Z2max of the wedge");
00575 }
00576 
00577 short Wedge::mustExecute() const
00578 {
00579     if (Xmin.isTouched() ||
00580         Ymin.isTouched() ||
00581         Zmin.isTouched() ||
00582         X2min.isTouched() ||
00583         Z2min.isTouched() ||
00584         Xmax.isTouched() ||
00585         Ymax.isTouched() ||
00586         Zmax.isTouched() ||
00587         X2max.isTouched() ||
00588         Z2max.isTouched())
00589         return 1;
00590     return Primitive::mustExecute();
00591 }
00592 
00593 App::DocumentObjectExecReturn *Wedge::execute(void)
00594 {
00595     double xmin = Xmin.getValue();
00596     double ymin = Ymin.getValue();
00597     double zmin = Zmin.getValue();
00598     double z2min = Z2min.getValue();
00599     double x2min = X2min.getValue();
00600     double xmax = Xmax.getValue();
00601     double ymax = Ymax.getValue();
00602     double zmax = Zmax.getValue();
00603     double z2max = Z2max.getValue();
00604     double x2max = X2max.getValue();
00605 
00606 
00607     double dx = xmax-xmin;
00608     double dy = ymax-ymin;
00609     double dz = zmax-zmin;
00610     double dz2 = z2max-z2min;
00611     double dx2 = x2max-x2min;
00612 
00613     if (dx < Precision::Confusion())
00614         return new App::DocumentObjectExecReturn("delta x of wedge too small");
00615 
00616     if (dy < Precision::Confusion())
00617         return new App::DocumentObjectExecReturn("delta y of wedge too small");
00618 
00619     if (dz < Precision::Confusion())
00620         return new App::DocumentObjectExecReturn("delta z of wedge too small");
00621 
00622     if (dz2 < 0)
00623         return new App::DocumentObjectExecReturn("delta z2 of wedge is negative");
00624 
00625     if (dx2 < 0)
00626         return new App::DocumentObjectExecReturn("delta x2 of wedge is negative");
00627 
00628     try {
00629         gp_Pnt pnt(0.0,0.0,0.0);
00630         gp_Dir dir(0.0,0.0,1.0);
00631         BRepPrim_Wedge mkWedge(gp_Ax2(pnt,dir),
00632             xmin, ymin, zmin, z2min, x2min,
00633             xmax, ymax, zmax, z2max, x2max);
00634         BRepBuilderAPI_MakeSolid mkSolid;
00635         mkSolid.Add(mkWedge.Shell());
00636         this->Shape.setValue(mkSolid.Solid());
00637     }
00638     catch (Standard_Failure) {
00639         Handle_Standard_Failure e = Standard_Failure::Caught();
00640         return new App::DocumentObjectExecReturn(e->GetMessageString());
00641     }
00642 
00643     return App::DocumentObject::StdReturn;
00644 }
00645 
00646 void Wedge::onChanged(const App::Property* prop)
00647 {
00648     if (prop == &Xmin || prop == &Ymin || prop == &Zmin ||
00649         prop == &X2min || prop == &Z2min ||
00650         prop == &Xmax || prop == &Ymax || prop == &Zmax ||
00651         prop == &X2max || prop == &Z2max) {
00652         if (!isRestoring()) {
00653             App::DocumentObjectExecReturn *ret = recompute();
00654             delete ret;
00655         }
00656     }
00657     Part::Primitive::onChanged(prop);
00658 }

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