Complete remake of drawing dimensions
This commit is contained in:
@@ -622,6 +622,362 @@ PyObject* DrawUtil::colorToPyTuple(App::Color color)
|
||||
return pTuple;
|
||||
}
|
||||
|
||||
// Supplementary mathematical functions
|
||||
// ====================================
|
||||
|
||||
int DrawUtil::sgn(double x)
|
||||
{
|
||||
return (x > +Precision::Confusion()) - (x < -Precision::Confusion());
|
||||
}
|
||||
|
||||
double DrawUtil::sqr(double x)
|
||||
{
|
||||
return x*x;
|
||||
}
|
||||
|
||||
void DrawUtil::angleNormalize(double &fi)
|
||||
{
|
||||
while (fi <= -M_PI) {
|
||||
fi += M_2PI;
|
||||
}
|
||||
while (fi > M_PI) {
|
||||
fi -= M_2PI;
|
||||
}
|
||||
}
|
||||
|
||||
double DrawUtil::angleComposition(double fi, double delta)
|
||||
{
|
||||
fi += delta;
|
||||
|
||||
angleNormalize(fi);
|
||||
return fi;
|
||||
}
|
||||
|
||||
double DrawUtil::angleDifference(double fi1, double fi2, bool reflex)
|
||||
{
|
||||
angleNormalize(fi1);
|
||||
angleNormalize(fi2);
|
||||
|
||||
fi1 -= fi2;
|
||||
|
||||
if (((fi1 > +M_PI) || (fi1 <= -M_PI)) != reflex) {
|
||||
fi1 += fi1 > 0.0 ? -M_2PI : +M_2PI;
|
||||
}
|
||||
|
||||
return fi1;
|
||||
}
|
||||
|
||||
// Interval marking functions
|
||||
// ==========================
|
||||
|
||||
unsigned int DrawUtil::intervalMerge(std::vector<std::pair<double, bool>> &marking,
|
||||
double boundary, bool wraps)
|
||||
{
|
||||
// We will be returning the placement index instead of an iterator, because indices
|
||||
// are still valid after we insert on higher positions, while iterators may be invalidated
|
||||
// due to the insertion triggered reallocation
|
||||
unsigned int i = 0;
|
||||
bool last = false;
|
||||
|
||||
if (wraps && marking.size() > 0) {
|
||||
last = marking.back().second;
|
||||
}
|
||||
|
||||
while (i < marking.size()) {
|
||||
if (marking[i].first == boundary) {
|
||||
return i;
|
||||
}
|
||||
if (marking[i].first > boundary) {
|
||||
break;
|
||||
}
|
||||
|
||||
last = marking[i].second;
|
||||
++i;
|
||||
}
|
||||
|
||||
if (!wraps && i >= marking.size()) {
|
||||
last = false;
|
||||
}
|
||||
|
||||
marking.insert(marking.begin() + i, std::pair<double, bool>(boundary, last));
|
||||
return i;
|
||||
}
|
||||
|
||||
void DrawUtil::intervalMarkLinear(std::vector<std::pair<double, bool>> &marking,
|
||||
double start, double length, bool value)
|
||||
{
|
||||
if (length == 0.0) {
|
||||
return;
|
||||
}
|
||||
if (length < 0.0) {
|
||||
length = -length;
|
||||
start -= length;
|
||||
}
|
||||
|
||||
unsigned int startIndex = intervalMerge(marking, start, false);
|
||||
unsigned int endIndex = intervalMerge(marking, start + length, false);
|
||||
|
||||
while (startIndex < endIndex) {
|
||||
marking[startIndex].second = value;
|
||||
++startIndex;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawUtil::intervalMarkCircular(std::vector<std::pair<double, bool>> &marking,
|
||||
double start, double length, bool value)
|
||||
{
|
||||
if (length == 0.0) {
|
||||
return;
|
||||
}
|
||||
if (length < 0.0) {
|
||||
length = -length;
|
||||
start -= length;
|
||||
}
|
||||
if (length > M_2PI) {
|
||||
length = M_2PI;
|
||||
}
|
||||
|
||||
angleNormalize(start);
|
||||
|
||||
double end = start + length;
|
||||
if (end > M_PI) {
|
||||
end -= M_2PI;
|
||||
}
|
||||
|
||||
// Just make sure the point is stored, its index is read last
|
||||
intervalMerge(marking, end, true);
|
||||
unsigned int startIndex = intervalMerge(marking, start, true);
|
||||
unsigned int endIndex = intervalMerge(marking, end, true);
|
||||
|
||||
do {
|
||||
marking[startIndex].second = value;
|
||||
++startIndex;
|
||||
startIndex %= marking.size();
|
||||
}
|
||||
while (startIndex != endIndex);
|
||||
}
|
||||
|
||||
// Supplementary 2D analytic geometry functions
|
||||
//=============================================
|
||||
|
||||
int DrawUtil::findRootForValue(double Ax2, double Bxy, double Cy2, double Dx, double Ey, double F,
|
||||
double value, bool findX, double roots[])
|
||||
{
|
||||
double qA = 0.0;
|
||||
double qB = 0.0;
|
||||
double qC = 0.0;
|
||||
|
||||
if (findX) {
|
||||
qA = Ax2;
|
||||
qB = Bxy*value + Dx;
|
||||
qC = Cy2*value*value + Ey*value + F;
|
||||
}
|
||||
else {
|
||||
qA = Cy2;
|
||||
qB = Bxy*value + Ey;
|
||||
qC = Ax2*value*value + Dx*value + F;
|
||||
}
|
||||
|
||||
if (fabs(qA) < Precision::Confusion()) {
|
||||
// No quadratic coefficient - the equation is linear
|
||||
if (fabs(qB) < Precision::Confusion()) {
|
||||
// Not even linear coefficient - test for zero
|
||||
if (fabs(qC) > Precision::Confusion()) {
|
||||
// This equation has no solution
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
// Signal infinite number of solutions by returning 2, but do not touch root variables
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
else {
|
||||
roots[0] = -qC/qB;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
double qD = sqr(qB) - 4.0*qA*qC;
|
||||
if (qD < -Precision::Confusion()) {
|
||||
// Negative discriminant => no real roots
|
||||
return 0;
|
||||
}
|
||||
else if (qD > +Precision::Confusion()) {
|
||||
// Two distinctive roots
|
||||
roots[0] = (-qB + sqrt(qD))*0.5/qA;
|
||||
roots[1] = (-qB - sqrt(qD))*0.5/qA;
|
||||
return 2;
|
||||
}
|
||||
else {
|
||||
// Double root
|
||||
roots[0] = -qB*0.5/qA;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool DrawUtil::mergeBoundedPoint(const Base::Vector2d &point, const Base::BoundBox2d &boundary,
|
||||
std::vector<Base::Vector2d> &storage)
|
||||
{
|
||||
if (!boundary.Contains(point, Precision::Confusion())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < storage.size(); ++i) {
|
||||
if (point.IsEqual(storage[i], Precision::Confusion())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
storage.push_back(point);
|
||||
return true;
|
||||
}
|
||||
|
||||
void DrawUtil::findConicRectangleIntersections(double conicAx2, double conicBxy, double conicCy2,
|
||||
double conicDx, double conicEy, double conicF,
|
||||
const Base::BoundBox2d &rectangle,
|
||||
std::vector<Base::Vector2d> &intersections)
|
||||
{
|
||||
double roots[2];
|
||||
int rootCount;
|
||||
|
||||
// Find intersections with rectangle left side line
|
||||
roots[0] = rectangle.MinY;
|
||||
roots[1] = rectangle.MaxY;
|
||||
rootCount = findRootForValue(conicAx2, conicBxy, conicCy2, conicDx, conicEy, conicF,
|
||||
rectangle.MinX, false, roots);
|
||||
if (rootCount > 0) {
|
||||
mergeBoundedPoint(Base::Vector2d(rectangle.MinX, roots[0]), rectangle, intersections);
|
||||
}
|
||||
if (rootCount > 1) {
|
||||
mergeBoundedPoint(Base::Vector2d(rectangle.MinX, roots[1]), rectangle, intersections);
|
||||
}
|
||||
|
||||
// Find intersections with rectangle right side line
|
||||
roots[0] = rectangle.MinY;
|
||||
roots[1] = rectangle.MaxY;
|
||||
rootCount = findRootForValue(conicAx2, conicBxy, conicCy2, conicDx, conicEy, conicF,
|
||||
rectangle.MaxX, false, roots);
|
||||
if (rootCount > 0) {
|
||||
mergeBoundedPoint(Base::Vector2d(rectangle.MaxX, roots[0]), rectangle, intersections);
|
||||
}
|
||||
if (rootCount > 1) {
|
||||
mergeBoundedPoint(Base::Vector2d(rectangle.MaxX, roots[1]), rectangle, intersections);
|
||||
}
|
||||
|
||||
// Find intersections with rectangle top side line
|
||||
roots[0] = rectangle.MinX;
|
||||
roots[1] = rectangle.MaxX;
|
||||
rootCount = findRootForValue(conicAx2, conicBxy, conicCy2, conicDx, conicEy, conicF,
|
||||
rectangle.MinY, true, roots);
|
||||
if (rootCount > 0) {
|
||||
mergeBoundedPoint(Base::Vector2d(roots[0], rectangle.MinY), rectangle, intersections);
|
||||
}
|
||||
if (rootCount > 1) {
|
||||
mergeBoundedPoint(Base::Vector2d(roots[1], rectangle.MinY), rectangle, intersections);
|
||||
}
|
||||
|
||||
// Find intersections with rectangle top side line
|
||||
roots[0] = rectangle.MinX;
|
||||
roots[1] = rectangle.MaxX;
|
||||
rootCount = findRootForValue(conicAx2, conicBxy, conicCy2, conicDx, conicEy, conicF,
|
||||
rectangle.MaxY, true, roots);
|
||||
if (rootCount > 0) {
|
||||
mergeBoundedPoint(Base::Vector2d(roots[0], rectangle.MaxY), rectangle, intersections);
|
||||
}
|
||||
if (rootCount > 1) {
|
||||
mergeBoundedPoint(Base::Vector2d(roots[1], rectangle.MaxY), rectangle, intersections);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawUtil::findLineRectangleIntersections(const Base::Vector2d &linePoint, double lineAngle,
|
||||
const Base::BoundBox2d &rectangle,
|
||||
std::vector<Base::Vector2d> &intersections)
|
||||
{
|
||||
Base::Vector2d lineDirection(Base::Vector2d::FromPolar(1.0, lineAngle));
|
||||
findConicRectangleIntersections(0.0, 0.0, 0.0, +lineDirection.y, -lineDirection.x,
|
||||
lineDirection.x*linePoint.y - lineDirection.y*linePoint.x,
|
||||
rectangle, intersections);
|
||||
}
|
||||
|
||||
void DrawUtil::findCircleRectangleIntersections(const Base::Vector2d &circleCenter, double circleRadius,
|
||||
const Base::BoundBox2d &rectangle,
|
||||
std::vector<Base::Vector2d> &intersections)
|
||||
{
|
||||
findConicRectangleIntersections(1.0, 0.0, 1.0, -2.0*circleCenter.x, -2.0*circleCenter.y,
|
||||
sqr(circleCenter.x) + sqr(circleCenter.y) - sqr(circleRadius),
|
||||
rectangle, intersections);
|
||||
}
|
||||
|
||||
void DrawUtil::findLineSegmentRectangleIntersections(const Base::Vector2d &linePoint, double lineAngle,
|
||||
double segmentBasePosition, double segmentLength,
|
||||
const Base::BoundBox2d &rectangle,
|
||||
std::vector<Base::Vector2d> &intersections)
|
||||
{
|
||||
findLineRectangleIntersections(linePoint, lineAngle, rectangle, intersections);
|
||||
|
||||
if (segmentLength < 0.0) {
|
||||
segmentLength = -segmentLength;
|
||||
segmentBasePosition -= segmentLength;
|
||||
}
|
||||
|
||||
// Dispose the points on rectangle but not within the line segment boundaries
|
||||
Base::Vector2d segmentDirection(Base::Vector2d::FromPolar(1.0, lineAngle));
|
||||
for (unsigned int i = 0; i < intersections.size(); ) {
|
||||
double pointPosition = segmentDirection*(intersections[i] - linePoint);
|
||||
|
||||
if (pointPosition < segmentBasePosition - Precision::Confusion()
|
||||
|| pointPosition > segmentBasePosition + segmentLength + Precision::Confusion()) {
|
||||
intersections.erase(intersections.begin() + i);
|
||||
}
|
||||
else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to add the line segment end points
|
||||
mergeBoundedPoint(linePoint + segmentBasePosition*segmentDirection,
|
||||
rectangle, intersections);
|
||||
mergeBoundedPoint(linePoint + (segmentBasePosition + segmentLength)*segmentDirection,
|
||||
rectangle, intersections);
|
||||
}
|
||||
|
||||
void DrawUtil::findCircularArcRectangleIntersections(const Base::Vector2d &circleCenter, double circleRadius,
|
||||
double arcBaseAngle, double arcRotation,
|
||||
const Base::BoundBox2d &rectangle,
|
||||
std::vector<Base::Vector2d> &intersections)
|
||||
{
|
||||
findCircleRectangleIntersections(circleCenter, circleRadius, rectangle, intersections);
|
||||
|
||||
if (arcRotation < 0.0) {
|
||||
arcRotation = -arcRotation;
|
||||
arcBaseAngle -= arcRotation;
|
||||
if (arcBaseAngle <= -M_PI) {
|
||||
arcBaseAngle += M_2PI;
|
||||
}
|
||||
}
|
||||
|
||||
// Dispose the points on rectangle but not within the circular arc boundaries
|
||||
for (unsigned int i = 0; i < intersections.size(); ) {
|
||||
double pointAngle = (intersections[i] - circleCenter).Angle();
|
||||
if (pointAngle < arcBaseAngle - Precision::Confusion()) {
|
||||
pointAngle += M_2PI;
|
||||
}
|
||||
|
||||
if (pointAngle > arcBaseAngle + arcRotation + Precision::Confusion()) {
|
||||
intersections.erase(intersections.begin() + i);
|
||||
}
|
||||
else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to add the circular arc end points
|
||||
mergeBoundedPoint(circleCenter + Base::Vector2d::FromPolar(circleRadius, arcBaseAngle),
|
||||
rectangle, intersections);
|
||||
mergeBoundedPoint(circleCenter + Base::Vector2d::FromPolar(circleRadius, arcBaseAngle + arcRotation),
|
||||
rectangle, intersections);
|
||||
}
|
||||
|
||||
//============================
|
||||
// various debugging routines.
|
||||
|
||||
@@ -49,6 +49,11 @@
|
||||
|
||||
#include "LineGroup.h"
|
||||
|
||||
|
||||
#ifndef M_2PI
|
||||
#define M_2PI ((M_PI)*2.0)
|
||||
#endif
|
||||
|
||||
#define VERTEXTOLERANCE (2.0 * Precision::Confusion())
|
||||
|
||||
namespace TechDraw
|
||||
@@ -103,6 +108,47 @@ class TechDrawExport DrawUtil {
|
||||
static App::Color pyTupleToColor(PyObject* pColor);
|
||||
static PyObject* colorToPyTuple(App::Color color);
|
||||
|
||||
// Supplementary mathematical functions
|
||||
static int sgn(double x);
|
||||
static double sqr(double x);
|
||||
static void angleNormalize(double &fi);
|
||||
static double angleComposition(double fi, double delta);
|
||||
static double angleDifference(double fi1, double fi2, bool reflex = false);
|
||||
|
||||
// Interval marking functions
|
||||
static unsigned int intervalMerge(std::vector<std::pair<double, bool>> &marking,
|
||||
double boundary, bool wraps);
|
||||
static void intervalMarkLinear(std::vector<std::pair<double, bool>> &marking,
|
||||
double start, double length, bool value);
|
||||
static void intervalMarkCircular(std::vector<std::pair<double, bool>> &marking,
|
||||
double start, double length, bool value);
|
||||
|
||||
// Supplementary 2D analytic geometry functions
|
||||
static int findRootForValue(double Ax2, double Bxy, double Cy2, double Dx, double Ey, double F,
|
||||
double value, bool findX, double roots[]);
|
||||
static bool mergeBoundedPoint(const Base::Vector2d &point, const Base::BoundBox2d &boundary,
|
||||
std::vector<Base::Vector2d> &storage);
|
||||
|
||||
static void findConicRectangleIntersections(double conicAx2, double conicBxy, double conicCy2,
|
||||
double conicDx, double conicEy, double conicF,
|
||||
const Base::BoundBox2d &rectangle,
|
||||
std::vector<Base::Vector2d> &intersections);
|
||||
static void findLineRectangleIntersections(const Base::Vector2d &linePoint, double lineAngle,
|
||||
const Base::BoundBox2d &rectangle,
|
||||
std::vector<Base::Vector2d> &intersections);
|
||||
static void findCircleRectangleIntersections(const Base::Vector2d &circleCenter, double circleRadius,
|
||||
const Base::BoundBox2d &rectangle,
|
||||
std::vector<Base::Vector2d> &intersections);
|
||||
|
||||
static void findLineSegmentRectangleIntersections(const Base::Vector2d &linePoint, double lineAngle,
|
||||
double segmentBasePosition, double segmentLength,
|
||||
const Base::BoundBox2d &rectangle,
|
||||
std::vector<Base::Vector2d> &intersections);
|
||||
static void findCircularArcRectangleIntersections(const Base::Vector2d &circleCenter, double circleRadius,
|
||||
double arcBaseAngle, double arcRotation,
|
||||
const Base::BoundBox2d &rectangle,
|
||||
std::vector<Base::Vector2d> &intersections);
|
||||
|
||||
//debugging routines
|
||||
static void dumpVertexes(const char* text, const TopoDS_Shape& s);
|
||||
static void dumpEdge(char* label, int i, TopoDS_Edge e);
|
||||
|
||||
@@ -97,6 +97,7 @@ DrawViewDimension::DrawViewDimension(void)
|
||||
References2D.setScope(App::LinkScope::Global);
|
||||
ADD_PROPERTY_TYPE(References3D,(0,0),"",(App::PropertyType)(App::Prop_None),"3D Geometry References");
|
||||
References3D.setScope(App::LinkScope::Global);
|
||||
|
||||
ADD_PROPERTY_TYPE(FormatSpec,("") , "Format",(App::PropertyType)(App::Prop_None),"Dimension Format");
|
||||
ADD_PROPERTY_TYPE(Arbitrary,(false) ,"Format",(App::PropertyType)(App::Prop_None),"Value overridden by user");
|
||||
|
||||
@@ -104,8 +105,10 @@ DrawViewDimension::DrawViewDimension(void)
|
||||
ADD_PROPERTY(Type,((long)0));
|
||||
MeasureType.setEnums(MeasureTypeEnums);
|
||||
ADD_PROPERTY(MeasureType, ((long)1)); //Projected (or True) measurement
|
||||
ADD_PROPERTY_TYPE(TheoreticalExact,(false),"",(App::PropertyType)(App::Prop_None),"Set for theoretical exact (basic) dimension");
|
||||
ADD_PROPERTY_TYPE(OverTolerance ,(0.0),"",App::Prop_None,"+ Tolerance value");
|
||||
ADD_PROPERTY_TYPE(UnderTolerance ,(0.0),"",App::Prop_None,"- Tolerance value");
|
||||
ADD_PROPERTY_TYPE(Inverted,(false),"",(App::PropertyType)(App::Prop_None),"The dimensional value is displayed inverted");
|
||||
|
||||
//hide the properties the user can't edit in the property editor
|
||||
// References2D.setStatus(App::Property::Hidden,true);
|
||||
@@ -509,7 +512,7 @@ App::DocumentObjectExecReturn *DrawViewDimension::execute(void)
|
||||
return DrawView::execute();
|
||||
}
|
||||
|
||||
std::string DrawViewDimension::getFormatedValue(bool obtuse)
|
||||
std::string DrawViewDimension::getFormatedValue()
|
||||
{
|
||||
// Base::Console().Message("DVD::getFormatedValue()\n");
|
||||
std::string result;
|
||||
@@ -518,7 +521,7 @@ std::string DrawViewDimension::getFormatedValue(bool obtuse)
|
||||
}
|
||||
|
||||
QString specStr = QString::fromUtf8(FormatSpec.getStrValue().data(),FormatSpec.getStrValue().size());
|
||||
double val = std::abs(getDimValue()); //internal units!
|
||||
double val = getDimValue();
|
||||
|
||||
bool angularMeasure = false;
|
||||
Base::Quantity qVal;
|
||||
@@ -527,9 +530,6 @@ std::string DrawViewDimension::getFormatedValue(bool obtuse)
|
||||
(Type.isValue("Angle3Pt")) ) {
|
||||
angularMeasure = true;
|
||||
qVal.setUnit(Base::Unit::Angle);
|
||||
if (obtuse) {
|
||||
qVal.setValue(fabs(360.0 - val));
|
||||
}
|
||||
} else {
|
||||
qVal.setUnit(Base::Unit::Length);
|
||||
}
|
||||
@@ -712,6 +712,17 @@ double DrawViewDimension::getDimValue()
|
||||
result = legAngle;
|
||||
}
|
||||
}
|
||||
|
||||
result = fabs(result);
|
||||
if (Inverted.getValue()) {
|
||||
if (Type.isValue("Angle") || Type.isValue("Angle3Pt")) {
|
||||
result = 360 - result;
|
||||
}
|
||||
else {
|
||||
result = -result;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -97,6 +97,9 @@ public:
|
||||
App::PropertyLinkSubList References2D; //Points to Projection SubFeatures
|
||||
App::PropertyLinkSubList References3D; //Points to 3D Geometry SubFeatures
|
||||
App::PropertyEnumeration Type; //DistanceX,DistanceY,Diameter, etc
|
||||
|
||||
App::PropertyBool TheoreticalExact;
|
||||
App::PropertyBool Inverted;
|
||||
App::PropertyString FormatSpec;
|
||||
App::PropertyBool Arbitrary;
|
||||
App::PropertyFloat OverTolerance;
|
||||
@@ -120,7 +123,7 @@ public:
|
||||
//return PyObject as DrawViewDimensionPy
|
||||
virtual PyObject *getPyObject(void);
|
||||
|
||||
virtual std::string getFormatedValue(bool obtuse = false);
|
||||
virtual std::string getFormatedValue();
|
||||
virtual double getDimValue();
|
||||
DrawViewPart* getViewPart() const;
|
||||
virtual QRectF getRect() const { return QRectF(0,0,1,1);} //pretend dimensions always fit!
|
||||
|
||||
@@ -330,12 +330,7 @@
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>ISO Levelled</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>ASME Regular</string>
|
||||
<string>ISO Referencing</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
@@ -343,6 +338,11 @@
|
||||
<string>ASME Inlined</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>ASME Referencing</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
||||
@@ -699,6 +699,12 @@ int QGIView::calculateFontPixelSize(double sizeInMillimetres)
|
||||
return (int) (Rez::guiX(sizeInMillimetres) + 0.5);
|
||||
}
|
||||
|
||||
int QGIView::calculateFontPixelWidth(const QFont &font)
|
||||
{
|
||||
// Return the width of digit 0, most likely the most wide digit
|
||||
return QFontMetrics(font).width(QChar::fromLatin1('0'));
|
||||
}
|
||||
|
||||
const double QGIView::DefaultFontSizeInMM = 5.0;
|
||||
|
||||
void QGIView::dumpRect(char* text, QRectF r) {
|
||||
|
||||
@@ -115,6 +115,7 @@ public:
|
||||
static Gui::ViewProvider* getViewProvider(App::DocumentObject* obj);
|
||||
static QGVPage* getGraphicsView(TechDraw::DrawView* dv);
|
||||
static int calculateFontPixelSize(double sizeInMillimetres);
|
||||
static int calculateFontPixelWidth(const QFont &font);
|
||||
static const double DefaultFontSizeInMM;
|
||||
|
||||
MDIViewPage* getMDIViewPage(void) const;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,6 +31,7 @@
|
||||
#include <QColor>
|
||||
#include <QFont>
|
||||
#include <Base/Vector3D.h>
|
||||
#include "Rez.h"
|
||||
#include "QGIView.h"
|
||||
#include "QGCustomText.h"
|
||||
|
||||
@@ -92,6 +93,11 @@ public:
|
||||
double getTolAdjust(void);
|
||||
bool hasHover;
|
||||
|
||||
bool isFramed(void) { return m_isFramed; }
|
||||
void setFramed(bool framed) { m_isFramed = framed; }
|
||||
|
||||
double getLineWidth(void) { return m_lineWidth; }
|
||||
void setLineWidth(double lineWidth) { m_lineWidth = lineWidth; }
|
||||
|
||||
Q_SIGNALS:
|
||||
void dragging(bool);
|
||||
@@ -115,6 +121,9 @@ protected:
|
||||
|
||||
double posX;
|
||||
double posY;
|
||||
|
||||
bool m_isFramed;
|
||||
double m_lineWidth;
|
||||
|
||||
private:
|
||||
};
|
||||
@@ -152,23 +161,75 @@ public Q_SLOTS:
|
||||
void datumLabelDragFinished(void);
|
||||
void select(bool state);
|
||||
void hover(bool state);
|
||||
void updateDim(bool obtuse = false);
|
||||
void updateDim();
|
||||
|
||||
protected:
|
||||
|
||||
static double getIsoStandardLinePlacement(double labelAngle);
|
||||
static double computeLineAndLabelAngles(Base::Vector2d lineTarget, Base::Vector2d labelCenter,
|
||||
double lineLabelDistance, double &lineAngle, double &labelAngle);
|
||||
static bool computeLineRectangleExitPoint(const QRectF &rectangle, Base::Vector2d targetPoint,
|
||||
Base::Vector2d &exitPoint);
|
||||
static double getAnglePlacementFactor(double testAngle, double endAngle, double startRotation);
|
||||
static int compareAngleStraightness(double straightAngle, double leftAngle, double rightAngle,
|
||||
double leftStrikeFactor, double rightStrikeFactor);
|
||||
|
||||
Base::Vector2d computeLineOriginPoint(Base::Vector2d lineTarget, double projectedLabelDistance,
|
||||
double lineAngle, double labelWidth, double direction) const;
|
||||
Base::Vector2d getIsoJointPoint(Base::Vector2d labelCenter, double width, double dir) const;
|
||||
Base::Vector2d getAsmeJointPoint(Base::Vector2d labelCenter, double width, double dir) const;
|
||||
static double getIsoStandardLinePlacement(double labelAngle);
|
||||
Base::Vector2d getIsoRefOutsetPoint(const Base::BoundBox2d &labelRectangle, bool right) const;
|
||||
Base::Vector2d getIsoRefJointPoint(const Base::BoundBox2d &labelRectangle, bool right) const;
|
||||
Base::Vector2d getAsmeRefOutsetPoint(const Base::BoundBox2d &labelRectangle, bool right) const;
|
||||
Base::Vector2d getAsmeRefJointPoint(const Base::BoundBox2d &labelRectangle, bool right) const;
|
||||
|
||||
static Base::Vector2d computePerpendicularIntersection(const Base::Vector2d &linePoint,
|
||||
const Base::Vector2d &perpendicularPoint, double lineAngle);
|
||||
static Base::Vector2d computeExtensionLinePoints(const Base::Vector2d &originPoint,
|
||||
const Base::Vector2d &linePoint, double hintAngle,
|
||||
double overhangSize, double gapSize, Base::Vector2d &startPoint);
|
||||
static double computeLineAndLabelAngles(const Base::Vector2d &rotationCenter, const Base::Vector2d &labelCenter,
|
||||
double lineLabelDistance, double &lineAngle, double &labelAngle);
|
||||
static double computeLineStrikeFactor(const Base::BoundBox2d &labelRectangle, const Base::Vector2d &lineOrigin,
|
||||
double lineAngle, const std::vector<std::pair<double, bool>> &drawMarking);
|
||||
static double computeArcStrikeFactor(const Base::BoundBox2d &labelRectangle, const Base::Vector2d &arcCenter,
|
||||
double arcRadius, const std::vector<std::pair<double, bool>> &drawMarking);
|
||||
|
||||
static double normalizeStartPosition(double &startPosition, double &lineAngle);
|
||||
static double normalizeStartRotation(double &startRotation);
|
||||
bool constructDimensionLine(const Base::Vector2d &targetPoint, double lineAngle,
|
||||
double startPosition, double jointPosition, const Base::BoundBox2d &labelRectangle,
|
||||
int arrowCount, int standardStyle, bool flipArrows,
|
||||
std::vector<std::pair<double, bool>> &outputMarking) const;
|
||||
bool constructDimensionArc(const Base::Vector2d &arcCenter, double arcRadius, double endAngle,
|
||||
double startRotation, double handednessFactor, double jointRotation,
|
||||
const Base::BoundBox2d &labelRectangle, int arrowCount, int standardStyle,
|
||||
bool flipArrows, std::vector<std::pair<double, bool>> &outputMarking) const;
|
||||
|
||||
void draw() override;
|
||||
|
||||
void resetArrows(void) const;
|
||||
void drawArrows(int count, const Base::Vector2d positions[], double angles[], bool flipped) const;
|
||||
|
||||
void drawSingleLine(QPainterPath &painterPath, const Base::Vector2d &lineOrigin, double lineAngle,
|
||||
double startPosition, double endPosition) const;
|
||||
void drawMultiLine(QPainterPath &painterPath, const Base::Vector2d &lineOrigin, double lineAngle,
|
||||
const std::vector<std::pair<double, bool>> &drawMarking) const;
|
||||
void drawSingleArc(QPainterPath &painterPath, const Base::Vector2d &arcCenter, double arcRadius,
|
||||
double startAngle, double endAngle) const;
|
||||
void drawMultiArc(QPainterPath &painterPath, const Base::Vector2d &arcCenter, double arcRadius,
|
||||
const std::vector<std::pair<double, bool>> &drawMarking) const;
|
||||
|
||||
void drawDimensionLine(QPainterPath &painterPath, const Base::Vector2d &targetPoint, double lineAngle,
|
||||
double startPosition, double jointPosition, const Base::BoundBox2d &labelRectangle,
|
||||
int arrowCount, int standardStyle, bool flipArrows) const;
|
||||
void drawDimensionArc(QPainterPath &painterPath, const Base::Vector2d &arcCenter, double arcRadius,
|
||||
double endAngle, double startRotation, double jointAngle,
|
||||
const Base::BoundBox2d &labelRectangle, int arrowCount,
|
||||
int standardStyle, bool flipArrows) const;
|
||||
|
||||
void drawDistanceExecutive(const Base::Vector2d &startPoint, const Base::Vector2d &endPoint, double lineAngle,
|
||||
const Base::BoundBox2d &labelRectangle, int standardStyle, int renderExtent, bool flipArrows) 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;
|
||||
|
||||
void drawDistance(TechDraw::DrawViewDimension *dimension, ViewProviderDimension *viewProvider) const;
|
||||
void drawRadius(TechDraw::DrawViewDimension *dimension, ViewProviderDimension *viewProvider) const;
|
||||
void drawDiameter(TechDraw::DrawViewDimension *dimension, ViewProviderDimension *viewProvider) const;
|
||||
void drawAngle(TechDraw::DrawViewDimension *dimension, ViewProviderDimension *viewProvider) const;
|
||||
|
||||
virtual QVariant itemChange( GraphicsItemChange change,
|
||||
const QVariant &value ) override;
|
||||
@@ -186,26 +247,29 @@ protected:
|
||||
QGIArrow* aHead2;
|
||||
//QGICMark* centerMark
|
||||
double m_lineWidth;
|
||||
bool m_obtuse;
|
||||
|
||||
private:
|
||||
static const double TextOffsetFudge;
|
||||
static inline Base::Vector2d fromQtApp(const Base::Vector3d &v) { return Base::Vector2d(v.x, -v.y); }
|
||||
static inline Base::BoundBox2d fromQtGui(const QRectF &r)
|
||||
{ return Base::BoundBox2d(Rez::appX(r.left()), -Rez::appX(r.top()),
|
||||
Rez::appX(r.right()), -Rez::appX(r.bottom())); }
|
||||
|
||||
double getDefaultTextHorizontalOffset(double direction) const;
|
||||
double getDefaultTextVerticalOffset() const;
|
||||
double getDefaultReferenceLineOverhang() const;
|
||||
double getDefaultHorizontalLeaderLength() const;
|
||||
static inline QPointF toQtGui(const Base::Vector2d &v) { return QPointF(Rez::guiX(v.x), -Rez::guiX(v.y)); }
|
||||
static inline QRectF toQtGui(const Base::BoundBox2d &r)
|
||||
{ return QRectF(Rez::guiX(r.MinX), -Rez::guiX(r.MaxY),
|
||||
Rez::guiX(r.Width()), Rez::guiX(r.Height())); }
|
||||
|
||||
static bool angleWithinSector(double testAngle, double startAngle, double endAngle, bool clockwise);
|
||||
static double addAngles(double angle1, double angle2);
|
||||
static inline double toDeg(double a) { return a*180/M_PI; }
|
||||
static inline double toQtRad(double a) { return -a; }
|
||||
static inline double toQtDeg(double a) { return -a*180.0/M_PI; }
|
||||
|
||||
static const int INNER_SECTOR = 0;
|
||||
static const int OUTER_SECTOR = 1;
|
||||
static const int OPPOSITE_SECTOR = 2;
|
||||
static const int COMPLEMENT_SECTOR = 3;
|
||||
double getDefaultExtensionLineOverhang() const;
|
||||
double getDefaultArrowTailLength() const;
|
||||
double getDefaultIsoDimensionLineSpacing() const;
|
||||
double getDefaultIsoReferenceLineOverhang() const;
|
||||
double getDefaultAsmeHorizontalLeaderLength() const;
|
||||
double getDefaultAsmeExtensionLineGap() const;
|
||||
|
||||
static int classifyPointToArcPosition(double pointDistance, double pointAngle,
|
||||
double radius, double startAngle, double endAngle, bool clockwise);
|
||||
};
|
||||
|
||||
} // namespace MDIViewPageGui
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2004 Jürgen Riegel <juergen.riegel@web.de> *
|
||||
* Copyright (c) 2004 Jürgen Riegel <juergen.riegel@web.de> *
|
||||
* Copyright (c) 2012 Luke Parry <l.parry@warwick.ac.uk> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
@@ -44,7 +44,10 @@
|
||||
using namespace TechDrawGui;
|
||||
|
||||
const char *ViewProviderDimension::StandardAndStyleEnums[]=
|
||||
{ "ISO Oriented", "ISO Levelled", "ASME Regular", "ASME Inlined", NULL };
|
||||
{ "ISO Oriented", "ISO Referencing", "ASME Inlined", "ASME Referencing", NULL };
|
||||
|
||||
const char *ViewProviderDimension::RenderingExtentEnums[]=
|
||||
{ "None", "Minimal", "Confined", "Reduced", "Normal", "Expanded", NULL };
|
||||
|
||||
PROPERTY_SOURCE(TechDrawGui::ViewProviderDimension, TechDrawGui::ViewProviderDrawingView)
|
||||
|
||||
@@ -83,11 +86,12 @@ ViewProviderDimension::ViewProviderDimension()
|
||||
ADD_PROPERTY_TYPE(Color,(fcColor),group,App::Prop_None,"The color of the Dimension");
|
||||
|
||||
int standardStyle = hGrp->GetInt("StandardAndStyle", STD_STYLE_ISO_ORIENTED);
|
||||
ADD_PROPERTY_TYPE(StandardAndStyle, (standardStyle), group, App::Prop_None, "Specify the standard according to which this dimension is drawn");
|
||||
ADD_PROPERTY_TYPE(StandardAndStyle, (standardStyle), group, App::Prop_None, "Specifies the standard according to which this dimension is drawn");
|
||||
StandardAndStyle.setEnums(StandardAndStyleEnums);
|
||||
|
||||
ADD_PROPERTY_TYPE(ExtendToCenter, (true), group, App::Prop_None,"Prolong the leader line right upto the center point");
|
||||
ADD_PROPERTY_TYPE(FlipArrowheads, (false), group, App::Prop_None,"Reverse the normal direction of arrowheads on dimline");
|
||||
ADD_PROPERTY_TYPE(RenderingExtent, (REND_EXTENT_NORMAL), group, App::Prop_None,"Select the rendering mode by space requirements");
|
||||
RenderingExtent.setEnums(RenderingExtentEnums);
|
||||
ADD_PROPERTY_TYPE(FlipArrowheads, (false), group, App::Prop_None,"Reverts the usual direction of dimension line terminators");
|
||||
}
|
||||
|
||||
ViewProviderDimension::~ViewProviderDimension()
|
||||
@@ -139,7 +143,7 @@ void ViewProviderDimension::onChanged(const App::Property* p)
|
||||
(p == &Fontsize) ||
|
||||
(p == &LineWidth) ||
|
||||
(p == &StandardAndStyle) ||
|
||||
(p == &ExtendToCenter) ||
|
||||
(p == &RenderingExtent) ||
|
||||
(p == &FlipArrowheads))
|
||||
{
|
||||
QGIView* qgiv = getQView();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2004 Jürgen Riegel <juergen.riegel@web.de> *
|
||||
* Copyright (c) 2004 Jürgen Riegel <juergen.riegel@web.de> *
|
||||
* Copyright (c) 2012 Luke Parry <l.parry@warwick.ac.uk> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
@@ -49,13 +49,20 @@ public:
|
||||
App::PropertyFloat LineWidth;
|
||||
App::PropertyColor Color;
|
||||
|
||||
static const int STD_STYLE_ISO_ORIENTED = 0;
|
||||
static const int STD_STYLE_ISO_LEVELLED = 1;
|
||||
static const int STD_STYLE_ASME_REGULAR = 2;
|
||||
static const int STD_STYLE_ASME_INLINED = 3;
|
||||
|
||||
static const int STD_STYLE_ISO_ORIENTED = 0;
|
||||
static const int STD_STYLE_ISO_REFERENCING = 1;
|
||||
static const int STD_STYLE_ASME_INLINED = 2;
|
||||
static const int STD_STYLE_ASME_REFERENCING = 3;
|
||||
App::PropertyEnumeration StandardAndStyle;
|
||||
App::PropertyBool ExtendToCenter;
|
||||
|
||||
static const int REND_EXTENT_NONE = 0;
|
||||
static const int REND_EXTENT_MINIMAL = 1;
|
||||
static const int REND_EXTENT_CONFINED = 2;
|
||||
static const int REND_EXTENT_REDUCED = 3;
|
||||
static const int REND_EXTENT_NORMAL = 4;
|
||||
static const int REND_EXTENT_EXPANDED = 5;
|
||||
App::PropertyEnumeration RenderingExtent;
|
||||
|
||||
App::PropertyBool FlipArrowheads;
|
||||
|
||||
virtual void attach(App::DocumentObject *);
|
||||
@@ -71,6 +78,7 @@ public:
|
||||
private:
|
||||
|
||||
static const char *StandardAndStyleEnums[];
|
||||
static const char *RenderingExtentEnums[];
|
||||
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user