diff --git a/src/Mod/TechDraw/App/DrawViewDetail.cpp b/src/Mod/TechDraw/App/DrawViewDetail.cpp index ed88fc043c..16f806b96b 100644 --- a/src/Mod/TechDraw/App/DrawViewDetail.cpp +++ b/src/Mod/TechDraw/App/DrawViewDetail.cpp @@ -66,8 +66,9 @@ #include -# include -# include +#include +#include +#include "QtConcurrent/qtconcurrentrun.h" #include #include @@ -102,7 +103,8 @@ using namespace std; PROPERTY_SOURCE(TechDraw::DrawViewDetail, TechDraw::DrawViewPart) -DrawViewDetail::DrawViewDetail() +DrawViewDetail::DrawViewDetail() : + m_waitingForDetail(false) { static const char *dgroup = "Detail"; @@ -192,30 +194,25 @@ void DrawViewDetail::onChanged(const App::Property* prop) App::DocumentObjectExecReturn *DrawViewDetail::execute() { -// Base::Console().Message("DVD::execute() - %s\n", Label.getValue()); +// Base::Console().Message("DVD::execute() - %s\n", getNameInDocument()); if (!keepUpdated()) { return App::DocumentObject::StdReturn; } App::DocumentObject* baseObj = BaseView.getValue(); if (!baseObj) { - bool isRestoring = getDocument()->testStatus(App::Document::Status::Restoring); - if (isRestoring) { - Base::Console().Warning("DVD::execute - No BaseView (but document is restoring) - %s\n", - getNameInDocument()); - } else { - Base::Console().Error("Error: DVD::execute - No BaseView(s) linked. - %s\n", + Base::Console().Log("DVD::execute - No BaseView(s) linked. - %s\n", getNameInDocument()); - } return DrawView::execute(); } - DrawViewPart* dvp = nullptr; if (!baseObj->getTypeId().isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) { - return new App::DocumentObjectExecReturn("BaseView object is not a DrawViewPart object"); + Base::Console().Log("DVD::execute - %s - BaseView object is not a DrawViewPart object\n", + getNameInDocument()); + return DrawView::execute(); } - dvp = static_cast(baseObj); + DrawViewPart* dvp = static_cast(baseObj); DrawProjGroupItem* dpgi = nullptr; if (dvp->isDerivedFrom(TechDraw::DrawProjGroupItem::getClassTypeId())) { @@ -239,14 +236,8 @@ App::DocumentObjectExecReturn *DrawViewDetail::execute() } if (shape.IsNull()) { - bool isRestoring = getDocument()->testStatus(App::Document::Status::Restoring); - if (isRestoring) { - Base::Console().Warning("DVD::execute - source shape is invalid - (but document is restoring) - %s\n", - getNameInDocument()); - } else { - Base::Console().Error("Error: DVD::execute - Source shape is Null. - %s\n", - getNameInDocument()); - } + Base::Console().Log("DVD::execute - %s - Source shape is Null\n", + getNameInDocument()); return DrawView::execute(); } @@ -279,14 +270,32 @@ App::DocumentObjectExecReturn *DrawViewDetail::execute() //try to create a detail of the solids & shells in shape //if there are no solids/shells in shape, use the edges in shape -void DrawViewDetail::detailExec(TopoDS_Shape shape, +void DrawViewDetail::detailExec(TopoDS_Shape& shape, DrawViewPart* dvp, DrawViewSection* dvs) { if (waitingForResult()) { - Base::Console().Message("DVD::detailExec - waiting for result\n"); +// Base::Console().Message("DVD::detailExec - waiting for result\n"); return; } + QObject::connect(&m_detailWatcher, SIGNAL(finished()), this, SLOT(onMakeDetailFinished())); + m_detailFuture = QtConcurrent::run(this, &DrawViewDetail::makeDetailShape, shape, dvp, dvs); + m_detailWatcher.setFuture(m_detailFuture); +} + +//this runs in a separate thread since it can sometimes take a long time +void DrawViewDetail::makeDetailShape(TopoDS_Shape& shape, + DrawViewPart* dvp, + DrawViewSection* dvs) +{ + if (waitingForDetail()) { +// Base::Console().Message("DVD::makeDetailShape - already in progress. returning\n"); + return; + } + waitingForDetail(true); + showProgressMessage(getNameInDocument(), "is making detail shape"); + +// auto start = chrono::high_resolution_clock::now(); Base::Vector3d anchor = AnchorPoint.getValue(); //this is a 2D point (in unrotated coords) Base::Vector3d dirDetail = dvp->Direction.getValue(); @@ -314,11 +323,9 @@ void DrawViewDetail::detailExec(TopoDS_Shape shape, shapeCenter = Base::Vector3d(0.0, 0.0, 0.0); - gp_Ax2 viewAxis; - - viewAxis = dvp->getProjectionCS(shapeCenter); + m_viewAxis = dvp->getProjectionCS(shapeCenter); anchor = Base::Vector3d(anchor.x,anchor.y, 0.0); //anchor coord in projection CS - Base::Vector3d anchorOffset3d = DrawUtil::toR3(viewAxis, anchor); //actual anchor coords in R3 + Base::Vector3d anchorOffset3d = DrawUtil::toR3(m_viewAxis, anchor); //actual anchor coords in R3 Bnd_Box bbxSource; bbxSource.SetGap(0.0); @@ -434,59 +441,77 @@ void DrawViewDetail::detailExec(TopoDS_Shape shape, //centroid of result inputCenter = TechDraw::findCentroid(pieces, dirDetail); - Base::Vector3d centroid(inputCenter.X(), - inputCenter.Y(), - inputCenter.Z()); - m_saveCentroid += centroid; //center of massaged shape + Base::Vector3d centroid(inputCenter.X(), + inputCenter.Y(), + inputCenter.Z()); + m_saveCentroid += centroid; //center of massaged shape - TopoDS_Shape scaledShape; - if ((solidCount > 0) || - (shellCount > 0)) { - //align shape with detail anchor - TopoDS_Shape centeredShape = TechDraw::moveShape(pieces, - anchorOffset3d * -1.0); - scaledShape = TechDraw::scaleShape(centeredShape, - getScale()); - if (debugDetail()) { - BRepTools::Write(scaledShape, "DVDScaled.brep"); //debug + if ((solidCount > 0) || + (shellCount > 0)) { + //align shape with detail anchor + TopoDS_Shape centeredShape = TechDraw::moveShape(pieces, + anchorOffset3d * -1.0); + m_scaledShape = TechDraw::scaleShape(centeredShape, + getScale()); + if (debugDetail()) { + BRepTools::Write(m_scaledShape, "DVDScaled.brep"); //debug + } + } else { + //no solids, no shells, do what you can with edges + TopoDS_Shape projectedEdges = projectEdgesOntoFace(myShape, aProjFace, gdir); + TopoDS_Shape centeredShape = TechDraw::moveShape(projectedEdges, + anchorOffset3d * -1.0); + if (debugDetail()) { + BRepTools::Write(projectedEdges, "DVDProjectedEdges.brep"); //debug + BRepTools::Write(centeredShape, "DVDCenteredShape.brep"); //debug + } + m_scaledShape = TechDraw::scaleShape(centeredShape, + getScale()); } - } else { - //no solids, no shells, do what you can with edges - TopoDS_Shape projectedEdges = projectEdgesOntoFace(myShape, aProjFace, gdir); - TopoDS_Shape centeredShape = TechDraw::moveShape(projectedEdges, - anchorOffset3d * -1.0); - if (debugDetail()) { - BRepTools::Write(projectedEdges, "DVDProjectedEdges.brep"); //debug - BRepTools::Write(centeredShape, "DVDCenteredShape.brep"); //debug + + Base::Vector3d stdOrg(0.0,0.0,0.0); + m_viewAxis = dvp->getProjectionCS(stdOrg); + + if (!DrawUtil::fpCompare(Rotation.getValue(),0.0)) { + m_scaledShape = TechDraw::rotateShape(m_scaledShape, + m_viewAxis, + Rotation.getValue()); } - scaledShape = TechDraw::scaleShape(centeredShape, - getScale()); - } + } //end try block - Base::Vector3d stdOrg(0.0,0.0,0.0); - gp_Ax2 viewAxis = dvp->getProjectionCS(stdOrg); - - if (!DrawUtil::fpCompare(Rotation.getValue(),0.0)) { - scaledShape = TechDraw::rotateShape(scaledShape, - viewAxis, - Rotation.getValue()); - } - - geometryObject = buildGeometryObject(scaledShape,viewAxis); - } catch (Standard_Failure& e1) { - Base::Console().Message("LOG - DVD::execute - failed to create detail %s - %s **\n",getNameInDocument(),e1.GetMessageString()); + Base::Console().Message("DVD::makeDetailShape - failed to create detail %s - %s **\n",getNameInDocument(),e1.GetMessageString()); return; } + +// auto end = chrono::high_resolution_clock::now(); +// auto diff = end - start; +// double diffOut = chrono::duration (diff).count(); +// Base::Console().Message("DVD::makeDetailShape - %s spent: %.3f millisecs making detail shape\n", getNameInDocument(), diffOut); + showProgressMessage(getNameInDocument(), "has finished making detail 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(); } -TopoDS_Shape DrawViewDetail::projectEdgesOntoFace(TopoDS_Shape edgeShape, TopoDS_Face projFace, gp_Dir projDir) +//continue processing after makeDetailShape thread is finished +void DrawViewDetail::onMakeDetailFinished(void) +{ + waitingForDetail(false); + QObject::disconnect(&m_detailWatcher, SIGNAL(finished()), this, SLOT(onMakeDetailFinished())); + + //ancestor's buildGeometryObject will run HLR and face finding in a separate thread + geometryObject = buildGeometryObject(m_scaledShape, m_viewAxis); + +} +TopoDS_Shape DrawViewDetail::projectEdgesOntoFace(TopoDS_Shape &edgeShape, + TopoDS_Face &projFace, + gp_Dir& projDir) { BRep_Builder builder; TopoDS_Compound edges; diff --git a/src/Mod/TechDraw/App/DrawViewDetail.h b/src/Mod/TechDraw/App/DrawViewDetail.h index 650f569a58..24363bc242 100644 --- a/src/Mod/TechDraw/App/DrawViewDetail.h +++ b/src/Mod/TechDraw/App/DrawViewDetail.h @@ -23,6 +23,9 @@ #ifndef _DrawViewDetail_h_ #define _DrawViewDetail_h_ +#include +#include + #include #include #include @@ -47,6 +50,7 @@ namespace TechDraw class TechDrawExport DrawViewDetail : public DrawViewPart { PROPERTY_HEADER_WITH_OVERRIDE(Part::DrawViewDetail); + Q_OBJECT public: /// Constructor @@ -67,22 +71,37 @@ public: void unsetupObject() override; - void detailExec(TopoDS_Shape s, + void detailExec(TopoDS_Shape& s, DrawViewPart* baseView, DrawViewSection* sectionAlias); - double getFudgeRadius(); - TopoDS_Shape projectEdgesOntoFace(TopoDS_Shape edgeShape, TopoDS_Face projFace, gp_Dir projDir); + void makeDetailShape(TopoDS_Shape& shape, + DrawViewPart* dvp, + DrawViewSection* dvs); + void postHlrTasks(void) override; + void waitingForDetail(bool s) { m_waitingForDetail = s; } + bool waitingForDetail(void) { return m_waitingForDetail; } + + double getFudgeRadius(void); + TopoDS_Shape projectEdgesOntoFace(TopoDS_Shape& edgeShape, + TopoDS_Face& projFace, + gp_Dir& projDir); std::vector getDetailRefs() const override; - void postHlrTasks(void) override; +public Q_SLOTS: + void onMakeDetailFinished(void); protected: - Base::Vector3d toR3(const gp_Ax2 fromSystem, const Base::Vector3d fromPoint); - void getParameters(); + void getParameters(void); double m_fudge; bool debugDetail() const; + TopoDS_Shape m_scaledShape; + gp_Ax2 m_viewAxis; + + QFutureWatcher m_detailWatcher; + QFuture m_detailFuture; + bool m_waitingForDetail; }; typedef App::FeaturePythonT DrawViewDetailPython; diff --git a/src/Mod/TechDraw/App/DrawViewPart.cpp b/src/Mod/TechDraw/App/DrawViewPart.cpp index 9fd1c54d96..7ed9736b00 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.cpp +++ b/src/Mod/TechDraw/App/DrawViewPart.cpp @@ -287,36 +287,26 @@ App::DocumentObjectExecReturn *DrawViewPart::execute(void) if (!keepUpdated()) { return App::DocumentObject::StdReturn; } + + if (waitingForResult()) { + return DrawView::execute(); + } - App::Document* doc = getDocument(); - bool isRestoring = doc->testStatus(App::Document::Status::Restoring); const std::vector& links = getAllSources(); if (links.empty()) { - if (isRestoring) { - Base::Console().Warning("DVP::execute - No Sources (but document is restoring) - %s\n", - getNameInDocument()); - } else { - Base::Console().Error("Error: DVP::execute - No Source(s) linked. - %s\n", - getNameInDocument()); - } - return App::DocumentObject::StdReturn; + Base::Console().Log("DVP::execute - %s - No Source(s) linked.\n", + getNameInDocument()); + return DrawView::execute(); } TopoDS_Shape shape = getSourceShape(); if (shape.IsNull()) { - if (isRestoring) { - Base::Console().Warning("DVP::execute - source shape is invalid - (but document is restoring) - %s\n", - getNameInDocument()); - } else { - Base::Console().Error("Error: DVP::execute - Source shape is Null. - %s\n", - getNameInDocument()); - } - return App::DocumentObject::StdReturn; + Base::Console().Log("DVP::execute - %s - Source shape is Null.\n", + getNameInDocument()); + return DrawView::execute(); } - - bool haveX = checkXDirection(); - if (!haveX) { + if (!checkXDirection()) { //block touch/onChanged stuff Base::Vector3d newX = getXDirection(); XDirection.setValue(newX); @@ -381,11 +371,9 @@ void DrawViewPart::onChanged(const App::Property* prop) } DrawView::onChanged(prop); - -//TODO: when scale changes, any Dimensions for this View sb recalculated. DVD should pick this up subject to topological naming issues. } -void DrawViewPart::partExec(TopoDS_Shape shape) +void DrawViewPart::partExec(TopoDS_Shape& shape) { // Base::Console().Message("DVP::partExec()\n"); if (waitingForResult()) { @@ -402,19 +390,15 @@ void DrawViewPart::partExec(TopoDS_Shape shape) geometryObject = makeGeometryForShape(shape); } -GeometryObject* DrawViewPart::makeGeometryForShape(TopoDS_Shape shape) +GeometryObject* DrawViewPart::makeGeometryForShape(TopoDS_Shape& shape) { // Base::Console().Message("DVP::makeGeometryForShape()\n"); +// BRepTools::Write(shape, "DVPShape.brep"); //debug gp_Pnt inputCenter; Base::Vector3d stdOrg(0.0,0.0,0.0); - gp_Ax2 viewAxis = getProjectionCS(stdOrg); - -// BRepTools::Write(shape, "DVPShape.brep"); //debug - inputCenter = TechDraw::findCentroid(shape, viewAxis); - Base::Vector3d centroid(inputCenter.X(), inputCenter.Y(), inputCenter.Z()); @@ -438,7 +422,7 @@ GeometryObject* DrawViewPart::makeGeometryForShape(TopoDS_Shape shape) } //note: slightly different than routine with same name in DrawProjectSplit -TechDraw::GeometryObject* DrawViewPart::buildGeometryObject(TopoDS_Shape shape, gp_Ax2 viewAxis) +TechDraw::GeometryObject* DrawViewPart::buildGeometryObject(TopoDS_Shape& shape, gp_Ax2& viewAxis) { // Base::Console().Message("DVP::buildGeometryObject()\n"); TechDraw::GeometryObject* go = new TechDraw::GeometryObject(getNameInDocument(), this); @@ -454,12 +438,12 @@ TechDraw::GeometryObject* DrawViewPart::buildGeometryObject(TopoDS_Shape shape, //the post hlr processing manually } else { // Base::Console().Message("DVP::buildGeometryObject - starting projectShape\n"); - waitingForHlr(true); + //project shape runs in a separate thread since if can take a long time QObject::connect(&m_hlrWatcher, SIGNAL(finished()), this, SLOT(onHlrFinished())); m_hlrFuture = QtConcurrent::run(go, &GeometryObject::projectShape, shape, viewAxis); m_hlrWatcher.setFuture(m_hlrFuture); + waitingForHlr(true); } - return go; } @@ -473,11 +457,11 @@ void DrawViewPart::onHlrFinished(void) waitingForHlr(false); QObject::disconnect(&m_hlrWatcher, SIGNAL(finished()), this, SLOT(onHlrFinished())); - showProgressMessage(getNameInDocument(), "has finished finding hidden lines"); postHlrTasks(); + //start face finding in a separate thread if (handleFaces() && !CoarseView.getValue()) { try { // Base::Console().Message("DVP::onHlrFinished - starting extractFaces\n"); @@ -485,26 +469,25 @@ void DrawViewPart::onHlrFinished(void) m_faceFuture = QtConcurrent::run(this, &DrawViewPart::extractFaces); m_faceWatcher.setFuture(m_faceFuture); } - catch (Standard_Failure& e4) { + catch (Standard_Failure& e) { waitingForFaces(false); - Base::Console().Message("DVP::partExec - extractFaces failed for %s - %s **\n",getNameInDocument(),e4.GetMessageString()); + Base::Console().Error("DVP::partExec - %s - extractFaces failed - %s **\n",getNameInDocument(), e.GetMessageString()); + throw Base::RuntimeError("DVP::onHlrFinished - error extracting faces"); } } +} +//run any tasks that need to been done after geometry is available +void DrawViewPart::postHlrTasks(void) +{ + //add geometry that doesn't come from HLR addCosmeticVertexesToGeom(); addCosmeticEdgesToGeom(); addCenterLinesToGeom(); - addReferencesToGeom(); - requestPaint(); -} - -void DrawViewPart::postHlrTasks(void) -{ - //DVDetail and DVSection have special needs. - //dimensions and balloons need to be recomputed here to get their references sorted - + //dimensions and balloons need to be recomputed here because their + //references will be invalid until the geometry exists std::vector dims = getDimensions(); for (auto& d : dims) { d->recomputeFeature(); @@ -513,6 +496,8 @@ void DrawViewPart::postHlrTasks(void) for (auto& b : bals) { b->recomputeFeature(); } + + requestPaint(); } //! make faces from the existing edge geometry diff --git a/src/Mod/TechDraw/App/DrawViewPart.h b/src/Mod/TechDraw/App/DrawViewPart.h index 8f4c543a87..a4a50f0348 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.h +++ b/src/Mod/TechDraw/App/DrawViewPart.h @@ -226,10 +226,10 @@ protected: void onChanged(const App::Property* prop) override; void unsetupObject() override; - virtual TechDraw::GeometryObject* buildGeometryObject(TopoDS_Shape shape, gp_Ax2 viewAxis); //const?? - virtual TechDraw::GeometryObject* makeGeometryForShape(TopoDS_Shape shape); //const?? - void partExec(TopoDS_Shape shape); - virtual void addShapes2d(); + virtual TechDraw::GeometryObject* buildGeometryObject(TopoDS_Shape& shape, gp_Ax2& viewAxis); + virtual TechDraw::GeometryObject* makeGeometryForShape(TopoDS_Shape& shape); //const?? + void partExec(TopoDS_Shape& shape); + virtual void addShapes2d(void); void extractFaces(); diff --git a/src/Mod/TechDraw/App/DrawViewSection.cpp b/src/Mod/TechDraw/App/DrawViewSection.cpp index 1f5fc1d84e..a7eab18891 100644 --- a/src/Mod/TechDraw/App/DrawViewSection.cpp +++ b/src/Mod/TechDraw/App/DrawViewSection.cpp @@ -65,8 +65,9 @@ #include -# include -# include +#include +#include +#include "QtConcurrent/qtconcurrentrun.h" #include #include @@ -115,7 +116,8 @@ const char* DrawViewSection::CutSurfaceEnums[]= {"Hide", PROPERTY_SOURCE(TechDraw::DrawViewSection, TechDraw::DrawViewPart) -DrawViewSection::DrawViewSection() +DrawViewSection::DrawViewSection() : + m_waitingForCut(false) { static const char *sgroup = "Section"; static const char *fgroup = "Cut Surface Format"; @@ -349,21 +351,42 @@ App::DocumentObjectExecReturn *DrawViewSection::execute() return DrawView::execute(); } -void DrawViewSection::sectionExec(TopoDS_Shape baseShape) +void DrawViewSection::sectionExec(TopoDS_Shape& baseShape) { // Base::Console().Message("DVS::sectionExec() - %s\n", getNameInDocument()); if (waitingForResult()) { // Base::Console().Message("DVS::sectionExec - waiting for result\n"); return; } + try { + QObject::connect(&m_cutWatcher, SIGNAL(finished()), this, SLOT(onSectionCutFinished())); + m_cutFuture = QtConcurrent::run(this, &DrawViewSection::makeSectionCut, baseShape); + m_cutWatcher.setFuture(m_cutFuture); + } + catch (...) { + Base::Console().Message("DVS::sectionExec - failed to make section cut"); + return; + } +} + +void DrawViewSection::makeSectionCut(TopoDS_Shape &baseShape) +{ +// Base::Console().Message("DVS::makeSectionCut()\n"); + if (waitingForCut()) { +// Base::Console().Message("DVS::makeSectionCut - waiting for cut - returning\n"); + return; + } + + waitingForCut(true); + showProgressMessage(getNameInDocument(), "is making section cut"); + + // auto start = chrono::high_resolution_clock::now(); // cut base shape with tool //is SectionOrigin valid? Bnd_Box centerBox; BRepBndLib::AddOptimal(baseShape, centerBox); centerBox.SetGap(0.0); - -// make tool gp_Pln pln = getSectionPlane(); gp_Dir gpNormal = pln.Axis().Direction(); Base::Vector3d orgPnt = SectionOrigin.getValue(); @@ -372,6 +395,7 @@ void DrawViewSection::sectionExec(TopoDS_Shape baseShape) Base::Console().Warning("DVS: SectionOrigin doesn't intersect part in %s\n",getNameInDocument()); } + // make cutting tool // Make the extrusion face double dMax = sqrt(centerBox.SquareExtent()); BRepBuilderAPI_MakeFace mkFace(pln, -dMax,dMax,-dMax,dMax); @@ -420,20 +444,19 @@ void DrawViewSection::sectionExec(TopoDS_Shape baseShape) BRepBndLib::AddOptimal(rawShape, testBox); testBox.SetGap(0.0); if (testBox.IsVoid()) { //prism & input don't intersect. rawShape is garbage, don't bother. - Base::Console().Warning("DVS::execute - prism & input don't intersect - %s\n", Label.getValue()); + Base::Console().Warning("DVS::makeSectionCut - prism & input don't intersect - %s\n", Label.getValue()); return; } // build display geometry as in DVP, with minor mods - gp_Ax2 viewAxis; TopoDS_Shape centeredShape; try { Base::Vector3d origin(0.0, 0.0, 0.0); - viewAxis = getProjectionCS(origin); + m_viewAxis = getProjectionCS(origin); gp_Pnt inputCenter; inputCenter = TechDraw::findCentroid(rawShape, - viewAxis); + m_viewAxis); Base::Vector3d centroid(inputCenter.X(), inputCenter.Y(), inputCenter.Z()); @@ -443,36 +466,49 @@ void DrawViewSection::sectionExec(TopoDS_Shape baseShape) m_cutShape = centeredShape; m_saveCentroid = centroid; - TopoDS_Shape scaledShape = TechDraw::scaleShape(centeredShape, - getScale()); + m_scaledShape = TechDraw::scaleShape(centeredShape, + getScale()); if (!DrawUtil::fpCompare(Rotation.getValue(),0.0)) { - scaledShape = TechDraw::rotateShape(scaledShape, - viewAxis, - Rotation.getValue()); + m_scaledShape = TechDraw::rotateShape(m_scaledShape, + m_viewAxis, + Rotation.getValue()); } if (debugSection()) { BRepTools::Write(m_cutShape, "DVSmCutShape.brep"); //debug - BRepTools::Write(scaledShape, "DVSScaled.brep"); //debug -// DrawUtil::dumpCS("DVS::execute - CS to GO", viewAxis); + BRepTools::Write(m_scaledShape, "DVSScaled.brep"); //debug +// DrawUtil::dumpCS("DVS::makeSectionCut - CS to GO", viewAxis); } m_rawShape = rawShape; //save for postHlrTasks - m_viewAxis= viewAxis; //save for postHlrTasks - geometryObject = buildGeometryObject(scaledShape,viewAxis); } catch (Standard_Failure& e1) { - Base::Console().Warning("DVS::execute - failed to build base shape %s - %s **\n", + Base::Console().Warning("DVS::makeSectionCut - failed to build base shape %s - %s **\n", getNameInDocument(),e1.GetMessageString()); return; } -//display geometry for cut shape is in geometryObject as in DVP + +// auto end = chrono::high_resolution_clock::now(); +// auto diff = end - start; +// double diffOut = chrono::duration (diff).count(); +// Base::Console().Message("DVS::makeSectionCut - %s spent: %.3f millisecs making section cut\n", getNameInDocument(), diffOut); +} + +void DrawViewSection::onSectionCutFinished() +{ + waitingForCut(false); + QObject::disconnect(&m_cutWatcher, SIGNAL(finished()), this, SLOT(onSectionCutFinished())); + + //display geometry for cut shape is in geometryObject as in DVP + geometryObject = buildGeometryObject(m_scaledShape, m_viewAxis); } void DrawViewSection::postHlrTasks(void) { // Base::Console().Message("DVS::postHlrTasks() - %s\n", getNameInDocument()); +// auto start = chrono::high_resolution_clock::now(); + // build section face geometry TopoDS_Compound faceIntersections = findSectionPlaneIntersections(m_rawShape); TopoDS_Shape centeredShapeF = TechDraw::moveShape(faceIntersections, @@ -538,6 +574,11 @@ void DrawViewSection::postHlrTasks(void) tdSectionFaces.push_back(sectionFace); } +// auto end = chrono::high_resolution_clock::now(); +// auto diff = end - start; +// double diffOut = chrono::duration (diff).count(); +// Base::Console().Message("DVS::sectionExec - %s spent: %.3f millisecs finding section faces\n", getNameInDocument(), diffOut); + App::DocumentObject* base = BaseView.getValue(); if (base != nullptr) { if (base->getTypeId().isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) { @@ -546,6 +587,7 @@ void DrawViewSection::postHlrTasks(void) } } requestPaint(); + DrawViewPart::postHlrTasks(); } gp_Pln DrawViewSection::getSectionPlane() const @@ -561,14 +603,14 @@ gp_Pln DrawViewSection::getSectionPlane() const TopoDS_Compound DrawViewSection::findSectionPlaneIntersections(const TopoDS_Shape& shape) { // Base::Console().Message("DVS::findSectionPlaneIntersections()\n"); - TopoDS_Compound result; if(shape.IsNull()){ Base::Console().Warning("DrawViewSection::getSectionSurface - Sectional View shape is Empty\n"); - return result; + return TopoDS_Compound(); } gp_Pln plnSection = getSectionPlane(); BRep_Builder builder; + TopoDS_Compound result; builder.MakeCompound(result); TopExp_Explorer expFaces(shape, TopAbs_FACE); @@ -775,23 +817,6 @@ gp_Ax2 DrawViewSection::getSectionCS() const return sectionCS; } -gp_Ax2 DrawViewSection::rotateCSArbitrary(gp_Ax2 oldCS, - Base::Vector3d axis, - double degAngle) const -{ - gp_Ax2 newCS; - - gp_Pnt oldOrg = oldCS.Location(); - - gp_Dir gAxis(axis.x, axis.y, axis.z); - gp_Ax1 rotAxis = gp_Ax1(oldOrg, gAxis); - - double radAngle = degAngle * M_PI / 180.0; - - newCS = oldCS.Rotated(rotAxis, radAngle); - return newCS; -} - std::vector DrawViewSection::getDrawableLines(int i) { // Base::Console().Message("DVS::getDrawableLines(%d) - lineSets: %d\n", i, m_lineSets.size()); @@ -966,6 +991,8 @@ void DrawViewSection::setupPatIncluded() } } +#include + // Python Drawing feature --------------------------------------------------------- namespace App { diff --git a/src/Mod/TechDraw/App/DrawViewSection.h b/src/Mod/TechDraw/App/DrawViewSection.h index 96676a2ebb..c2e06d5b16 100644 --- a/src/Mod/TechDraw/App/DrawViewSection.h +++ b/src/Mod/TechDraw/App/DrawViewSection.h @@ -25,6 +25,9 @@ #ifndef _DrawViewSection_h_ #define _DrawViewSection_h_ +#include +#include + #include #include #include @@ -60,6 +63,7 @@ class DashSet; class TechDrawExport DrawViewSection : public DrawViewPart { PROPERTY_HEADER_WITH_OVERRIDE(Part::DrawViewSection); + Q_OBJECT public: DrawViewSection(); @@ -92,16 +96,17 @@ public: void unsetupObject() override; short mustExecute() const override; - void sectionExec(TopoDS_Shape s); + void sectionExec(TopoDS_Shape& s); + void makeSectionCut(TopoDS_Shape &baseShape); + void postHlrTasks(void) override; + void waitingForCut(bool s) { m_waitingForCut = s; } + bool waitingForCut(void) { return m_waitingForCut; } std::vector getTDFaceGeometry() {return tdSectionFaces;} void setCSFromBase(const std::string sectionName); gp_Ax2 getCSFromBase(const std::string sectionName) const; - gp_Ax2 rotateCSArbitrary(gp_Ax2 oldCS, - Base::Vector3d axis, - double degAngle) const; gp_Ax2 getSectionCS() const; Base::Vector3d getXDirection() const override; //don't use XDirection.getValue() @@ -123,7 +128,9 @@ public: std::pair sectionLineEnds(); bool showSectionEdges(void); - void postHlrTasks(void) override; + +public Q_SLOTS: + void onSectionCutFinished(void); protected: TopoDS_Compound sectionFaces; //tSectionFaces @@ -149,6 +156,11 @@ protected: TopoDS_Shape m_rawShape; gp_Ax2 m_viewAxis; + TopoDS_Shape m_scaledShape; + + QFutureWatcher m_cutWatcher; + QFuture m_cutFuture; + bool m_waitingForCut; };