From a539cec1a34030929f435d31f2e35f35f1bc5586 Mon Sep 17 00:00:00 2001 From: WandererFan Date: Sat, 30 Jul 2016 20:13:04 -0400 Subject: [PATCH] Correct Radius leader behaviour --- src/Mod/TechDraw/App/Geometry.cpp | 73 +++++++++++++++++++++-- src/Mod/TechDraw/App/Geometry.h | 8 ++- src/Mod/TechDraw/Gui/QGIViewDimension.cpp | 48 +++++++++++++-- src/Mod/TechDraw/Gui/QGIViewDimension.h | 2 + 4 files changed, 119 insertions(+), 12 deletions(-) diff --git a/src/Mod/TechDraw/App/Geometry.cpp b/src/Mod/TechDraw/App/Geometry.cpp index 0080df0c198b..28e4ce939c92 100644 --- a/src/Mod/TechDraw/App/Geometry.cpp +++ b/src/Mod/TechDraw/App/Geometry.cpp @@ -29,6 +29,10 @@ #include #include #include +#include +#include +#include +#include #include #include #include @@ -43,12 +47,13 @@ #include #include #include +#include #endif // #ifndef _PreComp_ #include #include #include -#include +//#include #include "Geometry.h" using namespace TechDrawGeometry; @@ -231,8 +236,8 @@ AOE::AOE(const TopoDS_Edge &e) : Ellipse(e) gp_Vec v3(0,0,1); double a = v3.DotCross(v1,v2); - startAngle = f; - endAngle = l; + startAngle = fmod(f,2.0*M_PI); + endAngle = fmod(l,2.0*M_PI); cw = (a < 0) ? true: false; largeArc = (l-f > M_PI) ? true : false; @@ -272,8 +277,8 @@ AOC::AOC(const TopoDS_Edge &e) : Circle(e) gp_Vec v3(0,0,1); double a = v3.DotCross(v1,v2); - startAngle = f; - endAngle = l; + startAngle = fmod(f,2.0*M_PI); + endAngle = fmod(l,2.0*M_PI); cw = (a < 0) ? true: false; largeArc = (l-f > M_PI) ? true : false; @@ -282,6 +287,64 @@ AOC::AOC(const TopoDS_Edge &e) : Circle(e) midPnt = Base::Vector2D(m.X(), m.Y()); } +bool AOC::isOnArc(Base::Vector3d p) +{ + bool result = false; + double minDist = -1.0; + gp_Pnt pnt(p.x,p.y,p.z); + TopoDS_Vertex v = BRepBuilderAPI_MakeVertex(pnt); + BRepExtrema_DistShapeShape extss(occEdge, v); + if (extss.IsDone()) { + int count = extss.NbSolution(); + if (count != 0) { + minDist = extss.Value(); + if (minDist < Precision::Confusion()) { + result = true; + } + } + } + return result; +} + +double AOC::distToArc(Base::Vector3d p) +{ + double minDist = -1.0; + gp_Pnt pnt(p.x,p.y,p.z); + TopoDS_Vertex v = BRepBuilderAPI_MakeVertex(pnt); + BRepExtrema_DistShapeShape extss(occEdge, v); + if (extss.IsDone()) { + int count = extss.NbSolution(); + if (count != 0) { + minDist = extss.Value(); + } + } + return minDist; +} + + +bool AOC::intersectsArc(Base::Vector3d p1,Base::Vector3d p2) +{ + bool result = false; + double minDist = -1.0; + gp_Pnt pnt1(p1.x,p1.y,p1.z); + TopoDS_Vertex v1 = BRepBuilderAPI_MakeVertex(pnt1); + gp_Pnt pnt2(p2.x,p2.y,p2.z); + TopoDS_Vertex v2 = BRepBuilderAPI_MakeVertex(pnt2); + BRepBuilderAPI_MakeEdge mkEdge(v1,v2); + TopoDS_Edge line = mkEdge.Edge(); + BRepExtrema_DistShapeShape extss(occEdge, line); + if (extss.IsDone()) { + int count = extss.NbSolution(); + if (count != 0) { + minDist = extss.Value(); + if (minDist < Precision::Confusion()) { + result = true; + } + } + } + return result; +} + //! Generic is a multiline Generic::Generic(const TopoDS_Edge &e) diff --git a/src/Mod/TechDraw/App/Geometry.h b/src/Mod/TechDraw/App/Geometry.h index e6cfe9493d77..34f169a4e80a 100644 --- a/src/Mod/TechDraw/App/Geometry.h +++ b/src/Mod/TechDraw/App/Geometry.h @@ -24,6 +24,8 @@ #define TECHDRAW_GEOMETRY_H #include +#include + #include #include #include @@ -138,7 +140,7 @@ class TechDrawExport AOC: public Circle Base::Vector2D endPnt; Base::Vector2D midPnt; - /// Angle in radian + /// Angle in radian ??angle with horizontal? double startAngle; /// Angle in radian @@ -147,6 +149,10 @@ class TechDrawExport AOC: public Circle /// Arc is drawn clockwise from startAngle to endAngle if true, counterclockwise if false bool cw; // TODO: Instead of this (and similar one in AOE), why not reorder startAngle and endAngle? bool largeArc; + + bool isOnArc(Base::Vector3d v); + bool intersectsArc(Base::Vector3d p1,Base::Vector3d p2); + double distToArc(Base::Vector3d p); }; /// Handles degree 1 to 3 Bezier segments diff --git a/src/Mod/TechDraw/Gui/QGIViewDimension.cpp b/src/Mod/TechDraw/Gui/QGIViewDimension.cpp index b96bc0692516..5273581c411a 100644 --- a/src/Mod/TechDraw/Gui/QGIViewDimension.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewDimension.cpp @@ -768,6 +768,8 @@ void QGIViewDimension::draw() Base::Vector3d pointOnCurve,curveCenter; double radius; + TechDrawGeometry::AOC* geomArc; + bool isArc = false; if(dim->References2D.getValues().size() == 1 && TechDraw::DrawUtil::getGeomTypeFromName(SubNames[0]) == "Edge") { int idx = TechDraw::DrawUtil::getIndexFromName(SubNames[0]); @@ -783,7 +785,9 @@ void QGIViewDimension::draw() curveCenter = Base::Vector3d(circ->center.fX,circ->center.fY,0.0); pointOnCurve = Base::Vector3d(curveCenter.x + radius, curveCenter.y,0.0); } else if (geom->geomType == TechDrawGeometry::ARCOFCIRCLE) { + isArc = true; TechDrawGeometry::AOC *circ = static_cast(geom); + geomArc = circ; radius = circ->radius; curveCenter = Base::Vector3d(circ->center.fX,circ->center.fY,0.0); pointOnCurve = Base::Vector3d(circ->midPnt.fX, circ->midPnt.fY,0.0); @@ -837,6 +841,42 @@ void QGIViewDimension::draw() pointOnCurve = curveCenter - dirDimLine * radius; kinkPoint = dLineStart; //no kink } + + //handle partial arc weird cases + if (isArc) { + Base::Vector3d midPt(geomArc->midPnt.fX, geomArc->midPnt.fY,0.0); + Base::Vector3d startPt(geomArc->startPnt.fX, geomArc->startPnt.fY,0.0); + Base::Vector3d endPt(geomArc->endPnt.fX, geomArc->endPnt.fY,0.0); + if (outerPlacement && + !geomArc->intersectsArc(curveCenter,kinkPoint) ) { + pointOnCurve = midPt; + } else if (!outerPlacement) { + if ((midPt - lblCenter).Length() > (midPt - curveCenter).Length()) { //label is farther than center + dirDimLine = dirDimLine * -1; + } + dLineStart = curveCenter + dirDimLine * margin; + pointOnCurve = curveCenter + dirDimLine * radius; + kinkPoint = dLineStart; + if (!geomArc->intersectsArc(dLineStart,pointOnCurve)) { //keep pathological case within arc + if ((pointOnCurve - endPt).Length() < (pointOnCurve - startPt).Length()) { + if (!geomArc->cw ) { + pointOnCurve = endPt; + } else { + pointOnCurve = startPt; + } + } else { + if (!geomArc->cw) { + pointOnCurve = startPt; + } else { + pointOnCurve = endPt; + } + } + dLineStart = curveCenter + (pointOnCurve - curveCenter).Normalize() * margin; + kinkPoint = dLineStart; + } + } + } + QPainterPath dLinePath; //radius dimension line path dLinePath.moveTo(dLineStart.x, dLineStart.y); dLinePath.lineTo(kinkPoint.x, kinkPoint.y); @@ -862,19 +902,16 @@ void QGIViewDimension::draw() } centerMark->setPath(clpath); - aHead1->flip(true); aHead1->draw(); - aHead2->draw(); Base::Vector3d ar1Pos = pointOnCurve; - float arAngle = atan2(dirDimLine.y, dirDimLine.x) * 180 / M_PI; + Base::Vector3d dirArrowLine = (pointOnCurve - kinkPoint).Normalize(); + float arAngle = atan2(dirArrowLine.y, dirArrowLine.x) * 180 / M_PI; aHead1->setPos(ar1Pos.x, ar1Pos.y); aHead1->setRotation(arAngle); aHead1->setHighlighted(isSelected() || hasHover); aHead1->show(); - aHead2->setRotation(arAngle); - aHead2->setHighlighted(isSelected() || hasHover); aHead2->hide(); } else if(strcmp(dimType, "Angle") == 0) { // Only use two straight line edeges for angle @@ -1172,5 +1209,4 @@ void QGIViewDimension::setPens(void) centerMark->setPen(m_clPen); } - #include diff --git a/src/Mod/TechDraw/Gui/QGIViewDimension.h b/src/Mod/TechDraw/Gui/QGIViewDimension.h index 927192050f6a..3e613d615022 100644 --- a/src/Mod/TechDraw/Gui/QGIViewDimension.h +++ b/src/Mod/TechDraw/Gui/QGIViewDimension.h @@ -27,6 +27,7 @@ #include #include #include +#include #include "QGIView.h" #include "QGCustomText.h" @@ -36,6 +37,7 @@ class DrawViewDimension; namespace TechDrawGeometry { class BaseGeom; +class AOC; } namespace TechDrawGui