diff --git a/src/Mod/Part/App/TopoShape.cpp b/src/Mod/Part/App/TopoShape.cpp index 884ec6de75..32eb152d58 100644 --- a/src/Mod/Part/App/TopoShape.cpp +++ b/src/Mod/Part/App/TopoShape.cpp @@ -1286,6 +1286,42 @@ TopoDS_Shape TopoShape::cut(TopoDS_Shape shape) const return mkCut.Shape(); } +TopoDS_Shape TopoShape::cut(const std::vector& shapes, Standard_Real tolerance) const +{ + if (this->_Shape.IsNull()) + Standard_Failure::Raise("Base shape is null"); +#if OCC_VERSION_HEX < 0x060900 + (void)shapes; + (void)tolerance; + throw Base::RuntimeError("Multi cut is available only in OCC 6.9.0 and up."); +#else + BRepAlgoAPI_Cut mkCut; + mkCut.SetRunParallel(true); + TopTools_ListOfShape shapeArguments,shapeTools; + shapeArguments.Append(this->_Shape); + for (std::vector::const_iterator it = shapes.begin(); it != shapes.end(); ++it) { + if (it->IsNull()) + throw Base::ValueError("Tool shape is null"); + if (tolerance > 0.0) + // workaround for http://dev.opencascade.org/index.php?q=node/1056#comment-520 + shapeTools.Append(BRepBuilderAPI_Copy(*it).Shape()); + else + shapeTools.Append(*it); + } + + mkCut.SetArguments(shapeArguments); + mkCut.SetTools(shapeTools); + if (tolerance > 0.0) + mkCut.SetFuzzyValue(tolerance); + mkCut.Build(); + if (!mkCut.IsDone()) + throw Base::RuntimeError("Multi cut failed"); + + TopoDS_Shape resShape = mkCut.Shape(); + return resShape; +#endif +} + TopoDS_Shape TopoShape::common(TopoDS_Shape shape) const { if (this->_Shape.IsNull()) @@ -1296,6 +1332,42 @@ TopoDS_Shape TopoShape::common(TopoDS_Shape shape) const return mkCommon.Shape(); } +TopoDS_Shape TopoShape::common(const std::vector& shapes, Standard_Real tolerance) const +{ + if (this->_Shape.IsNull()) + Standard_Failure::Raise("Base shape is null"); +#if OCC_VERSION_HEX < 0x060900 + (void)shapes; + (void)tolerance; + throw Base::RuntimeError("Multi common is available only in OCC 6.9.0 and up."); +#else + BRepAlgoAPI_Common mkCommon; + mkCommon.SetRunParallel(true); + TopTools_ListOfShape shapeArguments,shapeTools; + shapeArguments.Append(this->_Shape); + for (std::vector::const_iterator it = shapes.begin(); it != shapes.end(); ++it) { + if (it->IsNull()) + throw Base::ValueError("Tool shape is null"); + if (tolerance > 0.0) + // workaround for http://dev.opencascade.org/index.php?q=node/1056#comment-520 + shapeTools.Append(BRepBuilderAPI_Copy(*it).Shape()); + else + shapeTools.Append(*it); + } + + mkCommon.SetArguments(shapeArguments); + mkCommon.SetTools(shapeTools); + if (tolerance > 0.0) + mkCommon.SetFuzzyValue(tolerance); + mkCommon.Build(); + if (!mkCommon.IsDone()) + throw Base::RuntimeError("Multi common failed"); + + TopoDS_Shape resShape = mkCommon.Shape(); + return resShape; +#endif +} + TopoDS_Shape TopoShape::fuse(TopoDS_Shape shape) const { if (this->_Shape.IsNull()) @@ -1306,75 +1378,7 @@ TopoDS_Shape TopoShape::fuse(TopoDS_Shape shape) const return mkFuse.Shape(); } -TopoDS_Shape TopoShape::multiCut(const std::vector& shapes, Standard_Real tolerance) const -{ - if (this->_Shape.IsNull()) - Standard_Failure::Raise("Base shape is null"); -#if OCC_VERSION_HEX < 0x060900 - (void)shapes; - (void)tolerance; - throw Base::AttributeError("multiCut is available only in OCC 6.9.0 and up."); -#else - BRepAlgoAPI_Cut mkCut; - mkCut.SetRunParallel(true); - TopTools_ListOfShape shapeArguments,shapeTools; - shapeArguments.Append(this->_Shape); - for (std::vector::const_iterator it = shapes.begin(); it != shapes.end(); ++it) { - if (it->IsNull()) - throw Base::Exception("Tool shape is null"); - if (tolerance > 0.0) - // workaround for http://dev.opencascade.org/index.php?q=node/1056#comment-520 - shapeTools.Append(BRepBuilderAPI_Copy(*it).Shape()); - else - shapeTools.Append(*it); - } - mkCut.SetArguments(shapeArguments); - mkCut.SetTools(shapeTools); - if (tolerance > 0.0) - mkCut.SetFuzzyValue(tolerance); - mkCut.Build(); - if (!mkCut.IsDone()) - throw Base::Exception("MultiCut failed"); - TopoDS_Shape resShape = mkCut.Shape(); - return resShape; -#endif -} - -TopoDS_Shape TopoShape::multiCommon(const std::vector& shapes, Standard_Real tolerance) const -{ - if (this->_Shape.IsNull()) - Standard_Failure::Raise("Base shape is null"); -#if OCC_VERSION_HEX < 0x060900 - (void)shapes; - (void)tolerance; - throw Base::AttributeError("multiCommon is available only in OCC 6.9.0 and up."); -#else - BRepAlgoAPI_Common mkCommon; - mkCommon.SetRunParallel(true); - TopTools_ListOfShape shapeArguments,shapeTools; - shapeArguments.Append(this->_Shape); - for (std::vector::const_iterator it = shapes.begin(); it != shapes.end(); ++it) { - if (it->IsNull()) - throw Base::Exception("Tool shape is null"); - if (tolerance > 0.0) - // workaround for http://dev.opencascade.org/index.php?q=node/1056#comment-520 - shapeTools.Append(BRepBuilderAPI_Copy(*it).Shape()); - else - shapeTools.Append(*it); - } - mkCommon.SetArguments(shapeArguments); - mkCommon.SetTools(shapeTools); - if (tolerance > 0.0) - mkCommon.SetFuzzyValue(tolerance); - mkCommon.Build(); - if (!mkCommon.IsDone()) - throw Base::Exception("MultiCommon failed"); - TopoDS_Shape resShape = mkCommon.Shape(); - return resShape; -#endif -} - -TopoDS_Shape TopoShape::multiFuse(const std::vector& shapes, Standard_Real tolerance) const +TopoDS_Shape TopoShape::fuse(const std::vector& shapes, Standard_Real tolerance) const { if (this->_Shape.IsNull()) Standard_Failure::Raise("Base shape is null"); @@ -1383,7 +1387,7 @@ TopoDS_Shape TopoShape::multiFuse(const std::vector& shapes, Stand Standard_Failure::Raise("Fuzzy Booleans are not supported in this version of OCCT"); TopoDS_Shape resShape = this->_Shape; if (resShape.IsNull()) - throw Base::Exception("Object shape is null"); + throw Base::ValueError("Object shape is null"); for (std::vector::const_iterator it = shapes.begin(); it != shapes.end(); ++it) { if (it->IsNull()) throw Base::Exception("Input shape is null"); @@ -1391,7 +1395,7 @@ TopoDS_Shape TopoShape::multiFuse(const std::vector& shapes, Stand BRepAlgoAPI_Fuse mkFuse(resShape, *it); // Let's check if the fusion has been successful if (!mkFuse.IsDone()) - throw Base::Exception("Fusion failed"); + throw Base::RuntimeError("Fusion failed"); resShape = mkFuse.Shape(); } #else @@ -1416,46 +1420,13 @@ TopoDS_Shape TopoShape::multiFuse(const std::vector& shapes, Stand mkFuse.SetFuzzyValue(tolerance); mkFuse.Build(); if (!mkFuse.IsDone()) - throw Base::Exception("MultiFusion failed"); + throw Base::RuntimeError("Multi fuse failed"); + TopoDS_Shape resShape = mkFuse.Shape(); #endif return resShape; } -TopoDS_Shape TopoShape::multiSection(const std::vector& shapes, Standard_Real tolerance) const -{ - if (this->_Shape.IsNull()) - Standard_Failure::Raise("Base shape is null"); -#if OCC_VERSION_HEX < 0x060900 - (void)shapes; - (void)tolerance; - throw Base::AttributeError("multiSection is available only in OCC 6.9.0 and up."); -#else - BRepAlgoAPI_Section mkSection; - mkSection.SetRunParallel(true); - TopTools_ListOfShape shapeArguments,shapeTools; - shapeArguments.Append(this->_Shape); - for (std::vector::const_iterator it = shapes.begin(); it != shapes.end(); ++it) { - if (it->IsNull()) - throw Base::Exception("Tool shape is null"); - if (tolerance > 0.0) - // workaround for http://dev.opencascade.org/index.php?q=node/1056#comment-520 - shapeTools.Append(BRepBuilderAPI_Copy(*it).Shape()); - else - shapeTools.Append(*it); - } - mkSection.SetArguments(shapeArguments); - mkSection.SetTools(shapeTools); - if (tolerance > 0.0) - mkSection.SetFuzzyValue(tolerance); - mkSection.Build(); - if (!mkSection.IsDone()) - throw Base::Exception("MultiSection failed"); - TopoDS_Shape resShape = mkSection.Shape(); - return resShape; -#endif -} - TopoDS_Shape TopoShape::oldFuse(TopoDS_Shape shape) const { if (this->_Shape.IsNull()) @@ -1476,6 +1447,42 @@ TopoDS_Shape TopoShape::section(TopoDS_Shape shape) const return mkSection.Shape(); } +TopoDS_Shape TopoShape::section(const std::vector& shapes, Standard_Real tolerance) const +{ + if (this->_Shape.IsNull()) + Standard_Failure::Raise("Base shape is null"); +#if OCC_VERSION_HEX < 0x060900 + (void)shapes; + (void)tolerance; + throw Base::RuntimeError("Multi section is available only in OCC 6.9.0 and up."); +#else + BRepAlgoAPI_Section mkSection; + mkSection.SetRunParallel(true); + TopTools_ListOfShape shapeArguments,shapeTools; + shapeArguments.Append(this->_Shape); + for (std::vector::const_iterator it = shapes.begin(); it != shapes.end(); ++it) { + if (it->IsNull()) + throw Base::ValueError("Tool shape is null"); + if (tolerance > 0.0) + // workaround for http://dev.opencascade.org/index.php?q=node/1056#comment-520 + shapeTools.Append(BRepBuilderAPI_Copy(*it).Shape()); + else + shapeTools.Append(*it); + } + + mkSection.SetArguments(shapeArguments); + mkSection.SetTools(shapeTools); + if (tolerance > 0.0) + mkSection.SetFuzzyValue(tolerance); + mkSection.Build(); + if (!mkSection.IsDone()) + throw Base::RuntimeError("Multi section failed"); + + TopoDS_Shape resShape = mkSection.Shape(); + return resShape; +#endif +} + std::list TopoShape::slice(const Base::Vector3d& dir, double d) const { CrossSection cs(dir.x, dir.y, dir.z, this->_Shape); diff --git a/src/Mod/Part/App/TopoShape.h b/src/Mod/Part/App/TopoShape.h index 3dad2df8b7..00f5ad1cfc 100644 --- a/src/Mod/Part/App/TopoShape.h +++ b/src/Mod/Part/App/TopoShape.h @@ -154,14 +154,14 @@ public: /** @name Boolean operation*/ //@{ TopoDS_Shape cut(TopoDS_Shape) const; + TopoDS_Shape cut(const std::vector&, Standard_Real tolerance = 0.0) const; TopoDS_Shape common(TopoDS_Shape) const; + TopoDS_Shape common(const std::vector&, Standard_Real tolerance = 0.0) const; TopoDS_Shape fuse(TopoDS_Shape) const; - TopoDS_Shape multiCut(const std::vector&, Standard_Real tolerance = 0.0) const; - TopoDS_Shape multiCommon(const std::vector&, Standard_Real tolerance = 0.0) const; - TopoDS_Shape multiFuse(const std::vector&, Standard_Real tolerance = 0.0) const; - TopoDS_Shape multiSection(const std::vector&, Standard_Real tolerance = 0.0) const; + TopoDS_Shape fuse(const std::vector&, Standard_Real tolerance = 0.0) const; TopoDS_Shape oldFuse(TopoDS_Shape) const; TopoDS_Shape section(TopoDS_Shape) const; + TopoDS_Shape section(const std::vector&, Standard_Real tolerance = 0.0) const; std::list slice(const Base::Vector3d&, double) const; TopoDS_Compound slices(const Base::Vector3d&, const std::vector&) const; /** diff --git a/src/Mod/Part/App/TopoShapePy.xml b/src/Mod/Part/App/TopoShapePy.xml index c19f61d992..ab11fe4eb6 100644 --- a/src/Mod/Part/App/TopoShapePy.xml +++ b/src/Mod/Part/App/TopoShapePy.xml @@ -140,35 +140,19 @@ This is a more detailed check as done in isValid(). - Union of this and a given topo shape. - - - - - multiCut((tool1,tool2,...),[tolerance=0.0]) -> Shape + Union of this and a given (list of) topo shape. +fuse(tool) -> Shape + or +fuse((tool1,tool2,...),[tolerance=0.0]) -> Shape -Substraction of this and a given list of topo shapes. +Union of this and a given list of topo shapes. -Supports: +Supports (OCCT 6.9.0 and above): - Fuzzy Boolean operations (global tolerance for a Boolean operation) - Support of multiple arguments for a single Boolean operation - Parallelization of Boolean Operations algorithm -OCC 6.9.0 or later is required. - - - - - multiCommon((tool1,tool2,...),[tolerance=0.0]) -> Shape - -Intersection of this and a given list of topo shapes. - -Supports: -- Fuzzy Boolean operations (global tolerance for a Boolean operation) -- Support of multiple arguments for a single Boolean operation (s1 AND (s2 OR s2)) -- Parallelization of Boolean Operations algorithm - -OCC 6.9.0 or later is required. +Beginning from OCCT 6.8.1 a tolerance value can be specified. @@ -182,21 +166,8 @@ Supports (OCCT 6.9.0 and above): - Support of multiple arguments for a single Boolean operation - Parallelization of Boolean Operations algorithm -Beginning from OCCT 6.8.1 a tolerance value can be specified. - - - - - multiSection((tool1,tool2,...),[tolerance=0.0]) -> Shape - -Section of this and a given list of topo shapes. - -Supports: -- Fuzzy Boolean operations (global tolerance for a Boolean operation) -- Support of multiple arguments for a single Boolean operation -- Parallelization of Boolean Operations algorithm - -OCC 6.9.0 or later is required. +Beginning from OCCT 6.8.1 a tolerance value can be specified. +Deprecated: use fuse() instead. @@ -206,12 +177,36 @@ OCC 6.9.0 or later is required. - Intersection of this and a given topo shape. + Intersection of this and a given (list of) topo shape. +common(tool) -> Shape + or +common((tool1,tool2,...),[tolerance=0.0]) -> Shape + +Intersection of this and a given list of topo shapes. + +Supports: +- Fuzzy Boolean operations (global tolerance for a Boolean operation) +- Support of multiple arguments for a single Boolean operation (s1 AND (s2 OR s2)) +- Parallelization of Boolean Operations algorithm + +OCC 6.9.0 or later is required. - Section of this with a given topo shape. + Section of this with a given (list of) topo shape. +section(tool) -> Shape + or +section((tool1,tool2,...),[tolerance=0.0]) -> Shape + +Section of this and a given list of topo shapes. + +Supports: +- Fuzzy Boolean operations (global tolerance for a Boolean operation) +- Support of multiple arguments for a single Boolean operation +- Parallelization of Boolean Operations algorithm + +OCC 6.9.0 or later is required. @@ -226,7 +221,19 @@ OCC 6.9.0 or later is required. - Difference of this and a given topo shape. + Difference of this and a given (list of) topo shape +cut(tool) -> Shape + or +cut((tool1,tool2,...),[tolerance=0.0]) -> Shape + +Substraction of this and a given list of topo shapes. + +Supports: +- Fuzzy Boolean operations (global tolerance for a Boolean operation) +- Support of multiple arguments for a single Boolean operation +- Parallelization of Boolean Operations algorithm + +OCC 6.9.0 or later is required. diff --git a/src/Mod/Part/App/TopoShapePyImp.cpp b/src/Mod/Part/App/TopoShapePyImp.cpp index 232c306b01..dcc1cd385b 100644 --- a/src/Mod/Part/App/TopoShapePyImp.cpp +++ b/src/Mod/Part/App/TopoShapePyImp.cpp @@ -759,90 +759,56 @@ PyObject* TopoShapePy::check(PyObject *args) 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::multiCut(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()); + if (PyArg_ParseTuple(args, "O!", &(TopoShapePy::Type), &pcObj)) { + 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)); } - else { - PyErr_SetString(PyExc_TypeError, "non-shape object in sequence"); - return 0; - } - } - try { - TopoDS_Shape multiCutShape = this->getTopoShapePtr()->multiCut(shapeVec,tolerance); - return new TopoShapePy(new TopoShape(multiCutShape)); - } - 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::multiCommon(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()); + 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; } - else { - PyErr_SetString(PyExc_TypeError, "non-shape object in sequence"); - return 0; - } } - try { - TopoDS_Shape multiCommonShape = this->getTopoShapePtr()->multiCommon(shapeVec,tolerance); - return new TopoShapePy(new TopoShape(multiCommonShape)); - } - 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; + + PyErr_Clear(); + double tolerance = 0.0; + if (PyArg_ParseTuple(args, "O|d", &pcObj, &tolerance)) { + 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()->fuse(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; + } } + + PyErr_SetString(PyExc_TypeError, "shape or sequence of shape expected"); + return 0; } PyObject* TopoShapePy::multiFuse(PyObject *args) @@ -864,7 +830,7 @@ PyObject* TopoShapePy::multiFuse(PyObject *args) } } try { - TopoDS_Shape multiFusedShape = this->getTopoShapePtr()->multiFuse(shapeVec,tolerance); + TopoDS_Shape multiFusedShape = this->getTopoShapePtr()->fuse(shapeVec,tolerance); return new TopoShapePy(new TopoShape(multiFusedShape)); } catch (Standard_Failure) { @@ -878,39 +844,6 @@ PyObject* TopoShapePy::multiFuse(PyObject *args) } } -PyObject* TopoShapePy::multiSection(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 multiSectionShape = this->getTopoShapePtr()->multiSection(shapeVec,tolerance); - return new TopoShapePy(new TopoShape(multiSectionShape)); - } - 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; @@ -937,47 +870,111 @@ PyObject* TopoShapePy::oldFuse(PyObject *args) PyObject* TopoShapePy::common(PyObject *args) { PyObject *pcObj; - if (!PyArg_ParseTuple(args, "O!", &(TopoShapePy::Type), &pcObj)) - return NULL; + if (PyArg_ParseTuple(args, "O!", &(TopoShapePy::Type), &pcObj)) { + 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; + } + } - 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; + PyErr_Clear(); + double tolerance = 0.0; + if (PyArg_ParseTuple(args, "O|d", &pcObj, &tolerance)) { + 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 multiCommonShape = this->getTopoShapePtr()->common(shapeVec,tolerance); + return new TopoShapePy(new TopoShape(multiCommonShape)); + } + 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; + } } + + PyErr_SetString(PyExc_TypeError, "shape or sequence of shape expected"); + return 0; } PyObject* TopoShapePy::section(PyObject *args) { PyObject *pcObj; - if (!PyArg_ParseTuple(args, "O!", &(TopoShapePy::Type), &pcObj)) - return NULL; + if (PyArg_ParseTuple(args, "O!", &(TopoShapePy::Type), &pcObj)) { + 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; + } + } - 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; + PyErr_Clear(); + double tolerance = 0.0; + if (PyArg_ParseTuple(args, "O|d", &pcObj, &tolerance)) { + 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 multiSectionShape = this->getTopoShapePtr()->section(shapeVec,tolerance); + return new TopoShapePy(new TopoShape(multiSectionShape)); + } + 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; + } } + + PyErr_SetString(PyExc_TypeError, "shape or sequence of shape expected"); + return 0; } PyObject* TopoShapePy::slice(PyObject *args) @@ -1038,24 +1035,56 @@ PyObject* TopoShapePy::slices(PyObject *args) PyObject* TopoShapePy::cut(PyObject *args) { PyObject *pcObj; - if (!PyArg_ParseTuple(args, "O!", &(TopoShapePy::Type), &pcObj)) - return NULL; + if (PyArg_ParseTuple(args, "O!", &(TopoShapePy::Type), &pcObj)) { + 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; + } + } - 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; + PyErr_Clear(); + double tolerance = 0.0; + if (PyArg_ParseTuple(args, "O|d", &pcObj, &tolerance)) { + 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 multiCutShape = this->getTopoShapePtr()->cut(shapeVec,tolerance); + return new TopoShapePy(new TopoShape(multiCutShape)); + } + 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; + } } + + PyErr_SetString(PyExc_TypeError, "shape or sequence of shape expected"); + return 0; } PyObject* TopoShapePy::generalFuse(PyObject *args) diff --git a/src/Mod/PartDesign/App/ShapeBinder.cpp b/src/Mod/PartDesign/App/ShapeBinder.cpp index 6c0a67f486..3d46c85cb9 100644 --- a/src/Mod/PartDesign/App/ShapeBinder.cpp +++ b/src/Mod/PartDesign/App/ShapeBinder.cpp @@ -142,7 +142,7 @@ Part::TopoShape ShapeBinder::buildShapeFromReferences( Part::Feature* obj, std:: try { if(!operators.empty() && !base.isNull()) - return base.multiFuse(operators); + return base.fuse(operators); } catch(...) { return base;