Skip to content

Commit

Permalink
[TD]Allow Aligned & Uniform Conventions on Radius Dims
Browse files Browse the repository at this point in the history
  • Loading branch information
WandererFan committed Aug 10, 2019
1 parent f704340 commit 641d946
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 5 deletions.
162 changes: 158 additions & 4 deletions src/Mod/TechDraw/Gui/QGIViewDimension.cpp
Expand Up @@ -36,7 +36,7 @@
# include <QPaintDevice>
# include <QSvgGenerator>

# include <math.h>
# include <cmath>
#endif

#include <App/Application.h>
Expand Down Expand Up @@ -70,7 +70,8 @@
#include "DrawGuiUtil.h"

#ifndef M_2PI
#define M_2PI 6.283185307179586476925287
// #define M_2PI 6.283185307179586476925287
#define M_2PI (M_PI * 2.0)
#endif

//TODO: hide the Qt coord system (+y down).
Expand Down Expand Up @@ -1174,7 +1175,13 @@ void QGIViewDimension::draw()
// dim->getViewPart()->addVertex(curveCenter,true);
// }
} else if(strcmp(dimType, "Radius") == 0) {
drawRadius(dim, vp);
if (prefRadiusAligned() == 0) { //ISO
drawRadiusAligned(dim, vp);
} else if (prefRadiusAligned() == 1) { //ASME
drawRadiusUniform(dim, vp);
} else {
Base::Console().Error("QGIVD::draw - bad radiusAligned pref: %d\n", prefRadiusAligned());
}
} else if( (strcmp(dimType, "Angle") == 0) ||
(strcmp(dimType, "Angle3Pt") == 0)) {
anglePoints pts = dim->getAnglePoints();
Expand Down Expand Up @@ -1423,7 +1430,9 @@ Base::Vector3d QGIViewDimension::computeLineOriginPoint(Base::Vector3d lineTarge
*Base::Vector3d(cos(lineAngle), sin(lineAngle), 0.0);
}

void QGIViewDimension::drawRadius(TechDraw::DrawViewDimension *dimension, ViewProviderDimension *viewProvider) const
//draw a Radius dimension using "aligned" convention (ISO)
void QGIViewDimension::drawRadiusAligned(TechDraw::DrawViewDimension *dimension,
ViewProviderDimension *viewProvider) const
{
// Preferred terminology according to ISO 129-1 for Radius:
// Dimensional Value, Leader Line, Reference Line, Terminator
Expand Down Expand Up @@ -1461,6 +1470,7 @@ void QGIViewDimension::drawRadius(TechDraw::DrawViewDimension *dimension, ViewPr
Base::Vector3d arcPoint;
double lineAngle;

//TODO: does this violate "Aligned" convention?
if (viewProvider->TiltText.getValue()) { // We may rotate the label so no reference line is needed
double devAngle = computeLineAndLabelAngles(curveCenter, labelCenter,
getDefaultTextVerticalOffset(), lineAngle, labelAngle);
Expand Down Expand Up @@ -1634,6 +1644,7 @@ void QGIViewDimension::drawRadius(TechDraw::DrawViewDimension *dimension, ViewPr
dimLines->setPath(radiusPath);

aHead1->setPos(arcPoint.x, arcPoint.y);
aHead1->setRotation(0.0);
aHead1->setDirMode(true);
aHead1->setDirection(lineAngle);
if (viewProvider->FlipArrowheads.getValue()) {
Expand All @@ -1647,6 +1658,141 @@ void QGIViewDimension::drawRadius(TechDraw::DrawViewDimension *dimension, ViewPr
aHead2->hide();
}

//Draw a Radius dimension using "uniform" alignment convention (Ansi/Asme)
void QGIViewDimension::drawRadiusUniform(TechDraw::DrawViewDimension* dim,
TechDrawGui::ViewProviderDimension* viewProvider) const
{
// 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
aHead1->setFlipped(false);

Base::Vector3d pointOnCurve,curveCenter;
double radius;
arcPoints pts = dim->getArcPoints();
bool isArc = pts.isArc;
radius = Rez::guiX(pts.radius);
curveCenter = Rez::guiX(pts.center);
pointOnCurve = Rez::guiX(pts.onCurve.first);
QRectF mappedRect = mapRectFromItem(datumLabel, datumLabel->boundingRect());
Base::Vector3d lblCenter = Base::Vector3d(mappedRect.center().x(), mappedRect.center().y(), 0.0);

// Note Bounding Box size is not the same width or height as text (only used for finding center)
float bbX = datumLabel->boundingRect().width();
float bbY = datumLabel->boundingRect().height();
datumLabel->setTransformOriginPoint(bbX / 2, bbY /2);
datumLabel->setRotation(0.0); //label is always right side up & horizontal

//if inside the arc (len(DimLine < radius)) arrow goes from center to edge away from label
//if outside the arc arrow kinks, then goes to edge nearest label
bool outerPlacement = false;
if ((lblCenter - curveCenter).Length() > radius) { //label is outside circle
outerPlacement = true;
}

Base::Vector3d dirDimLine = (lblCenter - curveCenter).Normalize();
if (fabs(dirDimLine.Length()) < (Precision::Confusion())) {
dirDimLine = Base::Vector3d(-1.0,0.0,0.0);
}
// Base::Vector3d adjustDir = dirDimLine; //adjust line lengths for arrowheads
double dimLineAdjust = Rez::guiX(QGIArrow::getOverlapAdjust(QGIArrow::getPrefArrowStyle(),
QGIArrow::getPrefArrowSize()));

Base::Vector3d dLineStart;
Base::Vector3d dLineEnd; //?? radius draws line from text to curve?? (diam is curve to text!)
Base::Vector3d kinkPoint;
double margin = Rez::guiX(5.f); //space around label
double kinkLength = Rez::guiX(5.0); //sb % of horizontal dist(lblCenter,curveCenter)???
if (outerPlacement) {
double offset = getDefaultTextHorizontalOffset(lblCenter.x > curveCenter.x);
dLineStart.y = lblCenter.y;
dLineStart.x = lblCenter.x + offset; //start at right or left of label
kinkLength = (lblCenter.x < curveCenter.x) ? kinkLength : -kinkLength;
kinkPoint.y = dLineStart.y;
kinkPoint.x = dLineStart.x + kinkLength;
pointOnCurve = curveCenter + (kinkPoint - curveCenter).Normalize() * radius;
dLineEnd = pointOnCurve + (kinkPoint - curveCenter).Normalize() * dimLineAdjust;
if ((kinkPoint - curveCenter).Length() < radius) {
dirDimLine = (curveCenter - kinkPoint).Normalize();
} else {
dirDimLine = (kinkPoint - curveCenter).Normalize();
}
} else {
dLineStart = curveCenter - dirDimLine * margin; //just beyond centerpoint
pointOnCurve = curveCenter - dirDimLine * radius;
dLineEnd = pointOnCurve + dirDimLine * dimLineAdjust;
kinkPoint = dLineStart; //no kink
}

//handle partial arc weird cases
if (isArc) {
Base::Vector3d midPt = Rez::guiX(pts.midArc);
Base::Vector3d startPt = Rez::guiX(pts.arcEnds.first);
Base::Vector3d endPt = Rez::guiX(pts.arcEnds.second);
if (outerPlacement &&
!dim->leaderIntersectsArc(Rez::appX(curveCenter),Rez::appX(kinkPoint))) { //keep pathological case within arc
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;
dLineEnd = pointOnCurve - dirDimLine * dimLineAdjust;
kinkPoint = dLineStart;
if (!dim->leaderIntersectsArc(Rez::appX(dLineStart),Rez::appX(pointOnCurve))) { //keep pathological case within arc
if ((pointOnCurve - endPt).Length() < (pointOnCurve - startPt).Length()) {
if (!pts.arcCW ) {
pointOnCurve = endPt;
} else {
pointOnCurve = startPt;
}
} else {
if (!pts.arcCW ) {
pointOnCurve = startPt;
} else {
pointOnCurve = endPt;
}
}
dLineStart = curveCenter + (pointOnCurve - curveCenter).Normalize() * margin;
dLineEnd = pointOnCurve - dirDimLine * dimLineAdjust;
kinkPoint = dLineStart;
}
}
}

QPainterPath dLinePath; //radius dimension line path
dLinePath.moveTo(dLineStart.x, dLineStart.y);
dLinePath.lineTo(kinkPoint.x, kinkPoint.y);
dLinePath.lineTo(dLineEnd.x, dLineEnd.y);

dimLines->setPath(dLinePath);

Base::Vector3d ar1Pos = pointOnCurve;
Base::Vector3d dirArrowLine = (pointOnCurve - kinkPoint).Normalize();
float arAngle = atan2(dirArrowLine.y, dirArrowLine.x) * 180 / M_PI;

//NOTE: in this case aHead1->dirMode is false and Qt rotation is used to point arrowhead
aHead1->setPos(ar1Pos.x, ar1Pos.y);
aHead1->setDirMode(false);
aHead1->setRotation(arAngle);
if (viewProvider->FlipArrowheads.getValue()) {
aHead1->flip();
}
aHead1->setStyle(QGIArrow::getPrefArrowStyle());
aHead1->setSize(QGIArrow::getPrefArrowSize());
aHead1->draw();
aHead1->show();

aHead2->hide();

// code for showCenterMark as attribute of Dimension instead of View
// if (dim->CentreLines.getValue()) {
// curveCenterMark->setPos(curveCenter.x,curveCenter.y);
// centerMark->show();
// dim->getViewPart()->addVertex(curveCenter,true);
// }
}

QColor QGIViewDimension::getNormalColor()
{
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
Expand Down Expand Up @@ -1864,5 +2010,13 @@ void QGIViewDimension::setPens(void)
aHead2->setWidth(m_lineWidth);
}

int QGIViewDimension::prefRadiusAligned(void)
{
int result = 0;
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/Standards");
result = hGrp->GetInt("RadiusAligned", 0); //default to ISO
return result;
}

#include <Mod/TechDraw/Gui/moc_QGIViewDimension.cpp>
8 changes: 7 additions & 1 deletion src/Mod/TechDraw/Gui/QGIViewDimension.h
Expand Up @@ -168,15 +168,21 @@ public Q_SLOTS:
Base::Vector3d computeLineOriginPoint(Base::Vector3d lineTarget, double projectedLabelDistance,
double lineAngle, double labelWidth, double direction) const;

void drawRadius(TechDraw::DrawViewDimension *dimension, ViewProviderDimension *viewProvider) const;
void draw() override;
void drawRadiusAligned(TechDraw::DrawViewDimension *dimension,
ViewProviderDimension *viewProvider) const;
void drawRadiusUniform(TechDraw::DrawViewDimension *dimension,
ViewProviderDimension *viewProvider) const;

virtual QVariant itemChange( GraphicsItemChange change,
const QVariant &value ) override;
virtual void setSvgPens(void);
virtual void setPens(void);
Base::Vector3d findIsoDir(Base::Vector3d ortho);
Base::Vector3d findIsoExt(Base::Vector3d isoDir);
QString getPrecision(void);

int prefRadiusAligned(void);

protected:
bool hasHover;
Expand Down

0 comments on commit 641d946

Please sign in to comment.