From 5b65757404cac9a7ed352a8879b92b019dfb7b5e Mon Sep 17 00:00:00 2001 From: wandererfan Date: Mon, 2 Oct 2023 11:01:02 -0400 Subject: [PATCH] [TD]fix sketch location in view --- src/Mod/TechDraw/App/DrawViewPart.cpp | 16 +++-- src/Mod/TechDraw/App/ShapeExtractor.cpp | 96 +++++++++++-------------- src/Mod/TechDraw/App/ShapeExtractor.h | 4 +- src/Mod/TechDraw/App/ShapeUtils.cpp | 9 +++ src/Mod/TechDraw/App/ShapeUtils.h | 1 + 5 files changed, 65 insertions(+), 61 deletions(-) diff --git a/src/Mod/TechDraw/App/DrawViewPart.cpp b/src/Mod/TechDraw/App/DrawViewPart.cpp index e6f39aef75..2a9dcb1922 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.cpp +++ b/src/Mod/TechDraw/App/DrawViewPart.cpp @@ -168,7 +168,7 @@ DrawViewPart::~DrawViewPart() //! XSource property lists TopoDS_Shape DrawViewPart::getSourceShape(bool fuse) const { - // Base::Console().Message("DVP::getSourceShape()\n"); +// Base::Console().Message("DVP::getSourceShape()\n"); const std::vector& links = getAllSources(); if (links.empty()) { return TopoDS_Shape(); @@ -203,11 +203,15 @@ std::vector DrawViewPart::getAllSources() const //! pick supported 2d shapes out of the Source properties and //! add them directly to the geometry without going through HLR +//! NOTE: this is for loose 2d shapes such as Part line or circle and is +//! not meant to include complex 2d shapes such as Sketches. void DrawViewPart::addShapes2d(void) { +// Base::Console().Message("DVP::addShapes2d()\n"); + // get all the 2d shapes in the sources, then pick through them for loose edges + // or vertices. std::vector shapes = ShapeExtractor::getShapes2d(getAllSources()); for (auto& s : shapes) { - //just vertices for now if (s.ShapeType() == TopAbs_VERTEX) { gp_Pnt gp = BRep_Tool::Pnt(TopoDS::Vertex(s)); Base::Vector3d vp(gp.X(), gp.Y(), gp.Z()); @@ -218,8 +222,7 @@ void DrawViewPart::addShapes2d(void) geometryObject->addVertex(v1); } else if (s.ShapeType() == TopAbs_EDGE) { - //not supporting edges yet. Why? - //Base::Console().Message("DVP::add2dShapes - found loose edge - isNull: %d\n", s.IsNull()); + Base::Console().Message("DVP::add2dShapes - found loose edge - isNull: %d\n", s.IsNull()); TopoDS_Shape sTrans = ShapeUtils::moveShape(s, m_saveCentroid * -1.0); TopoDS_Shape sScale = ShapeUtils::scaleShape(sTrans, @@ -229,7 +232,10 @@ void DrawViewPart::addShapes2d(void) BaseGeomPtr bg = projectEdge(edge); geometryObject->addEdge(bg); - //save connection between source feat and this edge + + } else { + // message for developers. + //Base::Console().Message("DEVEL: DVP::addShapes2d - shape is not a vertex or edge\n"); } } } diff --git a/src/Mod/TechDraw/App/ShapeExtractor.cpp b/src/Mod/TechDraw/App/ShapeExtractor.cpp index c31af9e1ab..51595262eb 100644 --- a/src/Mod/TechDraw/App/ShapeExtractor.cpp +++ b/src/Mod/TechDraw/App/ShapeExtractor.cpp @@ -41,15 +41,18 @@ #include #include #include +#include //#include #include "ShapeExtractor.h" #include "DrawUtil.h" #include "Preferences.h" +#include "ShapeUtils.h" using namespace TechDraw; using DU = DrawUtil; +using SU = ShapeUtils; std::vector ShapeExtractor::getShapes2d(const std::vector links, bool overridePref) { @@ -66,30 +69,23 @@ std::vector ShapeExtractor::getShapes2d(const std::vectorgetTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { - //need to apply global placement here. ??? because 2d shapes (Points so far) - //don't get gp from Part::feature::getShape() ???? - const Part::Feature* pf = static_cast(d); - Part::TopoShape ts = pf->Shape.getShape(); - ts.setPlacement(pf->globalPlacement()); - shapes2d.push_back(ts.getShape()); + shapes2d.push_back(getLocatedShape(d)); } } } } else { if (is2dObject(l)) { if (l->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { - //need to apply placement here - const Part::Feature* pf = static_cast(l); - Part::TopoShape ts = pf->Shape.getShape(); - ts.setPlacement(pf->globalPlacement()); - shapes2d.push_back(ts.getShape()); - } + shapes2d.push_back(getLocatedShape(l)); + } // other 2d objects would go here - Draft objects? } } } return shapes2d; } +//! get the located and oriented shapes corresponding to the the links. If the shapes are to be +//! fused, include2d should be false as 2d & 3d shapes may not fuse. TopoDS_Shape ShapeExtractor::getShapes(const std::vector links, bool include2d) { // Base::Console().Message("SE::getShapes() - links in: %d\n", links.size()); @@ -108,8 +104,8 @@ TopoDS_Shape ShapeExtractor::getShapes(const std::vector l } } else { auto shape = Part::Feature::getShape(l); - if(!shape.IsNull()) { - sourceShapes.push_back(shape); + if(!SU::isShapeReallyNull((shape))) { + sourceShapes.push_back(getLocatedShape(l)); } else { std::vector shapeList = getShapesFromObject(l); sourceShapes.insert(sourceShapes.end(), shapeList.begin(), shapeList.end()); @@ -120,33 +116,29 @@ TopoDS_Shape ShapeExtractor::getShapes(const std::vector l BRep_Builder builder; TopoDS_Compound comp; builder.MakeCompound(comp); - bool found = false; for (auto& s:sourceShapes) { - if (s.IsNull()) { + if (SU::isShapeReallyNull(s)) { continue; } else if (s.ShapeType() < TopAbs_SOLID) { //clean up composite shapes TopoDS_Shape cleanShape = stripInfiniteShapes(s); if (!cleanShape.IsNull()) { builder.Add(comp, cleanShape); - found = true; } } else if (Part::TopoShape(s).isInfinite()) { continue; //simple shape is infinite } else { //a simple shape - add to compound builder.Add(comp, s); - found = true; } } //it appears that an empty compound is !IsNull(), so we need to check a different way - //if we added anything to the compound. - if (found) { + if (!SU::isShapeReallyNull(comp)) { // BRepTools::Write(comp, "SEResult.brep"); //debug return comp; } - Base::Console().Error("ShapeExtractor failed to get shape.\n"); +// Base::Console().Error("DEVEL: ShapeExtractor failed to get any shape.\n"); return TopoDS_Shape(); } @@ -263,25 +255,7 @@ std::vector ShapeExtractor::getShapesFromObject(const App::Documen App::Property* gProp = docObj->getPropertyByName("Group"); App::Property* sProp = docObj->getPropertyByName("Shape"); if (docObj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { - const Part::Feature* pf = static_cast(docObj); - Part::TopoShape ts(pf->Shape.getShape()); - - //ts might be garbage, better check - try { - if (!ts.isNull()) { - ts.setPlacement(pf->globalPlacement()); - result.push_back(ts.getShape()); - } - } - catch (Standard_Failure& e) { - Base::Console().Error("ShapeExtractor - %s encountered OCC error: %s \n", docObj->getNameInDocument(), e.GetMessageString()); - return result; - } - catch (...) { - Base::Console().Error("ShapeExtractor failed to retrieve shape from %s\n", docObj->getNameInDocument()); - return result; - } - + result.push_back(getLocatedShape(docObj)); } else if (gex) { //is a group extension std::vector objs = gex->Group.getValues(); std::vector shapes; @@ -307,8 +281,7 @@ std::vector ShapeExtractor::getShapesFromObject(const App::Documen } else if (sProp) { //has a Shape property Part::PropertyPartShape* shape = dynamic_cast(sProp); if (shape) { - TopoDS_Shape occShape = shape->getValue(); - result.push_back(occShape); + result.push_back(getLocatedShape(docObj)); } } return result; @@ -392,21 +365,20 @@ bool ShapeExtractor::is2dObject(App::DocumentObject* obj) return false; } -//skip edges for now. +// just these for now bool ShapeExtractor::isEdgeType(App::DocumentObject* obj) { - (void) obj; bool result = false; -// Base::Type t = obj->getTypeId(); -// if (t.isDerivedFrom(Part::Line::getClassTypeId()) ) { -// result = true; -// } else if (t.isDerivedFrom(Part::Circle::getClassTypeId())) { -// result = true; -// } else if (t.isDerivedFrom(Part::Ellipse::getClassTypeId())) { -// result = true; -// } else if (t.isDerivedFrom(Part::RegularPolygon::getClassTypeId())) { -// result = true; -// } + Base::Type t = obj->getTypeId(); + if (t.isDerivedFrom(Part::Line::getClassTypeId()) ) { + result = true; + } else if (t.isDerivedFrom(Part::Circle::getClassTypeId())) { + result = true; + } else if (t.isDerivedFrom(Part::Ellipse::getClassTypeId())) { + result = true; + } else if (t.isDerivedFrom(Part::RegularPolygon::getClassTypeId())) { + result = true; + } return result; } @@ -439,9 +411,11 @@ bool ShapeExtractor::isDraftPoint(App::DocumentObject* obj) return false; } + +//! get the location of a point object Base::Vector3d ShapeExtractor::getLocation3dFromFeat(App::DocumentObject* obj) { -// Base::Console().Message("SE::getLocation3dFromFeat()\n"); + Base::Console().Message("SE::getLocation3dFromFeat()\n"); if (!isPointType(obj)) { return Base::Vector3d(0.0, 0.0, 0.0); } @@ -465,6 +439,18 @@ Base::Vector3d ShapeExtractor::getLocation3dFromFeat(App::DocumentObject* obj) return Base::Vector3d(0.0, 0.0, 0.0); } +//! get the located and oriented version of docObj shape +TopoDS_Shape ShapeExtractor::getLocatedShape(const App::DocumentObject* docObj) +{ + Part::TopoShape shape = Part::Feature::getShape(docObj); + const Part::Feature* pf = dynamic_cast(docObj); + if (pf) { + shape.setPlacement(pf->globalPlacement()); + } + return shape.getShape(); +} + +//! true if we should include loose 2d geometry bool ShapeExtractor::prefAdd2d() { return Preferences::getPreferenceGroup("General")->GetBool("ShowLoose2d", false); diff --git a/src/Mod/TechDraw/App/ShapeExtractor.h b/src/Mod/TechDraw/App/ShapeExtractor.h index 30aad1a5d8..0575cda726 100644 --- a/src/Mod/TechDraw/App/ShapeExtractor.h +++ b/src/Mod/TechDraw/App/ShapeExtractor.h @@ -50,11 +50,13 @@ public: static bool isEdgeType(App::DocumentObject* obj); static bool isPointType(App::DocumentObject* obj); static bool isDraftPoint(App::DocumentObject* obj); - static Base::Vector3d getLocation3dFromFeat(App::DocumentObject* obj); + static Base::Vector3d getLocation3dFromFeat(App::DocumentObject *obj); static bool prefAdd2d(); static TopoDS_Shape stripInfiniteShapes(TopoDS_Shape inShape); + static TopoDS_Shape getLocatedShape(const App::DocumentObject* docObj); + protected: private: diff --git a/src/Mod/TechDraw/App/ShapeUtils.cpp b/src/Mod/TechDraw/App/ShapeUtils.cpp index c0497a1ad2..cd1c4d8907 100644 --- a/src/Mod/TechDraw/App/ShapeUtils.cpp +++ b/src/Mod/TechDraw/App/ShapeUtils.cpp @@ -367,3 +367,12 @@ std::pair ShapeUtils::getEdgeEnds(TopoDS_Edge ed return result; } +//! check for shape is null or shape has no subshapes(vertex/edge/face/etc) +//! this handles the case of an empty compound which is not IsNull, but has no +//! content. +bool ShapeUtils::isShapeReallyNull(TopoDS_Shape shape) +{ + // if the shape is null or it has no subshapes, then it is really null + return shape.IsNull() || !TopoDS_Iterator(shape).More(); +} + diff --git a/src/Mod/TechDraw/App/ShapeUtils.h b/src/Mod/TechDraw/App/ShapeUtils.h index 2a8272e892..5d0225f6bb 100644 --- a/src/Mod/TechDraw/App/ShapeUtils.h +++ b/src/Mod/TechDraw/App/ShapeUtils.h @@ -108,6 +108,7 @@ public: static std::pair getEdgeEnds(TopoDS_Edge edge); + static bool isShapeReallyNull(TopoDS_Shape shape); }; }