diff --git a/src/Mod/TechDraw/App/DrawViewDetail.cpp b/src/Mod/TechDraw/App/DrawViewDetail.cpp index 08069d59e6..70e9fd76a2 100644 --- a/src/Mod/TechDraw/App/DrawViewDetail.cpp +++ b/src/Mod/TechDraw/App/DrawViewDetail.cpp @@ -67,10 +67,8 @@ #include #include -#include "DrawPage.h" #include "DrawUtil.h" #include "DrawViewSection.h" -#include "Geometry.h" #include "GeometryObject.h" #include "Preferences.h" @@ -418,20 +416,17 @@ void DrawViewDetail::makeDetailShape(TopoDS_Shape& shape, void DrawViewDetail::postHlrTasks(void) { // Base::Console().Message("DVD::postHlrTasks()\n"); - geometryObject->pruneVertexGeom(Base::Vector3d(0.0,0.0,0.0), - Radius.getValue() * getScale()); //remove vertices beyond clipradius DrawViewPart::postHlrTasks(); + geometryObject->pruneVertexGeom(Base::Vector3d(0.0, 0.0, 0.0), + Radius.getValue() * getScale()); //remove vertices beyond clipradius + //second pass if required if (ScaleType.isValue("Automatic") && !checkFit()) { double newScale = autoScale(); Scale.setValue(newScale); Scale.purgeTouched(); - if (geometryObject) { - delete geometryObject; - geometryObject = nullptr; - detailExec(m_saveShape, m_saveDvp, m_saveDvs); - } + detailExec(m_saveShape, m_saveDvp, m_saveDvs); } overrideKeepUpdated(false); } @@ -443,7 +438,7 @@ void DrawViewDetail::onMakeDetailFinished(void) QObject::disconnect(connectDetailWatcher); //ancestor's buildGeometryObject will run HLR and face finding in a separate thread - geometryObject = buildGeometryObject(m_scaledShape, m_viewAxis); + m_tempGeometryObject = buildGeometryObject(m_scaledShape, m_viewAxis); } diff --git a/src/Mod/TechDraw/App/DrawViewPart.cpp b/src/Mod/TechDraw/App/DrawViewPart.cpp index 745f24c762..7148f09fb3 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.cpp +++ b/src/Mod/TechDraw/App/DrawViewPart.cpp @@ -84,9 +84,6 @@ #include "EdgeWalker.h" #include "Geometry.h" #include "GeometryObject.h" -#include "LandmarkDimension.h" -#include "LineGroup.h" -#include "Preferences.h" #include "ShapeExtractor.h" #include "DrawViewPart.h" @@ -107,6 +104,7 @@ PROPERTY_SOURCE_WITH_EXTENSIONS(TechDraw::DrawViewPart, DrawViewPart::DrawViewPart(void) : geometryObject(nullptr), + m_tempGeometryObject(nullptr), m_waitingForFaces(false), m_waitingForHlr(false) { @@ -318,18 +316,14 @@ void DrawViewPart::onChanged(const App::Property* prop) void DrawViewPart::partExec(TopoDS_Shape& shape) { -// Base::Console().Message("DVP::partExec()\n"); +// Base::Console().Message("DVP::partExec() - %s\n", getNameInDocument()); if (waitingForHlr()) { //finish what we are already doing before starting a new cycle return; } - if (geometryObject) { - delete geometryObject; - geometryObject = nullptr; - } - - geometryObject = makeGeometryForShape(shape); + //we need to keep using the old geometryObject until the new one is fully populated + m_tempGeometryObject = makeGeometryForShape(shape); if (CoarseView.getValue()){ onHlrFinished(); //poly algo does not run in separate thread, so we need to invoke //the post hlr processing manually @@ -339,7 +333,7 @@ void DrawViewPart::partExec(TopoDS_Shape& shape) //prepare the shape for HLR processing by centering, scaling and rotating it GeometryObject* DrawViewPart::makeGeometryForShape(TopoDS_Shape& shape) { -// Base::Console().Message("DVP::makeGeometryForShape()\n"); +// Base::Console().Message("DVP::makeGeometryForShape() - %s\n", getNameInDocument()); gp_Pnt inputCenter; Base::Vector3d stdOrg(0.0,0.0,0.0); gp_Ax2 viewAxis = getProjectionCS(stdOrg); @@ -390,8 +384,7 @@ TechDraw::GeometryObject* DrawViewPart::buildGeometryObject(TopoDS_Shape& shape, //4 parameter signature instead of the 3 parameter signature prevents clazy warning: //https://github.com/KDE/clazy/blob/1.11/docs/checks/README-connect-3arg-lambda.md connectHlrWatcher = QObject::connect(&m_hlrWatcher, &QFutureWatcherBase::finished, - &m_hlrWatcher, [this] { this->onHlrFinished(); } - ); + &m_hlrWatcher, [this] { this->onHlrFinished(); } ); m_hlrFuture = QtConcurrent::run(go, &GeometryObject::projectShape, shape, viewAxis); m_hlrWatcher.setFuture(m_hlrFuture); waitingForHlr(true); @@ -403,6 +396,14 @@ TechDraw::GeometryObject* DrawViewPart::buildGeometryObject(TopoDS_Shape& shape, void DrawViewPart::onHlrFinished(void) { // Base::Console().Message("DVP::onHlrFinished() - %s\n", getNameInDocument()); + + //now that the new GeometryObject is fully populated, we can replace the old one + if (geometryObject) { + delete geometryObject; + } + geometryObject = m_tempGeometryObject; + m_tempGeometryObject = nullptr; //superfluous + //the last hlr related task is to make a bbox of the results bbox = geometryObject->calcBoundingBox(); @@ -413,8 +414,9 @@ void DrawViewPart::onHlrFinished(void) postHlrTasks(); //application level tasks that depend on HLR/GO being complete //start face finding in a separate thread. We don't find faces when using the polygon - //HLR method - if (handleFaces() && !CoarseView.getValue() && !waitingForFaces()) { + //HLR method. + if (handleFaces() && !CoarseView.getValue() && + !waitingForFaces() && !waitingForHlr()) { try { //note that &m_faceWatcher in the third parameter is not strictly required, but using the //4 parameter signature instead of the 3 parameter signature prevents clazy warning: @@ -472,21 +474,25 @@ void DrawViewPart::postHlrTasks(void) //! make faces from the edge geometry void DrawViewPart::extractFaces() { -// Base::Console().Message("DVP::extractFaces()\n"); - if (!geometryObject || - !this->hasGeometry()) { - //no geometry yet so don't bother +// Base::Console().Message("DVP::extractFaces() - %s waitingForHlr: %d waitingForFaces: %d\n", +// getNameInDocument(), waitingForHlr(), waitingForFaces()); + if ( !geometryObject ) { + //geometry is in flux, can not make faces right now return; } showProgressMessage(getNameInDocument(), "is extracting faces"); - geometryObject->clearFaceGeom(); + //make a copy of the input edges so the loose tolerances of face finding are + //not applied to the real edge geometry. See TopoDS_Shape::TShape(). const std::vector& goEdges = geometryObject->getVisibleFaceEdges(SmoothVisible.getValue(),SeamVisible.getValue()); - //make a copy of the input edges so the loose tolerances of face finding are - //not applied to the real edge geometry. See TopoDS_Shape::TShape(). + if (goEdges.empty()) { + Base::Console().Message("DVP::extractFaces - %s - no face edges available!\n", getNameInDocument()); + return; + } + std::vector copyEdges; for (auto& tdEdge: goEdges) { BRepBuilderAPI_Copy copier(tdEdge->occEdge, true, true); //copy occEdge with its geometry (TShape) and mesh info @@ -499,6 +505,7 @@ void DrawViewPart::extractFaces() nonZero.push_back(e); } } + geometryObject->clearFaceGeom(); //HLR algo does not provide all edge intersections for edge endpoints. //need to split long edges touched by Vertex of another edge diff --git a/src/Mod/TechDraw/App/DrawViewPart.h b/src/Mod/TechDraw/App/DrawViewPart.h index c0aac00c2e..1ee08715d0 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.h +++ b/src/Mod/TechDraw/App/DrawViewPart.h @@ -219,7 +219,8 @@ public Q_SLOTS: protected: bool checkXDirection() const; - TechDraw::GeometryObject *geometryObject; + TechDraw::GeometryObject* geometryObject; + TechDraw::GeometryObject* m_tempGeometryObject; //holds the new GO until hlr is completed Base::BoundBox3d bbox; void onChanged(const App::Property* prop) override; diff --git a/src/Mod/TechDraw/App/DrawViewSection.cpp b/src/Mod/TechDraw/App/DrawViewSection.cpp index 57523dd225..b2b0ae64d0 100644 --- a/src/Mod/TechDraw/App/DrawViewSection.cpp +++ b/src/Mod/TechDraw/App/DrawViewSection.cpp @@ -71,15 +71,11 @@ #include -#include "Preferences.h" #include "Geometry.h" #include "GeometryObject.h" -#include "Cosmetic.h" #include "HatchLine.h" -#include "EdgeWalker.h" #include "DrawUtil.h" #include "DrawProjGroupItem.h" -#include "DrawProjectSplit.h" #include "DrawGeomHatch.h" #include "DrawHatch.h" #include "DrawViewSection.h" @@ -279,10 +275,6 @@ void DrawViewSection::sectionExec(TopoDS_Shape& baseShape) //should be caught before this return; } - if (geometryObject) { - delete geometryObject; - geometryObject = nullptr; - } try { //note that &m_cutWatcher in the third parameter is not strictly required, but using the @@ -430,7 +422,7 @@ void DrawViewSection::onSectionCutFinished() postSectionCutTasks(); //display geometry for cut shape is in geometryObject as in DVP - geometryObject = buildGeometryObject(m_scaledShape, m_viewAxis); + m_tempGeometryObject = buildGeometryObject(m_scaledShape, m_viewAxis); } //activities that depend on updated geometry object