From 20f5db1ad1459e1956b58e17d2aafcc0cfa87d92 Mon Sep 17 00:00:00 2001 From: wandererfan Date: Thu, 8 Sep 2022 20:12:29 -0400 Subject: [PATCH] [TD]fix extent dimension --- src/Mod/TechDraw/App/DrawDimHelper.cpp | 194 +++++++-------------- src/Mod/TechDraw/App/DrawDimHelper.h | 29 ++- src/Mod/TechDraw/App/DrawViewDimExtent.cpp | 20 ++- src/Mod/TechDraw/App/DrawViewDimExtent.h | 2 + src/Mod/TechDraw/App/DrawViewDimension.cpp | 2 +- src/Mod/TechDraw/App/DrawViewDimension.h | 2 +- src/Mod/TechDraw/App/DrawViewPart.cpp | 4 +- src/Mod/TechDraw/Gui/CommandCreateDims.cpp | 4 - src/Mod/TechDraw/Gui/MDIViewPage.cpp | 16 +- src/Mod/TechDraw/Gui/MDIViewPage.h | 1 - 10 files changed, 93 insertions(+), 181 deletions(-) diff --git a/src/Mod/TechDraw/App/DrawDimHelper.cpp b/src/Mod/TechDraw/App/DrawDimHelper.cpp index 1b12997f8a..8d12f0c622 100644 --- a/src/Mod/TechDraw/App/DrawDimHelper.cpp +++ b/src/Mod/TechDraw/App/DrawDimHelper.cpp @@ -31,21 +31,19 @@ #include # include +#include + #include #include #include #include #include +#include +#include "BRepBuilderAPI_MakeShape.hxx" #include -#include -#include -#include -#include -#include -#include +#include +#include #include -#include -#include #include #include #endif @@ -76,16 +74,6 @@ using namespace TechDraw; -hTrimCurve::hTrimCurve(Handle(Geom2d_Curve) hCurveIn, - double parm1, - double parm2) : - hCurve(hCurveIn), - first(parm1), - last(parm2) -{ - //just a convenient struct for now. -} - //All this OCC math is being done on edges(&vertices) that have been through the center/scale/mirror process. //TODO: this needs to be exposed to Python @@ -187,55 +175,53 @@ std::pair DrawDimHelper::minMax(DrawViewPart* dv } Bnd_Box edgeBbx; - edgeBbx.SetGap(0.0); + edgeBbx.SetGap(1.0); //make the box a bit bigger - std::vector selCurves; - std::vector hTCurve2dList; + std::vector inEdges; for (auto& bg: selEdges) { - TopoDS_Edge e = bg->occEdge; - BRepBndLib::AddOptimal(e, edgeBbx); - double first = 0.0; - double last = 0.0; - Handle(Geom_Curve) hCurve = BRep_Tool::Curve(e, first, last); - Handle(Geom2d_Curve) hCurve2 = GeomAPI::To2d (hCurve, projPlane); - hTrimCurve temp(hCurve2, first, last); - hTCurve2dList.push_back(temp); + inEdges.push_back(bg->occEdge); + BRepBndLib::Add(bg->occEdge, edgeBbx); } - //can't use Bnd_Box2d here as BndLib_Add2dCurve::Add adds the poles of splines to the box. - //poles are not necessarily on the curve! 3d Bnd_Box does it properly. - //this has to be the bbx of the selected edges, not the dvp!!! double minX, minY, minZ, maxX, maxY, maxZ; edgeBbx.Get(minX, minY, minZ, maxX, maxY, maxZ); double xMid = (maxX + minX) / 2.0; double yMid = (maxY + minY) / 2.0; - gp_Pnt2d rightMid(maxX, yMid); - gp_Pnt2d leftMid(minX, yMid); - gp_Pnt2d topMid(xMid, maxY); - gp_Pnt2d bottomMid(xMid, minY); + gp_Pnt rightMid(maxX, yMid, 0.0); + gp_Pnt leftMid(minX, yMid, 0.0); + gp_Pnt topMid(xMid, maxY, 0.0); + gp_Pnt bottomMid(xMid, minY, 0.0); - gp_Dir2d xDir(1.0, 0.0); - gp_Dir2d yDir(0.0, 1.0); + gp_Dir xDir(1.0, 0.0, 0.0); + gp_Dir yDir(0.0, 1.0, 0.0); if (direction == HORIZONTAL) { - Handle(Geom2d_Line) boundaryLeft = new Geom2d_Line(leftMid, yDir); - gp_Pnt2d leftPoint = findClosestPoint(hTCurve2dList, - boundaryLeft); - Handle(Geom2d_Line) boundaryRight = new Geom2d_Line(rightMid, yDir); - gp_Pnt2d rightPoint = findClosestPoint(hTCurve2dList, - boundaryRight); + Handle(Geom_Line) lineLeft = new Geom_Line(leftMid, yDir); + BRepBuilderAPI_MakeEdge mkEdgeLeft(lineLeft); + TopoDS_Edge edgeLeft = mkEdgeLeft.Edge(); + gp_Pnt leftPoint = findClosestPoint(inEdges, + edgeLeft); + Handle(Geom_Line) lineRight = new Geom_Line(rightMid, yDir); + BRepBuilderAPI_MakeEdge mkEdgeRight(lineRight); + TopoDS_Edge edgeRight = mkEdgeRight.Edge(); + gp_Pnt rightPoint = findClosestPoint(inEdges, + edgeRight); refMin = Base::Vector3d(leftPoint.X(), leftPoint.Y(), 0.0); refMax = Base::Vector3d(rightPoint.X(), rightPoint.Y(), 0.0); } else if (direction == VERTICAL) { - Handle(Geom2d_Line) boundaryBottom = new Geom2d_Line(bottomMid, xDir); - gp_Pnt2d bottomPoint = findClosestPoint(hTCurve2dList, - boundaryBottom); - Handle(Geom2d_Line) boundaryTop = new Geom2d_Line(topMid, xDir); - gp_Pnt2d topPoint = findClosestPoint(hTCurve2dList, - boundaryTop); + Handle(Geom_Line) lineBottom = new Geom_Line(bottomMid, xDir); + BRepBuilderAPI_MakeEdge mkEdgeBottom(lineBottom); + TopoDS_Edge edgeBottom = mkEdgeBottom.Edge(); + gp_Pnt bottomPoint = findClosestPoint(inEdges, + edgeBottom); + Handle(Geom_Line) lineTop = new Geom_Line(topMid, xDir); + BRepBuilderAPI_MakeEdge mkEdgeTop(lineTop); + TopoDS_Edge edgeTop = mkEdgeTop.Edge(); + gp_Pnt topPoint = findClosestPoint(inEdges, + edgeTop); refMin = Base::Vector3d(bottomPoint.X(), bottomPoint.Y(), 0.0); refMax = Base::Vector3d(topPoint.X(), topPoint.Y(), 0.0); } @@ -247,87 +233,30 @@ std::pair DrawDimHelper::minMax(DrawViewPart* dv //given list of curves, find the closest point from any curve to a boundary //computation intensive for a cosmetic result. -gp_Pnt2d DrawDimHelper::findClosestPoint(std::vector hTCurve2dList, - Handle(Geom2d_Curve) boundary) +gp_Pnt DrawDimHelper::findClosestPoint(std::vector inEdges, + TopoDS_Edge& boundary) { -// Base::Console().Message("DDH::findClosestPoint() - curves: %d\n", hTCurve2dList.size()); +// Base::Console().Message("DDH::findClosestPoint() - edges: %d\n", inEdges.size()); // //find an extent point that is actually on one of the curves - gp_Pnt2d result(-1.0, -1.0); - Geom2dAdaptor_Curve aBoundary(boundary); - - double globalNearDist = FLT_MAX; - gp_Pnt2d globalNearPoint; - bool found = false; - for (auto& hCurve2d : hTCurve2dList) { - Geom2dAdaptor_Curve aCurve(hCurve2d.hCurve, - hCurve2d.first, - hCurve2d.last); - Extrema_ExtCC2d mkExtr(aBoundary, aCurve); - if (mkExtr.IsDone()) { - double nearDist = FLT_MAX; - int nearIdx = 0; - gp_Pnt2d nearPoint; - if (mkExtr.NbExt() > 0) { - int stop = mkExtr.NbExt(); - int i = 1; //this is OCC start (1) not conventional start (0) - for ( ; i <= stop; i++) { - double dist = mkExtr.SquareDistance(i); - if (dist < nearDist) { - found = true; - nearDist = dist; - nearIdx = i; - Extrema_POnCurv2d p1, p2; - mkExtr.Points(nearIdx, p1, p2); - nearPoint = p2.Value(); - } - } - } else { //no extrema? - might be a line parallel to boundary - if (mkExtr.IsParallel()) { - //get midpoint of aCurve - double mid = (hCurve2d.first + hCurve2d.last) / 2.0; - gp_Pnt2d midPoint = hCurve2d.hCurve->Value(mid); - //get distance midpoint to boundary => nearDist - Geom2dAPI_ProjectPointOnCurve mkProj(midPoint, boundary); - double dist = mkProj.LowerDistance() * mkProj.LowerDistance(); - if (dist < nearDist) { - found = true; - nearDist = dist; - nearPoint = mkProj.NearestPoint(); - } - } else { //skew and no extrema? - gp_Pnt2d pFirst = hCurve2d.hCurve->Value(hCurve2d.first); - Geom2dAPI_ProjectPointOnCurve mkFirst(pFirst, boundary); - double dist1 = mkFirst.LowerDistance() * mkFirst.LowerDistance(); - gp_Pnt2d pLast = hCurve2d.hCurve->Value(hCurve2d.last); - Geom2dAPI_ProjectPointOnCurve mkLast(pLast, boundary); - double dist2 = mkLast.LowerDistance() * mkLast.LowerDistance(); - if (dist1 < dist2) { - if (dist1 < nearDist) { - found = true; - nearDist = dist1; - nearPoint = mkFirst.NearestPoint(); - } - } else { - if (dist2 < nearDist) { - found = true; - nearDist = dist2; - nearPoint = mkLast.NearestPoint(); - } - } - } - } - if (nearDist < globalNearDist) { - globalNearDist = nearDist; - globalNearPoint = nearPoint; - } + double minDistance(std::numeric_limits::max()); + gp_Pnt nearPoint; + for (auto& edge : inEdges) { + BRepExtrema_DistShapeShape extss(edge, boundary); + if (!extss.IsDone()) { + Base::Console().Warning("DDH::findClosestPoint - BRepExtrema_DistShapeShape failed - 1\n"); + continue; + } + if (extss.NbSolution() == 0) { + Base::Console().Warning("DDH::findClosestPoint - BRepExtrema_DistShapeShape failed - 2\n"); + continue; + } + if (extss.Value() < minDistance) { + minDistance = extss.Value(); + nearPoint = extss.PointOnShape1(1); } } - if (found) { - result = globalNearPoint; - } - - return result; + return nearPoint; } DrawViewDimension* DrawDimHelper::makeDistDim(DrawViewPart* dvp, @@ -349,6 +278,8 @@ DrawViewDimension* DrawDimHelper::makeDistDim(DrawViewPart* dvp, dimName = doc->getUniqueObjectName("DimExtent"); } + std::vector gVerts = dvp->getVertexGeometry(); + Base::Vector3d cleanMin = DrawUtil::invertY(inMin); std::string tag1 = dvp->addCosmeticVertex(cleanMin); int iGV1 = dvp->add1CVToGV(tag1); @@ -357,6 +288,7 @@ DrawViewDimension* DrawDimHelper::makeDistDim(DrawViewPart* dvp, std::string tag2 = dvp->addCosmeticVertex(cleanMax); int iGV2 = dvp->add1CVToGV(tag2); + gVerts = dvp->getVertexGeometry(); std::vector objs; std::vector subs; @@ -385,18 +317,16 @@ DrawViewDimension* DrawDimHelper::makeDistDim(DrawViewPart* dvp, Base::Interpreter().runStringArg("App.activeDocument().%s.Type = '%s'", dimName.c_str(), dimType.c_str()); - Base::Interpreter().runStringArg("App.activeDocument().%s.addView(App.activeDocument().%s)", - pageName.c_str(), dimName.c_str()); - dim = dynamic_cast(doc->getObject(dimName.c_str())); if (!dim) { throw Base::TypeError("DDH::makeDistDim - dim not found\n"); } - dim->References2D.setValues(objs, subs); - dvp->requestPaint(); - dim->recomputeFeature(); + Base::Interpreter().runStringArg("App.activeDocument().%s.addView(App.activeDocument().%s)", + pageName.c_str(), dimName.c_str()); + + dvp->requestPaint(); return dim; } diff --git a/src/Mod/TechDraw/App/DrawDimHelper.h b/src/Mod/TechDraw/App/DrawDimHelper.h index e404920d0c..ad0ac3ee55 100644 --- a/src/Mod/TechDraw/App/DrawDimHelper.h +++ b/src/Mod/TechDraw/App/DrawDimHelper.h @@ -26,45 +26,36 @@ #include #include +#include +#include #include -#include +#include -class gp_Pnt2d; +#include namespace TechDraw { class BaseGeom; class DrawViewPart; - -class TechDrawExport hTrimCurve { - public: - hTrimCurve() : first(0.0), last(0.0) {} - hTrimCurve(Handle(Geom2d_Curve) hCurveIn, - double parm1, - double parm2); - ~hTrimCurve() = default; - - Handle(Geom2d_Curve) hCurve; - double first; - double last; -}; - +class DrawViewDimension; /// Additional functions for working with Dimensions class TechDrawExport DrawDimHelper { public: static void makeExtentDim(DrawViewPart* dvp, -// std::vector selEdges, std::vector edgeNames, int direction); - static gp_Pnt2d findClosestPoint(std::vector hCurve2dList, - Handle(Geom2d_Curve) boundary); + static gp_Pnt findClosestPoint(std::vector inEdges, + TopoDS_Edge& boundary); + + static TechDraw::DrawViewDimension* makeDistDim(DrawViewPart* dvp, std::string dimType, Base::Vector3d refMin, Base::Vector3d refMax, bool extent = false); + static std::pair minMax(DrawViewPart* dvp, std::vector edgeNames, int direction); diff --git a/src/Mod/TechDraw/App/DrawViewDimExtent.cpp b/src/Mod/TechDraw/App/DrawViewDimExtent.cpp index 2e131f730b..e190970be0 100644 --- a/src/Mod/TechDraw/App/DrawViewDimExtent.cpp +++ b/src/Mod/TechDraw/App/DrawViewDimExtent.cpp @@ -122,13 +122,16 @@ App::DocumentObjectExecReturn *DrawViewDimExtent::execute(void) std::vector cTags = CosmeticTags.getValues(); if (cTags.size() <= 1) { - return DrawViewDimension::execute(); + //not ready yet. + return DrawView::execute(); } TechDraw::VertexPtr v0 = dvp->getProjVertexByCosTag(cTags[0]); TechDraw::VertexPtr v1 = dvp->getProjVertexByCosTag(cTags[1]); - if (!v0 || !v1) - return DrawViewDimension::execute(); + if (!v0 || !v1) { + //either not ready yet or something has gone wrong + return DrawView::execute(); + } double length00 = (v0->pnt - refMin).Length(); double length11 = (v1->pnt - refMax).Length(); @@ -158,8 +161,9 @@ App::DocumentObjectExecReturn *DrawViewDimExtent::execute(void) std::vector DrawViewDimExtent::getSubNames(void) { std::vector edgeNames = Source.getSubValues(); +// Base::Console().Message("DVDE::getSubNames - edgeNames: %d\n", edgeNames.size()); if (edgeNames.empty() || - !edgeNames[0].empty()) { + edgeNames[0].empty()) { return std::vector(); //garbage first entry - nop } return edgeNames; @@ -179,7 +183,8 @@ pointPair DrawViewDimExtent::getPointsTwoVerts() } std::vector cTags = CosmeticTags.getValues(); - if (cTags.empty()) { + if (cTags.size() < 2) { +// Base::Console().Message("DVDE::getPointsTwoVerts - not enough tags!\n"); return errorValue; } @@ -201,8 +206,9 @@ bool DrawViewDimExtent::checkReferences2D() const } std::vector cTags = CosmeticTags.getValues(); - if (cTags.empty()) { - return false; + if (cTags.size() < 2) { + //still building this dimension, so treat as valid? + return true; } CosmeticVertex* cv0 = dvp->getCosmeticVertex(cTags[0]); diff --git a/src/Mod/TechDraw/App/DrawViewDimExtent.h b/src/Mod/TechDraw/App/DrawViewDimExtent.h index a36038e0e8..b96e13abc1 100644 --- a/src/Mod/TechDraw/App/DrawViewDimExtent.h +++ b/src/Mod/TechDraw/App/DrawViewDimExtent.h @@ -55,6 +55,8 @@ public: void unsetupObject() override; bool checkReferences2D() const override; + int getRefType() const override { return twoVertex; } + pointPair getLinearPoints() override { return getPointsTwoVerts(); } //return PyObject as DrawViewDimExtentPy PyObject *getPyObject() override; diff --git a/src/Mod/TechDraw/App/DrawViewDimension.cpp b/src/Mod/TechDraw/App/DrawViewDimension.cpp index 209c825590..b3c727c8cd 100644 --- a/src/Mod/TechDraw/App/DrawViewDimension.cpp +++ b/src/Mod/TechDraw/App/DrawViewDimension.cpp @@ -1183,7 +1183,7 @@ double DrawViewDimension::getDimValue() if ( Type.isValue("Distance") || Type.isValue("DistanceX") || Type.isValue("DistanceY") ) { - pointPair pts = m_linearPoints; + pointPair pts = getLinearPoints(); Base::Vector3d dimVec = pts.first - pts.second; if (Type.isValue("Distance")) { result = dimVec.Length() / getViewPart()->getScale(); diff --git a/src/Mod/TechDraw/App/DrawViewDimension.h b/src/Mod/TechDraw/App/DrawViewDimension.h index 2d05f177d4..ef7f990eed 100644 --- a/src/Mod/TechDraw/App/DrawViewDimension.h +++ b/src/Mod/TechDraw/App/DrawViewDimension.h @@ -199,7 +199,7 @@ public: void setAll3DMeasurement(); void clear3DMeasurements(); virtual bool checkReferences2D() const; - pointPair getLinearPoints() {return m_linearPoints; } + virtual pointPair getLinearPoints() {return m_linearPoints; } arcPoints getArcPoints() {return m_arcPoints; } anglePoints getAnglePoints() {return m_anglePoints; } bool leaderIntersectsArc(Base::Vector3d s, Base::Vector3d pointOnCircle); diff --git a/src/Mod/TechDraw/App/DrawViewPart.cpp b/src/Mod/TechDraw/App/DrawViewPart.cpp index 7a031fa98c..2bbbb9124a 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.cpp +++ b/src/Mod/TechDraw/App/DrawViewPart.cpp @@ -1263,10 +1263,10 @@ void DrawViewPart::addCosmeticVertexesToGeom() int DrawViewPart::add1CVToGV(std::string tag) { -// Base::Console().Message("DVP::add1CVToGV(%s) 2\n", tag.c_str()); +// Base::Console().Message("DVP::add1CVToGV(%s)\n", tag.c_str()); TechDraw::CosmeticVertex* cv = getCosmeticVertex(tag); if (!cv) { - Base::Console().Message("DVP::add1CVToGV 2 - cv %s not found\n", tag.c_str()); + Base::Console().Message("DVP::add1CVToGV - cv %s not found\n", tag.c_str()); return 0; } int iGV = geometryObject->addCosmeticVertex(cv->scaled(getScale()), diff --git a/src/Mod/TechDraw/Gui/CommandCreateDims.cpp b/src/Mod/TechDraw/Gui/CommandCreateDims.cpp index ad067b0448..dfc3a09f89 100644 --- a/src/Mod/TechDraw/Gui/CommandCreateDims.cpp +++ b/src/Mod/TechDraw/Gui/CommandCreateDims.cpp @@ -1196,11 +1196,7 @@ void execHExtent(Gui::Command* cmd) std::vector::iterator itSel = selection.begin(); for (; itSel != selection.end(); itSel++) { if ((*itSel).getObject()->isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) { - // baseFeat = static_cast ((*itSel).getObject()); SubNames = (*itSel).getSubNames(); - if (SubNames.empty() || SubNames[0].empty()) { - SubNames.clear(); - } } } diff --git a/src/Mod/TechDraw/Gui/MDIViewPage.cpp b/src/Mod/TechDraw/Gui/MDIViewPage.cpp index 06a0ce3c7f..907910c11b 100644 --- a/src/Mod/TechDraw/Gui/MDIViewPage.cpp +++ b/src/Mod/TechDraw/Gui/MDIViewPage.cpp @@ -840,6 +840,7 @@ void MDIViewPage::sceneSelectionChanged() //Note: Qt says: "no guarantee of selection order"!!! void MDIViewPage::setTreeToSceneSelect() { +// Base::Console().Message("MDIVP::setTreeToSceneSelect()\n"); bool saveBlock = blockSelection(true); // block selectionChanged signal from Tree/Observer blockSceneSelection(true); Gui::Selection().clearSelection(); @@ -1003,15 +1004,12 @@ bool MDIViewPage::compareSelections(std::vector treeSel, Q int treeCount = 0; int sceneCount = 0; - int subCount = 0; int ppCount = 0; std::vector treeNames; std::vector sceneNames; for (auto tn: treeSel) { if (tn.getObject()->isDerivedFrom(TechDraw::DrawView::getClassTypeId())) { - int treeSubs = tn.getSubNames().size(); - subCount += treeSubs; std::string s = tn.getObject()->getNameInDocument(); treeNames.push_back(s); } @@ -1081,20 +1079,10 @@ void MDIViewPage::showStatusMsg(const char* string1, const char* string2, const QString::fromUtf8(string2), QString::fromUtf8(string3)); if (Gui::getMainWindow()) { - Gui::getMainWindow()->showMessage(msg, 3000); + Gui::getMainWindow()->showMessage(msg, 6000); } } -//return the MDIViewPage that owns the scene -MDIViewPage *MDIViewPage::getFromScene(const QGSPage *scene) -{ - if (scene && scene->parent()) { - return dynamic_cast(scene->parent()); - } - - return nullptr; -} - // ---------------------------------------------------------------------------- void MDIViewPagePy::init_type() diff --git a/src/Mod/TechDraw/Gui/MDIViewPage.h b/src/Mod/TechDraw/Gui/MDIViewPage.h index 3ee2265c24..8747246bb5 100644 --- a/src/Mod/TechDraw/Gui/MDIViewPage.h +++ b/src/Mod/TechDraw/Gui/MDIViewPage.h @@ -102,7 +102,6 @@ public: void setTabText(std::string tabText); - static MDIViewPage *getFromScene(const QGSPage *scene); void contextMenuEvent(QContextMenuEvent *event) override; void setScene(QGSPage* scene, QGVPage* view);