diff --git a/src/Mod/TechDraw/App/ShapeExtractor.cpp b/src/Mod/TechDraw/App/ShapeExtractor.cpp index e2d070683d..292f146a14 100644 --- a/src/Mod/TechDraw/App/ShapeExtractor.cpp +++ b/src/Mod/TechDraw/App/ShapeExtractor.cpp @@ -163,32 +163,44 @@ std::vector ShapeExtractor::getXShapes(const App::Link* xLink) return xSourceShapes; } + bool needsTransform = false; std::vector children = xLink->getLinkedChildren(); - Base::Placement linkPlm; + Base::Placement linkPlm; // default constructor is an identity placement, i.e. no rotation nor translation if (xLink->hasPlacement()) { linkPlm = xLink->getLinkPlacementProperty()->getValue(); + needsTransform = true; + } + Base::Matrix4D linkScale; // default constructor is an identity matrix, possibly scale it with link's scale + if(xLink->getScaleProperty() || xLink->getScaleVectorProperty()) { + linkScale.scale(xLink->getScaleVector()); + needsTransform = true; } + Base::Matrix4D netTransform; if (!children.empty()) { for (auto& l:children) { -//What to do with LinkGroup??? -// if (l->getTypeId().isDerivedFrom(App::LinkGroup::getClassTypeId())) { -// Base::Console().Message("SE::getXShapes - found a LinkGroup\n"); -// } + bool childNeedsTransform = false; Base::Placement childPlm; + Base::Matrix4D childScale; if (l->getTypeId().isDerivedFrom(App::LinkElement::getClassTypeId())) { App::LinkElement* cLinkElem = static_cast(l); if (cLinkElem->hasPlacement()) { childPlm = cLinkElem->getLinkPlacementProperty()->getValue(); + childNeedsTransform = true; + } + if(cLinkElem->getScaleProperty() || cLinkElem->getScaleVectorProperty()) { + childScale.scale(cLinkElem->getScaleVector()); + childNeedsTransform = true; } } auto shape = Part::Feature::getShape(l); if(!shape.IsNull()) { - Base::Placement netPlm = linkPlm; - netPlm *= childPlm; - if (xLink->hasPlacement()) { + if (needsTransform || childNeedsTransform) { + // Multiplication is associative, but the braces show the idea of combining the two transforms: + // ( link placement and scale ) combined to ( child placement and scale ) + netTransform = (linkPlm.toMatrix() * linkScale) * (childPlm.toMatrix() * childScale); Part::TopoShape ts(shape); - ts.setPlacement(netPlm); + ts.transformGeometry(netTransform); shape = ts.getShape(); } if (shape.ShapeType() > TopAbs_COMPSOLID) { //simple shape @@ -209,9 +221,11 @@ std::vector ShapeExtractor::getXShapes(const App::Link* xLink) if (link != nullptr) { auto shape = Part::Feature::getShape(link); if(!shape.IsNull()) { - if (xLink->hasPlacement()) { + if (needsTransform) { + // Transform is just link placement and scale, no child objects + netTransform = linkPlm.toMatrix() * linkScale; Part::TopoShape ts(shape); - ts.setPlacement(linkPlm); + ts.transformGeometry(netTransform); shape = ts.getShape(); }