FeaturePartBox.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) Jürgen Riegel          (juergen.riegel@web.de) 2002     *
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 <BRepPrimAPI_MakeBox.hxx>
00027 # include <Precision.hxx>
00028 #endif
00029 
00030 
00031 #include <Base/Console.h>
00032 #include <Base/Reader.h>
00033 #include "FeaturePartBox.h"
00034 
00035 
00036 using namespace Part;
00037 
00038 
00039 PROPERTY_SOURCE(Part::Box, Part::Primitive)
00040 
00041 
00042 Box::Box()
00043 {
00044     ADD_PROPERTY_TYPE(Length,(10.0f),"Box",App::Prop_None,"The length of the box");
00045     ADD_PROPERTY_TYPE(Width ,(10.0f),"Box",App::Prop_None,"The width of the box");
00046     ADD_PROPERTY_TYPE(Height,(10.0f),"Box",App::Prop_None,"The height of the box");
00047 }
00048 
00049 short Box::mustExecute() const
00050 {
00051     if (Length.isTouched() ||
00052         Height.isTouched() ||
00053         Width.isTouched() )
00054         return 1;
00055     return Primitive::mustExecute();
00056 }
00057 
00058 App::DocumentObjectExecReturn *Box::execute(void)
00059 {
00060     double L = Length.getValue();
00061     double W = Width.getValue();
00062     double H = Height.getValue();
00063 
00064     if (L < Precision::Confusion())
00065         return new App::DocumentObjectExecReturn("Length of box too small");
00066 
00067     if (W < Precision::Confusion())
00068         return new App::DocumentObjectExecReturn("Width of box too small");
00069 
00070     if (H < Precision::Confusion())
00071         return new App::DocumentObjectExecReturn("Height of box too small");
00072 
00073     try {
00074         // Build a box using the dimension attributes
00075         BRepPrimAPI_MakeBox mkBox(L, W, H);
00076         TopoDS_Shape ResultShape = mkBox.Shape();
00077         this->Shape.setValue(ResultShape);
00078     }
00079     catch (Standard_Failure) {
00080         Handle_Standard_Failure e = Standard_Failure::Caught();
00081         return new App::DocumentObjectExecReturn(e->GetMessageString());
00082     }
00083 
00084     return App::DocumentObject::StdReturn;
00085 }
00086 
00092 void Box::Restore(Base::XMLReader &reader)
00093 {
00094     reader.readElement("Properties");
00095     int Cnt = reader.getAttributeAsInteger("Count");
00096 
00097     bool location_xyz = false;
00098     bool location_axis = false;
00099     bool distance_lhw = false;
00100     Base::Placement plm;
00101     App::PropertyDistance x,y,z;
00102     App::PropertyDistance l,w,h;
00103     App::PropertyVector Axis, Location;
00104     Axis.setValue(0.0f,0.0f,1.0f);
00105     for (int i=0 ;i<Cnt;i++) {
00106         reader.readElement("Property");
00107         const char* PropName = reader.getAttribute("name");
00108         const char* TypeName = reader.getAttribute("type");
00109         App::Property* prop = getPropertyByName(PropName);
00110         if (!prop) {
00111             // in case this comes from an old document we must use the new properties
00112             if (strcmp(PropName, "l") == 0) {
00113                 distance_lhw = true;
00114                 prop = &l;
00115             }
00116             else if (strcmp(PropName, "w") == 0) {
00117                 distance_lhw = true;
00118                 prop = &h; // by mistake w was considered as height
00119             }
00120             else if (strcmp(PropName, "h") == 0) {
00121                 distance_lhw = true;
00122                 prop = &w; // by mistake h was considered as width
00123             }
00124             else if (strcmp(PropName, "x") == 0) {
00125                 location_xyz = true;
00126                 prop = &x;
00127             }
00128             else if (strcmp(PropName, "y") == 0) {
00129                 location_xyz = true;
00130                 prop = &y;
00131             }
00132             else if (strcmp(PropName, "z") == 0) {
00133                 location_xyz = true;
00134                 prop = &z;
00135             }
00136             else if (strcmp(PropName, "Axis") == 0) {
00137                 location_axis = true;
00138                 prop = &Axis;
00139             }
00140             else if (strcmp(PropName, "Location") == 0) {
00141                 location_axis = true;
00142                 prop = &Location;
00143             }
00144         }
00145         else if (strcmp(PropName, "Length") == 0 && strcmp(TypeName,"PropertyDistance") == 0) {
00146             distance_lhw = true;
00147             prop = &l;
00148         }
00149         else if (strcmp(PropName, "Height") == 0 && strcmp(TypeName,"PropertyDistance") == 0) {
00150             distance_lhw = true;
00151             prop = &h;
00152         }
00153         else if (strcmp(PropName, "Width") == 0 && strcmp(TypeName,"PropertyDistance") == 0) {
00154             distance_lhw = true;
00155             prop = &w;
00156         }
00157 
00158         // NOTE: We must also check the type of the current property because a subclass
00159         // of PropertyContainer might change the type of a property but not its name.
00160         // In this case we would force to read-in a wrong property type and the behaviour
00161         // would be undefined.
00162         std::string tn = TypeName;
00163         if (strcmp(TypeName,"PropertyDistance") == 0) // missing prefix App::
00164             tn = std::string("App::") + tn;
00165         if (prop && strcmp(prop->getTypeId().getName(), tn.c_str()) == 0)
00166             prop->Restore(reader);
00167 
00168         reader.readEndElement("Property");
00169     }
00170 
00171     if (distance_lhw) {
00172         this->Length.setValue(l.getValue());
00173         this->Height.setValue(h.getValue());
00174         this->Width.setValue(w.getValue());
00175     }
00176 
00177     // for 0.7 releases or earlier
00178     if (location_xyz) {
00179         plm.setPosition(Base::Vector3d(x.getValue(),y.getValue(),z.getValue()));
00180         this->Placement.setValue(this->Placement.getValue() * plm);
00181         this->Shape.StatusBits.set(10); // override the shape's location later on
00182     }
00183     // for 0.8 releases
00184     else if (location_axis) {
00185         Base::Vector3f d = Axis.getValue();
00186         Base::Vector3f p = Location.getValue();
00187         Base::Rotation rot(Base::Vector3d(0.0,0.0,1.0),
00188                            Base::Vector3d(d.x,d.y,d.z));
00189         plm.setRotation(rot);
00190         plm.setPosition(Base::Vector3d(p.x,p.y,p.z));
00191         this->Placement.setValue(this->Placement.getValue() * plm);
00192         this->Shape.StatusBits.set(10); // override the shape's location later on
00193     }
00194 
00195     reader.readEndElement("Properties");
00196 }
00197 
00198 void Box::onChanged(const App::Property* prop)
00199 {
00200     if (prop == &Length || prop == &Width || prop == &Height) {
00201         if (!isRestoring()) {
00202             App::DocumentObjectExecReturn *ret = recompute();
00203             delete ret;
00204         }
00205     }
00206     else if (prop == &this->Shape) {
00207         // see Box::Restore
00208         if (this->Shape.StatusBits.test(10)) {
00209             this->Shape.StatusBits.reset(10);
00210             App::DocumentObjectExecReturn *ret = recompute();
00211             delete ret;
00212             return;
00213         }
00214     }
00215     Part::Primitive::onChanged(prop);
00216 }

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