From ef912cfea8658260888761c2cfc3b8d2f0eff855 Mon Sep 17 00:00:00 2001 From: wandererfan Date: Mon, 6 May 2019 20:02:21 -0400 Subject: [PATCH] Improve radius/diameter dims for ellipse,spline --- src/Mod/TechDraw/App/DrawView.cpp | 2 + src/Mod/TechDraw/App/DrawViewDimension.cpp | 69 +++++++++++++++++-- src/Mod/TechDraw/App/Geometry.cpp | 26 +++++-- src/Mod/TechDraw/App/Geometry.h | 3 +- src/Mod/TechDraw/Gui/CommandCreateDims.cpp | 59 +++++++++++++--- src/Mod/TechDraw/Gui/QGIViewDimension.cpp | 5 -- .../TechDraw/Gui/ViewProviderDrawingView.cpp | 7 +- 7 files changed, 147 insertions(+), 24 deletions(-) diff --git a/src/Mod/TechDraw/App/DrawView.cpp b/src/Mod/TechDraw/App/DrawView.cpp index 2a7378b144..5219d712b9 100644 --- a/src/Mod/TechDraw/App/DrawView.cpp +++ b/src/Mod/TechDraw/App/DrawView.cpp @@ -92,6 +92,7 @@ DrawView::~DrawView() App::DocumentObjectExecReturn *DrawView::execute(void) { +// Base::Console().Message("DV::execute() - %s\n", getNameInDocument()); handleXYLock(); requestPaint(); return App::DocumentObject::execute(); @@ -429,6 +430,7 @@ bool DrawView::keepUpdated(void) void DrawView::requestPaint(void) { +// Base::Console().Message("DV::requestPaint() - %s\n", getNameInDocument()); signalGuiPaint(this); } diff --git a/src/Mod/TechDraw/App/DrawViewDimension.cpp b/src/Mod/TechDraw/App/DrawViewDimension.cpp index 02b934296c..b01d169413 100644 --- a/src/Mod/TechDraw/App/DrawViewDimension.cpp +++ b/src/Mod/TechDraw/App/DrawViewDimension.cpp @@ -238,6 +238,7 @@ App::DocumentObjectExecReturn *DrawViewDimension::execute(void) //now we can check if Reference2ds have valid targets. if (!checkReferences2D()) { + Base::Console().Warning("%s has invalid 2D References\n", getNameInDocument()); return App::DocumentObject::StdReturn; } @@ -282,6 +283,37 @@ App::DocumentObjectExecReturn *DrawViewDimension::execute(void) pts.onCurve.first = pts.center + Base::Vector3d(1,0,0) * circle->radius; //arbitrary point on edge pts.onCurve.second = pts.center + Base::Vector3d(-1,0,0) * circle->radius; //arbitrary point on edge } + } else if ((base && base->geomType == TechDrawGeometry::GeomType::ELLIPSE) || + (base && base->geomType == TechDrawGeometry::GeomType::ARCOFELLIPSE)) { + TechDrawGeometry::Ellipse* ellipse = static_cast (base); + if (ellipse->closed()) { + double r1 = ellipse->minor; + double r2 = ellipse->major; + double rAvg = (r1 + r2) / 2.0; + pts.center = Base::Vector3d(ellipse->center.x, + ellipse->center.y, + 0.0); + pts.radius = rAvg; + pts.isArc = false; + pts.onCurve.first = pts.center + Base::Vector3d(1,0,0) * rAvg; //arbitrary point on edge + pts.onCurve.second = pts.center + Base::Vector3d(-1,0,0) * rAvg; //arbitrary point on edge + } else { + TechDrawGeometry::AOE* aoe = static_cast (base); + double r1 = aoe->minor; + double r2 = aoe->major; + double rAvg = (r1 + r2) / 2.0; + pts.isArc = true; + pts.center = Base::Vector3d(aoe->center.x, + aoe->center.y, + 0.0); + pts.radius = rAvg; + pts.arcEnds.first = Base::Vector3d(aoe->startPnt.x,aoe->startPnt.y,0.0); + pts.arcEnds.second = Base::Vector3d(aoe->endPnt.x,aoe->endPnt.y,0.0); + pts.midArc = Base::Vector3d(aoe->midPnt.x,aoe->midPnt.y,0.0); + pts.arcCW = aoe->cw; + pts.onCurve.first = Base::Vector3d(aoe->midPnt.x,aoe->midPnt.y,0.0); + pts.onCurve.second = pts.center + Base::Vector3d(-1,0,0) * rAvg; //arbitrary point on edge + } } else if (base && base->geomType == TechDrawGeometry::GeomType::BSPLINE) { TechDrawGeometry::BSpline* spline = static_cast (base); if (spline->isCircle()) { @@ -303,7 +335,7 @@ App::DocumentObjectExecReturn *DrawViewDimension::execute(void) pts.onCurve.second = pts.center + Base::Vector3d(-1,0,0) * rad; //arbitrary point on edge } } else { - //fubar - can't have non-circular spline as target of Diameter dimension + //fubar - can't have non-circular spline as target of Radius dimension Base::Console().Error("Dimension %s refers to invalid BSpline\n",getNameInDocument()); return App::DocumentObject::StdReturn; } @@ -338,6 +370,37 @@ App::DocumentObjectExecReturn *DrawViewDimension::execute(void) pts.onCurve.first = pts.center + Base::Vector3d(1,0,0) * circle->radius; //arbitrary point on edge pts.onCurve.second = pts.center + Base::Vector3d(-1,0,0) * circle->radius; //arbitrary point on edge } + } else if ( (base && base->geomType == TechDrawGeometry::GeomType::ELLIPSE) || + (base && base->geomType == TechDrawGeometry::GeomType::ARCOFELLIPSE) ) { + TechDrawGeometry::Ellipse* ellipse = static_cast (base); + if (ellipse->closed()) { + double r1 = ellipse->minor; + double r2 = ellipse->major; + double rAvg = (r1 + r2) / 2.0; + pts.center = Base::Vector3d(ellipse->center.x, + ellipse->center.y, + 0.0); + pts.radius = rAvg; + pts.isArc = false; + pts.onCurve.first = pts.center + Base::Vector3d(1,0,0) * rAvg; //arbitrary point on edge + pts.onCurve.second = pts.center + Base::Vector3d(-1,0,0) * rAvg; //arbitrary point on edge + } else { + TechDrawGeometry::AOE* aoe = static_cast (base); + double r1 = aoe->minor; + double r2 = aoe->major; + double rAvg = (r1 + r2) / 2.0; + pts.isArc = true; + pts.center = Base::Vector3d(aoe->center.x, + aoe->center.y, + 0.0); + pts.radius = rAvg; + pts.arcEnds.first = Base::Vector3d(aoe->startPnt.x,aoe->startPnt.y,0.0); + pts.arcEnds.second = Base::Vector3d(aoe->endPnt.x,aoe->endPnt.y,0.0); + pts.midArc = Base::Vector3d(aoe->midPnt.x,aoe->midPnt.y,0.0); + pts.arcCW = aoe->cw; + pts.onCurve.first = Base::Vector3d(aoe->midPnt.x,aoe->midPnt.y,0.0); + pts.onCurve.second = pts.center + Base::Vector3d(-1,0,0) * rAvg; //arbitrary point on edge + } } else if (base && base->geomType == TechDrawGeometry::GeomType::BSPLINE) { TechDrawGeometry::BSpline* spline = static_cast (base); if (spline->isCircle()) { @@ -360,7 +423,7 @@ App::DocumentObjectExecReturn *DrawViewDimension::execute(void) } } else { //fubar - can't have non-circular spline as target of Diameter dimension - Base::Console().Error("Dimension %s refers to invalid BSpline\n",getNameInDocument()); + Base::Console().Error("%s: can not make a Circle from this BSpline edge\n",getNameInDocument()); return App::DocumentObject::StdReturn; } } else { @@ -442,7 +505,6 @@ App::DocumentObjectExecReturn *DrawViewDimension::execute(void) } //TODO: if MeasureType = Projected and the Projected shape changes, the Dimension may become invalid (see tilted Cube example) - return DrawView::execute(); } @@ -627,7 +689,6 @@ double DrawViewDimension::getDimValue() } else if(Type.isValue("Radius")){ arcPoints pts = m_arcPoints; result = pts.radius / getViewPart()->getScale(); //Projected BaseGeom is scaled for drawing - } else if(Type.isValue("Diameter")){ arcPoints pts = m_arcPoints; diff --git a/src/Mod/TechDraw/App/Geometry.cpp b/src/Mod/TechDraw/App/Geometry.cpp index 7aa60fe8a4..f18832db0f 100644 --- a/src/Mod/TechDraw/App/Geometry.cpp +++ b/src/Mod/TechDraw/App/Geometry.cpp @@ -197,6 +197,22 @@ std::string BaseGeom::dump() return ss.str(); } +bool BaseGeom::closed(void) +{ + //return occEdge.Closed(); //based on a flag in occ. may not be correct! + bool result = false; + Base::Vector3d start(getStartPoint().x, + getStartPoint().y, + 0.0); + Base::Vector3d end(getEndPoint().x, + getEndPoint().y, + 0.0); + if (start.IsEqual(end, 0.00001)) { + result = true; + } + return result; +} + //! Convert 1 OCC edge into 1 BaseGeom (static factory method) BaseGeom* BaseGeom::baseFactory(TopoDS_Edge edge) @@ -252,7 +268,7 @@ BaseGeom* BaseGeom::baseFactory(TopoDS_Edge edge) delete bspline; bspline = nullptr; } else { - TopoDS_Edge circEdge = bspline->isCircle2(isArc); + TopoDS_Edge circEdge = bspline->asCircle(isArc); if (!circEdge.IsNull()) { if (isArc) { aoc = new AOC(circEdge); @@ -699,8 +715,8 @@ void BSpline::getCircleParms(bool& isCircle, double& radius, Base::Vector3d& cen } } -// can this BSpline be a circle? -TopoDS_Edge BSpline::isCircle2(bool& arc) +// make a circular edge from BSpline +TopoDS_Edge BSpline::asCircle(bool& arc) { TopoDS_Edge result; BRepAdaptor_Curve c(occEdge); @@ -743,7 +759,7 @@ TopoDS_Edge BSpline::isCircle2(bool& arc) projm.Perform(pm); } catch(const StdFail_NotDone &e) { - Base::Console().Log("Geometry::isCircle2 - init: %s\n",e.GetMessageString()); + Base::Console().Log("Geometry::asCircle - init: %s\n",e.GetMessageString()); return result; } if ( (proj1.NbPoints() == 0) || @@ -760,7 +776,7 @@ TopoDS_Edge BSpline::isCircle2(bool& arc) pcm = projm.NearestPoint(); } catch(const StdFail_NotDone &e) { - Base::Console().Log("Geometry::isCircle2 - nearPoint: %s\n",e.GetMessageString()); + Base::Console().Log("Geometry::asCircle - nearPoint: %s\n",e.GetMessageString()); return result; } diff --git a/src/Mod/TechDraw/App/Geometry.h b/src/Mod/TechDraw/App/Geometry.h index 5cc9ecb6b4..9647cd5a9b 100644 --- a/src/Mod/TechDraw/App/Geometry.h +++ b/src/Mod/TechDraw/App/Geometry.h @@ -81,6 +81,7 @@ class TechDrawExport BaseGeom Base::Vector2d nearPoint(Base::Vector2d p); Base::Vector2d nearPoint(const BaseGeom* p); static BaseGeom* baseFactory(TopoDS_Edge edge); + bool closed(void); std::string dump(); }; @@ -192,7 +193,7 @@ class TechDrawExport BSpline: public BaseGeom bool isLine(void); bool isCircle(void); - TopoDS_Edge isCircle2(bool& isArc); + TopoDS_Edge asCircle(bool& isArc); void getCircleParms(bool& isCircle, double& radius, Base::Vector3d& center, bool& isArc); bool intersectsArc(Base::Vector3d p1,Base::Vector3d p2); std::vector segments; diff --git a/src/Mod/TechDraw/Gui/CommandCreateDims.cpp b/src/Mod/TechDraw/Gui/CommandCreateDims.cpp index 31cb91d548..a446199300 100644 --- a/src/Mod/TechDraw/Gui/CommandCreateDims.cpp +++ b/src/Mod/TechDraw/Gui/CommandCreateDims.cpp @@ -283,12 +283,33 @@ void CmdTechDrawNewRadiusDimension::activated(int iMsg) if (edgeType == isCircle) { objs.push_back(objFeat); subs.push_back(SubNames[0]); + } else if (edgeType == isEllipse) { + QMessageBox::StandardButton result = + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Ellipse Curve Warning"), + QObject::tr("Selected edge is an Ellipse. Radius will be approximate. Continue?"), + QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel); + if (result == QMessageBox::Ok) { + objs.push_back(objFeat); + subs.push_back(SubNames[0]); + } else { + return; + } } else if (edgeType == isBSplineCircle) { QMessageBox::StandardButton result = - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Selection Warning"), - QObject::tr("Selected edge is a BSpline. Radius will be approximate."), - QMessageBox::Ok | QMessageBox::Cancel, - QMessageBox::Cancel); + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("BSpline Curve Warning"), + QObject::tr("Selected edge is a BSpline. Radius will be approximate. Continue?"), + QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel); + if (result == QMessageBox::Ok) { + objs.push_back(objFeat); + subs.push_back(SubNames[0]); + } else { + return; + } + } else if (edgeType == isBSpline) { + QMessageBox::StandardButton result = + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("BSpline Curve Warning"), + QObject::tr("Selected edge is a BSpline. Radius will be approximate. Continue?"), + QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel); if (result == QMessageBox::Ok) { objs.push_back(objFeat); subs.push_back(SubNames[0]); @@ -317,6 +338,7 @@ void CmdTechDrawNewRadiusDimension::activated(int iMsg) doCommand(Doc,"App.activeDocument().%s.addView(App.activeDocument().%s)",PageName.c_str(),FeatName.c_str()); commitCommand(); + dim->recomputeFeature(); //Horrible hack to force Tree update @@ -383,12 +405,33 @@ void CmdTechDrawNewDiameterDimension::activated(int iMsg) if (edgeType == isCircle) { objs.push_back(objFeat); subs.push_back(SubNames[0]); + } else if (edgeType == isEllipse) { + QMessageBox::StandardButton result = + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Ellipse Curve Warning"), + QObject::tr("Selected edge is an Ellipse. Diameter will be approximate. Continue?"), + QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel); + if (result == QMessageBox::Ok) { + objs.push_back(objFeat); + subs.push_back(SubNames[0]); + } else { + return; + } } else if (edgeType == isBSplineCircle) { QMessageBox::StandardButton result = - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Selection Warning"), - QObject::tr("Selected edge is a BSpline. Diameter will be approximate."), - QMessageBox::Ok | QMessageBox::Cancel, - QMessageBox::Cancel); + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("BSpline Curve Warning"), + QObject::tr("Selected edge is a BSpline. Diameter will be approximate. Continue?"), + QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel); + if (result == QMessageBox::Ok) { + objs.push_back(objFeat); + subs.push_back(SubNames[0]); + } else { + return; + } + } else if (edgeType == isBSpline) { + QMessageBox::StandardButton result = + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("BSpline Curve Warning"), + QObject::tr("Selected edge is a BSpline. Diameter will be approximate. Continue?"), + QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel); if (result == QMessageBox::Ok) { objs.push_back(objFeat); subs.push_back(SubNames[0]); diff --git a/src/Mod/TechDraw/Gui/QGIViewDimension.cpp b/src/Mod/TechDraw/Gui/QGIViewDimension.cpp index b3fc660cac..e401f318b4 100644 --- a/src/Mod/TechDraw/Gui/QGIViewDimension.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewDimension.cpp @@ -449,7 +449,6 @@ QString QGIViewDimension::getLabelText(void) QString second = datumLabel->getTolText()->toPlainText(); result = first + second; return result; - } void QGIViewDimension::datumLabelDragged(bool ctrl) @@ -1104,7 +1103,6 @@ void QGIViewDimension::draw() } else if(strcmp(dimType, "Radius") == 0) { // preferred terminology: Dimension Text, Dimension Line(s), Extension Lines, Arrowheads // radius gets 1 dimension line from the dimension text to a point on the curve - Base::Vector3d pointOnCurve,curveCenter; double radius; arcPoints pts = dim->getArcPoints(); @@ -1371,7 +1369,6 @@ void QGIViewDimension::draw() Base::Vector3d labelNorm(-labelVec.y, labelVec.x, 0.); double lAngle = atan2(labelNorm.y, labelNorm.x); -//<<<<<<<<<<< if (lAngle < 0.0) { lAngle = 2 * M_PI + lAngle; //map to +ve lAngle } @@ -1385,7 +1382,6 @@ void QGIViewDimension::draw() (lAngle <= 1.5*M_PI - angleFiddle)) { // < 260CW -> Q3 lAngle -= M_PI; // flip CCW } -//<<<<<<<<< // //if label is more/less vertical, make it vertical @@ -1424,7 +1420,6 @@ void QGIViewDimension::draw() } else { Base::Console().Log("INFO - QGIVD::draw - no parent to update\n"); } - } void QGIViewDimension::drawBorder(void) diff --git a/src/Mod/TechDraw/Gui/ViewProviderDrawingView.cpp b/src/Mod/TechDraw/Gui/ViewProviderDrawingView.cpp index fba922fbf7..f2a6d3b977 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderDrawingView.cpp +++ b/src/Mod/TechDraw/Gui/ViewProviderDrawingView.cpp @@ -86,8 +86,10 @@ void ViewProviderDrawingView::attach(App::DocumentObject *pcFeat) auto feature = getViewObject(); if (feature != nullptr) { connectGuiRepaint = feature->signalGuiPaint.connect(bnd); + //TODO: would be good to start the QGIV creation process here, but no guarantee we actually have + // MDIVP or QGVP yet. } else { - Base::Console().Log("VPDV::attach has no Feature!\n"); + Base::Console().Warning("VPDV::attach has no Feature!\n"); } } @@ -240,6 +242,7 @@ MDIViewPage* ViewProviderDrawingView::getMDIViewPage() const void ViewProviderDrawingView::onGuiRepaint(const TechDraw::DrawView* dv) { +// Base::Console().Message("VPDV::onGuiRepaint(%s)\n", dv->getNameInDocument()); if (dv == getViewObject()) { if (!dv->isRemoving() && !dv->isRestoring()) { @@ -247,6 +250,8 @@ void ViewProviderDrawingView::onGuiRepaint(const TechDraw::DrawView* dv) if (qgiv) { qgiv->updateView(true); } else { //we are not part of the Gui page yet. ask page to add us. + //TODO: this bit causes trouble. Should move QGIV creation to attach? + // is MDIVP/QGVP available at attach time? MDIViewPage* page = getMDIViewPage(); if (page != nullptr) { page->addView(dv);