From afb1c3541690d95e9b7c95be251bdae78a64bef3 Mon Sep 17 00:00:00 2001 From: Yash Suthar Date: Sun, 18 Jan 2026 04:51:45 +0530 Subject: [PATCH] Sketcher: Fix external geometry creation from LCS (#26946) * Sketcher: Fix external geometry creation from LCS Signed-off-by: Yash Suthar * Sketcher : Refactor used freecad_cast Signed-off-by: Yash Suthar --------- Signed-off-by: Yash Suthar --- src/Mod/Sketcher/App/SketchObject.cpp | 67 ++++++++++++++----- .../Sketcher/Gui/DrawSketchHandlerExternal.h | 5 +- 2 files changed, 56 insertions(+), 16 deletions(-) diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index 991d96deae..92c909b674 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -4207,6 +4207,15 @@ bool SketchObject::isExternalAllowed(App::Document* pDoc, App::DocumentObject* p // planes Part::BodyBase* body_this = Part::BodyBase::findBodyOf(this); Part::BodyBase* body_obj = Part::BodyBase::findBodyOf(pObj); + + // DatumElements in an LCS, get body from the parent LCS + if (!body_obj && pObj->isDerivedFrom()) { + auto* datum = static_cast(pObj); + if (auto* lcs = datum->getLCS()) { + body_obj = Part::BodyBase::findBodyOf(lcs); + } + } + App::Part* part_this = App::Part::getPartOfObject(this); App::Part* part_obj = App::Part::getPartOfObject(pObj); if (part_this == part_obj) {// either in the same part, or in the root of document @@ -9284,22 +9293,27 @@ void SketchObject::rebuildExternalGeometry(std::optional extToAdd try { TopoDS_Shape refSubShape; - if (Obj->isDerivedFrom()) { - auto* datum = static_cast(Obj); + // Handles LCS ,resolve to actual datum object + const App::DocumentObject* resolvedObj = Obj; + if (Obj->isDerivedFrom() && !SubElement.empty()) { + auto* lcs = static_cast(Obj); + // get the datum element by name + App::DatumElement* datum = lcs->getDatumElement(SubElement.c_str()); + if (datum) { + resolvedObj = datum; + } + } + + if (auto* datum = freecad_cast(resolvedObj)) { refSubShape = datum->getShape(); } - else if (Obj->isDerivedFrom()) { - auto* refObj = static_cast(Obj); + else if (auto* refObj = freecad_cast(resolvedObj)) { const Part::TopoShape& refShape = refObj->Shape.getShape(); refSubShape = refShape.getSubShape(SubElement.c_str()); } - else if (Obj->isDerivedFrom()) { - auto* pl = static_cast(Obj); - Base::Placement plm = pl->Placement.getValue(); - Base::Vector3d base = plm.getPosition(); - Base::Rotation rot = plm.getRotation(); - Base::Vector3d normal(0, 0, 1); - rot.multVec(normal, normal); + else if (auto* pl = freecad_cast(resolvedObj)) { + Base::Vector3d base = pl->getBasePoint(); + Base::Vector3d normal = pl->getDirection(); gp_Pln plane(gp_Pnt(base.x, base.y, base.z), gp_Dir(normal.x, normal.y, normal.z)); BRepBuilderAPI_MakeFace fBuilder(plane); if (!fBuilder.IsDone()) @@ -9309,8 +9323,7 @@ void SketchObject::rebuildExternalGeometry(std::optional extToAdd TopoDS_Face f = TopoDS::Face(fBuilder.Shape()); refSubShape = f; } - else if (Obj->isDerivedFrom()) { - auto* line = static_cast(Obj); + else if (auto* line = freecad_cast(resolvedObj)) { Base::Placement plm = line->Placement.getValue(); Base::Vector3d base = plm.getPosition(); Base::Vector3d dir = line->getDirection(); @@ -9324,8 +9337,7 @@ void SketchObject::rebuildExternalGeometry(std::optional extToAdd TopoDS_Edge e = TopoDS::Edge(eBuilder.Shape()); refSubShape = e; } - else if (Obj->isDerivedFrom()) { - auto* point = static_cast(Obj); + else if (auto* point = freecad_cast(resolvedObj)) { Base::Placement plm = point->Placement.getValue(); Base::Vector3d base = plm.getPosition(); gp_Pnt p(base.x, base.y, base.z); @@ -9338,6 +9350,31 @@ void SketchObject::rebuildExternalGeometry(std::optional extToAdd TopoDS_Vertex v = TopoDS::Vertex(eBuilder.Shape()); refSubShape = v; } + else if (auto* line = freecad_cast(resolvedObj)) { + Base::Vector3d base = line->getBasePoint(); + Base::Vector3d dir = line->getDirection(); + gp_Lin l(gp_Pnt(base.x, base.y, base.z), gp_Dir(dir.x, dir.y, dir.z)); + BRepBuilderAPI_MakeEdge eBuilder(l); + if (!eBuilder.IsDone()) { + throw Base::RuntimeError( + "Sketcher: addExternal(): Failed to build edge from App::Line"); + } + + TopoDS_Edge e = TopoDS::Edge(eBuilder.Shape()); + refSubShape = e; + } + else if (auto* point = freecad_cast(resolvedObj)) { + Base::Vector3d base = point->getBasePoint(); + gp_Pnt p(base.x, base.y, base.z); + BRepBuilderAPI_MakeVertex eBuilder(p); + if (!eBuilder.IsDone()) { + throw Base::RuntimeError( + "Sketcher: addExternal(): Failed to build vertex from App::Point"); + } + + TopoDS_Vertex v = TopoDS::Vertex(eBuilder.Shape()); + refSubShape = v; + } else { throw Base::TypeError( "Datum feature type is not yet supported as external geometry for a sketch"); diff --git a/src/Mod/Sketcher/Gui/DrawSketchHandlerExternal.h b/src/Mod/Sketcher/Gui/DrawSketchHandlerExternal.h index 63c47c089f..98bb1a798a 100644 --- a/src/Mod/Sketcher/Gui/DrawSketchHandlerExternal.h +++ b/src/Mod/Sketcher/Gui/DrawSketchHandlerExternal.h @@ -102,7 +102,8 @@ public: // return false; //} - if (pObj->isDerivedFrom() || pObj->isDerivedFrom()) { + if (pObj->isDerivedFrom() || pObj->isDerivedFrom() + || pObj->isDerivedFrom() || pObj->isDerivedFrom()) { return true; } @@ -173,8 +174,10 @@ public: throw Base::ValueError("Sketcher: External geometry: Invalid object in selection"); } std::string subName(msg.pSubName); + if (obj->isDerivedFrom() || obj->isDerivedFrom() || obj->isDerivedFrom() || obj->isDerivedFrom() + || obj->isDerivedFrom() || obj->isDerivedFrom() || (subName.size() > 4 && subName.substr(0, 4) == "Edge") || (subName.size() > 6 && subName.substr(0, 6) == "Vertex") || (subName.size() > 4 && subName.substr(0, 4) == "Face")) {