/*************************************************************************** * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2008 * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ***************************************************************************/ #include "PreCompiled.h" #ifndef _PreComp_ # include # include # include # include # include # include # include # include # include # include # include # include # include #if OCC_VERSION_HEX >= 0x060801 # include #endif # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include "TopoShape.h" #include #include #include "OCCError.h" #include #include #include #include #include #include #include #include #include using namespace Part; #ifndef M_PI #define M_PI 3.14159265358979323846 /* pi */ #endif #ifndef M_PI_2 #define M_PI_2 1.57079632679489661923 /* pi/2 */ #endif namespace Py { typedef ExtensionObject TopoShape; template<> bool TopoShape::accepts (PyObject *pyob) const { return (pyob && PyObject_TypeCheck(pyob, &(Part::TopoShapePy::Type))); } } // returns a string which represents the object e.g. when printed in python std::string TopoShapePy::representation(void) const { std::stringstream str; str << ""; return str.str(); } PyObject *TopoShapePy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper { // create a new instance of TopoShapePy and the Twin object return new TopoShapePy(new TopoShape); } int TopoShapePy::PyInit(PyObject* args, PyObject*) { PyObject *pcObj=0; if (!PyArg_ParseTuple(args, "|O", &pcObj)) return -1; if (pcObj) { TopoShape shape; try { Py::Sequence list(pcObj); bool first = true; for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { if (PyObject_TypeCheck((*it).ptr(), &(Part::GeometryPy::Type))) { TopoDS_Shape sh = static_cast((*it).ptr())-> getGeometryPtr()->toShape(); if (first) { first = false; shape.setShape(sh); } else { shape.setShape(shape.fuse(sh)); } } } } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return -1; } getTopoShapePtr()->setShape(shape.getShape()); } return 0; } //common code.. maybe put somewhere else? Py::Object shape2pyshape(const TopoDS_Shape &shape) { PyObject* ret = 0; if (!shape.IsNull()) { TopAbs_ShapeEnum type = shape.ShapeType(); switch (type) { case TopAbs_COMPOUND: ret = new TopoShapeCompoundPy(new TopoShape(shape)); break; case TopAbs_COMPSOLID: ret = new TopoShapeCompSolidPy(new TopoShape(shape)); break; case TopAbs_SOLID: ret = new TopoShapeSolidPy(new TopoShape(shape)); break; case TopAbs_SHELL: ret = new TopoShapeShellPy(new TopoShape(shape)); break; case TopAbs_FACE: ret = new TopoShapeFacePy(new TopoShape(shape)); break; case TopAbs_WIRE: ret = new TopoShapeWirePy(new TopoShape(shape)); break; case TopAbs_EDGE: ret = new TopoShapeEdgePy(new TopoShape(shape)); break; case TopAbs_VERTEX: ret = new TopoShapeVertexPy(new TopoShape(shape)); break; case TopAbs_SHAPE: ret = new TopoShapePy(new TopoShape(shape)); break; default: //shouldn't happen ret = new TopoShapePy(new TopoShape(shape)); break; } } else { ret = new TopoShapePy(new TopoShape(shape)); } assert(ret); return Py::asObject(ret); } PyObject* TopoShapePy::copy(PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; const TopoDS_Shape& shape = this->getTopoShapePtr()->getShape(); PyTypeObject* type = this->GetType(); PyObject* cpy = 0; // let the type object decide if (type->tp_new) cpy = type->tp_new(type, this, 0); if (!cpy) { PyErr_SetString(PyExc_TypeError, "failed to create copy of shape"); return 0; } if (!shape.IsNull()) { BRepBuilderAPI_Copy c(shape); static_cast(cpy)->getTopoShapePtr()->setShape(c.Shape()); } return cpy; } PyObject* TopoShapePy::cleaned(PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; const TopoDS_Shape& shape = this->getTopoShapePtr()->getShape(); PyTypeObject* type = this->GetType(); PyObject* cpy = 0; // let the type object decide if (type->tp_new) cpy = type->tp_new(type, this, 0); if (!cpy) { PyErr_SetString(PyExc_TypeError, "failed to create copy of shape"); return 0; } if (!shape.IsNull()) { BRepBuilderAPI_Copy c(shape); const TopoDS_Shape& copiedShape = c.Shape(); BRepTools::Clean(copiedShape); // remove triangulation static_cast(cpy)->getTopoShapePtr()->setShape(c.Shape()); } return cpy; } PyObject* TopoShapePy::replaceShape(PyObject *args) { PyObject *l; if (!PyArg_ParseTuple(args, "O",&l)) return NULL; try { Py::Sequence list(l); std::vector< std::pair > shapes; for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { Py::Tuple tuple(*it); Py::TopoShape sh1(tuple[0]); Py::TopoShape sh2(tuple[1]); shapes.push_back(std::make_pair( sh1.extensionObject()->getTopoShapePtr()->getShape(), sh2.extensionObject()->getTopoShapePtr()->getShape()) ); } PyTypeObject* type = this->GetType(); PyObject* inst = type->tp_new(type, this, 0); static_cast(inst)->getTopoShapePtr()->setShape (this->getTopoShapePtr()->replaceShape(shapes)); return inst; } catch (const Py::Exception&) { return 0; } catch (...) { PyErr_SetString(PartExceptionOCCError, "failed to replace shape"); return 0; } } PyObject* TopoShapePy::removeShape(PyObject *args) { PyObject *l; if (!PyArg_ParseTuple(args, "O",&l)) return NULL; try { Py::Sequence list(l); std::vector shapes; for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { Py::TopoShape sh(*it); shapes.push_back( sh.extensionObject()->getTopoShapePtr()->getShape() ); } PyTypeObject* type = this->GetType(); PyObject* inst = type->tp_new(type, this, 0); static_cast(inst)->getTopoShapePtr()->setShape (this->getTopoShapePtr()->removeShape(shapes)); return inst; } catch (...) { PyErr_SetString(PartExceptionOCCError, "failed to remove shape"); return 0; } } PyObject* TopoShapePy::read(PyObject *args) { char* Name; if (!PyArg_ParseTuple(args, "et","utf-8",&Name)) return NULL; std::string EncodedName = std::string(Name); PyMem_Free(Name); getTopoShapePtr()->read(EncodedName.c_str()); Py_Return; } PyObject* TopoShapePy::writeInventor(PyObject * args) { double dev=0.3, angle=0.4; int mode=2; if (!PyArg_ParseTuple(args, "|idd", &mode,&dev,&angle)) return NULL; std::stringstream result; BRepMesh_IncrementalMesh(getTopoShapePtr()->getShape(),dev); if (mode == 0) getTopoShapePtr()->exportFaceSet(dev, angle, result); else if (mode == 1) getTopoShapePtr()->exportLineSet(result); else { getTopoShapePtr()->exportFaceSet(dev, angle, result); getTopoShapePtr()->exportLineSet(result); } // NOTE: Cleaning the triangulation may cause problems on some algorithms like BOP //BRepTools::Clean(getTopoShapePtr()->getShape()); // remove triangulation return Py::new_reference_to(Py::String(result.str())); } PyObject* TopoShapePy::exportIges(PyObject *args) { char* Name; if (!PyArg_ParseTuple(args, "et","utf-8",&Name)) return NULL; std::string EncodedName = std::string(Name); PyMem_Free(Name); try { // write iges file getTopoShapePtr()->exportIges(EncodedName.c_str()); } catch (const Base::Exception& e) { PyErr_SetString(PartExceptionOCCError,e.what()); return NULL; } Py_Return; } PyObject* TopoShapePy::exportStep(PyObject *args) { char* Name; if (!PyArg_ParseTuple(args, "et","utf-8",&Name)) return NULL; std::string EncodedName = std::string(Name); PyMem_Free(Name); try { // write step file getTopoShapePtr()->exportStep(EncodedName.c_str()); } catch (const Base::Exception& e) { PyErr_SetString(PartExceptionOCCError,e.what()); return NULL; } Py_Return; } PyObject* TopoShapePy::exportBrep(PyObject *args) { char* Name; if (PyArg_ParseTuple(args, "et","utf-8",&Name)) { std::string EncodedName = std::string(Name); PyMem_Free(Name); try { // write brep file getTopoShapePtr()->exportBrep(EncodedName.c_str()); } catch (const Base::Exception& e) { PyErr_SetString(PartExceptionOCCError,e.what()); return NULL; } Py_Return; } PyErr_Clear(); PyObject* input; if (PyArg_ParseTuple(args, "O", &input)) { try { // write brep Base::PyStreambuf buf(input); std::ostream str(0); str.rdbuf(&buf); getTopoShapePtr()->exportBrep(str); } catch (const Base::Exception& e) { PyErr_SetString(PartExceptionOCCError,e.what()); return NULL; } Py_Return; } PyErr_SetString(PyExc_TypeError, "expect string or file object"); return NULL; } PyObject* TopoShapePy::exportBinary(PyObject *args) { char* input; if (!PyArg_ParseTuple(args, "s", &input)) return NULL; try { // read binary brep std::ofstream str(input, std::ios::out | std::ios::binary); getTopoShapePtr()->exportBinary(str); str.close(); } catch (const Base::Exception& e) { PyErr_SetString(PartExceptionOCCError,e.what()); return NULL; } Py_Return; } PyObject* TopoShapePy::dumpToString(PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; try { std::stringstream str; getTopoShapePtr()->dump(str); return Py::new_reference_to(Py::String(str.str())); } catch (const Base::Exception& e) { PyErr_SetString(PartExceptionOCCError,e.what()); return NULL; } catch (const std::exception& e) { PyErr_SetString(PartExceptionOCCError,e.what()); return NULL; } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return 0; } } PyObject* TopoShapePy::exportBrepToString(PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; try { // write brep file std::stringstream str; getTopoShapePtr()->exportBrep(str); return Py::new_reference_to(Py::String(str.str())); } catch (const Base::Exception& e) { PyErr_SetString(PartExceptionOCCError,e.what()); return NULL; } catch (const std::exception& e) { PyErr_SetString(PartExceptionOCCError,e.what()); return NULL; } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return 0; } } PyObject* TopoShapePy::importBrep(PyObject *args) { char* Name; if (PyArg_ParseTuple(args, "et","utf-8",&Name)) { std::string EncodedName = std::string(Name); PyMem_Free(Name); try { // write brep file getTopoShapePtr()->importBrep(EncodedName.c_str()); } catch (const Base::Exception& e) { PyErr_SetString(PartExceptionOCCError,e.what()); return NULL; } Py_Return; } PyErr_Clear(); PyObject* input; if (PyArg_ParseTuple(args, "O", &input)) { try { // read brep Base::PyStreambuf buf(input); std::istream str(0); str.rdbuf(&buf); getTopoShapePtr()->importBrep(str); } catch (const Base::Exception& e) { PyErr_SetString(PartExceptionOCCError,e.what()); return NULL; } Py_Return; } PyErr_SetString(PyExc_TypeError, "expect string or file object"); return NULL; } PyObject* TopoShapePy::importBinary(PyObject *args) { char* input; if (!PyArg_ParseTuple(args, "s", &input)) return NULL; try { // read binary brep std::ifstream str(input, std::ios::in | std::ios::binary); getTopoShapePtr()->importBinary(str); str.close(); } catch (const Base::Exception& e) { PyErr_SetString(PartExceptionOCCError,e.what()); return NULL; } Py_Return; } PyObject* TopoShapePy::importBrepFromString(PyObject *args) { char* input; if (!PyArg_ParseTuple(args, "s", &input)) return NULL; try { // read brep std::stringstream str(input); getTopoShapePtr()->importBrep(str); } catch (const Base::Exception& e) { PyErr_SetString(PartExceptionOCCError,e.what()); return NULL; } catch (const std::exception& e) { PyErr_SetString(PartExceptionOCCError,e.what()); return NULL; } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return 0; } Py_Return; } PyObject* TopoShapePy::__getstate__(PyObject *args) { return exportBrepToString(args); } PyObject* TopoShapePy::__setstate__(PyObject *args) { if (! getTopoShapePtr()) { PyErr_SetString(Base::BaseExceptionFreeCADError,"no c++ object"); return 0; } else { return importBrepFromString(args); } } PyObject* TopoShapePy::exportStl(PyObject *args) { double deflection = 0; char* Name; if (!PyArg_ParseTuple(args, "et|d","utf-8",&Name,&deflection)) return NULL; std::string EncodedName = std::string(Name); PyMem_Free(Name); try { // write stl file getTopoShapePtr()->exportStl(EncodedName.c_str(), deflection); } catch (const Base::Exception& e) { PyErr_SetString(PartExceptionOCCError,e.what()); return 0; } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return 0; } Py_Return; } PyObject* TopoShapePy::extrude(PyObject *args) { PyObject *pVec; if (PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type), &pVec)) { try { Base::Vector3d vec = static_cast(pVec)->value(); TopoDS_Shape shape = this->getTopoShapePtr()->makePrism(gp_Vec(vec.x,vec.y,vec.z)); TopAbs_ShapeEnum type = shape.ShapeType(); switch (type) { case TopAbs_COMPOUND: return new TopoShapeCompoundPy(new TopoShape(shape)); case TopAbs_COMPSOLID: return new TopoShapeCompSolidPy(new TopoShape(shape)); case TopAbs_SOLID: return new TopoShapeSolidPy(new TopoShape(shape)); case TopAbs_SHELL: return new TopoShapeShellPy(new TopoShape(shape)); case TopAbs_FACE: return new TopoShapeFacePy(new TopoShape(shape)); case TopAbs_WIRE: break; case TopAbs_EDGE: return new TopoShapeEdgePy(new TopoShape(shape)); case TopAbs_VERTEX: break; case TopAbs_SHAPE: break; default: break; } PyErr_SetString(PartExceptionOCCError, "extrusion for this shape type not supported"); return 0; } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return 0; } } return 0; } PyObject* TopoShapePy::revolve(PyObject *args) { PyObject *pPos,*pDir; double d=360; if (PyArg_ParseTuple(args, "O!O!|d", &(Base::VectorPy::Type), &pPos, &(Base::VectorPy::Type), &pDir,&d)) { try { const TopoDS_Shape& input = this->getTopoShapePtr()->getShape(); if (input.IsNull()) { PyErr_SetString(PartExceptionOCCError, "empty shape cannot be revolved"); return 0; } TopExp_Explorer xp; xp.Init(input,TopAbs_SOLID); if (xp.More()) { PyErr_SetString(PartExceptionOCCError, "shape must not contain solids"); return 0; } xp.Init(input,TopAbs_COMPSOLID); if (xp.More()) { PyErr_SetString(PartExceptionOCCError, "shape must not contain compound solids"); return 0; } Base::Vector3d pos = static_cast(pPos)->value(); Base::Vector3d dir = static_cast(pDir)->value(); TopoDS_Shape shape = this->getTopoShapePtr()->revolve( gp_Ax1(gp_Pnt(pos.x,pos.y,pos.z), gp_Dir(dir.x,dir.y,dir.z)),d*(M_PI/180)); TopAbs_ShapeEnum type = shape.ShapeType(); switch (type) { case TopAbs_COMPOUND: return new TopoShapeCompoundPy(new TopoShape(shape)); case TopAbs_COMPSOLID: return new TopoShapeCompSolidPy(new TopoShape(shape)); case TopAbs_SOLID: return new TopoShapeSolidPy(new TopoShape(shape)); case TopAbs_SHELL: return new TopoShapeShellPy(new TopoShape(shape)); case TopAbs_FACE: return new TopoShapeFacePy(new TopoShape(shape)); case TopAbs_WIRE: break; case TopAbs_EDGE: return new TopoShapeEdgePy(new TopoShape(shape)); case TopAbs_VERTEX: break; case TopAbs_SHAPE: break; default: break; } PyErr_SetString(PartExceptionOCCError, "revolution for this shape type not supported"); return 0; } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return 0; } } return 0; } PyObject* TopoShapePy::check(PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; if (!getTopoShapePtr()->getShape().IsNull()) { std::stringstream str; if (!getTopoShapePtr()->analyze(str)) { PyErr_SetString(PyExc_StandardError, str.str().c_str()); PyErr_Print(); } } Py_Return; } PyObject* TopoShapePy::fuse(PyObject *args) { PyObject *pcObj; if (!PyArg_ParseTuple(args, "O!", &(TopoShapePy::Type), &pcObj)) return NULL; TopoDS_Shape shape = static_cast(pcObj)->getTopoShapePtr()->getShape(); try { // Let's call algorithm computing a fuse operation: TopoDS_Shape fusShape = this->getTopoShapePtr()->fuse(shape); return new TopoShapePy(new TopoShape(fusShape)); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } catch (const std::exception& e) { PyErr_SetString(PartExceptionOCCError, e.what()); return NULL; } } PyObject* TopoShapePy::multiFuse(PyObject *args) { double tolerance = 0.0; PyObject *pcObj; if (!PyArg_ParseTuple(args, "O|d", &pcObj, &tolerance)) return NULL; std::vector shapeVec; Py::Sequence shapeSeq(pcObj); for (Py::Sequence::iterator it = shapeSeq.begin(); it != shapeSeq.end(); ++it) { PyObject* item = (*it).ptr(); if (PyObject_TypeCheck(item, &(Part::TopoShapePy::Type))) { shapeVec.push_back(static_cast(item)->getTopoShapePtr()->getShape()); } else { PyErr_SetString(PyExc_TypeError, "non-shape object in sequence"); return 0; } } try { TopoDS_Shape multiFusedShape = this->getTopoShapePtr()->multiFuse(shapeVec,tolerance); return new TopoShapePy(new TopoShape(multiFusedShape)); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } catch (const std::exception& e) { PyErr_SetString(PartExceptionOCCError, e.what()); return NULL; } } PyObject* TopoShapePy::oldFuse(PyObject *args) { PyObject *pcObj; if (!PyArg_ParseTuple(args, "O!", &(TopoShapePy::Type), &pcObj)) return NULL; TopoDS_Shape shape = static_cast(pcObj)->getTopoShapePtr()->getShape(); try { // Let's call algorithm computing a fuse operation: TopoDS_Shape fusShape = this->getTopoShapePtr()->oldFuse(shape); return new TopoShapePy(new TopoShape(fusShape)); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } catch (const std::exception& e) { PyErr_SetString(PartExceptionOCCError, e.what()); return NULL; } } PyObject* TopoShapePy::common(PyObject *args) { PyObject *pcObj; if (!PyArg_ParseTuple(args, "O!", &(TopoShapePy::Type), &pcObj)) return NULL; TopoDS_Shape shape = static_cast(pcObj)->getTopoShapePtr()->getShape(); try { // Let's call algorithm computing a common operation: TopoDS_Shape comShape = this->getTopoShapePtr()->common(shape); return new TopoShapePy(new TopoShape(comShape)); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } catch (const std::exception& e) { PyErr_SetString(PartExceptionOCCError, e.what()); return NULL; } } PyObject* TopoShapePy::section(PyObject *args) { PyObject *pcObj; if (!PyArg_ParseTuple(args, "O!", &(TopoShapePy::Type), &pcObj)) return NULL; TopoDS_Shape shape = static_cast(pcObj)->getTopoShapePtr()->getShape(); try { // Let's call algorithm computing a section operation: TopoDS_Shape secShape = this->getTopoShapePtr()->section(shape); return new TopoShapePy(new TopoShape(secShape)); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } catch (const std::exception& e) { PyErr_SetString(PartExceptionOCCError, e.what()); return NULL; } } PyObject* TopoShapePy::slice(PyObject *args) { PyObject *dir; double d; if (!PyArg_ParseTuple(args, "O!d", &(Base::VectorPy::Type), &dir, &d)) return NULL; try { Base::Vector3d vec = Py::Vector(dir, false).toVector(); std::list slice = this->getTopoShapePtr()->slice(vec, d); Py::List wire; for (std::list::iterator it = slice.begin(); it != slice.end(); ++it) { wire.append(Py::asObject(new TopoShapeWirePy(new TopoShape(*it)))); } return Py::new_reference_to(wire); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } catch (const std::exception& e) { PyErr_SetString(PartExceptionOCCError, e.what()); return NULL; } } PyObject* TopoShapePy::slices(PyObject *args) { PyObject *dir, *dist; if (!PyArg_ParseTuple(args, "O!O", &(Base::VectorPy::Type), &dir, &dist)) return NULL; try { Base::Vector3d vec = Py::Vector(dir, false).toVector(); Py::Sequence list(dist); std::vector d; d.reserve(list.size()); for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) d.push_back((double)Py::Float(*it)); TopoDS_Compound slice = this->getTopoShapePtr()->slices(vec, d); return new TopoShapeCompoundPy(new TopoShape(slice)); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } catch (const std::exception& e) { PyErr_SetString(PartExceptionOCCError, e.what()); return NULL; } } PyObject* TopoShapePy::cut(PyObject *args) { PyObject *pcObj; if (!PyArg_ParseTuple(args, "O!", &(TopoShapePy::Type), &pcObj)) return NULL; TopoDS_Shape shape = static_cast(pcObj)->getTopoShapePtr()->getShape(); try { // Let's call algorithm computing a cut operation: TopoDS_Shape cutShape = this->getTopoShapePtr()->cut(shape); return new TopoShapePy(new TopoShape(cutShape)); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } catch (const std::exception& e) { PyErr_SetString(PartExceptionOCCError, e.what()); return NULL; } } PyObject* TopoShapePy::generalFuse(PyObject *args) { double tolerance = 0.0; PyObject *pcObj; if (!PyArg_ParseTuple(args, "O|d", &pcObj, &tolerance)) return NULL; std::vector shapeVec; Py::Sequence shapeSeq(pcObj); for (Py::Sequence::iterator it = shapeSeq.begin(); it != shapeSeq.end(); ++it) { PyObject* item = (*it).ptr(); if (PyObject_TypeCheck(item, &(Part::TopoShapePy::Type))) { shapeVec.push_back(static_cast(item)->getTopoShapePtr()->getShape()); } else { PyErr_SetString(PyExc_TypeError, "non-shape object in sequence"); return 0; } } try { std::vector map; TopoDS_Shape gfaResultShape = this->getTopoShapePtr()->generalFuse(shapeVec,tolerance,&map); Py::Object shapePy = shape2pyshape(gfaResultShape); Py::List mapPy; for(TopTools_ListOfShape &shapes: map){ Py::List shapesPy; for(TopTools_ListIteratorOfListOfShape it(shapes); it.More(); it.Next()){ shapesPy.append(shape2pyshape(it.Value())); } mapPy.append(shapesPy); } Py::Tuple ret(2); ret[0] = shapePy; ret[1] = mapPy; return Py::new_reference_to(ret); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } catch (const std::exception& e) { PyErr_SetString(PartExceptionOCCError, e.what()); return NULL; } } PyObject* TopoShapePy::sewShape(PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; try { getTopoShapePtr()->sewShape(); Py_Return; } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } } PyObject* TopoShapePy::childShapes(PyObject *args) { PyObject* cumOri = Py_True; PyObject* cumLoc = Py_True; if (!PyArg_ParseTuple(args, "|O!O!", &(PyBool_Type), &cumOri, &(PyBool_Type), &cumLoc)) return NULL; try { TopoDS_Iterator it(getTopoShapePtr()->getShape(), PyObject_IsTrue(cumOri) ? Standard_True : Standard_False, PyObject_IsTrue(cumLoc) ? Standard_True : Standard_False); Py::List list; for (; it.More(); it.Next()) { const TopoDS_Shape& aChild = it.Value(); if (!aChild.IsNull()) { TopAbs_ShapeEnum type = aChild.ShapeType(); PyObject* pyChild = 0; switch (type) { case TopAbs_COMPOUND: pyChild = new TopoShapeCompoundPy(new TopoShape(aChild)); break; case TopAbs_COMPSOLID: pyChild = new TopoShapeCompSolidPy(new TopoShape(aChild)); break; case TopAbs_SOLID: pyChild = new TopoShapeSolidPy(new TopoShape(aChild)); break; case TopAbs_SHELL: pyChild = new TopoShapeShellPy(new TopoShape(aChild)); break; case TopAbs_FACE: pyChild = new TopoShapeFacePy(new TopoShape(aChild)); break; case TopAbs_WIRE: pyChild = new TopoShapeWirePy(new TopoShape(aChild)); break; case TopAbs_EDGE: pyChild = new TopoShapeEdgePy(new TopoShape(aChild)); break; case TopAbs_VERTEX: pyChild = new TopoShapeVertexPy(new TopoShape(aChild)); break; case TopAbs_SHAPE: break; default: break; } if (pyChild) { list.append(Py::Object(pyChild,true)); } } } return Py::new_reference_to(list); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } } PyObject* TopoShapePy::removeInternalWires(PyObject *args) { double minArea; if (!PyArg_ParseTuple(args, "d",&minArea)) return NULL; try { bool ok = getTopoShapePtr()->removeInternalWires(minArea); PyObject* ret = ok ? Py_True : Py_False; Py_INCREF(ret); return ret; } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } } PyObject* TopoShapePy::mirror(PyObject *args) { PyObject *v1, *v2; if (!PyArg_ParseTuple(args, "O!O!", &(Base::VectorPy::Type),&v1, &(Base::VectorPy::Type),&v2)) return NULL; Base::Vector3d base = Py::Vector(v1,false).toVector(); Base::Vector3d norm = Py::Vector(v2,false).toVector(); try { gp_Ax2 ax2(gp_Pnt(base.x,base.y,base.z), gp_Dir(norm.x,norm.y,norm.z)); TopoDS_Shape shape = this->getTopoShapePtr()->mirror(ax2); return new TopoShapePy(new TopoShape(shape)); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } } PyObject* TopoShapePy::transformGeometry(PyObject *args) { PyObject *obj; if (!PyArg_ParseTuple(args, "O!", &(Base::MatrixPy::Type),&obj)) return NULL; Base::Matrix4D mat = static_cast(obj)->value(); try { TopoDS_Shape shape = this->getTopoShapePtr()->transformGShape(mat); return new TopoShapePy(new TopoShape(shape)); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } } PyObject* TopoShapePy::transformShape(PyObject *args) { PyObject *obj; PyObject *copy = Py_False; if (!PyArg_ParseTuple(args, "O!|O!", &(Base::MatrixPy::Type),&obj,&(PyBool_Type), ©)) return NULL; Base::Matrix4D mat = static_cast(obj)->value(); try { this->getTopoShapePtr()->transformShape(mat, PyObject_IsTrue(copy) ? true : false); Py_Return; } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } } PyObject* TopoShapePy::translate(PyObject *args) { PyObject *obj; if (!PyArg_ParseTuple(args, "O", &obj)) return 0; Base::Vector3d vec; if (PyObject_TypeCheck(obj, &(Base::VectorPy::Type))) { vec = static_cast(obj)->value(); } else if (PyObject_TypeCheck(obj, &PyTuple_Type)) { vec = Base::getVectorFromTuple(obj); } else { PyErr_SetString(PyExc_TypeError, "either vector or tuple expected"); return 0; } gp_Trsf mov; mov.SetTranslation(gp_Vec(vec.x,vec.y,vec.z)); TopLoc_Location loc(mov); TopoDS_Shape shape = getTopoShapePtr()->getShape(); shape.Move(loc); getTopoShapePtr()->setShape(shape); Py_Return; } PyObject* TopoShapePy::rotate(PyObject *args) { PyObject *obj1, *obj2; double angle; if (!PyArg_ParseTuple(args, "OOd", &obj1, &obj2, &angle)) return NULL; try { // Vector also supports sequence Py::Sequence p1(obj1), p2(obj2); // Convert into OCC representation gp_Pnt pos = gp_Pnt((double)Py::Float(p1[0]), (double)Py::Float(p1[1]), (double)Py::Float(p1[2])); gp_Dir dir = gp_Dir((double)Py::Float(p2[0]), (double)Py::Float(p2[1]), (double)Py::Float(p2[2])); gp_Ax1 axis(pos, dir); gp_Trsf mov; mov.SetRotation(axis, angle*(M_PI/180)); TopLoc_Location loc(mov); TopoDS_Shape shape = getTopoShapePtr()->getShape(); shape.Move(loc); getTopoShapePtr()->setShape(shape); Py_Return; } catch (const Py::Exception&) { return NULL; } } PyObject* TopoShapePy::scale(PyObject *args) { double factor; PyObject* p=0; if (!PyArg_ParseTuple(args, "d|O!", &factor, &(Base::VectorPy::Type), &p)) return NULL; gp_Pnt pos(0,0,0); if (p) { Base::Vector3d pnt = static_cast(p)->value(); pos.SetX(pnt.x); pos.SetY(pnt.y); pos.SetZ(pnt.z); } if (fabs(factor) < Precision::Confusion()) { PyErr_SetString(PartExceptionOCCError, "scale factor too small"); return NULL; } try { gp_Trsf scl; scl.SetScale(pos, factor); BRepBuilderAPI_Transform BRepScale(scl); bool bCopy = true; BRepScale.Perform(getTopoShapePtr()->getShape(),bCopy); getTopoShapePtr()->setShape(BRepScale.Shape()); Py_Return; } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } } PyObject* TopoShapePy::makeFillet(PyObject *args) { // use two radii for all edges double radius1, radius2; PyObject *obj; if (PyArg_ParseTuple(args, "ddO", &radius1, &radius2, &obj)) { try { const TopoDS_Shape& shape = this->getTopoShapePtr()->getShape(); BRepFilletAPI_MakeFillet mkFillet(shape); Py::Sequence list(obj); for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { if (PyObject_TypeCheck((*it).ptr(), &(Part::TopoShapePy::Type))) { const TopoDS_Shape& edge = static_cast((*it).ptr())->getTopoShapePtr()->getShape(); if (edge.ShapeType() == TopAbs_EDGE) { //Add edge to fillet algorithm mkFillet.Add(radius1, radius2, TopoDS::Edge(edge)); } } } return new TopoShapePy(new TopoShape(mkFillet.Shape())); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } } PyErr_Clear(); // use one radius for all edges double radius; if (PyArg_ParseTuple(args, "dO", &radius, &obj)) { try { const TopoDS_Shape& shape = this->getTopoShapePtr()->getShape(); BRepFilletAPI_MakeFillet mkFillet(shape); Py::Sequence list(obj); for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { if (PyObject_TypeCheck((*it).ptr(), &(Part::TopoShapePy::Type))) { const TopoDS_Shape& edge = static_cast((*it).ptr())->getTopoShapePtr()->getShape(); if (edge.ShapeType() == TopAbs_EDGE) { //Add edge to fillet algorithm mkFillet.Add(radius, TopoDS::Edge(edge)); } } } return new TopoShapePy(new TopoShape(mkFillet.Shape())); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } } PyErr_SetString(PyExc_TypeError, "This method accepts:\n" "-- one radius and a list of edges\n" "-- two radii and a list of edges"); return NULL; } PyObject* TopoShapePy::makeChamfer(PyObject *args) { // use two radii for all edges double radius1, radius2; PyObject *obj; if (PyArg_ParseTuple(args, "ddO", &radius1, &radius2, &obj)) { try { const TopoDS_Shape& shape = this->getTopoShapePtr()->getShape(); BRepFilletAPI_MakeChamfer mkChamfer(shape); TopTools_IndexedMapOfShape mapOfEdges; TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace; TopExp::MapShapesAndAncestors(shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace); TopExp::MapShapes(shape, TopAbs_EDGE, mapOfEdges); Py::Sequence list(obj); for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { if (PyObject_TypeCheck((*it).ptr(), &(Part::TopoShapePy::Type))) { const TopoDS_Shape& edge = static_cast((*it).ptr())->getTopoShapePtr()->getShape(); if (edge.ShapeType() == TopAbs_EDGE) { //Add edge to fillet algorithm const TopoDS_Face& face = TopoDS::Face(mapEdgeFace.FindFromKey(edge).First()); mkChamfer.Add(radius1, radius2, TopoDS::Edge(edge), face); } } } return new TopoShapePy(new TopoShape(mkChamfer.Shape())); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } } PyErr_Clear(); // use one radius for all edges double radius; if (PyArg_ParseTuple(args, "dO", &radius, &obj)) { try { const TopoDS_Shape& shape = this->getTopoShapePtr()->getShape(); BRepFilletAPI_MakeChamfer mkChamfer(shape); TopTools_IndexedMapOfShape mapOfEdges; TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace; TopExp::MapShapesAndAncestors(shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace); TopExp::MapShapes(shape, TopAbs_EDGE, mapOfEdges); Py::Sequence list(obj); for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { if (PyObject_TypeCheck((*it).ptr(), &(Part::TopoShapePy::Type))) { const TopoDS_Shape& edge = static_cast((*it).ptr())->getTopoShapePtr()->getShape(); if (edge.ShapeType() == TopAbs_EDGE) { //Add edge to fillet algorithm const TopoDS_Face& face = TopoDS::Face(mapEdgeFace.FindFromKey(edge).First()); mkChamfer.Add(radius, TopoDS::Edge(edge), face); } } } return new TopoShapePy(new TopoShape(mkChamfer.Shape())); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } } PyErr_SetString(PyExc_TypeError, "This method accepts:\n" "-- one radius and a list of edges\n" "-- two radii and a list of edges"); return NULL; } PyObject* TopoShapePy::makeThickness(PyObject *args) { PyObject *obj; double offset, tolerance; PyObject* inter = Py_False; PyObject* self_inter = Py_False; short offsetMode = 0, join = 0; if (!PyArg_ParseTuple(args, "Odd|O!O!hh", &obj, &offset, &tolerance, &(PyBool_Type), &inter, &(PyBool_Type), &self_inter, &offsetMode, &join)) return 0; try { TopTools_ListOfShape facesToRemove; Py::Sequence list(obj); for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { if (PyObject_TypeCheck((*it).ptr(), &(Part::TopoShapePy::Type))) { const TopoDS_Shape& shape = static_cast((*it).ptr())->getTopoShapePtr()->getShape(); facesToRemove.Append(shape); } } TopoDS_Shape shape = this->getTopoShapePtr()->makeThickSolid(facesToRemove, offset, tolerance, PyObject_IsTrue(inter) ? true : false, PyObject_IsTrue(self_inter) ? true : false, offsetMode, join); return new TopoShapeSolidPy(new TopoShape(shape)); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } } PyObject* TopoShapePy::makeOffsetShape(PyObject *args, PyObject *keywds) { static char *kwlist[] = {"offset", "tolerance", "inter", "self_inter", "offsetMode", "join", "fill", NULL}; double offset, tolerance; PyObject* inter = Py_False; PyObject* self_inter = Py_False; PyObject* fill = Py_False; short offsetMode = 0, join = 0; if (!PyArg_ParseTupleAndKeywords(args, keywds, "dd|O!O!hhO!", kwlist, &offset, &tolerance, &(PyBool_Type), &inter, &(PyBool_Type), &self_inter, &offsetMode, &join, &(PyBool_Type), &fill)) return 0; try { TopoDS_Shape shape = this->getTopoShapePtr()->makeOffsetShape(offset, tolerance, PyObject_IsTrue(inter) ? true : false, PyObject_IsTrue(self_inter) ? true : false, offsetMode, join, PyObject_IsTrue(fill) ? true : false); return new TopoShapePy(new TopoShape(shape)); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } } PyObject* TopoShapePy::makeOffset2D(PyObject *args, PyObject *keywds) { static char *kwlist[] = {"offset", "join", "fill", "openResult", "intersection", NULL}; double offset; PyObject* fill = Py_False; PyObject* openResult = Py_False; PyObject* inter = Py_False; short join = 0; if (!PyArg_ParseTupleAndKeywords(args, keywds, "d|hO!O!O!", kwlist, &offset, &join, &(PyBool_Type), &fill, &(PyBool_Type), &openResult, &(PyBool_Type), &inter)) return 0; try { TopoDS_Shape resultShape = this->getTopoShapePtr()->makeOffset2D(offset, join, PyObject_IsTrue(fill) ? true : false, PyObject_IsTrue(openResult) ? true : false, PyObject_IsTrue(inter) ? true : false); return new_reference_to(shape2pyshape(resultShape)); } PY_CATCH_OCC; } PyObject* TopoShapePy::reverse(PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; TopoDS_Shape shape = getTopoShapePtr()->getShape(); shape.Reverse(); getTopoShapePtr()->setShape(shape); Py_Return; } PyObject* TopoShapePy::complement(PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; TopoDS_Shape shape = getTopoShapePtr()->getShape(); shape.Complement(); getTopoShapePtr()->setShape(shape); Py_Return; } PyObject* TopoShapePy::nullify(PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; TopoDS_Shape shape = getTopoShapePtr()->getShape(); shape.Nullify(); getTopoShapePtr()->setShape(shape); Py_Return; } PyObject* TopoShapePy::isNull(PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; bool null = getTopoShapePtr()->isNull(); return Py_BuildValue("O", (null ? Py_True : Py_False)); } PyObject* TopoShapePy::isClosed(PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; try { if (getTopoShapePtr()->getShape().IsNull()) Standard_Failure::Raise("Cannot determine the 'Closed'' flag of an empty shape"); return Py_BuildValue("O", (getTopoShapePtr()->isClosed() ? Py_True : Py_False)); } catch (...) { PyErr_SetString(PyExc_RuntimeError, "check failed, shape may be empty"); return NULL; } } PyObject* TopoShapePy::isEqual(PyObject *args) { PyObject *pcObj; if (!PyArg_ParseTuple(args, "O!", &(TopoShapePy::Type), &pcObj)) return NULL; TopoDS_Shape shape = static_cast(pcObj)->getTopoShapePtr()->getShape(); Standard_Boolean test = (getTopoShapePtr()->getShape().IsEqual(shape)); return Py_BuildValue("O", (test ? Py_True : Py_False)); } PyObject* TopoShapePy::isSame(PyObject *args) { PyObject *pcObj; if (!PyArg_ParseTuple(args, "O!", &(TopoShapePy::Type), &pcObj)) return NULL; TopoDS_Shape shape = static_cast(pcObj)->getTopoShapePtr()->getShape(); Standard_Boolean test = getTopoShapePtr()->getShape().IsSame(shape); return Py_BuildValue("O", (test ? Py_True : Py_False)); } PyObject* TopoShapePy::isPartner(PyObject *args) { PyObject *pcObj; if (!PyArg_ParseTuple(args, "O!", &(TopoShapePy::Type), &pcObj)) return NULL; TopoDS_Shape shape = static_cast(pcObj)->getTopoShapePtr()->getShape(); Standard_Boolean test = getTopoShapePtr()->getShape().IsPartner(shape); return Py_BuildValue("O", (test ? Py_True : Py_False)); } PyObject* TopoShapePy::isValid(PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; try { return Py_BuildValue("O", (getTopoShapePtr()->isValid() ? Py_True : Py_False)); } catch (...) { PyErr_SetString(PyExc_RuntimeError, "check failed, shape may be empty"); return NULL; } } PyObject* TopoShapePy::fix(PyObject *args) { double prec, mintol, maxtol; if (!PyArg_ParseTuple(args, "ddd", &prec, &mintol, &maxtol)) return NULL; try { return Py_BuildValue("O", (getTopoShapePtr()->fix(prec, mintol, maxtol) ? Py_True : Py_False)); } catch (...) { PyErr_SetString(PyExc_RuntimeError, "check failed, shape may be empty"); return NULL; } } PyObject* TopoShapePy::hashCode(PyObject *args) { int upper = IntegerLast(); if (!PyArg_ParseTuple(args, "|i",&upper)) return 0; int hc = getTopoShapePtr()->getShape().HashCode(upper); return Py_BuildValue("i", hc); } PyObject* TopoShapePy::tessellate(PyObject *args) { try { float tolerance; PyObject* ok = Py_False; if (!PyArg_ParseTuple(args, "f|O!",&tolerance,&PyBool_Type,&ok)) return 0; std::vector Points; std::vector Facets; if (PyObject_IsTrue(ok)) BRepTools::Clean(getTopoShapePtr()->getShape()); getTopoShapePtr()->getFaces(Points, Facets,tolerance); Py::Tuple tuple(2); Py::List vertex; for (std::vector::const_iterator it = Points.begin(); it != Points.end(); ++it) vertex.append(Py::Object(new Base::VectorPy(*it))); tuple.setItem(0, vertex); Py::List facet; for (std::vector::const_iterator it = Facets.begin(); it != Facets.end(); ++it) { Py::Tuple f(3); f.setItem(0,Py::Int((int)it->I1)); f.setItem(1,Py::Int((int)it->I2)); f.setItem(2,Py::Int((int)it->I3)); facet.append(f); } tuple.setItem(1, facet); return Py::new_reference_to(tuple); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } } PyObject* TopoShapePy::project(PyObject *args) { PyObject *obj; BRepAlgo_NormalProjection algo; algo.Init(this->getTopoShapePtr()->getShape()); if (PyArg_ParseTuple(args, "O", &obj)) { try { Py::Sequence list(obj); for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { if (PyObject_TypeCheck((*it).ptr(), &(Part::TopoShapePy::Type))) { const TopoDS_Shape& shape = static_cast((*it).ptr())->getTopoShapePtr()->getShape(); algo.Add(shape); } } algo.Compute3d(Standard_True); algo.SetLimit(Standard_True); algo.SetParams(1.e-6, 1.e-6, GeomAbs_C1, 14, 16); //algo.SetDefaultParams(); algo.Build(); return new TopoShapePy(new TopoShape(algo.Projection())); } catch (Standard_Failure) { PyErr_SetString(PartExceptionOCCError, "Failed to project shape"); return NULL; } } return 0; } PyObject* TopoShapePy::makeParallelProjection(PyObject *args) { PyObject *pShape, *pDir; if (PyArg_ParseTuple(args, "O!O!", &(Part::TopoShapePy::Type), &pShape, &Base::VectorPy::Type, &pDir)) { try { const TopoDS_Shape& shape = this->getTopoShapePtr()->getShape(); const TopoDS_Shape& wire = static_cast(pShape)->getTopoShapePtr()->getShape(); Base::Vector3d vec = Py::Vector(pDir,false).toVector(); BRepProj_Projection proj(wire, shape, gp_Dir(vec.x,vec.y,vec.z)); TopoDS_Shape projected = proj.Shape(); return new TopoShapePy(new TopoShape(projected)); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return 0; } } return 0; } PyObject* TopoShapePy::makePerspectiveProjection(PyObject *args) { PyObject *pShape, *pDir; if (PyArg_ParseTuple(args, "O!O!", &(Part::TopoShapePy::Type), &pShape, &Base::VectorPy::Type, &pDir)) { try { const TopoDS_Shape& shape = this->getTopoShapePtr()->getShape(); const TopoDS_Shape& wire = static_cast(pShape)->getTopoShapePtr()->getShape(); Base::Vector3d vec = Py::Vector(pDir,false).toVector(); BRepProj_Projection proj(wire, shape, gp_Pnt(vec.x,vec.y,vec.z)); TopoDS_Shape projected = proj.Shape(); return new TopoShapePy(new TopoShape(projected)); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return 0; } } return 0; } PyObject* TopoShapePy::makeShapeFromMesh(PyObject *args) { PyObject *tup; float tolerance; if (!PyArg_ParseTuple(args, "O!f",&PyTuple_Type, &tup, &tolerance)) return 0; try { Py::Tuple tuple(tup); Py::Sequence vertex(tuple[0]); Py::Sequence facets(tuple[1]); std::vector Points; for (Py::Sequence::iterator it = vertex.begin(); it != vertex.end(); ++it) { Py::Vector vec(*it); Points.push_back(vec.toVector()); } std::vector Facets; for (Py::Sequence::iterator it = facets.begin(); it != facets.end(); ++it) { Data::ComplexGeoData::Facet face; Py::Tuple f(*it); face.I1 = (int)Py::Int(f[0]); face.I2 = (int)Py::Int(f[1]); face.I3 = (int)Py::Int(f[2]); Facets.push_back(face); } getTopoShapePtr()->setFaces(Points, Facets,tolerance); Py_Return; } catch (const Py::Exception&) { return 0; } } PyObject* TopoShapePy::toNurbs(PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; try { // Convert into nurbs TopoDS_Shape nurbs = this->getTopoShapePtr()->toNurbs(); return new TopoShapePy(new TopoShape(nurbs)); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } } PyObject* TopoShapePy::isInside(PyObject *args) { PyObject *point; double tolerance; PyObject* checkFace = Py_False; TopAbs_State stateIn = TopAbs_IN; if (!PyArg_ParseTuple(args, "O!dO!", &(Base::VectorPy::Type), &point, &tolerance, &PyBool_Type, &checkFace)) return NULL; try { TopoDS_Shape shape = getTopoShapePtr()->getShape(); BRepClass3d_SolidClassifier solidClassifier(shape); Base::Vector3d pnt = static_cast(point)->value(); gp_Pnt vertex = gp_Pnt(pnt.x,pnt.y,pnt.z); solidClassifier.Perform(vertex, tolerance); Standard_Boolean test = (solidClassifier.State() == stateIn); if (PyObject_IsTrue(checkFace) && (solidClassifier.IsOnAFace())) test = Standard_True; return Py_BuildValue("O", (test ? Py_True : Py_False)); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } catch (const std::exception& e) { PyErr_SetString(PartExceptionOCCError, e.what()); return NULL; } } PyObject* TopoShapePy::removeSplitter(PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; try { // Remove redundant splitter TopoDS_Shape shape = this->getTopoShapePtr()->removeSplitter(); return new TopoShapePy(new TopoShape(shape)); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } } PyObject* TopoShapePy::getElement(PyObject *args) { char* input; if (!PyArg_ParseTuple(args, "s", &input)) return NULL; std::string name(input); try { if (name.size() > 4 && name.substr(0,4) == "Face" && name[4]>=48 && name[4]<=57) { std::unique_ptr s(static_cast (getTopoShapePtr()->getSubElementByName(input))); TopoDS_Shape Shape = s->Shape; return new TopoShapeFacePy(new TopoShape(Shape)); } else if (name.size() > 4 && name.substr(0,4) == "Edge" && name[4]>=48 && name[4]<=57) { std::unique_ptr s(static_cast (getTopoShapePtr()->getSubElementByName(input))); TopoDS_Shape Shape = s->Shape; return new TopoShapeEdgePy(new TopoShape(Shape)); } else if (name.size() > 6 && name.substr(0,6) == "Vertex" && name[6]>=48 && name[6]<=57) { std::unique_ptr s(static_cast (getTopoShapePtr()->getSubElementByName(input))); TopoDS_Shape Shape = s->Shape; return new TopoShapeVertexPy(new TopoShape(Shape)); } } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return 0; } return 0; } PyObject* TopoShapePy::getTolerance(PyObject *args) { int mode; PyObject* type=0; if (!PyArg_ParseTuple(args, "i|O!", &mode, &PyType_Type, &type)) return NULL; try { TopoDS_Shape shape = this->getTopoShapePtr()->getShape(); TopAbs_ShapeEnum shapetype = TopAbs_SHAPE; PyTypeObject* pyType = reinterpret_cast(type); if (pyType == 0) shapetype = TopAbs_SHAPE; else if (PyType_IsSubtype(pyType, &TopoShapeShellPy::Type)) shapetype = TopAbs_SHELL; else if (PyType_IsSubtype(pyType, &TopoShapeFacePy::Type)) shapetype = TopAbs_FACE; else if (PyType_IsSubtype(pyType, &TopoShapeEdgePy::Type)) shapetype = TopAbs_EDGE; else if (PyType_IsSubtype(pyType, &TopoShapeVertexPy::Type)) shapetype = TopAbs_VERTEX; else if (pyType != &TopoShapePy::Type) { if (PyType_IsSubtype(pyType, &TopoShapePy::Type)) { PyErr_SetString(PyExc_TypeError, "shape type must be Vertex, Edge, Face or Shell"); return 0; } else { PyErr_SetString(PyExc_TypeError, "type must be a shape type"); return 0; } } ShapeAnalysis_ShapeTolerance analysis; double tolerance = analysis.Tolerance(shape, mode, shapetype); return PyFloat_FromDouble(tolerance); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } } PyObject* TopoShapePy::overTolerance(PyObject *args) { double value; PyObject* type=0; if (!PyArg_ParseTuple(args, "d|O!", &value, &PyType_Type, &type)) return NULL; try { TopoDS_Shape shape = this->getTopoShapePtr()->getShape(); TopAbs_ShapeEnum shapetype = TopAbs_SHAPE; PyTypeObject* pyType = reinterpret_cast(type); if (pyType == 0) shapetype = TopAbs_SHAPE; else if (PyType_IsSubtype(pyType, &TopoShapeShellPy::Type)) shapetype = TopAbs_SHELL; else if (PyType_IsSubtype(pyType, &TopoShapeFacePy::Type)) shapetype = TopAbs_FACE; else if (PyType_IsSubtype(pyType, &TopoShapeEdgePy::Type)) shapetype = TopAbs_EDGE; else if (PyType_IsSubtype(pyType, &TopoShapeVertexPy::Type)) shapetype = TopAbs_VERTEX; else if (pyType != &TopoShapePy::Type) { if (PyType_IsSubtype(pyType, &TopoShapePy::Type)) { PyErr_SetString(PyExc_TypeError, "shape type must be Vertex, Edge, Face or Shell"); return 0; } else { PyErr_SetString(PyExc_TypeError, "type must be a shape type"); return 0; } } ShapeAnalysis_ShapeTolerance analysis; Handle(TopTools_HSequenceOfShape) seq = analysis.OverTolerance(shape, value, shapetype); Py::Tuple tuple(seq->Length()); std::size_t index=0; for (int i=seq->Lower(); i<= seq->Upper(); i++) { TopoDS_Shape item = seq->Value(i); tuple.setItem(index++, shape2pyshape(item)); } return Py::new_reference_to(tuple); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } } PyObject* TopoShapePy::inTolerance(PyObject *args) { double valmin; double valmax; PyObject* type=0; if (!PyArg_ParseTuple(args, "dd|O!", &valmin, &valmax, &PyType_Type, &type)) return NULL; try { TopoDS_Shape shape = this->getTopoShapePtr()->getShape(); TopAbs_ShapeEnum shapetype = TopAbs_SHAPE; PyTypeObject* pyType = reinterpret_cast(type); if (pyType == 0) shapetype = TopAbs_SHAPE; else if (PyType_IsSubtype(pyType, &TopoShapeShellPy::Type)) shapetype = TopAbs_SHELL; else if (PyType_IsSubtype(pyType, &TopoShapeFacePy::Type)) shapetype = TopAbs_FACE; else if (PyType_IsSubtype(pyType, &TopoShapeEdgePy::Type)) shapetype = TopAbs_EDGE; else if (PyType_IsSubtype(pyType, &TopoShapeVertexPy::Type)) shapetype = TopAbs_VERTEX; else if (pyType != &TopoShapePy::Type) { if (PyType_IsSubtype(pyType, &TopoShapePy::Type)) { PyErr_SetString(PyExc_TypeError, "shape type must be Vertex, Edge, Face or Shell"); return 0; } else { PyErr_SetString(PyExc_TypeError, "type must be a shape type"); return 0; } } ShapeAnalysis_ShapeTolerance analysis; Handle(TopTools_HSequenceOfShape) seq = analysis.InTolerance(shape, valmin, valmax, shapetype); Py::Tuple tuple(seq->Length()); std::size_t index=0; for (int i=seq->Lower(); i<= seq->Upper(); i++) { TopoDS_Shape item = seq->Value(i); tuple.setItem(index++, shape2pyshape(item)); } return Py::new_reference_to(tuple); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } } PyObject* TopoShapePy::globalTolerance(PyObject *args) { int mode; if (!PyArg_ParseTuple(args, "i", &mode)) return NULL; try { TopoDS_Shape shape = this->getTopoShapePtr()->getShape(); ShapeAnalysis_ShapeTolerance analysis; analysis.Tolerance(shape, mode); double tolerance = analysis.GlobalTolerance(mode); return PyFloat_FromDouble(tolerance); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } } PyObject* TopoShapePy::fixTolerance(PyObject *args) { double value; PyObject* type=0; if (!PyArg_ParseTuple(args, "d|O!", &value, &PyType_Type, &type)) return NULL; try { TopoDS_Shape shape = this->getTopoShapePtr()->getShape(); TopAbs_ShapeEnum shapetype = TopAbs_SHAPE; PyTypeObject* pyType = reinterpret_cast(type); if (pyType == 0) shapetype = TopAbs_SHAPE; else if (PyType_IsSubtype(pyType, &TopoShapeWirePy::Type)) shapetype = TopAbs_WIRE; else if (PyType_IsSubtype(pyType, &TopoShapeFacePy::Type)) shapetype = TopAbs_FACE; else if (PyType_IsSubtype(pyType, &TopoShapeEdgePy::Type)) shapetype = TopAbs_EDGE; else if (PyType_IsSubtype(pyType, &TopoShapeVertexPy::Type)) shapetype = TopAbs_VERTEX; else if (PyType_IsSubtype(pyType, &TopoShapePy::Type)) shapetype = TopAbs_SHAPE; else if (pyType != &TopoShapePy::Type) { PyErr_SetString(PyExc_TypeError, "type must be a shape type"); return 0; } ShapeFix_ShapeTolerance fix; fix.SetTolerance(shape, value, shapetype); Py_Return; } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } } PyObject* TopoShapePy::limitTolerance(PyObject *args) { double tmin; double tmax=0; PyObject* type=0; if (!PyArg_ParseTuple(args, "d|dO!", &tmin, &tmax, &PyType_Type, &type)) return NULL; try { TopoDS_Shape shape = this->getTopoShapePtr()->getShape(); TopAbs_ShapeEnum shapetype = TopAbs_SHAPE; PyTypeObject* pyType = reinterpret_cast(type); if (pyType == 0) shapetype = TopAbs_SHAPE; else if (PyType_IsSubtype(pyType, &TopoShapeWirePy::Type)) shapetype = TopAbs_WIRE; else if (PyType_IsSubtype(pyType, &TopoShapeFacePy::Type)) shapetype = TopAbs_FACE; else if (PyType_IsSubtype(pyType, &TopoShapeEdgePy::Type)) shapetype = TopAbs_EDGE; else if (PyType_IsSubtype(pyType, &TopoShapeVertexPy::Type)) shapetype = TopAbs_VERTEX; else if (PyType_IsSubtype(pyType, &TopoShapePy::Type)) shapetype = TopAbs_SHAPE; else if (pyType != &TopoShapePy::Type) { PyErr_SetString(PyExc_TypeError, "type must be a shape type"); return 0; } ShapeFix_ShapeTolerance fix; Standard_Boolean ok = fix.LimitTolerance(shape, tmin, tmax, shapetype); return PyBool_FromLong(ok ? 1 : 0); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return NULL; } } PyObject* _getSupportIndex(char* suppStr, TopoShape* ts, TopoDS_Shape suppShape) { std::stringstream ss; TopoDS_Shape subShape; unsigned long nSubShapes = ts->countSubShapes(suppStr); long supportIndex = -1; for (unsigned long j=1; j<=nSubShapes; j++){ ss.str(""); ss << suppStr << j; subShape = ts->getSubShape(ss.str().c_str()); if (subShape.IsEqual(suppShape)) { supportIndex = j-1; break; } } return PyInt_FromLong(supportIndex); } PyObject* TopoShapePy::proximity(PyObject *args) { #if OCC_VERSION_HEX >= 0x060801 #if OCC_VERSION_HEX >= 0x060901 typedef BRepExtrema_MapOfIntegerPackedMapOfInteger BRepExtrema_OverlappedSubShapes; #endif PyObject* ps2; Standard_Real tol = Precision::Confusion(); if (!PyArg_ParseTuple(args, "O!|d",&(TopoShapePy::Type), &ps2, &tol)) return 0; const TopoDS_Shape& s1 = getTopoShapePtr()->getShape(); const TopoDS_Shape& s2 = static_cast(ps2)->getTopoShapePtr()->getShape(); if (s1.IsNull()) { PyErr_SetString(PyExc_ValueError, "proximity: Shape object is invalid"); return 0; } if (s2.IsNull()) { PyErr_SetString(PyExc_ValueError, "proximity: Shape parameter is invalid"); return 0; } BRepExtrema_ShapeProximity proximity; proximity.LoadShape1 (s1); proximity.LoadShape2 (s2); if (tol > 0.0) proximity.SetTolerance (tol); proximity.Perform(); if (!proximity.IsDone()) { PyErr_SetString(PartExceptionOCCError, "BRepExtrema_ShapeProximity not done"); return 0; } //PyObject* overlappss1 = PyList_New(0); //PyObject* overlappss2 = PyList_New(0); PyObject* overlappssindex1 = PyList_New(0); PyObject* overlappssindex2 = PyList_New(0); for (BRepExtrema_OverlappedSubShapes::Iterator anIt1 (proximity.OverlapSubShapes1()); anIt1.More(); anIt1.Next()) { //PyList_Append(overlappss1, new TopoShapeFacePy(new TopoShape(proximity.GetSubShape1 (anIt1.Key())))); PyList_Append(overlappssindex1,PyInt_FromLong(anIt1.Key()+1)); } for (BRepExtrema_OverlappedSubShapes::Iterator anIt2 (proximity.OverlapSubShapes2()); anIt2.More(); anIt2.Next()) { //PyList_Append(overlappss2, new TopoShapeFacePy(new TopoShape(proximity.GetSubShape2 (anIt2.Key())))); PyList_Append(overlappssindex2,PyInt_FromLong(anIt2.Key()+1)); } //return Py_BuildValue("OO", overlappss1, overlappss2); //subshapes return Py_BuildValue("OO", overlappssindex1, overlappssindex2); //face indexes #else (void)args; PyErr_SetString(PyExc_NotImplementedError, "proximity requires OCCT >= 6.8.1"); return 0; #endif } PyObject* TopoShapePy::distToShape(PyObject *args) { PyObject* ps2; PyObject *pts,*geom,*pPt1,*pPt2,*pSuppType1,*pSuppType2, *pSupportIndex1, *pSupportIndex2, *pParm1, *pParm2; gp_Pnt P1,P2; BRepExtrema_SupportType supportType1,supportType2; TopoDS_Shape suppS1,suppS2; Standard_Real minDist = -1, t1,t2,u1,v1,u2,v2; if (!PyArg_ParseTuple(args, "O!",&(TopoShapePy::Type), &ps2)) return 0; const TopoDS_Shape& s1 = getTopoShapePtr()->getShape(); TopoShape* ts1 = getTopoShapePtr(); const TopoDS_Shape& s2 = static_cast(ps2)->getTopoShapePtr()->getShape(); TopoShape* ts2 = static_cast(ps2)->getTopoShapePtr(); if (s2.IsNull()) { PyErr_SetString(PyExc_TypeError, "distToShape: Shape parameter is invalid"); return 0; } BRepExtrema_DistShapeShape extss(s1, s2); if (!extss.IsDone()) { PyErr_SetString(PyExc_TypeError, "BRepExtrema_DistShapeShape failed"); return 0; } PyObject* solnPts = PyList_New(0); PyObject* solnGeom = PyList_New(0); int count = extss.NbSolution(); if (count != 0) { minDist = extss.Value(); //extss.Dump(std::cout); for (int i=1; i<= count; i++) { P1 = extss.PointOnShape1(i); pPt1 = new Base::VectorPy(new Base::Vector3d(P1.X(),P1.Y(),P1.Z())); supportType1 = extss.SupportTypeShape1(i); suppS1 = extss.SupportOnShape1(i); switch (supportType1) { case BRepExtrema_IsVertex: pSuppType1 = PyString_FromString("Vertex"); pSupportIndex1 = _getSupportIndex("Vertex",ts1,suppS1); pParm1 = Py_None; pParm2 = Py_None; break; case BRepExtrema_IsOnEdge: pSuppType1 = PyString_FromString("Edge"); pSupportIndex1 = _getSupportIndex("Edge",ts1,suppS1); extss.ParOnEdgeS1(i,t1); pParm1 = PyFloat_FromDouble(t1); pParm2 = Py_None; break; case BRepExtrema_IsInFace: pSuppType1 = PyString_FromString("Face"); pSupportIndex1 = _getSupportIndex("Face",ts1,suppS1); extss.ParOnFaceS1(i,u1,v1); pParm1 = PyTuple_New(2); pParm2 = Py_None; PyTuple_SetItem(pParm1,0,PyFloat_FromDouble(u1)); PyTuple_SetItem(pParm1,1,PyFloat_FromDouble(v1)); break; default: Base::Console().Message("distToShape: supportType1 is unknown: %d \n",supportType1); pSuppType1 = PyString_FromString("Unknown"); pSupportIndex1 = PyInt_FromLong(-1); pParm1 = Py_None; pParm2 = Py_None; } P2 = extss.PointOnShape2(i); pPt2 = new Base::VectorPy(new Base::Vector3d(P2.X(),P2.Y(),P2.Z())); supportType2 = extss.SupportTypeShape2(i); suppS2 = extss.SupportOnShape2(i); switch (supportType2) { case BRepExtrema_IsVertex: pSuppType2 = PyString_FromString("Vertex"); pSupportIndex2 = _getSupportIndex("Vertex",ts2,suppS2); pParm2 = Py_None; break; case BRepExtrema_IsOnEdge: pSuppType2 = PyString_FromString("Edge"); pSupportIndex2 = _getSupportIndex("Edge",ts2,suppS2); extss.ParOnEdgeS2(i,t2); pParm2 = PyFloat_FromDouble(t2); break; case BRepExtrema_IsInFace: pSuppType2 = PyString_FromString("Face"); pSupportIndex2 = _getSupportIndex("Face",ts2,suppS2); extss.ParOnFaceS2(i,u2,v2); pParm2 = PyTuple_New(2); PyTuple_SetItem(pParm2,0,PyFloat_FromDouble(u2)); PyTuple_SetItem(pParm2,1,PyFloat_FromDouble(v2)); break; default: Base::Console().Message("distToShape: supportType2 is unknown: %d \n",supportType1); pSuppType2 = PyString_FromString("Unknown"); pSupportIndex2 = PyInt_FromLong(-1); } pts = PyTuple_New(2); PyTuple_SetItem(pts,0,pPt1); PyTuple_SetItem(pts,1,pPt2); PyList_Append(solnPts, pts); geom = PyTuple_New(6); PyTuple_SetItem(geom,0,pSuppType1); PyTuple_SetItem(geom,1,pSupportIndex1); PyTuple_SetItem(geom,2,pParm1); PyTuple_SetItem(geom,3,pSuppType2); PyTuple_SetItem(geom,4,pSupportIndex2); PyTuple_SetItem(geom,5,pParm2); PyList_Append(solnGeom, geom); } } else { PyErr_SetString(PyExc_TypeError, "distToShape: No Solutions Found."); return 0; } return Py_BuildValue("dOO", minDist, solnPts,solnGeom); } // End of Methods, Start of Attributes #if 0 // see ComplexGeoDataPy::Matrix which does the same Py::Object TopoShapePy::getLocation(void) const { const TopLoc_Location& loc = getTopoShapePtr()->getShape().Location(); gp_Trsf trf = (gp_Trsf)loc; Base::Matrix4D mat; mat[0][0] = trf.Value(1,1); mat[0][1] = trf.Value(1,2); mat[0][2] = trf.Value(1,3); mat[0][3] = trf.Value(1,4); mat[1][0] = trf.Value(2,1); mat[1][1] = trf.Value(2,2); mat[1][2] = trf.Value(2,3); mat[1][3] = trf.Value(2,4); mat[2][0] = trf.Value(3,1); mat[2][1] = trf.Value(3,2); mat[2][2] = trf.Value(3,3); mat[2][3] = trf.Value(3,4); return Py::Object(new Base::MatrixPy(mat)); } void TopoShapePy::setLocation(Py::Object o) { PyObject* p = o.ptr(); if (PyObject_TypeCheck(p, &(Base::MatrixPy::Type))) { Base::Matrix4D mat = static_cast(p)->value(); Base::Rotation rot(mat); Base::Vector3d axis; double angle; rot.getValue(axis, angle); gp_Trsf trf; trf.SetRotation(gp_Ax1(gp_Pnt(), gp_Dir(axis.x, axis.y, axis.z)), angle); trf.SetTranslationPart(gp_Vec(mat[0][3],mat[1][3],mat[2][3])); TopLoc_Location loc(trf); getTopoShapePtr()->getShape().Location(loc); } else { std::string error = std::string("type must be 'Matrix', not "); error += p->ob_type->tp_name; throw Py::TypeError(error); } } #endif Py::String TopoShapePy::getShapeType(void) const { TopoDS_Shape sh = getTopoShapePtr()->getShape(); if (sh.IsNull()) throw Py::Exception(Base::BaseExceptionFreeCADError, "cannot determine type of null shape"); TopAbs_ShapeEnum type = sh.ShapeType(); std::string name; switch (type) { case TopAbs_COMPOUND: name = "Compound"; break; case TopAbs_COMPSOLID: name = "CompSolid"; break; case TopAbs_SOLID: name = "Solid"; break; case TopAbs_SHELL: name = "Shell"; break; case TopAbs_FACE: name = "Face"; break; case TopAbs_WIRE: name = "Wire"; break; case TopAbs_EDGE: name = "Edge"; break; case TopAbs_VERTEX: name = "Vertex"; break; case TopAbs_SHAPE: name = "Shape"; break; } return Py::String(name); } Py::String TopoShapePy::getOrientation(void) const { TopoDS_Shape sh = getTopoShapePtr()->getShape(); if (sh.IsNull()) throw Py::Exception(Base::BaseExceptionFreeCADError, "cannot determine orientation of null shape"); TopAbs_Orientation type = sh.Orientation(); std::string name; switch (type) { case TopAbs_FORWARD: name = "Forward"; break; case TopAbs_REVERSED: name = "Reversed"; break; case TopAbs_INTERNAL: name = "Internal"; break; case TopAbs_EXTERNAL: name = "External"; break; } return Py::String(name); } void TopoShapePy::setOrientation(Py::String arg) { TopoDS_Shape sh = getTopoShapePtr()->getShape(); if (sh.IsNull()) throw Py::Exception(Base::BaseExceptionFreeCADError, "cannot determine orientation of null shape"); std::string name = (std::string)arg; TopAbs_Orientation type; if (name == "Forward") { type = TopAbs_FORWARD; } else if (name == "Reversed") { type = TopAbs_REVERSED; } else if (name == "Internal") { type = TopAbs_INTERNAL; } else if (name == "External") { type = TopAbs_EXTERNAL; } else { throw Py::AttributeError("Invalid orientation type"); } sh.Orientation(type); getTopoShapePtr()->setShape(sh); } Py::List TopoShapePy::getFaces(void) const { Py::List ret; TopTools_IndexedMapOfShape M; TopExp_Explorer Ex(getTopoShapePtr()->getShape(),TopAbs_FACE); while (Ex.More()) { M.Add(Ex.Current()); Ex.Next(); } for (Standard_Integer k = 1; k <= M.Extent(); k++) { const TopoDS_Shape& shape = M(k); ret.append(Py::Object(new TopoShapeFacePy(new TopoShape(shape)),true)); } return ret; } Py::List TopoShapePy::getVertexes(void) const { Py::List ret; TopTools_IndexedMapOfShape M; TopExp_Explorer Ex(getTopoShapePtr()->getShape(),TopAbs_VERTEX); while (Ex.More()) { M.Add(Ex.Current()); Ex.Next(); } for (Standard_Integer k = 1; k <= M.Extent(); k++) { const TopoDS_Shape& shape = M(k); ret.append(Py::Object(new TopoShapeVertexPy(new TopoShape(shape)),true)); } return ret; } Py::List TopoShapePy::getShells(void) const { Py::List ret; TopTools_IndexedMapOfShape M; TopExp_Explorer Ex(getTopoShapePtr()->getShape(),TopAbs_SHELL); while (Ex.More()) { M.Add(Ex.Current()); Ex.Next(); } for (Standard_Integer k = 1; k <= M.Extent(); k++) { const TopoDS_Shape& shape = M(k); ret.append(Py::Object(new TopoShapeShellPy(new TopoShape(shape)),true)); } return ret; } Py::List TopoShapePy::getSolids(void) const { Py::List ret; TopTools_IndexedMapOfShape M; TopExp_Explorer Ex(getTopoShapePtr()->getShape(),TopAbs_SOLID); while (Ex.More()) { M.Add(Ex.Current()); Ex.Next(); } for (Standard_Integer k = 1; k <= M.Extent(); k++) { const TopoDS_Shape& shape = M(k); ret.append(Py::Object(new TopoShapeSolidPy(new TopoShape(shape)),true)); } return ret; } Py::List TopoShapePy::getCompSolids(void) const { Py::List ret; TopTools_IndexedMapOfShape M; TopExp_Explorer Ex(getTopoShapePtr()->getShape(),TopAbs_COMPSOLID); while (Ex.More()) { M.Add(Ex.Current()); Ex.Next(); } for (Standard_Integer k = 1; k <= M.Extent(); k++) { const TopoDS_Shape& shape = M(k); ret.append(Py::Object(new TopoShapeCompSolidPy(new TopoShape(shape)),true)); } return ret; } Py::List TopoShapePy::getEdges(void) const { Py::List ret; TopTools_IndexedMapOfShape M; TopExp_Explorer Ex(getTopoShapePtr()->getShape(),TopAbs_EDGE); while (Ex.More()) { M.Add(Ex.Current()); Ex.Next(); } for (Standard_Integer k = 1; k <= M.Extent(); k++) { const TopoDS_Shape& shape = M(k); ret.append(Py::Object(new TopoShapeEdgePy(new TopoShape(shape)),true)); } return ret; } Py::List TopoShapePy::getWires(void) const { Py::List ret; TopTools_IndexedMapOfShape M; TopExp_Explorer Ex(getTopoShapePtr()->getShape(),TopAbs_WIRE); while (Ex.More()) { M.Add(Ex.Current()); Ex.Next(); } for (Standard_Integer k = 1; k <= M.Extent(); k++) { const TopoDS_Shape& shape = M(k); ret.append(Py::Object(new TopoShapeWirePy(new TopoShape(shape)),true)); } return ret; } Py::List TopoShapePy::getCompounds(void) const { Py::List ret; TopTools_IndexedMapOfShape M; TopExp_Explorer Ex(getTopoShapePtr()->getShape(),TopAbs_COMPOUND); while (Ex.More()) { M.Add(Ex.Current()); Ex.Next(); } for (Standard_Integer k = 1; k <= M.Extent(); k++) { const TopoDS_Shape& shape = M(k); ret.append(Py::Object(new TopoShapeCompoundPy(new TopoShape(shape)),true)); } return ret; } Py::Float TopoShapePy::getLength(void) const { const TopoDS_Shape& shape = getTopoShapePtr()->getShape(); if (shape.IsNull()) throw Py::RuntimeError("shape is invalid"); GProp_GProps props; BRepGProp::LinearProperties(shape, props); return Py::Float(props.Mass()); } Py::Float TopoShapePy::getArea(void) const { const TopoDS_Shape& shape = getTopoShapePtr()->getShape(); if (shape.IsNull()) throw Py::RuntimeError("shape is invalid"); GProp_GProps props; BRepGProp::SurfaceProperties(shape, props); return Py::Float(props.Mass()); } Py::Float TopoShapePy::getVolume(void) const { const TopoDS_Shape& shape = getTopoShapePtr()->getShape(); if (shape.IsNull()) throw Py::RuntimeError("shape is invalid"); GProp_GProps props; BRepGProp::VolumeProperties(shape, props); return Py::Float(props.Mass()); } PyObject *TopoShapePy::getCustomAttributes(const char* attr) const { if (!attr) return 0; std::string name(attr); try { if (name.size() > 4 && name.substr(0,4) == "Face" && name[4]>=48 && name[4]<=57) { std::unique_ptr s(static_cast (getTopoShapePtr()->getSubElementByName(attr))); TopoDS_Shape Shape = s->Shape; return new TopoShapeFacePy(new TopoShape(Shape)); } else if (name.size() > 4 && name.substr(0,4) == "Edge" && name[4]>=48 && name[4]<=57) { std::unique_ptr s(static_cast (getTopoShapePtr()->getSubElementByName(attr))); TopoDS_Shape Shape = s->Shape; return new TopoShapeEdgePy(new TopoShape(Shape)); } else if (name.size() > 6 && name.substr(0,6) == "Vertex" && name[6]>=48 && name[6]<=57) { std::unique_ptr s(static_cast (getTopoShapePtr()->getSubElementByName(attr))); TopoDS_Shape Shape = s->Shape; return new TopoShapeVertexPy(new TopoShape(Shape)); } } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); return 0; } return 0; } int TopoShapePy::setCustomAttributes(const char* , PyObject *) { return 0; }