TopoShapePyImp.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) Jürgen Riegel          (juergen.riegel@web.de) 2008     *
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 <sstream>
00027 # include <BRepMesh.hxx>
00028 # include <BRepBuilderAPI_Copy.hxx>
00029 # include <BRepBuilderAPI_Sewing.hxx>
00030 # include <BRepClass3d_SolidClassifier.hxx>
00031 # include <BRepFilletAPI_MakeFillet.hxx>
00032 # include <BRepFilletAPI_MakeChamfer.hxx>
00033 # include <BRepOffsetAPI_MakePipe.hxx>
00034 # include <BRepOffsetAPI_MakePipeShell.hxx>
00035 # include <BRepTools.hxx>
00036 # include <gp_Ax1.hxx>
00037 # include <gp_Ax2.hxx>
00038 # include <gp_Dir.hxx>
00039 # include <gp_Pnt.hxx>
00040 # include <gp_Trsf.hxx>
00041 # include <TopExp_Explorer.hxx>
00042 # include <TopoDS.hxx>
00043 # include <TopoDS_Iterator.hxx>
00044 # include <TopTools_IndexedMapOfShape.hxx>
00045 # include <TopLoc_Location.hxx>
00046 # include <TopExp.hxx>
00047 # include <Precision.hxx>
00048 #endif
00049 
00050 #include <BRepGProp.hxx>
00051 #include <GProp_GProps.hxx>
00052 #include <BRepAlgo_NormalProjection.hxx>
00053 
00054 
00055 #include <Base/GeometryPyCXX.h>
00056 #include <Base/Matrix.h>
00057 #include <Base/Rotation.h>
00058 #include <Base/MatrixPy.h>
00059 #include <Base/Vector3D.h>
00060 #include <Base/VectorPy.h>
00061 #include <CXX/Extensions.hxx>
00062 
00063 #include "TopoShape.h"
00064 #include "TopoShapePy.h"
00065 #include "TopoShapePy.cpp"
00066 
00067 #include "GeometryPy.h"
00068 #include "TopoShapeFacePy.h"
00069 #include "TopoShapeEdgePy.h"
00070 #include "TopoShapeWirePy.h"
00071 #include "TopoShapeVertexPy.h"
00072 #include "TopoShapeSolidPy.h"
00073 #include "TopoShapeShellPy.h"
00074 #include "TopoShapeCompSolidPy.h"
00075 #include "TopoShapeCompoundPy.h"
00076 
00077 using namespace Part;
00078 
00079 #ifndef M_PI
00080     #define M_PI    3.14159265358979323846 /* pi */
00081 #endif
00082 
00083 #ifndef M_PI_2
00084     #define M_PI_2  1.57079632679489661923 /* pi/2 */
00085 #endif
00086 
00087 namespace Py {
00088     typedef ExtensionObject<TopoShapePy> TopoShape;
00089     template<>
00090     bool TopoShape::accepts (PyObject *pyob) const
00091     {
00092         return (pyob && PyObject_TypeCheck(pyob, &(Part::TopoShapePy::Type)));
00093     }
00094 }
00095 
00096 // returns a string which represents the object e.g. when printed in python
00097 std::string TopoShapePy::representation(void) const
00098 {
00099     std::stringstream str;
00100     str << "<Shape object at " << getTopoShapePtr() << ">";
00101 
00102     return str.str();
00103 }
00104 
00105 PyObject *TopoShapePy::PyMake(struct _typeobject *, PyObject *, PyObject *)  // Python wrapper
00106 {
00107     // create a new instance of TopoShapePy and the Twin object 
00108     return new TopoShapePy(new TopoShape);
00109 }
00110 
00111 int TopoShapePy::PyInit(PyObject* args, PyObject*)
00112 {
00113     PyObject *pcObj=0;
00114     if (!PyArg_ParseTuple(args, "|O!", &(PyList_Type), &pcObj))
00115         return -1;
00116 
00117     if (pcObj) {
00118         TopoShape shape;
00119         try {
00120             Py::List list(pcObj);
00121             bool first = true;
00122             for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
00123                 if (PyObject_TypeCheck((*it).ptr(), &(Part::GeometryPy::Type))) {
00124                     TopoDS_Shape sh = static_cast<GeometryPy*>((*it).ptr())->
00125                         getGeometryPtr()->toShape();
00126                     if (first) {
00127                         first = false;
00128                         shape._Shape = sh;
00129                     }
00130                     else {
00131                         shape._Shape = shape.fuse(sh);
00132                     }
00133                 }
00134             }
00135         }
00136         catch (Standard_Failure) {
00137             Handle_Standard_Failure e = Standard_Failure::Caught();
00138             PyErr_SetString(PyExc_Exception, e->GetMessageString());
00139             return -1;
00140         }
00141 
00142         getTopoShapePtr()->_Shape = shape._Shape;
00143     }
00144 
00145     return 0;
00146 }
00147 
00148 PyObject* TopoShapePy::copy(PyObject *args)
00149 {
00150     if (!PyArg_ParseTuple(args, ""))
00151         return NULL;
00152 
00153     const TopoDS_Shape& shape = this->getTopoShapePtr()->_Shape;
00154     PyTypeObject* type = this->GetType();
00155     PyObject* cpy = 0;
00156     // let the type object decide
00157     if (type->tp_new)
00158         cpy = type->tp_new(type, this, 0);
00159     if (!cpy) {
00160         PyErr_SetString(PyExc_TypeError, "failed to create copy of shape");
00161         return 0;
00162     }
00163 
00164     static_cast<TopoShapePy*>(cpy)->getTopoShapePtr()->_Shape = shape;
00165     return cpy;
00166 }
00167 
00168 PyObject* TopoShapePy::replaceShape(PyObject *args)
00169 {
00170     PyObject *l;
00171     if (!PyArg_ParseTuple(args, "O!",&PyList_Type,&l))
00172         return NULL;
00173 
00174     try {
00175         Py::List list(l);
00176         std::vector< std::pair<TopoDS_Shape, TopoDS_Shape> > shapes;
00177         for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
00178             Py::Tuple tuple(*it);
00179             Py::TopoShape sh1(tuple[0]);
00180             Py::TopoShape sh2(tuple[1]);
00181             shapes.push_back(std::make_pair(
00182                 sh1.extensionObject()->getTopoShapePtr()->_Shape,
00183                 sh2.extensionObject()->getTopoShapePtr()->_Shape)
00184             );
00185         }
00186         PyTypeObject* type = this->GetType();
00187         PyObject* inst = type->tp_new(type, this, 0);
00188         static_cast<TopoShapePy*>(inst)->getTopoShapePtr()->_Shape = 
00189             this->getTopoShapePtr()->replaceShape(shapes);
00190         return inst;
00191     }
00192     catch (const Py::Exception&) {
00193         return 0;
00194     }
00195     catch (...) {
00196         PyErr_SetString(PyExc_Exception, "failed to replace shape");
00197         return 0;
00198     }
00199 }
00200 
00201 PyObject* TopoShapePy::removeShape(PyObject *args)
00202 {
00203     PyObject *l;
00204     if (!PyArg_ParseTuple(args, "O!",&PyList_Type,&l))
00205         return NULL;
00206 
00207     try {
00208         Py::List list(l);
00209         std::vector<TopoDS_Shape> shapes;
00210         for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
00211             Py::Tuple tuple(*it);
00212             Py::TopoShape sh(tuple[0]);
00213             shapes.push_back(
00214                 sh.extensionObject()->getTopoShapePtr()->_Shape
00215             );
00216         }
00217         PyTypeObject* type = this->GetType();
00218         PyObject* inst = type->tp_new(type, this, 0);
00219         static_cast<TopoShapePy*>(inst)->getTopoShapePtr()->_Shape = 
00220             this->getTopoShapePtr()->removeShape(shapes);
00221         return inst;
00222     }
00223     catch (...) {
00224         PyErr_SetString(PyExc_Exception, "failed to remove shape");
00225         return 0;
00226     }
00227 }
00228 
00229 PyObject*  TopoShapePy::read(PyObject *args)
00230 {
00231     char* filename;
00232     if (!PyArg_ParseTuple(args, "s", &filename))
00233         return NULL;
00234 
00235     getTopoShapePtr()->read(filename);
00236     Py_Return;
00237 }
00238 
00239 PyObject* TopoShapePy::writeInventor(PyObject * args)
00240 {
00241     double dev=0.3, angle=0.4;
00242     int mode=2;
00243     if (!PyArg_ParseTuple(args, "|idd", &mode,&dev,&angle))
00244         return NULL;
00245 
00246     std::stringstream result;
00247     BRepMesh::Mesh(getTopoShapePtr()->_Shape,dev);
00248     if (mode == 0)
00249         getTopoShapePtr()->exportFaceSet(dev, angle, result);
00250     else if (mode == 1)
00251         getTopoShapePtr()->exportLineSet(result);
00252     else {
00253         getTopoShapePtr()->exportFaceSet(dev, angle, result);
00254         getTopoShapePtr()->exportLineSet(result);
00255     }
00256     // NOTE: Cleaning the triangulation may cause problems on some algorithms like BOP
00257     //BRepTools::Clean(getTopoShapePtr()->_Shape); // remove triangulation
00258     return Py::new_reference_to(Py::String(result.str()));
00259 }
00260 
00261 PyObject*  TopoShapePy::exportIges(PyObject *args)
00262 {
00263     char* filename;
00264     if (!PyArg_ParseTuple(args, "s", &filename))
00265         return NULL;
00266 
00267     try {
00268         // write iges file
00269         getTopoShapePtr()->exportIges(filename);
00270     }
00271     catch (const Base::Exception& e) {
00272         PyErr_SetString(PyExc_Exception,e.what());
00273         return NULL;
00274     }
00275 
00276     Py_Return;
00277 }
00278 
00279 PyObject*  TopoShapePy::exportStep(PyObject *args)
00280 {
00281     char* filename;
00282     if (!PyArg_ParseTuple(args, "s", &filename))
00283         return NULL;
00284 
00285     try {
00286         // write step file
00287         getTopoShapePtr()->exportStep(filename);
00288     }
00289     catch (const Base::Exception& e) {
00290         PyErr_SetString(PyExc_Exception,e.what());
00291         return NULL;
00292     }
00293 
00294     Py_Return;
00295 }
00296 
00297 PyObject*  TopoShapePy::exportBrep(PyObject *args)
00298 {
00299     char* filename;
00300     if (!PyArg_ParseTuple(args, "s", &filename))
00301         return NULL;
00302 
00303     try {
00304         // write brep file
00305         getTopoShapePtr()->exportBrep(filename);
00306     }
00307     catch (const Base::Exception& e) {
00308         PyErr_SetString(PyExc_Exception,e.what());
00309         return NULL;
00310     }
00311 
00312     Py_Return;
00313 }
00314 
00315 PyObject*  TopoShapePy::exportStl(PyObject *args)
00316 {
00317     char* filename;
00318     if (!PyArg_ParseTuple(args, "s", &filename))
00319         return NULL;
00320 
00321     try {
00322         // write stl file
00323         getTopoShapePtr()->exportStl(filename);
00324     }
00325     catch (const Base::Exception& e) {
00326         PyErr_SetString(PyExc_Exception,e.what());
00327         return NULL;
00328     }
00329 
00330     Py_Return;
00331 }
00332 
00333 PyObject* TopoShapePy::extrude(PyObject *args)
00334 {
00335     PyObject *pVec;
00336     if (PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type), &pVec)) {
00337         try {
00338             Base::Vector3d vec = static_cast<Base::VectorPy*>(pVec)->value();
00339             TopoDS_Shape shape = this->getTopoShapePtr()->makePrism(gp_Vec(vec.x,vec.y,vec.z));
00340             TopAbs_ShapeEnum type = shape.ShapeType();
00341             switch (type)
00342             {
00343             case TopAbs_COMPOUND:
00344                 return new TopoShapeCompoundPy(new TopoShape(shape));
00345             case TopAbs_COMPSOLID:
00346                 return new TopoShapeCompSolidPy(new TopoShape(shape));
00347             case TopAbs_SOLID:
00348                 return new TopoShapeSolidPy(new TopoShape(shape));
00349             case TopAbs_SHELL:
00350                 return new TopoShapeShellPy(new TopoShape(shape));
00351             case TopAbs_FACE:
00352                 return new TopoShapeFacePy(new TopoShape(shape));
00353             case TopAbs_WIRE:
00354                 break;
00355             case TopAbs_EDGE:
00356                 return new TopoShapeEdgePy(new TopoShape(shape));
00357             case TopAbs_VERTEX:
00358                 break;
00359             case TopAbs_SHAPE:
00360                 break;
00361             default:
00362                 break;
00363             }
00364 
00365             PyErr_SetString(PyExc_Exception, "extrusion for this shape type not supported");
00366             return 0;
00367         }
00368         catch (Standard_Failure) {
00369             Handle_Standard_Failure e = Standard_Failure::Caught();
00370             PyErr_SetString(PyExc_Exception, e->GetMessageString());
00371             return 0;
00372         }
00373     }
00374 
00375     return 0;
00376 }
00377 
00378 PyObject* TopoShapePy::revolve(PyObject *args)
00379 {
00380     PyObject *pPos,*pDir;
00381     double d=360;
00382     if (PyArg_ParseTuple(args, "O!O!|d", &(Base::VectorPy::Type), &pPos, &(Base::VectorPy::Type), &pDir,&d)) {
00383         try {
00384             const TopoDS_Shape& input = this->getTopoShapePtr()->_Shape;
00385             if (input.IsNull()) {
00386                 PyErr_SetString(PyExc_Exception, "empty shape cannot be revolved");
00387                 return 0;
00388             }
00389 
00390             TopExp_Explorer xp;
00391             xp.Init(input,TopAbs_SOLID);
00392             if (xp.More()) {
00393                 PyErr_SetString(PyExc_Exception, "shape must not contain solids");
00394                 return 0;
00395             }
00396             xp.Init(input,TopAbs_COMPSOLID);
00397             if (xp.More()) {
00398                 PyErr_SetString(PyExc_Exception, "shape must not contain compound solids");
00399                 return 0;
00400             }
00401 
00402             Base::Vector3d pos = static_cast<Base::VectorPy*>(pPos)->value();
00403             Base::Vector3d dir = static_cast<Base::VectorPy*>(pDir)->value();
00404             TopoDS_Shape shape = this->getTopoShapePtr()->revolve(
00405                 gp_Ax1(gp_Pnt(pos.x,pos.y,pos.z), gp_Dir(dir.x,dir.y,dir.z)),d*(M_PI/180));
00406             TopAbs_ShapeEnum type = shape.ShapeType();
00407             switch (type)
00408             {
00409             case TopAbs_COMPOUND:
00410                 return new TopoShapeCompoundPy(new TopoShape(shape));
00411             case TopAbs_COMPSOLID:
00412                 return new TopoShapeCompSolidPy(new TopoShape(shape));
00413             case TopAbs_SOLID:
00414                 return new TopoShapeSolidPy(new TopoShape(shape));
00415             case TopAbs_SHELL:
00416                 return new TopoShapeShellPy(new TopoShape(shape));
00417             case TopAbs_FACE:
00418                 return new TopoShapeFacePy(new TopoShape(shape));
00419             case TopAbs_WIRE:
00420                 break;
00421             case TopAbs_EDGE:
00422                 return new TopoShapeEdgePy(new TopoShape(shape));
00423             case TopAbs_VERTEX:
00424                 break;
00425             case TopAbs_SHAPE:
00426                 break;
00427             default:
00428                 break;
00429             }
00430 
00431             PyErr_SetString(PyExc_Exception, "revolution for this shape type not supported");
00432             return 0;
00433         }
00434         catch (Standard_Failure) {
00435             Handle_Standard_Failure e = Standard_Failure::Caught();
00436             PyErr_SetString(PyExc_Exception, e->GetMessageString());
00437             return 0;
00438         }
00439     }
00440 
00441     return 0;
00442 }
00443 
00444 PyObject*  TopoShapePy::check(PyObject *args)
00445 {
00446     if (!PyArg_ParseTuple(args, ""))
00447         return NULL;
00448     if (!getTopoShapePtr()->_Shape.IsNull()) {
00449         std::stringstream str;
00450         if (!getTopoShapePtr()->analyze(str)) {
00451             PyErr_SetString(PyExc_StandardError, str.str().c_str());
00452             PyErr_Print();
00453         }
00454     }
00455 
00456     Py_Return; 
00457 }
00458 
00459 PyObject*  TopoShapePy::fuse(PyObject *args)
00460 {
00461     PyObject *pcObj;
00462     if (!PyArg_ParseTuple(args, "O!", &(TopoShapePy::Type), &pcObj))
00463         return NULL;
00464 
00465     TopoDS_Shape shape = static_cast<TopoShapePy*>(pcObj)->getTopoShapePtr()->_Shape;
00466     try {
00467         // Let's call algorithm computing a fuse operation:
00468         TopoDS_Shape fusShape = this->getTopoShapePtr()->fuse(shape);
00469         return new TopoShapePy(new TopoShape(fusShape));
00470     }
00471     catch (Standard_Failure) {
00472         Handle_Standard_Failure e = Standard_Failure::Caught();
00473         PyErr_SetString(PyExc_Exception, e->GetMessageString());
00474         return NULL;
00475     }
00476     catch (const std::exception& e) {
00477         PyErr_SetString(PyExc_Exception, e.what());
00478         return NULL;
00479     }
00480 }
00481 
00482 PyObject*  TopoShapePy::oldFuse(PyObject *args)
00483 {
00484     PyObject *pcObj;
00485     if (!PyArg_ParseTuple(args, "O!", &(TopoShapePy::Type), &pcObj))
00486         return NULL;
00487 
00488     TopoDS_Shape shape = static_cast<TopoShapePy*>(pcObj)->getTopoShapePtr()->_Shape;
00489     try {
00490         // Let's call algorithm computing a fuse operation:
00491         TopoDS_Shape fusShape = this->getTopoShapePtr()->oldFuse(shape);
00492         return new TopoShapePy(new TopoShape(fusShape));
00493     }
00494     catch (Standard_Failure) {
00495         Handle_Standard_Failure e = Standard_Failure::Caught();
00496         PyErr_SetString(PyExc_Exception, e->GetMessageString());
00497         return NULL;
00498     }
00499     catch (const std::exception& e) {
00500         PyErr_SetString(PyExc_Exception, e.what());
00501         return NULL;
00502     }
00503 }
00504 
00505 PyObject*  TopoShapePy::common(PyObject *args)
00506 {
00507     PyObject *pcObj;
00508     if (!PyArg_ParseTuple(args, "O!", &(TopoShapePy::Type), &pcObj))
00509         return NULL;
00510 
00511     TopoDS_Shape shape = static_cast<TopoShapePy*>(pcObj)->getTopoShapePtr()->_Shape;
00512     try {
00513         // Let's call algorithm computing a common operation:
00514         TopoDS_Shape comShape = this->getTopoShapePtr()->common(shape);
00515         return new TopoShapePy(new TopoShape(comShape));
00516     }
00517     catch (Standard_Failure) {
00518         Handle_Standard_Failure e = Standard_Failure::Caught();
00519         PyErr_SetString(PyExc_Exception, e->GetMessageString());
00520         return NULL;
00521     }
00522     catch (const std::exception& e) {
00523         PyErr_SetString(PyExc_Exception, e.what());
00524         return NULL;
00525     }
00526 }
00527 
00528 PyObject*  TopoShapePy::section(PyObject *args)
00529 {
00530     PyObject *pcObj;
00531     if (!PyArg_ParseTuple(args, "O!", &(TopoShapePy::Type), &pcObj))
00532         return NULL;
00533 
00534     TopoDS_Shape shape = static_cast<TopoShapePy*>(pcObj)->getTopoShapePtr()->_Shape;
00535     try {
00536         // Let's call algorithm computing a section operation:
00537         TopoDS_Shape secShape = this->getTopoShapePtr()->section(shape);
00538         return new TopoShapePy(new TopoShape(secShape));
00539     }
00540     catch (Standard_Failure) {
00541         Handle_Standard_Failure e = Standard_Failure::Caught();
00542         PyErr_SetString(PyExc_Exception, e->GetMessageString());
00543         return NULL;
00544     }
00545     catch (const std::exception& e) {
00546         PyErr_SetString(PyExc_Exception, e.what());
00547         return NULL;
00548     }
00549 }
00550 
00551 PyObject*  TopoShapePy::slice(PyObject *args)
00552 {
00553     PyObject *dir;
00554     double d;
00555     if (!PyArg_ParseTuple(args, "O!d", &(Base::VectorPy::Type), &dir, &d))
00556         return NULL;
00557 
00558     try {
00559         Base::Vector3d vec = Py::Vector(dir, false).toVector();
00560         std::list<TopoDS_Wire> slice = this->getTopoShapePtr()->slice(vec, d);
00561         Py::List wire;
00562         for (std::list<TopoDS_Wire>::iterator it = slice.begin(); it != slice.end(); ++it) {
00563             wire.append(Py::asObject(new TopoShapeWirePy(new TopoShape(*it))));
00564         }
00565 
00566         return Py::new_reference_to(wire);
00567     }
00568     catch (Standard_Failure) {
00569         Handle_Standard_Failure e = Standard_Failure::Caught();
00570         PyErr_SetString(PyExc_Exception, e->GetMessageString());
00571         return NULL;
00572     }
00573     catch (const std::exception& e) {
00574         PyErr_SetString(PyExc_Exception, e.what());
00575         return NULL;
00576     }
00577 }
00578 
00579 PyObject*  TopoShapePy::slices(PyObject *args)
00580 {
00581     PyObject *dir, *dist;
00582     if (!PyArg_ParseTuple(args, "O!O!", &(Base::VectorPy::Type), &dir,
00583                                         &PyList_Type, &dist))
00584         return NULL;
00585 
00586     try {
00587         Base::Vector3d vec = Py::Vector(dir, false).toVector();
00588         Py::List list(dist);
00589         std::vector<double> d;
00590         d.reserve(list.size());
00591         for (Py::List::iterator it = list.begin(); it != list.end(); ++it)
00592             d.push_back((double)Py::Float(*it));
00593         TopoDS_Compound slice = this->getTopoShapePtr()->slices(vec, d);
00594         return new TopoShapeCompoundPy(new TopoShape(slice));
00595     }
00596     catch (Standard_Failure) {
00597         Handle_Standard_Failure e = Standard_Failure::Caught();
00598         PyErr_SetString(PyExc_Exception, e->GetMessageString());
00599         return NULL;
00600     }
00601     catch (const std::exception& e) {
00602         PyErr_SetString(PyExc_Exception, e.what());
00603         return NULL;
00604     }
00605 }
00606 
00607 PyObject*  TopoShapePy::cut(PyObject *args)
00608 {
00609     PyObject *pcObj;
00610     if (!PyArg_ParseTuple(args, "O!", &(TopoShapePy::Type), &pcObj))
00611         return NULL;
00612 
00613     TopoDS_Shape shape = static_cast<TopoShapePy*>(pcObj)->getTopoShapePtr()->_Shape;
00614     try {
00615         // Let's call algorithm computing a cut operation:
00616         TopoDS_Shape cutShape = this->getTopoShapePtr()->cut(shape);
00617         return new TopoShapePy(new TopoShape(cutShape));
00618     }
00619     catch (Standard_Failure) {
00620         Handle_Standard_Failure e = Standard_Failure::Caught();
00621         PyErr_SetString(PyExc_Exception, e->GetMessageString());
00622         return NULL;
00623     }
00624     catch (const std::exception& e) {
00625         PyErr_SetString(PyExc_Exception, e.what());
00626         return NULL;
00627     }
00628 }
00629 
00630 PyObject*  TopoShapePy::sewShape(PyObject *args)
00631 {
00632     if (!PyArg_ParseTuple(args, ""))
00633         return NULL;
00634 
00635     try {
00636         getTopoShapePtr()->sewShape();
00637         Py_Return;
00638     }
00639     catch (Standard_Failure) {
00640         Handle_Standard_Failure e = Standard_Failure::Caught();
00641         PyErr_SetString(PyExc_Exception, e->GetMessageString());
00642         return NULL;
00643     }
00644 }
00645 
00646 PyObject*  TopoShapePy::removeInternalWires(PyObject *args)
00647 {
00648     double minArea;
00649     if (!PyArg_ParseTuple(args, "d",&minArea))
00650         return NULL;
00651 
00652     try {
00653         bool ok = getTopoShapePtr()->removeInternalWires(minArea);
00654         PyObject* ret = ok ? Py_True : Py_False;
00655         Py_INCREF(ret);
00656         return ret;
00657     }
00658     catch (Standard_Failure) {
00659         Handle_Standard_Failure e = Standard_Failure::Caught();
00660         PyErr_SetString(PyExc_Exception, e->GetMessageString());
00661         return NULL;
00662     }
00663 }
00664 
00665 PyObject*  TopoShapePy::mirror(PyObject *args)
00666 {
00667     PyObject *v1, *v2;
00668     if (!PyArg_ParseTuple(args, "O!O!", &(Base::VectorPy::Type),&v1,
00669                                         &(Base::VectorPy::Type),&v2))
00670         return NULL;
00671 
00672     Base::Vector3d base = Py::Vector(v1,false).toVector();
00673     Base::Vector3d norm = Py::Vector(v2,false).toVector();
00674 
00675     try {
00676         gp_Ax2 ax2(gp_Pnt(base.x,base.y,base.z), gp_Dir(norm.x,norm.y,norm.z));
00677         TopoDS_Shape shape = this->getTopoShapePtr()->mirror(ax2);
00678         return new TopoShapePy(new TopoShape(shape));
00679     }
00680     catch (Standard_Failure) {
00681         Handle_Standard_Failure e = Standard_Failure::Caught();
00682         PyErr_SetString(PyExc_Exception, e->GetMessageString());
00683         return NULL;
00684     }
00685 }
00686 
00687 PyObject*  TopoShapePy::transformGeometry(PyObject *args)
00688 {
00689     PyObject *obj;
00690     if (!PyArg_ParseTuple(args, "O!", &(Base::MatrixPy::Type),&obj))
00691         return NULL;
00692 
00693     Base::Matrix4D mat = static_cast<Base::MatrixPy*>(obj)->value();
00694     try {
00695         TopoDS_Shape shape = this->getTopoShapePtr()->transformGShape(mat);
00696         return new TopoShapePy(new TopoShape(shape));
00697     }
00698     catch (Standard_Failure) {
00699         Handle_Standard_Failure e = Standard_Failure::Caught();
00700         PyErr_SetString(PyExc_Exception, e->GetMessageString());
00701         return NULL;
00702     }
00703 }
00704 
00705 PyObject*  TopoShapePy::transformShape(PyObject *args)
00706 {
00707     PyObject *obj;
00708     if (!PyArg_ParseTuple(args, "O!", &(Base::MatrixPy::Type),&obj))
00709         return NULL;
00710 
00711     Base::Matrix4D mat = static_cast<Base::MatrixPy*>(obj)->value();
00712     try {
00713         this->getTopoShapePtr()->transformShape(mat);
00714         Py_Return;
00715     }
00716     catch (Standard_Failure) {
00717         Handle_Standard_Failure e = Standard_Failure::Caught();
00718         PyErr_SetString(PyExc_Exception, e->GetMessageString());
00719         return NULL;
00720     }
00721 }
00722 
00723 PyObject*  TopoShapePy::translate(PyObject *args)
00724 {
00725     PyObject *obj;
00726     if (!PyArg_ParseTuple(args, "O", &obj))
00727         return 0;
00728 
00729     Base::Vector3d vec;
00730     if (PyObject_TypeCheck(obj, &(Base::VectorPy::Type))) {
00731         vec = static_cast<Base::VectorPy*>(obj)->value();
00732     }
00733     else if (PyObject_TypeCheck(obj, &PyTuple_Type)) {
00734         vec = Base::getVectorFromTuple<double>(obj);
00735     }
00736     else {
00737         PyErr_SetString(PyExc_TypeError, "either vector or tuple expected");
00738         return 0;
00739     }
00740 
00741     gp_Trsf mov;
00742     mov.SetTranslation(gp_Vec(vec.x,vec.y,vec.z));
00743     TopLoc_Location loc(mov);
00744     getTopoShapePtr()->_Shape.Move(loc);
00745     Py_Return;
00746 }
00747 
00748 PyObject*  TopoShapePy::rotate(PyObject *args)
00749 {
00750     PyObject *obj1, *obj2;
00751     double angle;
00752     if (!PyArg_ParseTuple(args, "OOd", &obj1, &obj2, &angle))
00753         return NULL;
00754 
00755     try {
00756         // Vector also supports sequence
00757         Py::Sequence p1(obj1), p2(obj2);
00758         // Convert into OCC representation
00759         gp_Pnt pos = gp_Pnt((double)Py::Float(p1[0]),
00760                             (double)Py::Float(p1[1]),
00761                             (double)Py::Float(p1[2]));
00762         gp_Dir dir = gp_Dir((double)Py::Float(p2[0]),
00763                             (double)Py::Float(p2[1]),
00764                             (double)Py::Float(p2[2]));
00765 
00766         gp_Ax1 axis(pos, dir);
00767         gp_Trsf mov;
00768         mov.SetRotation(axis, angle*(M_PI/180));
00769         TopLoc_Location loc(mov);
00770         getTopoShapePtr()->_Shape.Move(loc);
00771         Py_Return;
00772     }
00773     catch (const Py::Exception&) {
00774         return NULL;
00775     }
00776 }
00777 
00778 PyObject*  TopoShapePy::scale(PyObject *args)
00779 {
00780     double factor;
00781     PyObject* p=0;
00782     if (!PyArg_ParseTuple(args, "d|O!", &factor, &(Base::VectorPy::Type), &p))
00783         return NULL;
00784 
00785     gp_Pnt pos(0,0,0);
00786     if (p) {
00787         Base::Vector3d pnt = static_cast<Base::VectorPy*>(p)->value();
00788         pos.SetX(pnt.x);
00789         pos.SetY(pnt.y);
00790         pos.SetZ(pnt.z);
00791     }
00792     if (fabs(factor) < Precision::Confusion()) {
00793         PyErr_SetString(PyExc_Exception, "scale factor too small");
00794         return NULL;
00795     }
00796 
00797     try {
00798         gp_Trsf scl;
00799         scl.SetScale(pos, factor);
00800         TopLoc_Location loc(scl);
00801         getTopoShapePtr()->_Shape.Move(loc);
00802         Py_Return;
00803     }
00804     catch (Standard_Failure) {
00805         Handle_Standard_Failure e = Standard_Failure::Caught();
00806         PyErr_SetString(PyExc_Exception, e->GetMessageString());
00807         return NULL;
00808     }
00809 }
00810 
00811 PyObject* TopoShapePy::makeFillet(PyObject *args)
00812 {
00813     // use one radius for all edges
00814     double radius;
00815     PyObject *obj;
00816     if (PyArg_ParseTuple(args, "dO!", &radius, &(PyList_Type), &obj)) {
00817         try {
00818             const TopoDS_Shape& shape = this->getTopoShapePtr()->_Shape;
00819             BRepFilletAPI_MakeFillet mkFillet(shape);
00820             Py::List list(obj);
00821             for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
00822                 if (PyObject_TypeCheck((*it).ptr(), &(Part::TopoShapePy::Type))) {
00823                     const TopoDS_Shape& edge = static_cast<TopoShapePy*>((*it).ptr())->getTopoShapePtr()->_Shape;
00824                     if (edge.ShapeType() == TopAbs_EDGE) {
00825                         //Add edge to fillet algorithm
00826                         mkFillet.Add(radius, TopoDS::Edge(edge));
00827                     }
00828                 }
00829             }
00830             return new TopoShapePy(new TopoShape(mkFillet.Shape()));
00831         }
00832         catch (Standard_Failure) {
00833             Handle_Standard_Failure e = Standard_Failure::Caught();
00834             PyErr_SetString(PyExc_Exception, e->GetMessageString());
00835             return NULL;
00836         }
00837     }
00838 
00839     // use two radii for all edges
00840     PyErr_Clear();
00841     double radius1, radius2;
00842     if (PyArg_ParseTuple(args, "ddO!", &radius1, &radius2, &(PyList_Type), &obj)) {
00843         try {
00844             const TopoDS_Shape& shape = this->getTopoShapePtr()->_Shape;
00845             BRepFilletAPI_MakeFillet mkFillet(shape);
00846             Py::List list(obj);
00847             for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
00848                 if (PyObject_TypeCheck((*it).ptr(), &(Part::TopoShapePy::Type))) {
00849                     const TopoDS_Shape& edge = static_cast<TopoShapePy*>((*it).ptr())->getTopoShapePtr()->_Shape;
00850                     if (edge.ShapeType() == TopAbs_EDGE) {
00851                         //Add edge to fillet algorithm
00852                         mkFillet.Add(radius1, radius2, TopoDS::Edge(edge));
00853                     }
00854                 }
00855             }
00856             return new TopoShapePy(new TopoShape(mkFillet.Shape()));
00857         }
00858         catch (Standard_Failure) {
00859             Handle_Standard_Failure e = Standard_Failure::Caught();
00860             PyErr_SetString(PyExc_Exception, e->GetMessageString());
00861             return NULL;
00862         }
00863     }
00864 
00865     PyErr_SetString(PyExc_TypeError, "This method accepts:\n"
00866         "-- one radius and a list of edges\n"
00867         "-- two radii and a list of edges");
00868     return NULL;
00869 }
00870 
00871 PyObject* TopoShapePy::makeChamfer(PyObject *args)
00872 {
00873     // use one radius for all edges
00874     double radius;
00875     PyObject *obj;
00876     if (PyArg_ParseTuple(args, "dO!", &radius, &(PyList_Type), &obj)) {
00877         try {
00878             const TopoDS_Shape& shape = this->getTopoShapePtr()->_Shape;
00879             BRepFilletAPI_MakeChamfer mkChamfer(shape);
00880             TopTools_IndexedMapOfShape mapOfEdges;
00881             TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace;
00882             TopExp::MapShapesAndAncestors(shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace);
00883             TopExp::MapShapes(shape, TopAbs_EDGE, mapOfEdges);
00884             Py::List list(obj);
00885             for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
00886                 if (PyObject_TypeCheck((*it).ptr(), &(Part::TopoShapePy::Type))) {
00887                     const TopoDS_Shape& edge = static_cast<TopoShapePy*>((*it).ptr())->getTopoShapePtr()->_Shape;
00888                     if (edge.ShapeType() == TopAbs_EDGE) {
00889                         //Add edge to fillet algorithm
00890                         const TopoDS_Face& face = TopoDS::Face(mapEdgeFace.FindFromKey(edge).First());
00891                         mkChamfer.Add(radius, TopoDS::Edge(edge), face);
00892                     }
00893                 }
00894             }
00895             return new TopoShapePy(new TopoShape(mkChamfer.Shape()));
00896         }
00897         catch (Standard_Failure) {
00898             Handle_Standard_Failure e = Standard_Failure::Caught();
00899             PyErr_SetString(PyExc_Exception, e->GetMessageString());
00900             return NULL;
00901         }
00902     }
00903 
00904     // use two radii for all edges
00905     PyErr_Clear();
00906     double radius1, radius2;
00907     if (PyArg_ParseTuple(args, "ddO!", &radius1, &radius2, &(PyList_Type), &obj)) {
00908         try {
00909             const TopoDS_Shape& shape = this->getTopoShapePtr()->_Shape;
00910             BRepFilletAPI_MakeChamfer mkChamfer(shape);
00911             TopTools_IndexedMapOfShape mapOfEdges;
00912             TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace;
00913             TopExp::MapShapesAndAncestors(shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace);
00914             TopExp::MapShapes(shape, TopAbs_EDGE, mapOfEdges);
00915             Py::List list(obj);
00916             for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
00917                 if (PyObject_TypeCheck((*it).ptr(), &(Part::TopoShapePy::Type))) {
00918                     const TopoDS_Shape& edge = static_cast<TopoShapePy*>((*it).ptr())->getTopoShapePtr()->_Shape;
00919                     if (edge.ShapeType() == TopAbs_EDGE) {
00920                         //Add edge to fillet algorithm
00921                         const TopoDS_Face& face = TopoDS::Face(mapEdgeFace.FindFromKey(edge).First());
00922                         mkChamfer.Add(radius1, radius2, TopoDS::Edge(edge), face);
00923                     }
00924                 }
00925             }
00926             return new TopoShapePy(new TopoShape(mkChamfer.Shape()));
00927         }
00928         catch (Standard_Failure) {
00929             Handle_Standard_Failure e = Standard_Failure::Caught();
00930             PyErr_SetString(PyExc_Exception, e->GetMessageString());
00931             return NULL;
00932         }
00933     }
00934 
00935     PyErr_SetString(PyExc_TypeError, "This method accepts:\n"
00936         "-- one radius and a list of edges\n"
00937         "-- two radii and a list of edges");
00938     return NULL;
00939 }
00940 
00941 PyObject* TopoShapePy::makeThickness(PyObject *args)
00942 {
00943     PyObject *obj;
00944     double offset, tolerance;
00945     if (!PyArg_ParseTuple(args, "O!dd", &(PyList_Type), &obj, &offset, &tolerance))
00946         return 0;
00947 
00948     try {
00949         TopTools_ListOfShape facesToRemove;
00950         Py::List list(obj);
00951         for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
00952             if (PyObject_TypeCheck((*it).ptr(), &(Part::TopoShapePy::Type))) {
00953                 const TopoDS_Shape& shape = static_cast<TopoShapePy*>((*it).ptr())->getTopoShapePtr()->_Shape;
00954                 facesToRemove.Append(shape);
00955             }
00956         }
00957 
00958         TopoDS_Shape shape = this->getTopoShapePtr()->makeThickSolid(facesToRemove, offset, tolerance);
00959         return new TopoShapeSolidPy(new TopoShape(shape));
00960     }
00961     catch (Standard_Failure) {
00962         Handle_Standard_Failure e = Standard_Failure::Caught();
00963         PyErr_SetString(PyExc_Exception, e->GetMessageString());
00964         return NULL;
00965     }
00966 }
00967 
00968 PyObject* TopoShapePy::makeOffsetShape(PyObject *args)
00969 {
00970     double offset, tolerance;
00971     PyObject* inter = Py_False;
00972     PyObject* self_inter = Py_False;
00973     short offsetMode = 0, join = 0;
00974     if (!PyArg_ParseTuple(args, "dd|O!O!hh",
00975         &offset, &tolerance,
00976         &(PyBool_Type), &inter,
00977         &(PyBool_Type), &self_inter,
00978         &offsetMode, &join))
00979         return 0;
00980 
00981     try {
00982         TopoDS_Shape shape = this->getTopoShapePtr()->makeOffset(offset, tolerance,
00983             (inter == Py_True), (self_inter == Py_True), offsetMode, join);
00984         return new TopoShapePy(new TopoShape(shape));
00985     }
00986     catch (Standard_Failure) {
00987         Handle_Standard_Failure e = Standard_Failure::Caught();
00988         PyErr_SetString(PyExc_Exception, e->GetMessageString());
00989         return NULL;
00990     }
00991 }
00992 
00993 PyObject*  TopoShapePy::reverse(PyObject *args)
00994 {
00995     if (!PyArg_ParseTuple(args, ""))
00996         return NULL;
00997 
00998     getTopoShapePtr()->_Shape.Reverse();
00999     Py_Return;
01000 }
01001 
01002 PyObject*  TopoShapePy::complement(PyObject *args)
01003 {
01004     if (!PyArg_ParseTuple(args, ""))
01005         return NULL;
01006 
01007     getTopoShapePtr()->_Shape.Complement();
01008     Py_Return;
01009 }
01010 
01011 PyObject*  TopoShapePy::nullify(PyObject *args)
01012 {
01013     if (!PyArg_ParseTuple(args, ""))
01014         return NULL;
01015 
01016     getTopoShapePtr()->_Shape.Nullify();
01017     Py_Return;
01018 }
01019 
01020 PyObject*  TopoShapePy::isNull(PyObject *args)
01021 {
01022     if (!PyArg_ParseTuple(args, ""))
01023         return NULL;
01024     bool null = getTopoShapePtr()->isNull();
01025     return Py_BuildValue("O", (null ? Py_True : Py_False));
01026 }
01027 
01028 PyObject*  TopoShapePy::isClosed(PyObject *args)
01029 {
01030     if (!PyArg_ParseTuple(args, ""))
01031         return NULL;
01032     try {
01033         return Py_BuildValue("O", (getTopoShapePtr()->isClosed() ? Py_True : Py_False));
01034     }
01035     catch (...) {
01036         PyErr_SetString(PyExc_RuntimeError, "check failed, shape may be empty");
01037         return NULL;
01038     }
01039 }
01040 
01041 PyObject*  TopoShapePy::isEqual(PyObject *args)
01042 {
01043     PyObject *pcObj;
01044     if (!PyArg_ParseTuple(args, "O!", &(TopoShapePy::Type), &pcObj))
01045         return NULL;
01046 
01047     TopoDS_Shape shape = static_cast<TopoShapePy*>(pcObj)->getTopoShapePtr()->_Shape;
01048     Standard_Boolean test = (getTopoShapePtr()->_Shape == shape);
01049     return Py_BuildValue("O", (test ? Py_True : Py_False));
01050 }
01051 
01052 PyObject*  TopoShapePy::isSame(PyObject *args)
01053 {
01054     PyObject *pcObj;
01055     if (!PyArg_ParseTuple(args, "O!", &(TopoShapePy::Type), &pcObj))
01056         return NULL;
01057 
01058     TopoDS_Shape shape = static_cast<TopoShapePy*>(pcObj)->getTopoShapePtr()->_Shape;
01059     Standard_Boolean test = getTopoShapePtr()->_Shape.IsSame(shape);
01060     return Py_BuildValue("O", (test ? Py_True : Py_False));
01061 }
01062 
01063 PyObject*  TopoShapePy::isValid(PyObject *args)
01064 {
01065     if (!PyArg_ParseTuple(args, ""))
01066         return NULL;
01067     try {
01068         return Py_BuildValue("O", (getTopoShapePtr()->isValid() ? Py_True : Py_False));
01069     }
01070     catch (...) {
01071         PyErr_SetString(PyExc_RuntimeError, "check failed, shape may be empty");
01072         return NULL;
01073     }
01074 }
01075 
01076 PyObject*  TopoShapePy::fix(PyObject *args)
01077 {
01078     double prec, mintol, maxtol;
01079     if (!PyArg_ParseTuple(args, "ddd", &prec, &mintol, &maxtol))
01080         return NULL;
01081     try {
01082         return Py_BuildValue("O", (getTopoShapePtr()->fix(prec, mintol, maxtol) ? Py_True : Py_False));
01083     }
01084     catch (...) {
01085         PyErr_SetString(PyExc_RuntimeError, "check failed, shape may be empty");
01086         return NULL;
01087     }
01088 }
01089 
01090 PyObject* TopoShapePy::hashCode(PyObject *args)
01091 {
01092     int upper = IntegerLast();
01093     if (!PyArg_ParseTuple(args, "|i",&upper))
01094         return 0;
01095     int hc = getTopoShapePtr()->_Shape.HashCode(upper);
01096     return Py_BuildValue("i", hc);
01097 }
01098 
01099 PyObject* TopoShapePy::tessellate(PyObject *args)
01100 {
01101     try {
01102         float tolerance;
01103         if (!PyArg_ParseTuple(args, "f",&tolerance))
01104             return 0;
01105         std::vector<Base::Vector3d> Points;
01106         std::vector<Data::ComplexGeoData::Facet> Facets;
01107         getTopoShapePtr()->getFaces(Points, Facets,tolerance);
01108         Py::Tuple tuple(2);
01109         Py::List vertex;
01110         for (std::vector<Base::Vector3d>::const_iterator it = Points.begin();
01111             it != Points.end(); ++it)
01112             vertex.append(Py::Object(new Base::VectorPy(*it)));
01113         tuple.setItem(0, vertex);
01114         Py::List facet;
01115         for (std::vector<Data::ComplexGeoData::Facet>::const_iterator
01116             it = Facets.begin(); it != Facets.end(); ++it) {
01117             Py::Tuple f(3);
01118             f.setItem(0,Py::Int((int)it->I1));
01119             f.setItem(1,Py::Int((int)it->I2));
01120             f.setItem(2,Py::Int((int)it->I3));
01121             facet.append(f);
01122         }
01123         tuple.setItem(1, facet);
01124         return Py::new_reference_to(tuple);
01125     }
01126     catch (Standard_Failure) {
01127         Handle_Standard_Failure e = Standard_Failure::Caught();
01128         PyErr_SetString(PyExc_Exception, e->GetMessageString());
01129         return NULL;
01130     }
01131 }
01132 
01133 PyObject* TopoShapePy::project(PyObject *args)
01134 {
01135     PyObject *obj;
01136 
01137     BRepAlgo_NormalProjection algo;
01138     algo.Init(this->getTopoShapePtr()->_Shape);
01139     if (PyArg_ParseTuple(args, "O!", &(PyList_Type), &obj)) {
01140         try {
01141             Py::List list(obj);
01142             for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
01143                 if (PyObject_TypeCheck((*it).ptr(), &(Part::TopoShapePy::Type))) {
01144                     const TopoDS_Shape& shape = static_cast<TopoShapePy*>((*it).ptr())->getTopoShapePtr()->_Shape;
01145                     algo.Add(shape);
01146                 }
01147             }
01148 
01149             algo.Compute3d(Standard_True);
01150             algo.SetLimit(Standard_True);
01151             algo.SetParams(1.e-6, 1.e-6, GeomAbs_C1, 14, 16);
01152             //algo.SetDefaultParams();
01153             algo.Build();
01154             return new TopoShapePy(new TopoShape(algo.Projection()));
01155         }
01156         catch (Standard_Failure) {
01157             PyErr_SetString(PyExc_Exception, "Failed to project shape");
01158             return NULL;
01159         }
01160     }
01161 
01162     return 0;
01163 }
01164 
01165 PyObject* TopoShapePy::makeShapeFromMesh(PyObject *args)
01166 {
01167     PyObject *tup;
01168     float tolerance;
01169     if (!PyArg_ParseTuple(args, "O!f",&PyTuple_Type, &tup, &tolerance))
01170         return 0;
01171 
01172     try {
01173         Py::Tuple tuple(tup);
01174         Py::List vertex(tuple[0]);
01175         Py::List facets(tuple[1]);
01176 
01177         std::vector<Base::Vector3d> Points;
01178         for (Py::List::iterator it = vertex.begin(); it != vertex.end(); ++it) {
01179             Py::Vector vec(*it);
01180             Points.push_back(vec.toVector());
01181         }
01182         std::vector<Data::ComplexGeoData::Facet> Facets;
01183         for (Py::List::iterator it = facets.begin(); it != facets.end(); ++it) {
01184             Data::ComplexGeoData::Facet face;
01185             Py::Tuple f(*it);
01186             face.I1 = (int)Py::Int(f[0]);
01187             face.I2 = (int)Py::Int(f[1]);
01188             face.I3 = (int)Py::Int(f[2]);
01189             Facets.push_back(face);
01190         }
01191 
01192         getTopoShapePtr()->setFaces(Points, Facets,tolerance);
01193         Py_Return;
01194     }
01195     catch (const Py::Exception&) {
01196         return 0;
01197     }
01198 }
01199 
01200 PyObject* TopoShapePy::toNurbs(PyObject *args)
01201 {
01202     if (!PyArg_ParseTuple(args, ""))
01203         return NULL;
01204 
01205     try {
01206         // Convert into nurbs
01207         TopoDS_Shape nurbs = this->getTopoShapePtr()->toNurbs();
01208         return new TopoShapePy(new TopoShape(nurbs));
01209     }
01210     catch (Standard_Failure) {
01211         Handle_Standard_Failure e = Standard_Failure::Caught();
01212         PyErr_SetString(PyExc_Exception, e->GetMessageString());
01213         return NULL;
01214     }
01215 }
01216 
01217 PyObject*  TopoShapePy::isInside(PyObject *args)
01218 {
01219     PyObject *point;
01220     double tolerance;
01221     PyObject* checkFace = Py_False;
01222     TopAbs_State stateIn = TopAbs_IN;
01223     if (!PyArg_ParseTuple(args, "O!dO!", &(Base::VectorPy::Type), &point, &tolerance,  &PyBool_Type, &checkFace))
01224         return NULL;
01225     try {
01226         TopoDS_Shape shape = getTopoShapePtr()->_Shape;
01227         BRepClass3d_SolidClassifier solidClassifier(shape);
01228         Base::Vector3d pnt = static_cast<Base::VectorPy*>(point)->value();
01229         gp_Pnt vertex = gp_Pnt(pnt.x,pnt.y,pnt.z);
01230         solidClassifier.Perform(vertex, tolerance);
01231         Standard_Boolean test = (solidClassifier.State() == stateIn);
01232         if ( (checkFace == Py_True) && (solidClassifier.IsOnAFace()) )
01233             test = Standard_True;
01234         return Py_BuildValue("O", (test ? Py_True : Py_False));
01235     }
01236     catch (Standard_Failure) {
01237         Handle_Standard_Failure e = Standard_Failure::Caught();
01238         PyErr_SetString(PyExc_Exception, e->GetMessageString());
01239         return NULL;
01240     }
01241     catch (const std::exception& e) {
01242         PyErr_SetString(PyExc_Exception, e.what());
01243         return NULL;
01244     }
01245 }
01246 
01247 #if 0 // see ComplexGeoDataPy::Matrix which does the same
01248 Py::Object TopoShapePy::getLocation(void) const
01249 {
01250     const TopLoc_Location& loc = getTopoShapePtr()->_Shape.Location();
01251     gp_Trsf trf = (gp_Trsf)loc;
01252     Base::Matrix4D mat;
01253     mat[0][0] = trf.Value(1,1);
01254     mat[0][1] = trf.Value(1,2);
01255     mat[0][2] = trf.Value(1,3);
01256     mat[0][3] = trf.Value(1,4);
01257     
01258     mat[1][0] = trf.Value(2,1);
01259     mat[1][1] = trf.Value(2,2);
01260     mat[1][2] = trf.Value(2,3);
01261     mat[1][3] = trf.Value(2,4);
01262     
01263     mat[2][0] = trf.Value(3,1);
01264     mat[2][1] = trf.Value(3,2);
01265     mat[2][2] = trf.Value(3,3);
01266     mat[2][3] = trf.Value(3,4);
01267     return Py::Object(new Base::MatrixPy(mat));
01268 }
01269 
01270 void TopoShapePy::setLocation(Py::Object o)
01271 {
01272     PyObject* p = o.ptr();
01273     if (PyObject_TypeCheck(p, &(Base::MatrixPy::Type))) {
01274         Base::Matrix4D mat = static_cast<Base::MatrixPy*>(p)->value();
01275         Base::Rotation rot(mat);
01276         Base::Vector3d axis;
01277         double angle;
01278         rot.getValue(axis, angle);
01279         gp_Trsf trf;
01280         trf.SetRotation(gp_Ax1(gp_Pnt(), gp_Dir(axis.x, axis.y, axis.z)), angle);
01281         trf.SetTranslationPart(gp_Vec(mat[0][3],mat[1][3],mat[2][3]));
01282         TopLoc_Location loc(trf);
01283         getTopoShapePtr()->_Shape.Location(loc);
01284     }
01285     else {
01286         std::string error = std::string("type must be 'Matrix', not ");
01287         error += p->ob_type->tp_name;
01288         throw Py::TypeError(error);
01289     }
01290 }
01291 #endif
01292 
01293 Py::String TopoShapePy::getShapeType(void) const
01294 {
01295     TopoDS_Shape sh = getTopoShapePtr()->_Shape;
01296     if (sh.IsNull())
01297         throw Py::Exception(PyExc_Exception, "cannot determine type of null shape");
01298     TopAbs_ShapeEnum type = sh.ShapeType();
01299     std::string name;
01300     switch (type)
01301     {
01302     case TopAbs_COMPOUND:
01303         name = "Compound";
01304         break;
01305     case TopAbs_COMPSOLID:
01306         name = "CompSolid";
01307         break;
01308     case TopAbs_SOLID:
01309         name = "Solid";
01310         break;
01311     case TopAbs_SHELL:
01312         name = "Shell";
01313         break;
01314     case TopAbs_FACE:
01315         name = "Face";
01316         break;
01317     case TopAbs_WIRE:
01318         name = "Wire";
01319         break;
01320     case TopAbs_EDGE:
01321         name = "Edge";
01322         break;
01323     case TopAbs_VERTEX:
01324         name = "Vertex";
01325         break;
01326     case TopAbs_SHAPE:
01327         name = "Shape";
01328         break;
01329     }
01330 
01331     return Py::String(name);
01332 }
01333 
01334 Py::String TopoShapePy::getOrientation(void) const
01335 {
01336     TopoDS_Shape sh = getTopoShapePtr()->_Shape;
01337     if (sh.IsNull())
01338         throw Py::Exception(PyExc_Exception, "cannot determine orientation of null shape");
01339     TopAbs_Orientation type = sh.Orientation();
01340     std::string name;
01341     switch (type)
01342     {
01343     case TopAbs_FORWARD:
01344         name = "Forward";
01345         break;
01346     case TopAbs_REVERSED:
01347         name = "Reversed";
01348         break;
01349     case TopAbs_INTERNAL:
01350         name = "Internal";
01351         break;
01352     case TopAbs_EXTERNAL:
01353         name = "External";
01354         break;
01355     }
01356 
01357     return Py::String(name);
01358 }
01359 
01360 void TopoShapePy::setOrientation(Py::String arg)
01361 {
01362     TopoDS_Shape& sh = getTopoShapePtr()->_Shape;
01363     if (sh.IsNull())
01364         throw Py::Exception(PyExc_Exception, "cannot determine orientation of null shape");
01365     std::string name = (std::string)arg;
01366     TopAbs_Orientation type;
01367     if (name == "Forward") {
01368         type = TopAbs_FORWARD;
01369     }
01370     else if (name == "Reversed") {
01371         type = TopAbs_REVERSED;
01372     }
01373     else if (name == "Internal") {
01374         type = TopAbs_INTERNAL;
01375     }
01376     else if (name == "External") {
01377         type = TopAbs_EXTERNAL;
01378     }
01379     else {
01380         throw Py::AttributeError("Invalid orientation type");
01381     }
01382 
01383     sh.Orientation(type);
01384 }
01385 
01386 Py::List TopoShapePy::getFaces(void) const
01387 {
01388     Py::List ret;
01389     TopTools_IndexedMapOfShape M;
01390 
01391     TopExp_Explorer Ex(getTopoShapePtr()->_Shape,TopAbs_FACE);
01392     while (Ex.More()) 
01393     {
01394         M.Add(Ex.Current());
01395         Ex.Next();
01396     }
01397 
01398     for (Standard_Integer k = 1; k <= M.Extent(); k++)
01399     {
01400         const TopoDS_Shape& shape = M(k);
01401         ret.append(Py::Object(new TopoShapeFacePy(new TopoShape(shape)),true));
01402     }
01403 
01404     return ret;
01405 }
01406 
01407 Py::List TopoShapePy::getVertexes(void) const
01408 {
01409     Py::List ret;
01410     TopTools_IndexedMapOfShape M;
01411 
01412     TopExp_Explorer Ex(getTopoShapePtr()->_Shape,TopAbs_VERTEX);
01413     while (Ex.More()) 
01414     {
01415         M.Add(Ex.Current());
01416         Ex.Next();
01417     }
01418 
01419     for (Standard_Integer k = 1; k <= M.Extent(); k++)
01420     {
01421         const TopoDS_Shape& shape = M(k);
01422         ret.append(Py::Object(new TopoShapeVertexPy(new TopoShape(shape)),true));
01423     }
01424 
01425     return ret;
01426 }
01427 
01428 Py::List TopoShapePy::getShells(void) const
01429 {
01430     Py::List ret;
01431     TopTools_IndexedMapOfShape M;
01432 
01433     TopExp_Explorer Ex(getTopoShapePtr()->_Shape,TopAbs_SHELL);
01434     while (Ex.More()) 
01435     {
01436         M.Add(Ex.Current());
01437         Ex.Next();
01438     }
01439 
01440     for (Standard_Integer k = 1; k <= M.Extent(); k++)
01441     {
01442         const TopoDS_Shape& shape = M(k);
01443         ret.append(Py::Object(new TopoShapeShellPy(new TopoShape(shape)),true));
01444     }
01445 
01446     return ret;
01447 }
01448 
01449 Py::List TopoShapePy::getSolids(void) const
01450 {
01451     Py::List ret;
01452     TopTools_IndexedMapOfShape M;
01453 
01454     TopExp_Explorer Ex(getTopoShapePtr()->_Shape,TopAbs_SOLID);
01455     while (Ex.More()) 
01456     {
01457         M.Add(Ex.Current());
01458         Ex.Next();
01459     }
01460 
01461     for (Standard_Integer k = 1; k <= M.Extent(); k++)
01462     {
01463         const TopoDS_Shape& shape = M(k);
01464         ret.append(Py::Object(new TopoShapeSolidPy(new TopoShape(shape)),true));
01465     }
01466 
01467     return ret;
01468 }
01469 
01470 Py::List TopoShapePy::getCompSolids(void) const
01471 {
01472     Py::List ret;
01473     TopTools_IndexedMapOfShape M;
01474 
01475     TopExp_Explorer Ex(getTopoShapePtr()->_Shape,TopAbs_COMPSOLID);
01476     while (Ex.More()) 
01477     {
01478         M.Add(Ex.Current());
01479         Ex.Next();
01480     }
01481 
01482     for (Standard_Integer k = 1; k <= M.Extent(); k++)
01483     {
01484         const TopoDS_Shape& shape = M(k);
01485         ret.append(Py::Object(new TopoShapeCompSolidPy(new TopoShape(shape)),true));
01486     }
01487 
01488     return ret;
01489 }
01490 
01491 Py::List TopoShapePy::getEdges(void) const
01492 {
01493     Py::List ret;
01494     TopTools_IndexedMapOfShape M;
01495 
01496     TopExp_Explorer Ex(getTopoShapePtr()->_Shape,TopAbs_EDGE);
01497     while (Ex.More()) 
01498     {
01499         M.Add(Ex.Current());
01500         Ex.Next();
01501     }
01502 
01503     for (Standard_Integer k = 1; k <= M.Extent(); k++)
01504     {
01505         const TopoDS_Shape& shape = M(k);
01506         ret.append(Py::Object(new TopoShapeEdgePy(new TopoShape(shape)),true));
01507     }
01508 
01509     return ret;
01510 }
01511 
01512 Py::List TopoShapePy::getWires(void) const
01513 {
01514     Py::List ret;
01515     TopTools_IndexedMapOfShape M;
01516 
01517     TopExp_Explorer Ex(getTopoShapePtr()->_Shape,TopAbs_WIRE);
01518     while (Ex.More())
01519     {
01520         M.Add(Ex.Current());
01521         Ex.Next();
01522     }
01523 
01524     for (Standard_Integer k = 1; k <= M.Extent(); k++)
01525     {
01526         const TopoDS_Shape& shape = M(k);
01527         ret.append(Py::Object(new TopoShapeWirePy(new TopoShape(shape)),true));
01528     }
01529 
01530     return ret;
01531 }
01532 
01533 Py::List TopoShapePy::getCompounds(void) const
01534 {
01535     Py::List ret;
01536     TopTools_IndexedMapOfShape M;
01537 
01538     TopExp_Explorer Ex(getTopoShapePtr()->_Shape,TopAbs_COMPOUND);
01539     while (Ex.More())
01540     {
01541         M.Add(Ex.Current());
01542         Ex.Next();
01543     }
01544 
01545     for (Standard_Integer k = 1; k <= M.Extent(); k++)
01546     {
01547         const TopoDS_Shape& shape = M(k);
01548         ret.append(Py::Object(new TopoShapeCompoundPy(new TopoShape(shape)),true));
01549     }
01550 
01551     return ret;
01552 }
01553 
01554 Py::Float TopoShapePy::getLength(void) const
01555 {
01556     GProp_GProps props;
01557     BRepGProp::LinearProperties(getTopoShapePtr()->_Shape, props);
01558     return Py::Float(props.Mass());
01559 }
01560 
01561 Py::Float TopoShapePy::getArea(void) const
01562 {
01563     GProp_GProps props;
01564     BRepGProp::SurfaceProperties(getTopoShapePtr()->_Shape, props);
01565     return Py::Float(props.Mass());
01566 }
01567 
01568 Py::Float TopoShapePy::getVolume(void) const
01569 {
01570     GProp_GProps props;
01571     BRepGProp::VolumeProperties(getTopoShapePtr()->_Shape, props);
01572     return Py::Float(props.Mass());
01573 }
01574 
01575 PyObject *TopoShapePy::getCustomAttributes(const char* attr) const
01576 {
01577     if (!attr) return 0;
01578     std::string name(attr);
01579     try {
01580         if (name.size() > 4 && name.substr(0,4) == "Face" && name[4]>=48 && name[4]<=57) {
01581             std::auto_ptr<Part::ShapeSegment> s(static_cast<Part::ShapeSegment*>
01582                 (getTopoShapePtr()->getSubElementByName(attr)));
01583             TopoDS_Shape Shape = s->Shape;
01584             return new TopoShapeFacePy(new TopoShape(Shape));
01585         }
01586         else if (name.size() > 4 && name.substr(0,4) == "Edge" && name[4]>=48 && name[4]<=57) {
01587             std::auto_ptr<Part::ShapeSegment> s(static_cast<Part::ShapeSegment*>
01588                 (getTopoShapePtr()->getSubElementByName(attr)));
01589             TopoDS_Shape Shape = s->Shape;
01590             return new TopoShapeEdgePy(new TopoShape(Shape));
01591         }
01592         else if (name.size() > 6 && name.substr(0,6) == "Vertex" && name[6]>=48 && name[6]<=57) {
01593             std::auto_ptr<Part::ShapeSegment> s(static_cast<Part::ShapeSegment*>
01594                 (getTopoShapePtr()->getSubElementByName(attr)));
01595             TopoDS_Shape Shape = s->Shape;
01596             return new TopoShapeVertexPy(new TopoShape(Shape));
01597         }
01598     }
01599     catch (Standard_Failure) {
01600         Handle_Standard_Failure e = Standard_Failure::Caught();
01601         PyErr_SetString(PyExc_Exception, e->GetMessageString());
01602         return 0;
01603     }
01604     return 0;
01605 }
01606 
01607 int TopoShapePy::setCustomAttributes(const char* attr, PyObject *obj)
01608 {
01609     return 0; 
01610 }

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