From ffa62cd52ef5119129d6dae5d70e28c4dfedd5be Mon Sep 17 00:00:00 2001 From: PaddleStroke Date: Wed, 20 Mar 2024 16:14:56 +0100 Subject: [PATCH] TechDraw: Add support for Assembly Exploded Views --- src/Mod/TechDraw/App/ShapeExtractor.cpp | 64 ++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/src/Mod/TechDraw/App/ShapeExtractor.cpp b/src/Mod/TechDraw/App/ShapeExtractor.cpp index 3994b75d3c..5e2d8efea4 100644 --- a/src/Mod/TechDraw/App/ShapeExtractor.cpp +++ b/src/Mod/TechDraw/App/ShapeExtractor.cpp @@ -35,6 +35,8 @@ #include #include +#include +#include #include #include #include @@ -43,6 +45,7 @@ #include #include #include +#include //#include #include "ShapeExtractor.h" @@ -88,23 +91,70 @@ TopoDS_Shape ShapeExtractor::getShapes(const std::vector l // Base::Console().Message("SE::getShapes - skipping 2d link: %s\n", l->Label.getValue()); continue; } - if (l->isDerivedFrom()) { - App::Link* xLink = dynamic_cast(l); + + // Copy the pointer as not const so it can be changed if needed. + App::DocumentObject* obj = l; + + bool isExplodedView = false; + auto proxy = dynamic_cast(l->getPropertyByName("Proxy")); + Base::PyGILStateLocker lock; + if (proxy && proxy->getValue().hasAttr("saveAssemblyAndExplode")) { + isExplodedView = true; + + Py::Object explodedViewPy = proxy->getValue(); + Py::Object attr = explodedViewPy.getAttr("saveAssemblyAndExplode"); + + if (attr.ptr() && attr.isCallable()) { + Py::Tuple args(1); + args.setItem(0, Py::asObject(l->getPyObject())); + Py::Callable methode(attr); + Py::Object pyResult = methode.apply(args); + + if (PyObject_TypeCheck(pyResult.ptr(), &(Part::TopoShapePy::Type))) { + auto* shapepy = static_cast(pyResult.ptr()); + const TopoDS_Shape& shape = shapepy->getTopoShapePtr()->getShape(); + sourceShapes.push_back(shape); + } + } + + for (auto* inObj : l->getInList()) { + if (inObj->isDerivedFrom(App::Part::getClassTypeId())) { + // we replace obj by the assembly + obj = inObj; + break; + } + } + } + + if (obj->isDerivedFrom()) { + App::Link* xLink = dynamic_cast(obj); std::vector xShapes = getXShapes(xLink); if (!xShapes.empty()) { sourceShapes.insert(sourceShapes.end(), xShapes.begin(), xShapes.end()); continue; } - } else { - auto shape = Part::Feature::getShape(l); - // if link l has a shape, we use that shape. + } + else { + auto shape = Part::Feature::getShape(obj); + // if link obj has a shape, we use that shape. if(!SU::isShapeReallyNull((shape))) { - sourceShapes.push_back(getLocatedShape(l)); + sourceShapes.push_back(getLocatedShape(obj)); } else { - std::vector shapeList = getShapesFromObject(l); + std::vector shapeList = getShapesFromObject(obj); sourceShapes.insert(sourceShapes.end(), shapeList.begin(), shapeList.end()); } } + + if (isExplodedView) { + Py::Object explodedViewPy = proxy->getValue(); + + Py::Object attr = explodedViewPy.getAttr("restoreAssembly"); + if (attr.ptr() && attr.isCallable()) { + Py::Tuple args(1); + args.setItem(0, Py::asObject(l->getPyObject())); + Py::Callable(attr).apply(args); + } + } } BRep_Builder builder;