00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00128 #endif
00129
00130 #ifndef M_PI_2
00131 #define M_PI_2 1.57079632679489661923
00132 #endif
00133
00134
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
00143 Base::FileInfo file(Name);
00144
00145
00146 if (file.extension() == "")
00147 Py_Error(PyExc_Exception,"no file ending");
00148
00149 if (file.hasExtension("stp") || file.hasExtension("step")) {
00150
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
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
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
00198 Base::FileInfo file(Name);
00199
00200
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
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
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
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))
00298 return NULL;
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
00307
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))
00320 return NULL;
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
00351
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
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
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;
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
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))
00854 return NULL;
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
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
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
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
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))
01054 return NULL;
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
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
01077 const Standard_Integer aMinDeg = 1, aMaxDeg = BSplCLib::MaxDegree(), aNbIt = 0;
01078 Standard_Real aTol3d = 1e-4, aTol2d = Precision::Parametric (aTol3d);
01079
01080
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
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
01231 return sorted;
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
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
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}
01482 };