[TD]Allow override of dimension line angles
This commit is contained in:
committed by
WandererFan
parent
96aa87a45f
commit
959061720f
@@ -584,7 +584,7 @@ bool DrawUtil::isBetween(const Base::Vector3d pt, const Base::Vector3d end1, con
|
||||
Base::Vector3d DrawUtil::Intersect2d(Base::Vector3d p1, Base::Vector3d d1,
|
||||
Base::Vector3d p2, Base::Vector3d d2)
|
||||
{
|
||||
Base::Vector3d result(0,0,0);
|
||||
Base::Vector3d result(0.0, 0.0, 0.0);
|
||||
Base::Vector3d p12(p1.x+d1.x, p1.y+d1.y, 0.0);
|
||||
double A1 = d1.y;
|
||||
double B1 = -d1.x;
|
||||
@@ -608,6 +608,34 @@ Base::Vector3d DrawUtil::Intersect2d(Base::Vector3d p1, Base::Vector3d d1,
|
||||
return result;
|
||||
}
|
||||
|
||||
Base::Vector2d DrawUtil::Intersect2d(Base::Vector2d p1, Base::Vector2d d1,
|
||||
Base::Vector2d p2, Base::Vector2d d2)
|
||||
{
|
||||
Base::Vector2d result(0.0, 0.0);
|
||||
Base::Vector2d p12(p1.x+d1.x, p1.y+d1.y);
|
||||
double A1 = d1.y;
|
||||
double B1 = -d1.x;
|
||||
double C1 = A1*p1.x + B1*p1.y;
|
||||
|
||||
Base::Vector2d p22(p2.x+d2.x, p2.y+d2.y);
|
||||
double A2 = d2.y;
|
||||
double B2 = -d2.x;
|
||||
double C2 = A2*p2.x + B2*p2.y;
|
||||
|
||||
double det = A1*B2 - A2*B1;
|
||||
if(det == 0){
|
||||
Base::Console().Message("Lines are parallel\n");
|
||||
}else{
|
||||
double x = (B2*C1 - B1*C2)/det;
|
||||
double y = (A1*C2 - A2*C1)/det;
|
||||
result.x = x;
|
||||
result.y = y;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
std::string DrawUtil::shapeToString(TopoDS_Shape s)
|
||||
{
|
||||
std::ostringstream buffer;
|
||||
|
||||
@@ -109,6 +109,8 @@ class TechDrawExport DrawUtil {
|
||||
//! find intersection in 2d for 2 lines in point+direction form
|
||||
static Base::Vector3d Intersect2d(Base::Vector3d p1, Base::Vector3d d1,
|
||||
Base::Vector3d p2, Base::Vector3d d2);
|
||||
static Base::Vector2d Intersect2d(Base::Vector2d p1, Base::Vector2d d1,
|
||||
Base::Vector2d p2, Base::Vector2d d2);
|
||||
static Base::Vector3d gpPnt2V3(const gp_Pnt gp) { return Base::Vector3d(gp.X(),gp.Y(),gp.Z()); }
|
||||
static gp_Pnt V32gpPnt(const Base::Vector3d v) { return gp_Pnt(v.x,v.y,v.z); }
|
||||
static std::string shapeToString(TopoDS_Shape s);
|
||||
|
||||
@@ -131,6 +131,10 @@ DrawViewDimension::DrawViewDimension(void)
|
||||
UnderTolerance.setConstraints(&ToleranceConstraint);
|
||||
ADD_PROPERTY_TYPE(Inverted, (false), "", App::Prop_Output, "The dimensional value is displayed inverted");
|
||||
|
||||
ADD_PROPERTY_TYPE(AngleOverride,(false), "Override", App::Prop_Output, "User specified angles");
|
||||
ADD_PROPERTY_TYPE(LineAngle,(0.0), "Override", App::Prop_Output, "Dimension line angle");
|
||||
ADD_PROPERTY_TYPE(ExtensionAngle,(0.0), "Override", App::Prop_Output, "Extension line angle");
|
||||
|
||||
// hide the DrawView properties that don't apply to Dimensions
|
||||
ScaleType.setStatus(App::Property::ReadOnly, true);
|
||||
ScaleType.setStatus(App::Property::Hidden, true);
|
||||
|
||||
@@ -110,6 +110,10 @@ public:
|
||||
App::PropertyQuantityConstraint OverTolerance;
|
||||
App::PropertyQuantityConstraint UnderTolerance;
|
||||
|
||||
App::PropertyBool AngleOverride;
|
||||
App::PropertyAngle LineAngle;
|
||||
App::PropertyAngle ExtensionAngle;
|
||||
|
||||
enum RefType{
|
||||
invalidRef,
|
||||
oneEdge,
|
||||
|
||||
@@ -77,6 +77,7 @@
|
||||
#include "QGIViewDimension.h"
|
||||
#include "ViewProviderDimension.h"
|
||||
#include "DrawGuiUtil.h"
|
||||
#include "QGIVertex.h"
|
||||
|
||||
#define NORMAL 0
|
||||
#define PRE 1
|
||||
@@ -864,6 +865,12 @@ Base::Vector2d QGIViewDimension::getAsmeRefJointPoint(const Base::BoundBox2d &la
|
||||
labelRectangle.GetCenter().y);
|
||||
}
|
||||
|
||||
//find intersection of line L (through linePoint at angle lineAngle) and a line perpendicular to L
|
||||
//passing through perpendicularPoint
|
||||
//tricky vector algebra note:
|
||||
//a*b is the magnitude of the projection of a onto b
|
||||
//so we project a vector linePoint-perpendicularPoint onto unit vector in lineAngle direction giving
|
||||
//the distance from linePoint to intersection, then make a displacement vector and add it to linePoint
|
||||
Base::Vector2d QGIViewDimension::computePerpendicularIntersection(const Base::Vector2d &linePoint,
|
||||
const Base::Vector2d &perpendicularPoint, double lineAngle)
|
||||
{
|
||||
@@ -872,6 +879,12 @@ Base::Vector2d QGIViewDimension::computePerpendicularIntersection(const Base::Ve
|
||||
lineAngle);
|
||||
}
|
||||
|
||||
//calculate the end points of 1 extension line
|
||||
//originPoint - a point on the distance line (end point)
|
||||
//linePoint - point on dimension line that is perpendicular projection of distance line point
|
||||
// onto dimension line
|
||||
//1 extension line end point is the return value
|
||||
//1 extension line end point is modified parameter startPoint
|
||||
Base::Vector2d QGIViewDimension::computeExtensionLinePoints(const Base::Vector2d &originPoint,
|
||||
const Base::Vector2d &linePoint, double hintAngle, double overhangSize,
|
||||
double gapSize, Base::Vector2d &startPoint)
|
||||
@@ -1254,6 +1267,9 @@ void QGIViewDimension::drawSingleLine(QPainterPath &painterPath, const Base::Vec
|
||||
painterPath.lineTo(toQtGui(lineOrigin + Base::Vector2d::FromPolar(endPosition, lineAngle)));
|
||||
}
|
||||
|
||||
|
||||
//adds line segments to painterPath from lineOrigin along lineAngle
|
||||
//segment length is determined by drawMarking entries
|
||||
void QGIViewDimension::drawMultiLine(QPainterPath &painterPath, const Base::Vector2d &lineOrigin, double lineAngle,
|
||||
const std::vector<std::pair<double, bool>> &drawMarking) const
|
||||
{
|
||||
@@ -1330,6 +1346,11 @@ void QGIViewDimension::drawMultiArc(QPainterPath &painterPath, const Base::Vecto
|
||||
while (currentIndex != entryIndex);
|
||||
}
|
||||
|
||||
|
||||
//adds dimension line to painterPath
|
||||
//dimension line starts at targetPoint and continues for a distance (startPosition?) along lineAngle
|
||||
//jointPosition - distance of reference line from 1 extension line??
|
||||
//lineAngle - Clockwise angle of distance line with horizontal
|
||||
void QGIViewDimension::drawDimensionLine(QPainterPath &painterPath, const Base::Vector2d &targetPoint, double lineAngle,
|
||||
double startPosition, double jointPosition, const Base::BoundBox2d &labelRectangle,
|
||||
int arrowCount, int standardStyle, bool flipArrows) const
|
||||
@@ -1387,6 +1408,14 @@ void QGIViewDimension::drawDimensionArc(QPainterPath &painterPath, const Base::V
|
||||
drawArrows(arrowCount, arrowPositions, arrowAngles, flipArrows);
|
||||
}
|
||||
|
||||
//draw any of 3 distance dimension types
|
||||
//startPoint, endPoint - ends of actual distance line
|
||||
//lineAngle - angle of actual line with horizontal
|
||||
//target points - projection of reference line ends on to extension line
|
||||
//startCross & endCross - real intersection of extension lines and dimension line
|
||||
//dimension line - main annotation line
|
||||
//reference line - line under dimension text in referenced styles
|
||||
//joint points - ends of reference line
|
||||
void QGIViewDimension::drawDistanceExecutive(const Base::Vector2d &startPoint, const Base::Vector2d &endPoint,
|
||||
double lineAngle, const Base::BoundBox2d &labelRectangle,
|
||||
int standardStyle, int renderExtent, bool flipArrows) const
|
||||
@@ -1396,6 +1425,7 @@ void QGIViewDimension::drawDistanceExecutive(const Base::Vector2d &startPoint, c
|
||||
Base::Vector2d labelCenter(labelRectangle.GetCenter());
|
||||
double labelAngle = 0.0;
|
||||
|
||||
//startCross and endCross are points where extension line intersects dimension line
|
||||
Base::Vector2d startCross;
|
||||
Base::Vector2d endCross;
|
||||
int arrowCount = renderExtent >= ViewProviderDimension::REND_EXTENT_NORMAL
|
||||
@@ -1404,7 +1434,9 @@ void QGIViewDimension::drawDistanceExecutive(const Base::Vector2d &startPoint, c
|
||||
|
||||
if (standardStyle == ViewProviderDimension::STD_STYLE_ISO_REFERENCING
|
||||
|| standardStyle == ViewProviderDimension::STD_STYLE_ASME_REFERENCING) {
|
||||
// The dimensional value text must stay horizontal
|
||||
// The dimensional value text must stay horizontal in these styles
|
||||
|
||||
//jointPoints are the ends of the reference line
|
||||
Base::Vector2d jointPoints[2];
|
||||
|
||||
if (standardStyle == ViewProviderDimension::STD_STYLE_ISO_REFERENCING) {
|
||||
@@ -1416,7 +1448,7 @@ void QGIViewDimension::drawDistanceExecutive(const Base::Vector2d &startPoint, c
|
||||
jointPoints[1] = getAsmeRefJointPoint(labelRectangle, true);
|
||||
}
|
||||
|
||||
// Find target points, i.e. points where the extension line intersects the dimension line
|
||||
//targetPoints are the projection of reference line endpoints onto endPoint's extension line
|
||||
Base::Vector2d targetPoints[2];
|
||||
targetPoints[0] = computePerpendicularIntersection(jointPoints[0], endPoint, lineAngle);
|
||||
targetPoints[1] = computePerpendicularIntersection(jointPoints[1], endPoint, lineAngle);
|
||||
@@ -1427,6 +1459,9 @@ void QGIViewDimension::drawDistanceExecutive(const Base::Vector2d &startPoint, c
|
||||
lineDirection *= normalizeStartPosition(startPosition, lineAngle);
|
||||
|
||||
// Find the positions where the reference line attaches to the dimension line
|
||||
//jointPoints are the ends of the reference line
|
||||
//targetPoints - projection of reference line on to extension line
|
||||
//jointPositions - displacement of jointPoints from ext line
|
||||
double jointPositions[2];
|
||||
jointPositions[0] = lineDirection*(jointPoints[0] - targetPoints[0]);
|
||||
jointPositions[1] = lineDirection*(jointPoints[1] - targetPoints[1]);
|
||||
@@ -1463,6 +1498,7 @@ void QGIViewDimension::drawDistanceExecutive(const Base::Vector2d &startPoint, c
|
||||
selected = 0;
|
||||
}
|
||||
|
||||
//find points where extension lines meet dimension line
|
||||
endCross = targetPoints[selected];
|
||||
startCross = targetPoints[selected] + Base::Vector2d::FromPolar(startPosition, lineAngle);
|
||||
|
||||
@@ -1470,12 +1506,14 @@ void QGIViewDimension::drawDistanceExecutive(const Base::Vector2d &startPoint, c
|
||||
labelRectangle, arrowCount, standardStyle, flipArrows);
|
||||
|
||||
Base::Vector2d outsetPoint(standardStyle == ViewProviderDimension::STD_STYLE_ISO_REFERENCING
|
||||
? getIsoRefOutsetPoint(labelRectangle, selected == 1)
|
||||
? getIsoRefOutsetPoint(labelRectangle, selected == 1) // 0 = left, 1 = right
|
||||
: getAsmeRefOutsetPoint(labelRectangle, selected == 1));
|
||||
|
||||
//add the reference line to the QPainterPath
|
||||
distancePath.moveTo(toQtGui(outsetPoint));
|
||||
distancePath.lineTo(toQtGui(jointPoints[selected]));
|
||||
}
|
||||
|
||||
else if (standardStyle == ViewProviderDimension::STD_STYLE_ISO_ORIENTED) {
|
||||
// We may rotate the label so no leader and reference lines are needed
|
||||
double placementFactor = getIsoStandardLinePlacement(lineAngle);
|
||||
@@ -1490,24 +1528,26 @@ void QGIViewDimension::drawDistanceExecutive(const Base::Vector2d &startPoint, c
|
||||
lineAngle + M_PI_2));
|
||||
|
||||
// Compute the dimensional line start and end crossings with (virtual) extension lines
|
||||
//check for isometric direction and if iso compute non-perpendicular intersection of dim line and ext lines
|
||||
Base::Vector2d lineDirection(Base::Vector2d::FromPolar(1.0, lineAngle));
|
||||
startCross = computePerpendicularIntersection(labelProjection, startPoint, lineAngle);
|
||||
endCross = computePerpendicularIntersection(labelProjection, endPoint, lineAngle);
|
||||
|
||||
// Find linear coefficients of crossings
|
||||
Base::Vector2d lineDirection(Base::Vector2d::FromPolar(1.0, lineAngle));
|
||||
double startPosition = arrowCount > 1 ? lineDirection*(startCross - endCross) : 0.0;
|
||||
double labelPosition = lineDirection*(labelProjection - endCross);
|
||||
|
||||
drawDimensionLine(distancePath, endCross, lineAngle, startPosition, labelPosition,
|
||||
labelRectangle, arrowCount, standardStyle, flipArrows);
|
||||
}
|
||||
|
||||
else if (standardStyle == ViewProviderDimension::STD_STYLE_ASME_INLINED) {
|
||||
// Text must remain horizontal, but it may split the leader line
|
||||
Base::Vector2d lineDirection(Base::Vector2d::FromPolar(1.0, lineAngle));
|
||||
startCross = computePerpendicularIntersection(labelCenter, startPoint, lineAngle);
|
||||
endCross = computePerpendicularIntersection(labelCenter, endPoint, lineAngle);
|
||||
|
||||
// Find linear coefficients of crossings
|
||||
Base::Vector2d lineDirection(Base::Vector2d::FromPolar(1.0, lineAngle));
|
||||
double startPosition = arrowCount > 1 ? lineDirection*(startCross - endCross) : 0.0;
|
||||
double labelPosition = lineDirection*(labelCenter - endCross);
|
||||
|
||||
@@ -1530,13 +1570,192 @@ void QGIViewDimension::drawDistanceExecutive(const Base::Vector2d &startPoint, c
|
||||
Base::Vector2d extensionOrigin;
|
||||
Base::Vector2d extensionTarget(computeExtensionLinePoints(endPoint, endCross, lineAngle + M_PI_2,
|
||||
getDefaultExtensionLineOverhang(), gapSize, extensionOrigin));
|
||||
|
||||
//draw 1st extension line
|
||||
distancePath.moveTo(toQtGui(extensionOrigin));
|
||||
distancePath.lineTo(toQtGui(extensionTarget));
|
||||
|
||||
if (arrowCount > 1) {
|
||||
extensionTarget = computeExtensionLinePoints(startPoint, startCross, lineAngle + M_PI_2,
|
||||
getDefaultExtensionLineOverhang(), gapSize, extensionOrigin);
|
||||
//draw second extension line
|
||||
distancePath.moveTo(toQtGui(extensionOrigin));
|
||||
distancePath.lineTo(toQtGui(extensionTarget));
|
||||
}
|
||||
}
|
||||
|
||||
datumLabel->setTransformOriginPoint(datumLabel->boundingRect().center());
|
||||
datumLabel->setRotation(toQtDeg(labelAngle));
|
||||
|
||||
dimLines->setPath(distancePath);
|
||||
}
|
||||
|
||||
//draw any of 3 distance dimension types with user override of dimension and extension line directions
|
||||
//startPoint, endPoint - ends of actual distance line
|
||||
//lineAngle - desired angle of dimension line with horizontal
|
||||
//extensionAngle - desired angle of extension lines with horizontal
|
||||
void QGIViewDimension::drawDistanceOverride(const Base::Vector2d &startPoint, const Base::Vector2d &endPoint,
|
||||
double lineAngle, const Base::BoundBox2d &labelRectangle,
|
||||
int standardStyle, int renderExtent, bool flipArrows, double extensionAngle) const
|
||||
{
|
||||
QPainterPath distancePath;
|
||||
|
||||
Base::Vector2d labelCenter(labelRectangle.GetCenter());
|
||||
double labelAngle = 0.0;
|
||||
|
||||
//startCross and endCross are points where extension lines intersect dimension line
|
||||
Base::Vector2d startCross;
|
||||
Base::Vector2d endCross;
|
||||
Base::Vector2d lineDirection(Base::Vector2d::FromPolar(1.0, lineAngle));
|
||||
Base::Vector2d extensionDirection(Base::Vector2d::FromPolar(1.0, extensionAngle));
|
||||
|
||||
int arrowCount = renderExtent >= ViewProviderDimension::REND_EXTENT_NORMAL
|
||||
|| renderExtent == ViewProviderDimension::REND_EXTENT_CONFINED
|
||||
? 2 : 1;
|
||||
|
||||
if (standardStyle == ViewProviderDimension::STD_STYLE_ISO_REFERENCING
|
||||
|| standardStyle == ViewProviderDimension::STD_STYLE_ASME_REFERENCING) {
|
||||
// The dimensional value text must stay horizontal in these styles
|
||||
|
||||
//refEndPoints are the ends of the reference line
|
||||
Base::Vector2d refEndPoints[2];
|
||||
|
||||
if (standardStyle == ViewProviderDimension::STD_STYLE_ISO_REFERENCING) {
|
||||
refEndPoints[0] = getIsoRefJointPoint(labelRectangle, false);
|
||||
refEndPoints[1] = getIsoRefJointPoint(labelRectangle, true);
|
||||
}
|
||||
else {
|
||||
refEndPoints[0] = getAsmeRefJointPoint(labelRectangle, false);
|
||||
refEndPoints[1] = getAsmeRefJointPoint(labelRectangle, true);
|
||||
}
|
||||
|
||||
//targetPoints are the projection of reference line endpoints onto endPoint's extension line
|
||||
Base::Vector2d targetPoints[2];
|
||||
targetPoints[0] = DrawUtil::Intersect2d(refEndPoints[0], lineDirection, endPoint, extensionDirection);
|
||||
targetPoints[1] = DrawUtil::Intersect2d(refEndPoints[1], lineDirection, endPoint, extensionDirection);
|
||||
Base::Vector2d pointOnStartExtension = DrawUtil::Intersect2d(endPoint, lineDirection, startPoint, extensionDirection);
|
||||
double startPosition = arrowCount > 1 ? lineDirection*( pointOnStartExtension - endPoint) : 0.0;
|
||||
|
||||
// Compute and normalize (i.e. make < 0) the start position
|
||||
lineDirection *= normalizeStartPosition(startPosition, lineAngle);
|
||||
|
||||
// Find the positions where the reference line attaches to the dimension line
|
||||
//refEndPoints are the ends of the reference line
|
||||
//targetPoints - projection of reference line on to extension line
|
||||
//jointPositions - displacement of refEndPoints from extension line
|
||||
double jointPositions[2];
|
||||
jointPositions[0] = lineDirection*(refEndPoints[0] - targetPoints[0]);
|
||||
jointPositions[1] = lineDirection*(refEndPoints[1] - targetPoints[1]);
|
||||
|
||||
// Orient the leader line angle correctly towards the target point
|
||||
double angles[2];
|
||||
angles[0] = jointPositions[0] > 0.0 ? DrawUtil::angleComposition(lineAngle, M_PI) : lineAngle;
|
||||
angles[1] = jointPositions[1] > 0.0 ? DrawUtil::angleComposition(lineAngle, M_PI) : lineAngle;
|
||||
|
||||
// Select the placement, where the label is not obscured by the leader line
|
||||
// or (if both behave the same) the one that bends the reference line less
|
||||
double strikeFactors[2];
|
||||
|
||||
std::vector<std::pair<double, bool>> lineMarking;
|
||||
constructDimensionLine(targetPoints[0], lineAngle, startPosition, jointPositions[0],
|
||||
labelRectangle, arrowCount, standardStyle, flipArrows, lineMarking);
|
||||
strikeFactors[0] = computeLineStrikeFactor(labelRectangle, targetPoints[0], lineAngle, lineMarking);
|
||||
|
||||
lineMarking.clear();
|
||||
constructDimensionLine(targetPoints[1], lineAngle, startPosition, jointPositions[1],
|
||||
labelRectangle, arrowCount, standardStyle, flipArrows, lineMarking);
|
||||
strikeFactors[1] = computeLineStrikeFactor(labelRectangle, targetPoints[1], lineAngle, lineMarking);
|
||||
|
||||
int selected = compareAngleStraightness(0.0, angles[0], angles[1], strikeFactors[0], strikeFactors[1]);
|
||||
if (selected == 0) {
|
||||
// Select the side closer, so the label is on the outer side of the dimension line
|
||||
Base::Vector2d perpendicularDir(lineDirection.Perpendicular());
|
||||
if (fabs((refEndPoints[0] - endPoint)*perpendicularDir)
|
||||
> fabs((refEndPoints[1] - endPoint)*perpendicularDir)) {
|
||||
selected = 1;
|
||||
}
|
||||
}
|
||||
else if (selected < 0) {
|
||||
selected = 0;
|
||||
}
|
||||
|
||||
//find points where extension lines meet dimension line
|
||||
Base::Vector2d pointOnDimLine(refEndPoints[selected].x, refEndPoints[selected].y);
|
||||
startCross = DrawUtil::Intersect2d(startPoint, extensionDirection, pointOnDimLine, lineDirection);
|
||||
endCross = DrawUtil::Intersect2d(endPoint, extensionDirection, pointOnDimLine, lineDirection);
|
||||
|
||||
drawDimensionLine(distancePath, endCross, lineAngle, startPosition, jointPositions[selected],
|
||||
labelRectangle, arrowCount, standardStyle, flipArrows);
|
||||
|
||||
Base::Vector2d outsetPoint(standardStyle == ViewProviderDimension::STD_STYLE_ISO_REFERENCING
|
||||
? getIsoRefOutsetPoint(labelRectangle, selected == 1) // 0 = left, 1 = right
|
||||
: getAsmeRefOutsetPoint(labelRectangle, selected == 1));
|
||||
|
||||
//add the reference line to the QPainterPath
|
||||
distancePath.moveTo(toQtGui(outsetPoint));
|
||||
distancePath.lineTo(toQtGui(refEndPoints[selected]));
|
||||
}
|
||||
|
||||
else if (standardStyle == ViewProviderDimension::STD_STYLE_ISO_ORIENTED) {
|
||||
// We may rotate the label so no leader and reference lines are needed
|
||||
double placementFactor = getIsoStandardLinePlacement(lineAngle);
|
||||
labelAngle = placementFactor > 0.0 ? DrawUtil::angleComposition(lineAngle, M_PI) : lineAngle;
|
||||
|
||||
// Find out the projection of label center on the line with given angle
|
||||
Base::Vector2d labelProjection(
|
||||
labelCenter
|
||||
+ Base::Vector2d::FromPolar(
|
||||
placementFactor*(labelRectangle.Height()*0.5
|
||||
+ getDefaultIsoDimensionLineSpacing()),
|
||||
lineAngle + M_PI_2));
|
||||
|
||||
// Compute the dimensional line start and end crossings with (virtual) extension lines
|
||||
startCross = DrawUtil::Intersect2d(startPoint, extensionDirection, labelProjection, lineDirection);
|
||||
endCross = DrawUtil::Intersect2d(endPoint, extensionDirection, labelProjection, lineDirection);
|
||||
|
||||
// Find linear coefficients of crossings
|
||||
double startPosition = arrowCount > 1 ? lineDirection*(startCross - endCross) : 0.0;
|
||||
double labelPosition = lineDirection*(labelProjection - endCross);
|
||||
|
||||
drawDimensionLine(distancePath, endCross, lineAngle, startPosition, labelPosition,
|
||||
labelRectangle, arrowCount, standardStyle, flipArrows);
|
||||
}
|
||||
|
||||
else if (standardStyle == ViewProviderDimension::STD_STYLE_ASME_INLINED) {
|
||||
// Text must remain horizontal, but it may split the leader line
|
||||
startCross = DrawUtil::Intersect2d(startPoint, extensionDirection, labelCenter, lineDirection);
|
||||
endCross = DrawUtil::Intersect2d(endPoint, extensionDirection, labelCenter, lineDirection);
|
||||
|
||||
// Find linear coefficients of crossings
|
||||
double startPosition = arrowCount > 1 ? lineDirection*(startCross - endCross) : 0.0;
|
||||
double labelPosition = lineDirection*(labelCenter - endCross);
|
||||
|
||||
drawDimensionLine(distancePath, endCross, lineAngle, startPosition, labelPosition,
|
||||
labelRectangle, arrowCount, standardStyle, flipArrows);
|
||||
}
|
||||
else {
|
||||
Base::Console().Error("QGIVD::drawDistanceExecutive - this Standard&Style is not supported: %d\n",
|
||||
standardStyle);
|
||||
arrowCount = 0;
|
||||
}
|
||||
|
||||
if (arrowCount > 0 && renderExtent >= ViewProviderDimension::REND_EXTENT_REDUCED) {
|
||||
double gapSize = 0.0;
|
||||
if (standardStyle == ViewProviderDimension::STD_STYLE_ASME_REFERENCING
|
||||
|| standardStyle == ViewProviderDimension::STD_STYLE_ASME_INLINED) {
|
||||
gapSize = getDefaultAsmeExtensionLineGap();
|
||||
}
|
||||
|
||||
Base::Vector2d extensionOrigin;
|
||||
Base::Vector2d extensionTarget(computeExtensionLinePoints(endPoint, endCross, lineAngle + M_PI_2,
|
||||
getDefaultExtensionLineOverhang(), gapSize, extensionOrigin));
|
||||
//draw 1st extension line
|
||||
distancePath.moveTo(toQtGui(extensionOrigin));
|
||||
distancePath.lineTo(toQtGui(extensionTarget));
|
||||
|
||||
if (arrowCount > 1) {
|
||||
extensionTarget = computeExtensionLinePoints(startPoint, startCross, lineAngle + M_PI_2,
|
||||
getDefaultExtensionLineOverhang(), gapSize, extensionOrigin);
|
||||
//draw second extension line
|
||||
distancePath.moveTo(toQtGui(extensionOrigin));
|
||||
distancePath.lineTo(toQtGui(extensionTarget));
|
||||
}
|
||||
@@ -1738,8 +1957,6 @@ void QGIViewDimension::drawRadiusExecutive(const Base::Vector2d ¢erPoint, co
|
||||
|
||||
void QGIViewDimension::drawDistance(TechDraw::DrawViewDimension *dimension, ViewProviderDimension *viewProvider) const
|
||||
{
|
||||
QPainterPath distancePath;
|
||||
|
||||
Base::BoundBox2d labelRectangle(fromQtGui(mapRectFromItem(datumLabel, datumLabel->boundingRect())));
|
||||
|
||||
pointPair linePoints = dimension->getLinearPoints();
|
||||
@@ -1760,8 +1977,17 @@ void QGIViewDimension::drawDistance(TechDraw::DrawViewDimension *dimension, View
|
||||
int renderExtent = viewProvider->RenderingExtent.getValue();
|
||||
bool flipArrows = viewProvider->FlipArrowheads.getValue();
|
||||
|
||||
drawDistanceExecutive(fromQtApp(linePoints.first), fromQtApp(linePoints.second), lineAngle,
|
||||
labelRectangle, standardStyle, renderExtent, flipArrows);
|
||||
|
||||
if (dimension->AngleOverride.getValue()) {
|
||||
drawDistanceOverride(fromQtApp(linePoints.first), fromQtApp(linePoints.second),
|
||||
dimension->LineAngle.getValue() * M_PI / 180.0,
|
||||
labelRectangle, standardStyle, renderExtent, flipArrows,
|
||||
dimension->ExtensionAngle.getValue() * M_PI / 180.0);
|
||||
|
||||
} else {
|
||||
drawDistanceExecutive(fromQtApp(linePoints.first), fromQtApp(linePoints.second), lineAngle,
|
||||
labelRectangle, standardStyle, renderExtent, flipArrows);
|
||||
}
|
||||
}
|
||||
|
||||
void QGIViewDimension::drawRadius(TechDraw::DrawViewDimension *dimension, ViewProviderDimension *viewProvider) const
|
||||
@@ -2137,7 +2363,7 @@ QColor QGIViewDimension::prefNormalColor()
|
||||
}
|
||||
|
||||
//! find the closest isometric axis given an ortho vector
|
||||
Base::Vector3d QGIViewDimension::findIsoDir(Base::Vector3d ortho)
|
||||
Base::Vector3d QGIViewDimension::findIsoDir(Base::Vector3d ortho) const
|
||||
{
|
||||
std::vector<Base::Vector3d> isoDirs = { Base::Vector3d(0.866,0.5,0.0), //iso X
|
||||
Base::Vector3d(-0.866,-0.5,0.0), //iso -X
|
||||
@@ -2161,7 +2387,7 @@ Base::Vector3d QGIViewDimension::findIsoDir(Base::Vector3d ortho)
|
||||
}
|
||||
|
||||
//! find the iso extension direction corresponding to an iso dist direction
|
||||
Base::Vector3d QGIViewDimension::findIsoExt(Base::Vector3d dir)
|
||||
Base::Vector3d QGIViewDimension::findIsoExt(Base::Vector3d dir) const
|
||||
{
|
||||
Base::Vector3d dirExt(1,0,0);
|
||||
Base::Vector3d isoX(0.866,0.5,0.0); //iso X
|
||||
@@ -2331,5 +2557,19 @@ double QGIViewDimension::toQtDeg(double a)
|
||||
return -a*180.0/M_PI;
|
||||
}
|
||||
|
||||
void QGIViewDimension::makeMarkC(double x, double y, QColor c) const
|
||||
{
|
||||
QGIVertex* vItem = new QGIVertex(-1);
|
||||
vItem->setParentItem(const_cast<QGIViewDimension*>(this));
|
||||
vItem->setPos(x,y);
|
||||
vItem->setWidth(2.0);
|
||||
vItem->setRadius(20.0);
|
||||
vItem->setNormalColor(c);
|
||||
vItem->setFillColor(c);
|
||||
vItem->setPrettyNormal();
|
||||
vItem->setZValue(ZVALUE::VERTEX);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include <Mod/TechDraw/Gui/moc_QGIViewDimension.cpp>
|
||||
|
||||
@@ -236,6 +236,10 @@ protected:
|
||||
|
||||
void drawDistanceExecutive(const Base::Vector2d &startPoint, const Base::Vector2d &endPoint, double lineAngle,
|
||||
const Base::BoundBox2d &labelRectangle, int standardStyle, int renderExtent, bool flipArrows) const;
|
||||
void drawDistanceOverride(const Base::Vector2d &startPoint, const Base::Vector2d &endPoint,
|
||||
double lineAngle, const Base::BoundBox2d &labelRectangle,
|
||||
int standardStyle, int renderExtent, bool flipArrows, double extensionAngle) const;
|
||||
|
||||
void drawRadiusExecutive(const Base::Vector2d ¢erPoint, const Base::Vector2d &midPoint, double radius,
|
||||
double endAngle, double startRotation, const Base::BoundBox2d &labelRectangle,
|
||||
double centerOverhang, int standardStyle, int renderExtent, bool flipArrow) const;
|
||||
@@ -249,8 +253,8 @@ protected:
|
||||
const QVariant &value ) override;
|
||||
virtual void setSvgPens(void);
|
||||
virtual void setPens(void);
|
||||
Base::Vector3d findIsoDir(Base::Vector3d ortho);
|
||||
Base::Vector3d findIsoExt(Base::Vector3d isoDir);
|
||||
Base::Vector3d findIsoDir(Base::Vector3d ortho) const;
|
||||
Base::Vector3d findIsoExt(Base::Vector3d isoDir) const;
|
||||
QString getPrecision(void);
|
||||
|
||||
virtual void mouseReleaseEvent( QGraphicsSceneMouseEvent * event) override;
|
||||
@@ -264,6 +268,8 @@ protected:
|
||||
double m_lineWidth;
|
||||
|
||||
void arrowPositionsToFeature(const Base::Vector2d positions[]) const;
|
||||
void makeMarkC(double x, double y, QColor c = Qt::red) const;
|
||||
|
||||
|
||||
private:
|
||||
static inline Base::Vector2d fromQtApp(const Base::Vector3d &v) { return Base::Vector2d(v.x, -v.y); }
|
||||
|
||||
@@ -26,12 +26,15 @@
|
||||
#include <cmath>
|
||||
#endif // #ifndef _PreComp_
|
||||
|
||||
# include <QMessageBox>
|
||||
|
||||
#include <Base/Console.h>
|
||||
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
#include <Gui/Command.h>
|
||||
#include <Gui/Document.h>
|
||||
#include <Gui/MainWindow.h>
|
||||
#include <Gui/Selection.h>
|
||||
#include <Gui/ViewProvider.h>
|
||||
|
||||
@@ -41,6 +44,8 @@
|
||||
|
||||
#include <Mod/TechDraw/App/DrawViewDimension.h>
|
||||
#include <Mod/TechDraw/App/DrawPage.h>
|
||||
#include <Mod/TechDraw/App/DrawUtil.h>
|
||||
#include <Mod/TechDraw/App/Geometry.h>
|
||||
|
||||
#include "QGIViewDimension.h"
|
||||
#include "ViewProviderDimension.h"
|
||||
@@ -124,7 +129,22 @@ TaskDimension::TaskDimension(QGIViewDimension *parent, ViewProviderDimension *di
|
||||
connect(ui->qsbFontSize, SIGNAL(valueChanged(double)), this, SLOT(onFontsizeChanged()));
|
||||
ui->comboDrawingStyle->setCurrentIndex(dimensionVP->StandardAndStyle.getValue());
|
||||
connect(ui->comboDrawingStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(onDrawingStyleChanged()));
|
||||
}
|
||||
}
|
||||
|
||||
// Lines
|
||||
ui->rbOverride->setChecked(parent->dvDimension->AngleOverride.getValue());
|
||||
connect(ui->rbOverride, SIGNAL(toggled(bool)), this, SLOT(onOverrideToggled()));
|
||||
ui->dsbDimAngle->setValue(parent->dvDimension->LineAngle.getValue());
|
||||
connect(ui->dsbDimAngle, SIGNAL(valueChanged(double)), this, SLOT(onDimAngleChanged()));
|
||||
ui->dsbExtAngle->setValue(parent->dvDimension->ExtensionAngle.getValue());
|
||||
connect(ui->dsbExtAngle, SIGNAL(valueChanged(double)), this, SLOT(onExtAngleChanged()));
|
||||
connect(ui->pbDimUseDefault, SIGNAL(clicked()), this, SLOT(onDimUseDefaultClicked()));
|
||||
connect(ui->pbDimUseSelection, SIGNAL(clicked()), this, SLOT(onDimUseSelectionClicked()));
|
||||
connect(ui->pbExtUseDefault, SIGNAL(clicked()), this, SLOT(onExtUseDefaultClicked()));
|
||||
connect(ui->pbExtUseSelection, SIGNAL(clicked()), this, SLOT(onExtUseSelectionClicked()));
|
||||
|
||||
Gui::Document* doc = m_dimensionVP->getDocument();
|
||||
doc->openCommand("TaskDimension");
|
||||
}
|
||||
|
||||
TaskDimension::~TaskDimension()
|
||||
@@ -294,6 +314,104 @@ void TaskDimension::onDrawingStyleChanged()
|
||||
recomputeFeature();
|
||||
}
|
||||
|
||||
void TaskDimension::onOverrideToggled()
|
||||
{
|
||||
m_parent->dvDimension->AngleOverride.setValue(ui->rbOverride->isChecked());
|
||||
recomputeFeature();
|
||||
|
||||
}
|
||||
|
||||
void TaskDimension::onDimAngleChanged()
|
||||
{
|
||||
m_parent->dvDimension->LineAngle.setValue(ui->dsbDimAngle->value());
|
||||
recomputeFeature();
|
||||
}
|
||||
|
||||
void TaskDimension::onExtAngleChanged()
|
||||
{
|
||||
m_parent->dvDimension->ExtensionAngle.setValue(ui->dsbExtAngle->value());
|
||||
recomputeFeature();
|
||||
}
|
||||
|
||||
void TaskDimension::onDimUseDefaultClicked()
|
||||
{
|
||||
pointPair points = m_parent->dvDimension->getLinearPoints();
|
||||
//duplicate coordinate conversion logic from QGIViewDimension
|
||||
Base::Vector2d first2(points.first.x, -points.first.y);
|
||||
Base::Vector2d second2(points.second.x, -points.second.y);
|
||||
double lineAngle = (second2 - first2).Angle();
|
||||
ui->dsbDimAngle->setValue(lineAngle * 180.0 / M_PI);
|
||||
}
|
||||
|
||||
void TaskDimension::onDimUseSelectionClicked()
|
||||
{
|
||||
std::pair<double, bool> result = getAngleFromSelection();
|
||||
if (result.second) {
|
||||
ui->dsbDimAngle->setValue(result.first * 180.0 / M_PI);
|
||||
}
|
||||
}
|
||||
|
||||
void TaskDimension::onExtUseDefaultClicked()
|
||||
{
|
||||
pointPair points = m_parent->dvDimension->getLinearPoints();
|
||||
//duplicate coordinate conversion logic from QGIViewDimension
|
||||
Base::Vector2d first2(points.first.x, -points.first.y);
|
||||
Base::Vector2d second2(points.second.x, -points.second.y);
|
||||
Base::Vector2d lineDirection = second2 - first2;
|
||||
Base::Vector2d extensionDirection(-lineDirection.y, lineDirection.x);
|
||||
double extensionAngle = extensionDirection.Angle();
|
||||
ui->dsbExtAngle->setValue(extensionAngle * 180.0 / M_PI);
|
||||
}
|
||||
void TaskDimension::onExtUseSelectionClicked()
|
||||
{
|
||||
std::pair<double, bool> result = getAngleFromSelection();
|
||||
if (result.second) {
|
||||
ui->dsbExtAngle->setValue(result.first * 180.0 / M_PI);
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<double, bool> TaskDimension::getAngleFromSelection()
|
||||
{
|
||||
std::pair<double, bool> result;
|
||||
result.first = 0.0;
|
||||
result.second = true;
|
||||
std::vector<Gui::SelectionObject> selection = Gui::Selection().getSelectionEx();
|
||||
TechDraw::DrawViewPart * objFeat = 0;
|
||||
std::vector<std::string> SubNames;
|
||||
if (!selection.empty()) {
|
||||
objFeat = static_cast<TechDraw::DrawViewPart*> (selection.front().getObject());
|
||||
SubNames = selection.front().getSubNames();
|
||||
if (SubNames.size() == 2) { //expecting Vertices
|
||||
std::string geomName0 = DrawUtil::getGeomTypeFromName(SubNames[0]);
|
||||
int geomIndex0 = DrawUtil::getIndexFromName(SubNames[0]);
|
||||
std::string geomName1 = DrawUtil::getGeomTypeFromName(SubNames[1]);
|
||||
int geomIndex1 = DrawUtil::getIndexFromName(SubNames[1]);
|
||||
if ((geomName0 == "Vertex") && (geomName1 == "Vertex")) {
|
||||
TechDraw::VertexPtr v0 = objFeat->getProjVertexByIndex(geomIndex0);
|
||||
TechDraw::VertexPtr v1 = objFeat->getProjVertexByIndex(geomIndex1);
|
||||
Base::Vector2d v02(v0->point().x, -v0->point().y);
|
||||
Base::Vector2d v12(v1->point().x, -v1->point().y);
|
||||
result.first = (v12 - v02).Angle();
|
||||
return result;
|
||||
}
|
||||
} else if (SubNames.size() == 1) { //expecting Edge
|
||||
std::string geomName0 = DrawUtil::getGeomTypeFromName(SubNames[0]);
|
||||
int geomIndex0 = DrawUtil::getIndexFromName(SubNames[0]);
|
||||
if (geomName0 == "Edge") {
|
||||
TechDraw::BaseGeomPtr edge = objFeat->getGeomByIndex(geomIndex0);
|
||||
Base::Vector2d v02(edge->getStartPoint().x, -edge->getStartPoint().y);
|
||||
Base::Vector2d v12(edge->getEndPoint().x, -edge->getEndPoint().y);
|
||||
result.first = (v12 - v02).Angle();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect Selection"),
|
||||
QObject::tr("Select 2 Vertexes or 1 Edge"));
|
||||
result.second = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
TaskDlgDimension::TaskDlgDimension(QGIViewDimension *parent, ViewProviderDimension *dimensionVP) :
|
||||
|
||||
@@ -60,11 +60,19 @@ private Q_SLOTS:
|
||||
void onColorChanged();
|
||||
void onFontsizeChanged();
|
||||
void onDrawingStyleChanged();
|
||||
void onOverrideToggled();
|
||||
void onDimAngleChanged();
|
||||
void onExtAngleChanged();
|
||||
void onDimUseDefaultClicked();
|
||||
void onDimUseSelectionClicked();
|
||||
void onExtUseDefaultClicked();
|
||||
void onExtUseSelectionClicked();
|
||||
|
||||
private:
|
||||
std::unique_ptr<Ui_TaskDimension> ui;
|
||||
QGIViewDimension *m_parent;
|
||||
ViewProviderDimension *m_dimensionVP;
|
||||
std::pair<double, bool> getAngleFromSelection();
|
||||
};
|
||||
|
||||
class TaskDlgDimension : public Gui::TaskView::TaskDialog
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>330</width>
|
||||
<height>417</height>
|
||||
<height>698</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -166,7 +166,7 @@ be used instead if the dimension value</string>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="leFormatSpecifierUnderTolerance">
|
||||
<property name="toolTip">
|
||||
<string>Specifies the undertolerance format in printf() style, or arbitrary text</string>
|
||||
<string>Specifies the undertolerance format in printf() style, or arbitrary text</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -305,6 +305,115 @@ be used instead if the dimension value</string>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="gbLines">
|
||||
<property name="title">
|
||||
<string>Lines</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Extension line angle</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QPushButton" name="pbDimUseDefault">
|
||||
<property name="toolTip">
|
||||
<string>Set dimension line angle to default (ortho view).</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use default</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QRadioButton" name="rbOverride">
|
||||
<property name="toolTip">
|
||||
<string>Use override angles if checked. Use default angles if unchecked.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Override angles</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="pbDimUseSelection">
|
||||
<property name="toolTip">
|
||||
<string>Set dimension line angle to match selected edge or vertices.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use selection</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QDoubleSpinBox" name="dsbDimAngle">
|
||||
<property name="toolTip">
|
||||
<string>Angle of dimension line with drawing X axis (degrees)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>-360.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>360.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QDoubleSpinBox" name="dsbExtAngle">
|
||||
<property name="toolTip">
|
||||
<string>Angle of extension lines with drawing X axis (degrees)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>-360.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>360.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Dimension line angle</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QPushButton" name="pbExtUseSelection">
|
||||
<property name="toolTip">
|
||||
<string>Set extension line angle to match selected edge or vertices.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use selection</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QPushButton" name="pbExtUseDefault">
|
||||
<property name="toolTip">
|
||||
<string>Set extension line angle to default (ortho).</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use default</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
|
||||
Reference in New Issue
Block a user