Correct Radius leader behaviour

This commit is contained in:
WandererFan 2016-07-30 20:13:04 -04:00 committed by Yorik van Havre
parent 40fa4e0d40
commit a539cec1a3
4 changed files with 119 additions and 12 deletions

View File

@ -29,6 +29,10 @@
#include <BRep_Tool.hxx>
#include <BRepAdaptor_HCurve.hxx>
#include <BRepLib.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepExtrema_DistShapeShape.hxx>
#include <Precision.hxx>
#include <gp_Circ.hxx>
#include <gp_Elips.hxx>
#include <gp_Pnt.hxx>
@ -43,12 +47,13 @@
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <cmath>
#endif // #ifndef _PreComp_
#include <Base/Console.h>
#include <Base/Exception.h>
#include <Base/Tools2D.h>
#include <Base/Vector3D.h>
//#include <Base/Vector3D.h>
#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)

View File

@ -24,6 +24,8 @@
#define TECHDRAW_GEOMETRY_H
#include <Base/Tools2D.h>
#include <Base/Vector3D.h>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Edge.hxx>
@ -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

View File

@ -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<TechDrawGeometry::AOC *>(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 <Mod/TechDraw/Gui/moc_QGIViewDimension.cpp>

View File

@ -27,6 +27,7 @@
#include <QGraphicsView>
#include <QStyleOptionGraphicsItem>
#include <QGraphicsPathItem>
#include <Base/Vector3D.h>
#include "QGIView.h"
#include "QGCustomText.h"
@ -36,6 +37,7 @@ class DrawViewDimension;
namespace TechDrawGeometry {
class BaseGeom;
class AOC;
}
namespace TechDrawGui