AppPartPy.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 #include "PreCompiled.h"
00024 #ifndef _PreComp_
00025 # include <BRepAdaptor_Curve.hxx>
00026 # include <BRepCheck_Analyzer.hxx>
00027 # include <BRepPrimAPI_MakeBox.hxx>
00028 # include <BRepPrimAPI_MakeCone.hxx>
00029 # include <BRepPrimAPI_MakeTorus.hxx>
00030 # include <BRepPrimAPI_MakeCylinder.hxx>
00031 # include <BRepPrimAPI_MakeSphere.hxx>
00032 # include <BRepPrimAPI_MakeRevolution.hxx>
00033 # include <BRepPrim_Wedge.hxx>
00034 # include <BRep_Builder.hxx>
00035 # include <BRep_Tool.hxx>
00036 # include <BRepBuilderAPI_MakeFace.hxx>
00037 # include <BRepBuilderAPI_MakeEdge.hxx>
00038 # include <BRepBuilderAPI_MakeWire.hxx>
00039 # include <BRepBuilderAPI_MakePolygon.hxx>
00040 # include <BRepBuilderAPI_MakeShell.hxx>
00041 # include <BRepBuilderAPI_MakeSolid.hxx>
00042 # include <BRepOffsetAPI_Sewing.hxx>
00043 # include <BRepFill.hxx>
00044 # include <BRepLib.hxx>
00045 # include <gp_Circ.hxx>
00046 # include <gp_Pnt.hxx>
00047 # include <gp_Lin.hxx>
00048 # include <GCE2d_MakeSegment.hxx>
00049 # include <Geom2d_Line.hxx>
00050 # include <Geom_Circle.hxx>
00051 # include <Geom_Line.hxx>
00052 # include <Geom_Plane.hxx>
00053 # include <Geom_BSplineSurface.hxx>
00054 # include <Geom_ConicalSurface.hxx>
00055 # include <Geom_CylindricalSurface.hxx>
00056 # include <Geom_OffsetSurface.hxx>
00057 # include <GeomAPI_PointsToBSplineSurface.hxx>
00058 # include <Handle_Geom_Circle.hxx>
00059 # include <Handle_Geom_Plane.hxx>
00060 # include <Handle_Geom2d_TrimmedCurve.hxx>
00061 # include <ShapeUpgrade_ShellSewing.hxx>
00062 # include <Standard_ConstructionError.hxx>
00063 # include <Standard_DomainError.hxx>
00064 # include <TopoDS.hxx>
00065 # include <TopoDS_Edge.hxx>
00066 # include <TopoDS_Face.hxx>
00067 # include <TopoDS_Wire.hxx>
00068 # include <TopoDS_Shell.hxx>
00069 # include <TopoDS_Solid.hxx>
00070 # include <TopoDS_Compound.hxx>
00071 # include <TopExp_Explorer.hxx>
00072 # include <TColgp_HArray2OfPnt.hxx>
00073 # include <TColStd_Array1OfReal.hxx>
00074 # include <TColStd_Array1OfInteger.hxx>
00075 # include <Precision.hxx>
00076 #endif
00077 
00078 #include <BRepOffsetAPI_ThruSections.hxx>
00079 #include <BSplCLib.hxx>
00080 #include <GeomFill_AppSurf.hxx>
00081 #include <GeomFill_Line.hxx>
00082 #include <GeomFill_Pipe.hxx>
00083 #include <GeomFill_SectionGenerator.hxx>
00084 #include <NCollection_List.hxx>
00085 #include <BRepFill_Filling.hxx>
00086 
00087 #include <Base/Console.h>
00088 #include <Base/PyObjectBase.h>
00089 #include <Base/Interpreter.h>
00090 #include <Base/Exception.h>
00091 #include <Base/FileInfo.h>
00092 #include <Base/GeometryPyCXX.h>
00093 #include <Base/VectorPy.h>
00094 #include <App/Application.h>
00095 #include <App/Document.h>
00096 #include <App/DocumentObjectPy.h>
00097 
00098 #include "TopoShape.h"
00099 #include "TopoShapePy.h"
00100 #include "TopoShapeEdgePy.h"
00101 #include "TopoShapeWirePy.h"
00102 #include "TopoShapeFacePy.h"
00103 #include "TopoShapeCompoundPy.h"
00104 #include "TopoShapeCompSolidPy.h"
00105 #include "TopoShapeSolidPy.h"
00106 #include "TopoShapeShellPy.h"
00107 #include "TopoShapeVertexPy.h"
00108 #include "GeometryPy.h"
00109 #include "GeometryCurvePy.h"
00110 #include "BSplineSurfacePy.h"
00111 #include "FeaturePartBox.h"
00112 #include "FeaturePartCut.h"
00113 #include "FeaturePartImportStep.h"
00114 #include "FeaturePartImportIges.h"
00115 #include "FeaturePartImportBrep.h"
00116 #include "ImportIges.h"
00117 #include "ImportStep.h"
00118 #include "edgecluster.h"
00119 
00120 using Base::Console;
00121 using namespace Part;
00122 using namespace std;
00123 
00124 extern const char* BRepBuilderAPI_FaceErrorText(BRepBuilderAPI_FaceError fe);
00125 
00126 #ifndef M_PI
00127     #define M_PI    3.14159265358979323846 /* pi */
00128 #endif
00129 
00130 #ifndef M_PI_2
00131     #define M_PI_2  1.57079632679489661923 /* pi/2 */
00132 #endif
00133 
00134 /* module functions */
00135 static PyObject * open(PyObject *self, PyObject *args)
00136 {
00137     const char* Name;
00138     if (!PyArg_ParseTuple(args, "s",&Name))
00139         return NULL;                         
00140 
00141     PY_TRY {
00142         //Base::Console().Log("Open in Part with %s",Name);
00143         Base::FileInfo file(Name);
00144 
00145         // extract ending
00146         if (file.extension() == "")
00147             Py_Error(PyExc_Exception,"no file ending");
00148 
00149         if (file.hasExtension("stp") || file.hasExtension("step")) {
00150             // create new document and add Import feature
00151             App::Document *pcDoc = App::GetApplication().newDocument("Unnamed");
00152 #if 1
00153             ImportStepParts(pcDoc,Name);
00154 #else
00155             Part::ImportStep *pcFeature = (Part::ImportStep *)pcDoc->addObject("Part::ImportStep",file.fileNamePure().c_str());
00156             pcFeature->FileName.setValue(Name);
00157 #endif 
00158             pcDoc->recompute();
00159         }
00160 #if 1
00161         else if (file.hasExtension("igs") || file.hasExtension("iges")) {
00162             App::Document *pcDoc = App::GetApplication().newDocument("Unnamed");
00163             ImportIgesParts(pcDoc,Name);
00164             pcDoc->recompute();
00165         }
00166 #endif
00167         else {
00168             try {
00169                 TopoShape shape;
00170                 shape.read(Name);
00171 
00172                 // create new document set loaded shape
00173                 App::Document *pcDoc = App::GetApplication().newDocument(file.fileNamePure().c_str());
00174                 Part::Feature *object = static_cast<Part::Feature *>(pcDoc->addObject
00175                     ("Part::Feature",file.fileNamePure().c_str()));
00176                 object->Shape.setValue(shape);
00177                 pcDoc->recompute();
00178             }
00179             catch (const Base::Exception& e) {
00180                 Py_Error(PyExc_Exception, e.what());
00181             }
00182         }
00183     } PY_CATCH;
00184 
00185     Py_Return;
00186 }
00187 
00188 /* module functions */
00189 static PyObject * insert(PyObject *self, PyObject *args)
00190 {
00191     const char* Name;
00192     const char* DocName;
00193     if (!PyArg_ParseTuple(args, "ss",&Name,&DocName))
00194         return NULL;                         
00195 
00196     PY_TRY {
00197         //Base::Console().Log("Insert in Part with %s",Name);
00198         Base::FileInfo file(Name);
00199 
00200         // extract ending
00201         if (file.extension() == "")
00202             Py_Error(PyExc_Exception,"no file ending");
00203         App::Document *pcDoc = App::GetApplication().getDocument(DocName);
00204         if (!pcDoc) {
00205             pcDoc = App::GetApplication().newDocument(DocName);
00206         }
00207 
00208         if (file.hasExtension("stp") || file.hasExtension("step")) {
00209 #if 1
00210             ImportStepParts(pcDoc,Name);
00211 #else
00212             // add Import feature
00213             Part::ImportStep *pcFeature = (Part::ImportStep *)pcDoc->addObject("Part::ImportStep",file.fileNamePure().c_str());
00214             pcFeature->FileName.setValue(Name);
00215 #endif 
00216             pcDoc->recompute();
00217         }
00218 #if 1
00219         else if (file.hasExtension("igs") || file.hasExtension("iges")) {
00220             ImportIgesParts(pcDoc,Name);
00221             pcDoc->recompute();
00222         }
00223 #endif
00224         else {
00225             try {
00226                 TopoShape shape;
00227                 shape.read(Name);
00228 
00229                 Part::Feature *object = static_cast<Part::Feature *>(pcDoc->addObject
00230                     ("Part::Feature",file.fileNamePure().c_str()));
00231                 object->Shape.setValue(shape);
00232                 pcDoc->recompute();
00233             }
00234             catch (const Base::Exception& e) {
00235                 Py_Error(PyExc_Exception, e.what());
00236             }
00237         }
00238     } PY_CATCH;
00239 
00240     Py_Return;
00241 }
00242 
00243 /* module functions */
00244 static PyObject * exporter(PyObject *self, PyObject *args)
00245 {
00246     PyObject* object;
00247     const char* filename;
00248     if (!PyArg_ParseTuple(args, "Os",&object,&filename))
00249         return NULL;
00250 
00251     BRep_Builder builder;
00252     TopoDS_Compound comp;
00253     builder.MakeCompound(comp);
00254 
00255     PY_TRY {
00256         Py::List list(object);
00257         for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
00258             PyObject* item = (*it).ptr();
00259             if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) {
00260                 App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(item)->getDocumentObjectPtr();
00261                 if (obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
00262                     Part::Feature* part = static_cast<Part::Feature*>(obj);
00263                     const TopoDS_Shape& shape = part->Shape.getValue();
00264                     if (!shape.IsNull())
00265                         builder.Add(comp, shape);
00266                 }
00267                 else {
00268                     Base::Console().Message("'%s' is not a shape, export will be ignored.\n", obj->Label.getValue());
00269                 }
00270             }
00271         }
00272     } PY_CATCH;
00273 
00274     TopoShape shape(comp);
00275     shape.write(filename);
00276 
00277     Py_Return;
00278 }
00279 
00280 /* module functions */
00281 static PyObject * read(PyObject *self, PyObject *args)
00282 {
00283     const char* Name;
00284     if (!PyArg_ParseTuple(args, "s",&Name))
00285         return NULL;                         
00286     PY_TRY {
00287         TopoShape* shape = new TopoShape();
00288         shape->read(Name);
00289         return new TopoShapePy(shape); 
00290     } PY_CATCH;
00291 }
00292 
00293 static PyObject * 
00294 show(PyObject *self, PyObject *args)
00295 {
00296     PyObject *pcObj;
00297     if (!PyArg_ParseTuple(args, "O!", &(TopoShapePy::Type), &pcObj))     // convert args: Python->C
00298         return NULL;                             // NULL triggers exception
00299 
00300     PY_TRY {
00301         App::Document *pcDoc = App::GetApplication().getActiveDocument();        
00302         if (!pcDoc)
00303             pcDoc = App::GetApplication().newDocument();
00304         TopoShapePy* pShape = static_cast<TopoShapePy*>(pcObj);
00305         Part::Feature *pcFeature = (Part::Feature *)pcDoc->addObject("Part::Feature", "Shape");
00306         // copy the data
00307         //TopoShape* shape = new MeshObject(*pShape->getTopoShapeObjectPtr());
00308         pcFeature->Shape.setValue(pShape->getTopoShapePtr()->_Shape);
00309         pcDoc->recompute();
00310     } PY_CATCH;
00311 
00312     Py_Return;
00313 }
00314 
00315 static PyObject * 
00316 makeCompound(PyObject *self, PyObject *args)
00317 {
00318     PyObject *pcObj;
00319     if (!PyArg_ParseTuple(args, "O!", &(PyList_Type), &pcObj))     // convert args: Python->C
00320         return NULL;                             // NULL triggers exception
00321 
00322     PY_TRY {
00323         BRep_Builder builder;
00324         TopoDS_Compound Comp;
00325         builder.MakeCompound(Comp);
00326         
00327         try {
00328             Py::List list(pcObj);
00329             for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
00330                 if (PyObject_TypeCheck((*it).ptr(), &(Part::TopoShapePy::Type))) {
00331                     const TopoDS_Shape& sh = static_cast<TopoShapePy*>((*it).ptr())->
00332                         getTopoShapePtr()->_Shape;
00333                     if (!sh.IsNull())
00334                         builder.Add(Comp, sh);
00335                 }
00336             }
00337         }
00338         catch (Standard_Failure) {
00339             Handle_Standard_Failure e = Standard_Failure::Caught();
00340             PyErr_SetString(PyExc_Exception, e->GetMessageString());
00341             return 0;
00342         }
00343 
00344         return new TopoShapeCompoundPy(new TopoShape(Comp));
00345     } PY_CATCH;
00346 }
00347 
00348 static PyObject * makeFilledFace(PyObject *self, PyObject *args)
00349 {
00350     // http://opencascade.blogspot.com/2010/03/surface-modeling-part6.html
00351     // TODO: GeomPlate_BuildPlateSurface
00352     PyObject *obj;
00353     if (!PyArg_ParseTuple(args, "O!", &(PyList_Type), &obj))
00354         return NULL;
00355 
00356     PY_TRY {
00357         BRepFill_Filling builder;
00358         
00359         try {
00360             Py::List list(obj);
00361             for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
00362                 if (PyObject_TypeCheck((*it).ptr(), &(Part::TopoShapeEdgePy::Type))) {
00363                     const TopoDS_Shape& sh = static_cast<TopoShapeEdgePy*>((*it).ptr())->
00364                         getTopoShapePtr()->_Shape;
00365                     if (!sh.IsNull())
00366                         builder.Add(TopoDS::Edge(sh), GeomAbs_C0);
00367                 }
00368             }
00369 
00370             builder.Build();
00371             if (builder.IsDone()) {
00372                 return new TopoShapeFacePy(new TopoShape(builder.Face()));
00373             }
00374             else {
00375                 PyErr_SetString(PyExc_Exception, "Failed to created face by filling edges");
00376                 return 0;
00377             }
00378         }
00379         catch (Standard_Failure) {
00380             Handle_Standard_Failure e = Standard_Failure::Caught();
00381             PyErr_SetString(PyExc_Exception, e->GetMessageString());
00382             return 0;
00383         }
00384     } PY_CATCH;
00385 }
00386 
00387 static PyObject * makeShell(PyObject *self, PyObject *args)
00388 {
00389     PyObject *obj;
00390     if (!PyArg_ParseTuple(args, "O!", &(PyList_Type), &obj))
00391         return NULL;
00392 
00393     PY_TRY {
00394         BRep_Builder builder;
00395         TopoDS_Shape shape;
00396         TopoDS_Shell shell;
00397         //BRepOffsetAPI_Sewing mkShell;
00398         builder.MakeShell(shell);
00399         
00400         try {
00401             Py::List list(obj);
00402             for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
00403                 if (PyObject_TypeCheck((*it).ptr(), &(Part::TopoShapeFacePy::Type))) {
00404                     const TopoDS_Shape& sh = static_cast<TopoShapeFacePy*>((*it).ptr())->
00405                         getTopoShapePtr()->_Shape;
00406                     if (!sh.IsNull())
00407                         builder.Add(shell, sh);
00408                 }
00409             }
00410 
00411             shape = shell;
00412             BRepCheck_Analyzer check(shell);
00413             if (!check.IsValid()) {
00414                 ShapeUpgrade_ShellSewing sewShell;
00415                 shape = sewShell.ApplySewing(shell);
00416             }
00417         }
00418         catch (Standard_Failure) {
00419             Handle_Standard_Failure e = Standard_Failure::Caught();
00420             PyErr_SetString(PyExc_Exception, e->GetMessageString());
00421             return 0;
00422         }
00423 
00424         return new TopoShapeShellPy(new TopoShape(shape));
00425     } PY_CATCH;
00426 }
00427 
00428 static PyObject * makeSolid(PyObject *self, PyObject *args)
00429 {
00430     PyObject *obj;
00431     if (!PyArg_ParseTuple(args, "O!", &(TopoShapePy::Type), &obj))
00432         return NULL;
00433 
00434     try {
00435         BRepBuilderAPI_MakeSolid mkSolid;
00436         const TopoDS_Shape& shape = static_cast<TopoShapePy*>(obj)
00437             ->getTopoShapePtr()->_Shape;
00438         TopExp_Explorer anExp (shape, TopAbs_SHELL);
00439         int count=0;
00440         for (; anExp.More(); anExp.Next()) {
00441             ++count;
00442             mkSolid.Add(TopoDS::Shell(anExp.Current()));
00443         }
00444 
00445         if (count == 0)
00446             Standard_Failure::Raise("No shells found in shape");
00447 
00448         const TopoDS_Solid& solid = mkSolid.Solid();
00449         return new TopoShapeSolidPy(new TopoShape(solid));
00450     }
00451     catch (Standard_Failure) {
00452         PyErr_SetString(PyExc_Exception, "creation of solid failed");
00453         return NULL;
00454     }
00455 }
00456 
00457 static PyObject * makePlane(PyObject *self, PyObject *args)
00458 {
00459     double length, width;
00460     PyObject *pPnt=0, *pDir=0;
00461     if (!PyArg_ParseTuple(args, "dd|O!O!", &length, &width,
00462                                            &(Base::VectorPy::Type), &pPnt,
00463                                            &(Base::VectorPy::Type), &pDir))
00464         return NULL;
00465 
00466     if (length < Precision::Confusion()) {
00467         PyErr_SetString(PyExc_Exception, "length of plane too small");
00468         return NULL;
00469     }
00470     if (width < Precision::Confusion()) {
00471         PyErr_SetString(PyExc_Exception, "width of plane too small");
00472         return NULL;
00473     }
00474 
00475     try {
00476         gp_Pnt p(0,0,0);
00477         gp_Dir d(0,0,1);
00478         if (pPnt) {
00479             Base::Vector3d pnt = static_cast<Base::VectorPy*>(pPnt)->value();
00480             p.SetCoord(pnt.x, pnt.y, pnt.z);
00481         }
00482         if (pDir) {
00483             Base::Vector3d vec = static_cast<Base::VectorPy*>(pDir)->value();
00484             d.SetCoord(vec.x, vec.y, vec.z);
00485         }
00486         Handle_Geom_Plane aPlane = new Geom_Plane(p, d);
00487         BRepBuilderAPI_MakeFace Face(aPlane, 0.0, length, 0.0, width);
00488         return new TopoShapeFacePy(new TopoShape((Face.Face()))); 
00489     }
00490     catch (Standard_DomainError) {
00491         PyErr_SetString(PyExc_Exception, "creation of plane failed");
00492         return NULL;
00493     }
00494 }
00495 
00496 static PyObject * makeBox(PyObject *self, PyObject *args)
00497 {
00498     double length, width, height;
00499     PyObject *pPnt=0, *pDir=0;
00500     if (!PyArg_ParseTuple(args, "ddd|O!O!", &length, &width, &height,
00501                                             &(Base::VectorPy::Type), &pPnt,
00502                                             &(Base::VectorPy::Type), &pDir))
00503         return NULL;
00504 
00505     if (length < Precision::Confusion()) {
00506         PyErr_SetString(PyExc_Exception, "length of box too small");
00507         return NULL;
00508     }
00509     if (width < Precision::Confusion()) {
00510         PyErr_SetString(PyExc_Exception, "width of box too small");
00511         return NULL;
00512     }
00513     if (height < Precision::Confusion()) {
00514         PyErr_SetString(PyExc_Exception, "height of box too small");
00515         return NULL;
00516     }
00517 
00518     try {
00519         gp_Pnt p(0,0,0);
00520         gp_Dir d(0,0,1);
00521         if (pPnt) {
00522             Base::Vector3d pnt = static_cast<Base::VectorPy*>(pPnt)->value();
00523             p.SetCoord(pnt.x, pnt.y, pnt.z);
00524         }
00525         if (pDir) {
00526             Base::Vector3d vec = static_cast<Base::VectorPy*>(pDir)->value();
00527             d.SetCoord(vec.x, vec.y, vec.z);
00528         }
00529         BRepPrimAPI_MakeBox mkBox(gp_Ax2(p,d), length, width, height);
00530         TopoDS_Shape ResultShape = mkBox.Shape();
00531         return new TopoShapeSolidPy(new TopoShape(ResultShape)); 
00532     }
00533     catch (Standard_DomainError) {
00534         PyErr_SetString(PyExc_Exception, "creation of box failed");
00535         return NULL;
00536     }
00537 }
00538 
00539 static PyObject * makeWedge(PyObject *self, PyObject *args)
00540 {
00541     double xmin, ymin, zmin, z2min, x2min, xmax, ymax, zmax, z2max, x2max;
00542     PyObject *pPnt=0, *pDir=0;
00543     if (!PyArg_ParseTuple(args, "dddddddddd|O!O!",
00544         &xmin, &ymin, &zmin, &z2min, &x2min, &xmax, &ymax, &zmax, &z2max, &x2max,
00545         &(Base::VectorPy::Type), &pPnt, &(Base::VectorPy::Type), &pDir))
00546         return NULL;
00547 
00548     double dx = xmax-xmin;
00549     double dy = ymax-ymin;
00550     double dz = zmax-zmin;
00551     double dz2 = z2max-z2min;
00552     double dx2 = x2max-x2min;
00553     if (dx < Precision::Confusion()) {
00554         PyErr_SetString(PyExc_Exception, "delta x of wedge too small");
00555         return NULL;
00556     }
00557     if (dy < Precision::Confusion()) {
00558         PyErr_SetString(PyExc_Exception, "delta y of wedge too small");
00559         return NULL;
00560     }
00561     if (dz < Precision::Confusion()) {
00562         PyErr_SetString(PyExc_Exception, "delta z of wedge too small");
00563         return NULL;
00564     }
00565     if (dz2 < 0) {
00566         PyErr_SetString(PyExc_Exception, "delta z2 of wedge is negative");
00567         return NULL;
00568     }
00569     if (dx2 < 0) {
00570         PyErr_SetString(PyExc_Exception, "delta x2 of wedge is negative");
00571         return NULL;
00572     }
00573 
00574     try {
00575         gp_Pnt p(0,0,0);
00576         gp_Dir d(0,0,1);
00577         if (pPnt) {
00578             Base::Vector3d pnt = static_cast<Base::VectorPy*>(pPnt)->value();
00579             p.SetCoord(pnt.x, pnt.y, pnt.z);
00580         }
00581         if (pDir) {
00582             Base::Vector3d vec = static_cast<Base::VectorPy*>(pDir)->value();
00583             d.SetCoord(vec.x, vec.y, vec.z);
00584         }
00585         BRepPrim_Wedge mkWedge(gp_Ax2(p,d), xmin, ymin, zmin, z2min, x2min, xmax, ymax, zmax, z2max, x2max);
00586         TopoDS_Shape resultShape = mkWedge.Shell();
00587         return new TopoShapeShellPy(new TopoShape(resultShape)); 
00588     }
00589     catch (Standard_DomainError) {
00590         PyErr_SetString(PyExc_Exception, "creation of wedge failed");
00591         return NULL;
00592     }
00593 }
00594 
00595 static PyObject * makeCircle(PyObject *self, PyObject *args)
00596 {
00597     double radius, angle1=0.0, angle2=360;
00598     PyObject *pPnt=0, *pDir=0;
00599     if (!PyArg_ParseTuple(args, "d|O!O!dd", &radius,
00600                                             &(Base::VectorPy::Type), &pPnt,
00601                                             &(Base::VectorPy::Type), &pDir,
00602                                             &angle1, &angle2))
00603         return NULL;
00604 
00605     try {
00606         gp_Pnt loc(0,0,0);
00607         gp_Dir dir(0,0,1);
00608         if (pPnt) {
00609             Base::Vector3d pnt = static_cast<Base::VectorPy*>(pPnt)->value();
00610             loc.SetCoord(pnt.x, pnt.y, pnt.z);
00611         }
00612         if (pDir) {
00613             Base::Vector3d vec = static_cast<Base::VectorPy*>(pDir)->value();
00614             dir.SetCoord(vec.x, vec.y, vec.z);
00615         }
00616         gp_Ax1 axis(loc, dir);
00617         gp_Circ circle;
00618         circle.SetAxis(axis);
00619         circle.SetRadius(radius);
00620 
00621         Handle_Geom_Circle hCircle = new Geom_Circle (circle);
00622         BRepBuilderAPI_MakeEdge aMakeEdge(hCircle, angle1*(M_PI/180), angle2*(M_PI/180));
00623         TopoDS_Edge edge = aMakeEdge.Edge();
00624         return new TopoShapeEdgePy(new TopoShape(edge)); 
00625     }
00626     catch (Standard_Failure) {
00627         PyErr_SetString(PyExc_Exception, "creation of circle failed");
00628         return NULL;
00629     }
00630 }
00631 
00632 static PyObject * makeSphere(PyObject *self, PyObject *args)
00633 {
00634     double radius, angle1=-90, angle2=90, angle3=360;
00635     PyObject *pPnt=0, *pDir=0;
00636     if (!PyArg_ParseTuple(args, "d|O!O!ddd", &radius,
00637                                              &(Base::VectorPy::Type), &pPnt,
00638                                              &(Base::VectorPy::Type), &pDir,
00639                                              &angle1, &angle2, &angle3))
00640         return NULL;
00641 
00642     try {
00643         gp_Pnt p(0,0,0);
00644         gp_Dir d(0,0,1);
00645         if (pPnt) {
00646             Base::Vector3d pnt = static_cast<Base::VectorPy*>(pPnt)->value();
00647             p.SetCoord(pnt.x, pnt.y, pnt.z);
00648         }
00649         if (pDir) {
00650             Base::Vector3d vec = static_cast<Base::VectorPy*>(pDir)->value();
00651             d.SetCoord(vec.x, vec.y, vec.z);
00652         }
00653         BRepPrimAPI_MakeSphere mkSphere(gp_Ax2(p,d), radius, angle1*(M_PI/180), angle2*(M_PI/180), angle3*(M_PI/180));
00654         TopoDS_Shape shape = mkSphere.Shape();
00655         return new TopoShapeSolidPy(new TopoShape(shape));
00656     }
00657     catch (Standard_DomainError) {
00658         PyErr_SetString(PyExc_Exception, "creation of sphere failed");
00659         return NULL;
00660     }
00661 }
00662 
00663 static PyObject * makeCylinder(PyObject *self, PyObject *args)
00664 {
00665     double radius, height, angle=360;
00666     PyObject *pPnt=0, *pDir=0;
00667     if (!PyArg_ParseTuple(args, "dd|O!O!d", &radius, &height,
00668                                             &(Base::VectorPy::Type), &pPnt,
00669                                             &(Base::VectorPy::Type), &pDir,
00670                                             &angle))
00671         return NULL;
00672 
00673     try {
00674         gp_Pnt p(0,0,0);
00675         gp_Dir d(0,0,1);
00676         if (pPnt) {
00677             Base::Vector3d pnt = static_cast<Base::VectorPy*>(pPnt)->value();
00678             p.SetCoord(pnt.x, pnt.y, pnt.z);
00679         }
00680         if (pDir) {
00681             Base::Vector3d vec = static_cast<Base::VectorPy*>(pDir)->value();
00682             d.SetCoord(vec.x, vec.y, vec.z);
00683         }
00684         BRepPrimAPI_MakeCylinder mkCyl(gp_Ax2(p,d),radius, height, angle*(M_PI/180));
00685         TopoDS_Shape shape = mkCyl.Shape();
00686         return new TopoShapeSolidPy(new TopoShape(shape));
00687     }
00688     catch (Standard_DomainError) {
00689         PyErr_SetString(PyExc_Exception, "creation of cylinder failed");
00690         return NULL;
00691     }
00692 }
00693 
00694 static PyObject * makeCone(PyObject *self, PyObject *args)
00695 {
00696     double radius1, radius2,  height, angle=360;
00697     PyObject *pPnt=0, *pDir=0;
00698     if (!PyArg_ParseTuple(args, "ddd|O!O!d", &radius1, &radius2, &height,
00699                                              &(Base::VectorPy::Type), &pPnt,
00700                                              &(Base::VectorPy::Type), &pDir,
00701                                              &angle))
00702         return NULL;
00703 
00704     try {
00705         gp_Pnt p(0,0,0);
00706         gp_Dir d(0,0,1);
00707         if (pPnt) {
00708             Base::Vector3d pnt = static_cast<Base::VectorPy*>(pPnt)->value();
00709             p.SetCoord(pnt.x, pnt.y, pnt.z);
00710         }
00711         if (pDir) {
00712             Base::Vector3d vec = static_cast<Base::VectorPy*>(pDir)->value();
00713             d.SetCoord(vec.x, vec.y, vec.z);
00714         }
00715         BRepPrimAPI_MakeCone mkCone(gp_Ax2(p,d),radius1, radius2, height, angle*(M_PI/180));
00716         TopoDS_Shape shape = mkCone.Shape();
00717         return new TopoShapeSolidPy(new TopoShape(shape));
00718     }
00719     catch (Standard_DomainError) {
00720         PyErr_SetString(PyExc_Exception, "creation of cone failed");
00721         return NULL;
00722     }
00723 }
00724 
00725 static PyObject * makeTorus(PyObject *self, PyObject *args)
00726 {
00727     double radius1, radius2, angle1=0.0, angle2=360, angle=360;
00728     PyObject *pPnt=0, *pDir=0;
00729     if (!PyArg_ParseTuple(args, "dd|O!O!ddd", &radius1, &radius2,
00730                                               &(Base::VectorPy::Type), &pPnt,
00731                                               &(Base::VectorPy::Type), &pDir,
00732                                               &angle1, &angle2, &angle))
00733         return NULL;
00734 
00735     try {
00736         gp_Pnt p(0,0,0);
00737         gp_Dir d(0,0,1);
00738         if (pPnt) {
00739             Base::Vector3d pnt = static_cast<Base::VectorPy*>(pPnt)->value();
00740             p.SetCoord(pnt.x, pnt.y, pnt.z);
00741         }
00742         if (pDir) {
00743             Base::Vector3d vec = static_cast<Base::VectorPy*>(pDir)->value();
00744             d.SetCoord(vec.x, vec.y, vec.z);
00745         }
00746         BRepPrimAPI_MakeTorus mkTorus(gp_Ax2(p,d), radius1, radius2, angle1*(M_PI/180), angle2*(M_PI/180), angle*(M_PI/180));
00747         const TopoDS_Shape& shape = mkTorus.Shape();
00748         return new TopoShapeSolidPy(new TopoShape(shape));
00749     }
00750     catch (Standard_DomainError) {
00751         PyErr_SetString(PyExc_Exception, "creation of torus failed");
00752         return NULL;
00753     }
00754 }
00755 
00756 static PyObject * makeHelix(PyObject *self, PyObject *args)
00757 {
00758     double pitch, height, radius, angle=-1.0;
00759     if (!PyArg_ParseTuple(args, "ddd|d", &pitch, &height, &radius, &angle))
00760         return 0;
00761 
00762     try {
00763         TopoShape helix;
00764         TopoDS_Shape wire = helix.makeHelix(pitch, height, radius, angle);
00765         return new TopoShapeWirePy(new TopoShape(wire));
00766     }
00767     catch (Standard_Failure) {
00768         Handle_Standard_Failure e = Standard_Failure::Caught();
00769         PyErr_SetString(PyExc_Exception, e->GetMessageString());
00770         return 0;
00771     }
00772 }
00773 
00774 static PyObject * makeLine(PyObject *self, PyObject *args)
00775 {
00776     PyObject *obj1, *obj2;
00777     if (!PyArg_ParseTuple(args, "OO", &obj1, &obj2))
00778         return NULL;
00779 
00780     Base::Vector3d pnt1, pnt2;
00781     if (PyObject_TypeCheck(obj1, &(Base::VectorPy::Type))) {
00782         pnt1 = static_cast<Base::VectorPy*>(obj1)->value();
00783     }
00784     else if (PyObject_TypeCheck(obj1, &PyTuple_Type)) {
00785         try {
00786             pnt1 = Base::getVectorFromTuple<double>(obj1);
00787         }
00788         catch (const Py::Exception&) {
00789             return NULL;
00790         }
00791     }
00792     else {
00793         PyErr_SetString(PyExc_TypeError, "first argument must either be vector or tuple");
00794         return 0;
00795     }
00796     if (PyObject_TypeCheck(obj2, &(Base::VectorPy::Type))) {
00797         pnt2 = static_cast<Base::VectorPy*>(obj2)->value();
00798     }
00799     else if (PyObject_TypeCheck(obj2, &PyTuple_Type)) {
00800         try {
00801             pnt2 = Base::getVectorFromTuple<double>(obj2);
00802         }
00803         catch (const Py::Exception&) {
00804             return NULL;
00805         }
00806     }
00807     else {
00808         PyErr_SetString(PyExc_TypeError, "second argument must either be vector or tuple");
00809         return 0;
00810     }
00811 
00812     // Create directly the underlying line geometry
00813     BRepBuilderAPI_MakeEdge makeEdge(gp_Pnt(pnt1.x, pnt1.y, pnt1.z),
00814                                      gp_Pnt(pnt2.x, pnt2.y, pnt2.z));
00815 
00816     const char *error=0;
00817     switch (makeEdge.Error())
00818     {
00819     case BRepBuilderAPI_EdgeDone:
00820         break; // ok
00821     case BRepBuilderAPI_PointProjectionFailed:
00822         error = "Point projection failed";
00823         break;
00824     case BRepBuilderAPI_ParameterOutOfRange:
00825         error = "Parameter out of range";
00826         break;
00827     case BRepBuilderAPI_DifferentPointsOnClosedCurve:
00828         error = "Different points on closed curve";
00829         break;
00830     case BRepBuilderAPI_PointWithInfiniteParameter:
00831         error = "Point with infinite parameter";
00832         break;
00833     case BRepBuilderAPI_DifferentsPointAndParameter:
00834         error = "Different point and parameter";
00835         break;
00836     case BRepBuilderAPI_LineThroughIdenticPoints:
00837         error = "Line through identic points";
00838         break;
00839     }
00840     // Error 
00841     if (error) {
00842         PyErr_SetString(PyExc_RuntimeError, error);
00843         return NULL;
00844     }
00845 
00846     TopoDS_Edge edge = makeEdge.Edge();
00847     return new TopoShapeEdgePy(new TopoShape(edge)); 
00848 }
00849 
00850 static PyObject * makePolygon(PyObject *self, PyObject *args)
00851 {
00852     PyObject *pcObj;
00853     if (!PyArg_ParseTuple(args, "O!", &(PyList_Type), &pcObj))     // convert args: Python->C
00854         return NULL;                             // NULL triggers exception
00855 
00856     PY_TRY {
00857         BRepBuilderAPI_MakePolygon mkPoly;
00858         try {
00859             Py::List list(pcObj);
00860             for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
00861                 if (PyObject_TypeCheck((*it).ptr(), &(Base::VectorPy::Type))) {
00862                     Base::Vector3d v = static_cast<Base::VectorPy*>((*it).ptr())->value();
00863                     mkPoly.Add(gp_Pnt(v.x,v.y,v.z));
00864                 }
00865                 else if (PyObject_TypeCheck((*it).ptr(), &PyTuple_Type)) {
00866                     try {
00867                         Base::Vector3d v = Base::getVectorFromTuple<double>((*it).ptr());
00868                         mkPoly.Add(gp_Pnt(v.x,v.y,v.z));
00869                     }
00870                     catch (const Py::Exception&) {
00871                         return 0;
00872                     }
00873                 }
00874             }
00875 
00876             if (!mkPoly.IsDone())
00877                 Standard_Failure::Raise("Cannot create polygon because less than two vetices are given");
00878 
00879             return new TopoShapeWirePy(new TopoShape(mkPoly.Wire()));
00880         }
00881         catch (Standard_Failure) {
00882             Handle_Standard_Failure e = Standard_Failure::Caught();
00883             PyErr_SetString(PyExc_Exception, e->GetMessageString());
00884             return 0;
00885         }
00886     } PY_CATCH;
00887 }
00888 
00889 static PyObject * makeRevolution(PyObject *self, PyObject *args)
00890 {
00891     double vmin = DBL_MAX, vmax=-DBL_MAX;
00892     double angle=360;
00893     PyObject *pPnt=0, *pDir=0, *pCrv;
00894     Handle_Geom_Curve curve;
00895     if (PyArg_ParseTuple(args, "O!|dddO!O!", &(GeometryPy::Type), &pCrv,
00896                                              &vmin, &vmax, &angle,
00897                                              &(Base::VectorPy::Type), &pPnt,
00898                                              &(Base::VectorPy::Type), &pDir)) {
00899         GeometryPy* pcGeo = static_cast<GeometryPy*>(pCrv);
00900         curve = Handle_Geom_Curve::DownCast
00901             (pcGeo->getGeometryPtr()->handle());
00902         if (curve.IsNull()) {
00903             PyErr_SetString(PyExc_TypeError, "geometry is not a curve");
00904             return 0;
00905         }
00906         if (vmin == DBL_MAX)
00907             vmin = curve->FirstParameter();
00908 
00909         if (vmax == -DBL_MAX)
00910             vmax = curve->LastParameter();
00911     }
00912     else {
00913         PyErr_Clear();
00914         if (!PyArg_ParseTuple(args, "O!|dddO!O!", &(TopoShapePy::Type), &pCrv,
00915             &vmin, &vmax, &angle, &(Base::VectorPy::Type), &pPnt,
00916             &(Base::VectorPy::Type), &pDir)) {
00917             return 0;
00918         }
00919         const TopoDS_Shape& shape = static_cast<TopoShapePy*>(pCrv)->getTopoShapePtr()->_Shape;
00920         if (shape.IsNull()) {
00921             PyErr_SetString(PyExc_Exception, "shape is empty");
00922             return 0;
00923         }
00924 
00925         if (shape.ShapeType() != TopAbs_EDGE) {
00926             PyErr_SetString(PyExc_Exception, "shape is not an edge");
00927             return 0;
00928         }
00929 
00930         const TopoDS_Edge& edge = TopoDS::Edge(shape);
00931         BRepAdaptor_Curve adapt(edge);
00932 
00933         const Handle_Geom_Curve& hCurve = adapt.Curve().Curve();
00934         // Apply placement of the shape to the curve
00935         TopLoc_Location loc = edge.Location();
00936         curve = Handle_Geom_Curve::DownCast(hCurve->Transformed(loc.Transformation()));
00937         if (curve.IsNull()) {
00938             PyErr_SetString(PyExc_Exception, "invalid curve in edge");
00939             return 0;
00940         }
00941 
00942         if (vmin == DBL_MAX)
00943             vmin = adapt.FirstParameter();
00944         if (vmax == -DBL_MAX)
00945             vmax = adapt.LastParameter();
00946     }
00947 
00948     try {
00949         gp_Pnt p(0,0,0);
00950         gp_Dir d(0,0,1);
00951         if (pPnt) {
00952             Base::Vector3d pnt = static_cast<Base::VectorPy*>(pPnt)->value();
00953             p.SetCoord(pnt.x, pnt.y, pnt.z);
00954         }
00955         if (pDir) {
00956             Base::Vector3d vec = static_cast<Base::VectorPy*>(pDir)->value();
00957             d.SetCoord(vec.x, vec.y, vec.z);
00958         }
00959         BRepPrimAPI_MakeRevolution mkRev(gp_Ax2(p,d),curve, vmin, vmax, angle*(M_PI/180));
00960         TopoDS_Shape shape = mkRev.Solid();
00961         return new TopoShapeSolidPy(new TopoShape(shape));
00962     }
00963     catch (Standard_DomainError) {
00964         PyErr_SetString(PyExc_Exception, "creation of revolved shape failed");
00965         return NULL;
00966     }
00967 }
00968 
00969 static PyObject * makeRuledSurface(PyObject *self, PyObject *args)
00970 {
00971     // http://opencascade.blogspot.com/2009/10/surface-modeling-part1.html
00972     PyObject *sh1, *sh2;
00973     if (!PyArg_ParseTuple(args, "O!O!", &(TopoShapePy::Type), &sh1,
00974                                         &(TopoShapePy::Type), &sh2))
00975         return 0;
00976 
00977     const TopoDS_Shape& shape1 = static_cast<TopoShapePy*>(sh1)->getTopoShapePtr()->_Shape;
00978     const TopoDS_Shape& shape2 = static_cast<TopoShapePy*>(sh2)->getTopoShapePtr()->_Shape;
00979 
00980     try {
00981         if (shape1.ShapeType() == TopAbs_EDGE && shape2.ShapeType() == TopAbs_EDGE) {
00982             TopoDS_Face face = BRepFill::Face(TopoDS::Edge(shape1), TopoDS::Edge(shape2));
00983             return new TopoShapeFacePy(new TopoShape(face));
00984         }
00985         else if (shape1.ShapeType() == TopAbs_WIRE && shape2.ShapeType() == TopAbs_WIRE) {
00986             TopoDS_Shell shell = BRepFill::Shell(TopoDS::Wire(shape1), TopoDS::Wire(shape2));
00987             return new TopoShapeShellPy(new TopoShape(shell));
00988         }
00989         else {
00990             PyErr_SetString(PyExc_Exception, "curves must either be edges or wires");
00991             return 0;
00992         }
00993     }
00994     catch (Standard_Failure) {
00995         PyErr_SetString(PyExc_Exception, "creation of ruled surface failed");
00996         return 0;
00997     }
00998 }
00999 
01000 static PyObject * makeSweepSurface(PyObject *self, PyObject *args)
01001 {
01002     PyObject *path, *profile;
01003     double tolerance=0.001;
01004     int fillMode = 0;
01005 
01006     // Path + profile
01007     if (!PyArg_ParseTuple(args, "O!O!|di", &(TopoShapePy::Type), &path,
01008                                            &(TopoShapePy::Type), &profile,
01009                                            &tolerance, &fillMode))
01010         return 0;
01011 
01012     try {
01013         const TopoDS_Shape& path_shape = static_cast<TopoShapePy*>(path)->getTopoShapePtr()->_Shape;
01014         const TopoDS_Shape& prof_shape = static_cast<TopoShapePy*>(profile)->getTopoShapePtr()->_Shape;
01015 
01016         TopoShape myShape(path_shape);
01017         TopoDS_Shape face = myShape.makeSweep(prof_shape, tolerance, fillMode);
01018         return new TopoShapeFacePy(new TopoShape(face));
01019     }
01020     catch (Standard_Failure) {
01021         Handle_Standard_Failure e = Standard_Failure::Caught();
01022         PyErr_SetString(PyExc_Exception, e->GetMessageString());
01023         return 0;
01024     }
01025 }
01026 
01027 static PyObject * makeTube(PyObject *self, PyObject *args)
01028 {
01029     PyObject *pshape;
01030     double radius;
01031     double tolerance=0.001;
01032 
01033     // Path + radius
01034     if (!PyArg_ParseTuple(args, "O!d", &(TopoShapePy::Type), &pshape, &radius))
01035         return 0;
01036     try {
01037         const TopoDS_Shape& path_shape = static_cast<TopoShapePy*>(pshape)->getTopoShapePtr()->_Shape;
01038         TopoShape myShape(path_shape);
01039         TopoDS_Shape face = myShape.makeTube(radius, tolerance);
01040         return new TopoShapeFacePy(new TopoShape(face));
01041     }
01042     catch (Standard_Failure) {
01043         Handle_Standard_Failure e = Standard_Failure::Caught();
01044         PyErr_SetString(PyExc_Exception, e->GetMessageString());
01045         return 0;
01046     }
01047 }
01048 
01049 static PyObject * makeLoft(PyObject *self, PyObject *args)
01050 {
01051 #if 0
01052     PyObject *pcObj;
01053     if (!PyArg_ParseTuple(args, "O!", &(PyList_Type), &pcObj))     // convert args: Python->C
01054         return NULL;                             // NULL triggers exception
01055 
01056     NCollection_List<Handle_Geom_Curve> theSections;
01057     Py::List list(pcObj);
01058     for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
01059         if (PyObject_TypeCheck((*it).ptr(), &(Part::GeometryCurvePy::Type))) {
01060             Handle_Geom_Curve hCurve = Handle_Geom_Curve::DownCast(
01061                 static_cast<GeometryCurvePy*>((*it).ptr())->getGeomCurvePtr()->handle());
01062             theSections.Append(hCurve);
01063         }
01064     }
01065 
01066     //populate section generator
01067     GeomFill_SectionGenerator aSecGenerator;
01068     for (NCollection_List<Handle_Geom_Curve>::Iterator anIt(theSections); anIt.More(); anIt.Next()) {
01069         const Handle_Geom_Curve& aCurve = anIt.Value();
01070         aSecGenerator.AddCurve (aCurve);
01071     }
01072     aSecGenerator.Perform (Precision::PConfusion());
01073 
01074     Handle_GeomFill_Line aLine = new GeomFill_Line (theSections.Size());
01075 
01076     //parameters
01077     const Standard_Integer aMinDeg = 1, aMaxDeg = BSplCLib::MaxDegree(), aNbIt = 0;
01078     Standard_Real aTol3d = 1e-4, aTol2d = Precision::Parametric (aTol3d);
01079 
01080     //algorithm
01081     GeomFill_AppSurf anAlgo (aMinDeg, aMaxDeg, aTol3d, aTol2d, aNbIt);
01082     anAlgo.Perform (aLine, aSecGenerator);
01083 
01084     if (!anAlgo.IsDone()) {
01085         PyErr_SetString(PyExc_Exception, "Failed to create loft surface");
01086         return 0;
01087     }
01088 
01089     Handle_Geom_BSplineSurface aRes;
01090     aRes = new Geom_BSplineSurface(anAlgo.SurfPoles(), anAlgo.SurfWeights(),
01091         anAlgo.SurfUKnots(), anAlgo.SurfVKnots(), anAlgo.SurfUMults(), anAlgo.SurfVMults(),
01092         anAlgo.UDegree(), anAlgo.VDegree());
01093     return new BSplineSurfacePy(new GeomBSplineSurface(aRes));
01094 #else
01095     PyObject *pcObj;
01096     PyObject *psolid=0;
01097     PyObject *pruled=0;
01098     if (!PyArg_ParseTuple(args, "O!|O!O!", &(PyList_Type), &pcObj,
01099                                            &(PyBool_Type), &psolid,
01100                                            &(PyBool_Type), &pruled))
01101         return NULL;
01102 
01103     try {
01104         TopTools_ListOfShape profiles;
01105         Py::List list(pcObj);
01106         for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
01107             if (PyObject_TypeCheck((*it).ptr(), &(Part::TopoShapePy::Type))) {
01108                 const TopoDS_Shape& sh = static_cast<TopoShapePy*>((*it).ptr())->
01109                     getTopoShapePtr()->_Shape;
01110                 profiles.Append(sh);
01111             }
01112         }
01113 
01114         TopoShape myShape;
01115         Standard_Boolean anIsSolid = (psolid == Py_True) ? Standard_True : Standard_False;
01116         Standard_Boolean anIsRuled = (pruled == Py_True) ? Standard_True : Standard_False;
01117         TopoDS_Shape aResult = myShape.makeLoft(profiles, anIsSolid, anIsRuled);
01118         return new TopoShapePy(new TopoShape(aResult));
01119     }
01120     catch (Standard_Failure) {
01121         Handle_Standard_Failure e = Standard_Failure::Caught();
01122         PyErr_SetString(PyExc_Exception, e->GetMessageString());
01123         return 0;
01124     }
01125 #endif
01126 }
01127 
01128 static PyObject * toPythonOCC(PyObject *self, PyObject *args)
01129 {
01130     PyObject *pcObj;
01131     if (!PyArg_ParseTuple(args, "O!", &(TopoShapePy::Type), &pcObj))
01132         return NULL;
01133 
01134     try {
01135         TopoDS_Shape* shape = new TopoDS_Shape();
01136         (*shape) = static_cast<TopoShapePy*>(pcObj)->getTopoShapePtr()->_Shape;
01137         PyObject* proxy = 0;
01138         proxy = Base::Interpreter().createSWIGPointerObj("OCC.TopoDS", "TopoDS_Shape *", (void*)shape, 1);
01139         return proxy;
01140     }
01141     catch (const Base::Exception& e) {
01142         PyErr_SetString(PyExc_Exception, e.what());
01143         return NULL;
01144     }
01145 }
01146 
01147 static PyObject * fromPythonOCC(PyObject *self, PyObject *args)
01148 {
01149     PyObject *proxy;
01150     if (!PyArg_ParseTuple(args, "O", &proxy))
01151         return NULL;
01152 
01153     void* ptr;
01154     try {
01155         TopoShape* shape = new TopoShape();
01156         Base::Interpreter().convertSWIGPointerObj("OCC.TopoDS","TopoDS_Shape *", proxy, &ptr, 0);
01157         TopoDS_Shape* s = reinterpret_cast<TopoDS_Shape*>(ptr);
01158         shape->_Shape = (*s);
01159         return new TopoShapePy(shape);
01160     }
01161     catch (const Base::Exception& e) {
01162         PyErr_SetString(PyExc_Exception, e.what());
01163         return NULL;
01164     }
01165 }
01166 
01167 namespace Part {
01168 struct EdgePoints {
01169     gp_Pnt v1, v2;
01170     TopoDS_Edge edge;
01171 };
01172 
01173 static std::list<TopoDS_Edge> sort_Edges(double tol3d, const std::vector<TopoDS_Edge>& edges)
01174 {
01175     tol3d = tol3d * tol3d;
01176     std::list<EdgePoints>  edge_points;
01177     TopExp_Explorer xp;
01178     for (std::vector<TopoDS_Edge>::const_iterator it = edges.begin(); it != edges.end(); ++it) {
01179         EdgePoints ep;
01180         xp.Init(*it,TopAbs_VERTEX);
01181         ep.v1 = BRep_Tool::Pnt(TopoDS::Vertex(xp.Current()));
01182         xp.Next();
01183         ep.v2 = BRep_Tool::Pnt(TopoDS::Vertex(xp.Current()));
01184         ep.edge = *it;
01185         edge_points.push_back(ep);
01186     }
01187 
01188     if (edge_points.empty())
01189         return std::list<TopoDS_Edge>();
01190 
01191     std::list<TopoDS_Edge> sorted;
01192     gp_Pnt first, last;
01193     first = edge_points.front().v1;
01194     last  = edge_points.front().v2;
01195 
01196     sorted.push_back(edge_points.front().edge);
01197     edge_points.erase(edge_points.begin());
01198 
01199     while (!edge_points.empty()) {
01200         // search for adjacent edge
01201         std::list<EdgePoints>::iterator pEI;
01202         for (pEI = edge_points.begin(); pEI != edge_points.end(); ++pEI) {
01203             if (pEI->v1.SquareDistance(last) <= tol3d) {
01204                 last = pEI->v2;
01205                 sorted.push_back(pEI->edge);
01206                 edge_points.erase(pEI);
01207                 break;
01208             }
01209             else if (pEI->v2.SquareDistance(first) <= tol3d) {
01210                 first = pEI->v1;
01211                 sorted.push_front(pEI->edge);
01212                 edge_points.erase(pEI);
01213                 break;
01214             }
01215             else if (pEI->v2.SquareDistance(last) <= tol3d) {
01216                 last = pEI->v1;
01217                 sorted.push_back(pEI->edge);
01218                 edge_points.erase(pEI);
01219                 break;
01220             }
01221             else if (pEI->v1.SquareDistance(first) <= tol3d) {
01222                 first = pEI->v2;
01223                 sorted.push_front(pEI->edge);
01224                 edge_points.erase(pEI);
01225                 break;
01226             }
01227         }
01228 
01229         if ((pEI == edge_points.end()) || (last.SquareDistance(first) <= tol3d)) {
01230             // no adjacent edge found or polyline is closed
01231             return sorted;
01232             /*
01233             rclBorders.push_back(std::vector<TopoDS_Edge>(sorted.begin(), sorted.end()));
01234             sorted.clear();
01235 
01236             if (!edge_points.empty()) {
01237                 // new wire
01238                 first = edge_points.front()->v1;
01239                 last  = edge_points.front()->v2;
01240                 sorted.push_back(edge_points.front().edge);
01241                 edge_points.erase(edge_points.begin());
01242             }*/
01243         }
01244     }
01245 
01246     return sorted;
01247 }
01248 }
01249 
01250 static PyObject * getSortedClusters(PyObject *self, PyObject *args)
01251 {
01252     PyObject *obj;
01253     if (!PyArg_ParseTuple(args, "O!", &(PyList_Type), &obj)) {
01254         PyErr_SetString(PyExc_Exception, "list of edges expected");
01255         return 0;
01256     }
01257 
01258     Py::List list(obj);
01259     std::vector<TopoDS_Edge> edges;
01260     for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
01261         PyObject* item = (*it).ptr();
01262         if (PyObject_TypeCheck(item, &(Part::TopoShapePy::Type))) {
01263             const TopoDS_Shape& sh = static_cast<Part::TopoShapePy*>(item)->getTopoShapePtr()->_Shape;
01264             if (sh.ShapeType() == TopAbs_EDGE)
01265                 edges.push_back(TopoDS::Edge(sh));
01266             else {
01267                 PyErr_SetString(PyExc_TypeError, "shape is not an edge");
01268                 return 0;
01269             }
01270         }
01271         else {
01272             PyErr_SetString(PyExc_TypeError, "item is not a shape");
01273             return 0;
01274         }
01275     }
01276 
01277     Edgecluster acluster(edges);
01278     tEdgeClusterVector aclusteroutput = acluster.GetClusters();
01279 
01280     Py::List root_list;
01281     for (tEdgeClusterVector::iterator it=aclusteroutput.begin(); it != aclusteroutput.end();++it) {
01282         Py::List add_list;
01283         for (tEdgeVector::iterator it1=(*it).begin();it1 != (*it).end();++it1) {
01284             add_list.append(Py::Object(new TopoShapeEdgePy(new TopoShape(*it1)),true));
01285         }
01286         root_list.append(add_list);
01287     }
01288 
01289     return Py::new_reference_to(root_list);
01290 }
01291 
01292 
01293 static PyObject * sortEdges(PyObject *self, PyObject *args)
01294 {
01295     PyObject *obj;
01296     if (!PyArg_ParseTuple(args, "O!", &(PyList_Type), &obj)) {
01297         PyErr_SetString(PyExc_Exception, "list of edges expected");
01298         return 0;
01299     }
01300 
01301 
01302     Py::List list(obj);
01303     std::vector<TopoDS_Edge> edges;
01304     for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
01305         PyObject* item = (*it).ptr();
01306         if (PyObject_TypeCheck(item, &(Part::TopoShapePy::Type))) {
01307             const TopoDS_Shape& sh = static_cast<Part::TopoShapePy*>(item)->getTopoShapePtr()->_Shape;
01308             if (sh.ShapeType() == TopAbs_EDGE)
01309                 edges.push_back(TopoDS::Edge(sh));
01310             else {
01311                 PyErr_SetString(PyExc_TypeError, "shape is not an edge");
01312                 return 0;
01313             }
01314         }
01315         else {
01316             PyErr_SetString(PyExc_TypeError, "item is not a shape");
01317             return 0;
01318         }
01319     }
01320 
01321     std::list<TopoDS_Edge> sorted = sort_Edges(Precision::Confusion(), edges);
01322 
01323     Py::List sorted_list;
01324     for (std::list<TopoDS_Edge>::iterator it = sorted.begin(); it != sorted.end(); ++it) {
01325         sorted_list.append(Py::Object(new TopoShapeEdgePy(new TopoShape(*it)),true));
01326     }
01327 
01328     return Py::new_reference_to(sorted_list);
01329 }
01330 
01331 static PyObject * cast_to_shape(PyObject *self, PyObject *args)
01332 {
01333     PyObject *object;
01334     if (PyArg_ParseTuple(args,"O!",&(Part::TopoShapePy::Type), &object)) {
01335         TopoShape* ptr = static_cast<TopoShapePy*>(object)->getTopoShapePtr();
01336         TopoDS_Shape shape = ptr->_Shape;
01337         if (!shape.IsNull()) {
01338             TopAbs_ShapeEnum type = shape.ShapeType();
01339             switch (type)
01340             {
01341             case TopAbs_COMPOUND:
01342                 return new TopoShapeCompoundPy(new TopoShape(shape));
01343             case TopAbs_COMPSOLID:
01344                 return new TopoShapeCompSolidPy(new TopoShape(shape));
01345             case TopAbs_SOLID:
01346                 return new TopoShapeSolidPy(new TopoShape(shape));
01347             case TopAbs_SHELL:
01348                 return new TopoShapeShellPy(new TopoShape(shape));
01349             case TopAbs_FACE:
01350                 return new TopoShapeFacePy(new TopoShape(shape));
01351             case TopAbs_WIRE:
01352                 return new TopoShapeWirePy(new TopoShape(shape));
01353             case TopAbs_EDGE:
01354                 return new TopoShapeEdgePy(new TopoShape(shape));
01355             case TopAbs_VERTEX:
01356                 return new TopoShapeVertexPy(new TopoShape(shape));
01357             case TopAbs_SHAPE:
01358                 return new TopoShapePy(new TopoShape(shape));
01359             default:
01360                 break;
01361             }
01362         }
01363         else {
01364             PyErr_SetString(PyExc_Exception, "empty shape");
01365         }
01366     }
01367 
01368     return 0;
01369 }
01370 
01371 /* registration table  */
01372 struct PyMethodDef Part_methods[] = {
01373     {"open"       ,open      ,METH_VARARGS,
01374      "open(string) -- Create a new document and load the file into the document."},
01375 
01376     {"insert"     ,insert    ,METH_VARARGS,
01377      "insert(string,string) -- Insert the file into the given document."},
01378 
01379     {"export"     ,exporter  ,METH_VARARGS,
01380      "export(list,string) -- Export a list of objects into a single file."},
01381 
01382     {"read"       ,read      ,METH_VARARGS,
01383      "read(string) -- Load the file and return the shape."},
01384 
01385     {"show"       ,show      ,METH_VARARGS,
01386      "show(shape) -- Add the shape to the active document or create one if no document exists."},
01387 
01388     {"makeCompound"  ,makeCompound ,METH_VARARGS,
01389      "makeCompound(list) -- Create a compound out of a list of shapes."},
01390 
01391     {"makeShell"  ,makeShell ,METH_VARARGS,
01392      "makeShell(list) -- Create a shell out of a list of faces."},
01393 
01394     {"makeFilledFace"  ,makeFilledFace ,METH_VARARGS,
01395      "makeFilledFace(list) -- Create a face out of a list of edges."},
01396 
01397     {"makeSolid"  ,makeSolid ,METH_VARARGS,
01398      "makeSolid(shape) -- Create a solid out of the shells inside a shape."},
01399 
01400     {"makePlane"  ,makePlane ,METH_VARARGS,
01401      "makePlane(length,width,[pnt,dir]) -- Make a plane\n"
01402      "By default pnt=Vector(0,0,0) and dir=Vector(0,0,1)"},
01403 
01404     {"makeBox"    ,makeBox ,METH_VARARGS,
01405      "makeBox(length,width,height,[pnt,dir]) -- Make a box located\n"
01406      "in pnt with the dimensions (length,width,height)\n"
01407      "By default pnt=Vector(0,0,0) and dir=Vector(0,0,1)"},
01408 
01409     {"makeWedge"    ,makeWedge ,METH_VARARGS,
01410      "makeWedge(xmin, ymin, zmin, z2min, x2min,\n"
01411      "xmax, ymax, zmax, z2max, x2max,[pnt,dir])\n"
01412      " -- Make a wedge located in pnt\n"
01413      "By default pnt=Vector(0,0,0) and dir=Vector(0,0,1)"},
01414 
01415     {"makeLine"   ,makeLine  ,METH_VARARGS,
01416      "makeLine((x1,y1,z1),(x2,y2,z2)) -- Make a line of two points"},
01417 
01418     {"makePolygon"   ,makePolygon  ,METH_VARARGS,
01419      "makePolygon(list) -- Make a polygon of a list of points"},
01420 
01421     {"makeCircle" ,makeCircle,METH_VARARGS,
01422      "makeCircle(radius,[pnt,dir,angle1,angle2]) -- Make a circle with a given radius\n"
01423      "By default pnt=Vector(0,0,0), dir=Vector(0,0,1), angle1=0 and angle2=360"},
01424 
01425     {"makeSphere" ,makeSphere,METH_VARARGS,
01426      "makeSphere(radius,[pnt, dir, angle1,angle2,angle3]) -- Make a sphere with a given radius\n"
01427      "By default pnt=Vector(0,0,0), dir=Vector(0,0,1), angle1=0, angle2=90 and angle3=360"},
01428 
01429     {"makeCylinder" ,makeCylinder,METH_VARARGS,
01430      "makeCylinder(radius,height,[pnt,dir,angle]) -- Make a cylinder with a given radius and height\n"
01431      "By default pnt=Vector(0,0,0),dir=Vector(0,0,1) and angle=360"},
01432 
01433     {"makeCone" ,makeCone,METH_VARARGS,
01434      "makeCone(radius1,radius2,height,[pnt,dir,angle]) -- Make a cone with given radii and height\n"
01435      "By default pnt=Vector(0,0,0), dir=Vector(0,0,1) and angle=360"},
01436 
01437     {"makeTorus" ,makeTorus,METH_VARARGS,
01438      "makeTorus(radius1,radius2,[pnt,dir,angle1,angle2,angle]) -- Make a torus with a given radii and angles\n"
01439      "By default pnt=Vector(0,0,0),dir=Vector(0,0,1),angle1=0,angle1=360 and angle=360"},
01440 
01441     {"makeHelix" ,makeHelix,METH_VARARGS,
01442      "makeHelix(pitch,height,radius,[angle]) -- Make a helix with a given pitch, height and radius\n"
01443      "By default a cylindrical surface is used to create the helix. If the fourth parameter is set\n"
01444      "(the apex given in degree) a conical surface is used instead"},
01445 
01446     {"makeRevolution" ,makeRevolution,METH_VARARGS,
01447      "makeRevolution(Curve,[vmin,vmax,angle,pnt,dir]) -- Make a revolved shape\n"
01448      "by rotating the curve or a portion of it around an axis given by (pnt,dir).\n"
01449      "By default vmin/vmax=bounds of the curve,angle=360,pnt=Vector(0,0,0) and\n"
01450      "dir=Vector(0,0,1)"},
01451 
01452     {"makeRuledSurface" ,makeRuledSurface,METH_VARARGS,
01453      "makeRuledSurface(Edge|Wire,Edge|Wire) -- Make a ruled surface\n"
01454      "Create a ruled surface out of two edges or wires. If wires are used then"
01455      "these must have the same number of edges."},
01456 
01457     {"makeTube" ,makeTube,METH_VARARGS,
01458      "makeTube(edge,float) -- Create a tube."},
01459 
01460     {"makeSweepSurface" ,makeSweepSurface,METH_VARARGS,
01461      "makeSweepSurface(edge(path),edge(profile),[float]) -- Create a profile along a path."},
01462 
01463     {"makeLoft" ,makeLoft,METH_VARARGS,
01464      "makeLoft(list of wires) -- Create a loft shape."},
01465 
01466     {"cast_to_shape" ,cast_to_shape,METH_VARARGS,
01467      "cast_to_shape(shape) -- Cast to the actual shape type"},
01468 
01469     {"getSortedClusters" ,getSortedClusters,METH_VARARGS,
01470     "getSortedClusters(list of edges) -- Helper method to sort and cluster a variety of edges"},
01471 
01472     {"__sortEdges__" ,sortEdges,METH_VARARGS,
01473      "__sortEdges__(list of edges) -- Helper method to sort an unsorted list of edges so that afterwards\n"
01474      "two adjacent edges share a common vertex"},
01475 
01476     {"__toPythonOCC__" ,toPythonOCC,METH_VARARGS,
01477      "__toPythonOCC__(shape) -- Helper method to convert an internal shape to pythonocc shape"},
01478 
01479     {"__fromPythonOCC__" ,fromPythonOCC,METH_VARARGS,
01480      "__fromPythonOCC__(occ) -- Helper method to convert a pythonocc shape to an internal shape"},
01481     {NULL, NULL}        /* end of table marker */
01482 };

Generated on Wed Nov 23 18:59:56 2011 for FreeCAD by  doxygen 1.6.1