Merge pull request #20369 from WandererFan/SplineAsCircleYetAgain20347
[TD] Spline as circle yet again (fix 20347)
This commit is contained in:
@@ -1493,87 +1493,124 @@ TopoDS_Edge GeometryUtils::edgeFromCircleArc(TechDraw::AOCPtr c)
|
||||
}
|
||||
|
||||
//used by DVDim for approximate dims
|
||||
bool GeometryUtils::isCircle(TopoDS_Edge occEdge)
|
||||
bool GeometryUtils::isCircle(const TopoDS_Edge& occEdge)
|
||||
{
|
||||
double radius;
|
||||
double radius{0};
|
||||
Base::Vector3d center;
|
||||
bool isArc = false;
|
||||
return GeometryUtils::getCircleParms(occEdge, radius, center, isArc);
|
||||
}
|
||||
|
||||
//! tries to interpret a B-spline edge as a circle. Used by DVDim for approximate dimensions.
|
||||
//! calculates the curvature of the spline at a number of places and measures the deviation from the average
|
||||
//! a true circle has constant curvature and would have no deviation from the average.
|
||||
bool GeometryUtils::getCircleParms(TopoDS_Edge occEdge, double& radius, Base::Vector3d& center, bool& isArc)
|
||||
//! calculates the radius and center of circles using groups of 4 points on the b-spline. if the
|
||||
//! groups of 4 points all lie on a circle, we use that circle to get the radius and center.
|
||||
bool GeometryUtils::getCircleParms(const TopoDS_Edge& occEdge, double& radius, Base::Vector3d& center, bool& isArc)
|
||||
{
|
||||
int testCount = 5;
|
||||
double curveLimit = EWTOLERANCE;
|
||||
BRepAdaptor_Curve c(occEdge);
|
||||
Handle(Geom_BSplineCurve) spline = c.BSpline();
|
||||
double f, l;
|
||||
f = c.FirstParameter();
|
||||
l = c.LastParameter();
|
||||
double parmRange = fabs(l - f);
|
||||
double parmStep = parmRange/testCount;
|
||||
std::vector<double> curvatures;
|
||||
std::vector<gp_Pnt> centers;
|
||||
gp_Pnt curveCenter;
|
||||
double sumCurvature = 0;
|
||||
Base::Vector3d sumCenter, valueAt;
|
||||
try {
|
||||
GeomLProp_CLProps prop(spline, f, 3, Precision::Confusion());
|
||||
constexpr int PointCount{8}; // number of points on the edge to examine (>= 8)
|
||||
constexpr int TestCount{3}; // number of candidate circles to test
|
||||
|
||||
// check only the interior points of the edge
|
||||
for (int i = 1; i < (testCount - 1); i++) {
|
||||
prop.SetParameter(parmStep * i);
|
||||
curvatures.push_back(prop.Curvature());
|
||||
sumCurvature += prop.Curvature();
|
||||
prop.CentreOfCurvature(curveCenter);
|
||||
centers.push_back(curveCenter);
|
||||
sumCenter += Base::convertTo<Base::Vector3d>(curveCenter);
|
||||
}
|
||||
BRepAdaptor_Curve curveAdapt(occEdge);
|
||||
double firstParam = curveAdapt.FirstParameter();
|
||||
auto firstPoint = Base::convertTo<Base::Vector3d>(curveAdapt.Value(firstParam));
|
||||
double lastParam = curveAdapt.LastParameter();
|
||||
auto lastPoint = Base::convertTo<Base::Vector3d>(curveAdapt.Value(lastParam));
|
||||
|
||||
double parmRange = fabs(lastParam - firstParam);
|
||||
double parmStep = parmRange / PointCount;
|
||||
|
||||
std::vector<Base::Vector3d> pointsOnCurve;
|
||||
for (size_t iPoint = 0; iPoint < PointCount; iPoint++) {
|
||||
auto iPointMath = static_cast<double>(iPoint);
|
||||
auto newpoint = curveAdapt.Value(firstParam + iPointMath * parmStep);
|
||||
pointsOnCurve.push_back(Base::convertTo<Base::Vector3d>(newpoint));
|
||||
}
|
||||
catch (Standard_Failure&) {
|
||||
|
||||
auto edgeLong = edgeLength(occEdge);
|
||||
constexpr double LimitFactor{0.001}; // 0.1% not sure about this value
|
||||
double tolerance = edgeLong * LimitFactor;
|
||||
|
||||
isArc = true;
|
||||
if (firstPoint.IsEqual(lastPoint, tolerance)) {
|
||||
isArc = false;
|
||||
}
|
||||
|
||||
int passCount{0};
|
||||
int firstIndex{0};
|
||||
for (int iTest = 0; iTest < TestCount; iTest++) {
|
||||
firstIndex++;
|
||||
auto A = pointsOnCurve.at(firstIndex);
|
||||
auto B = pointsOnCurve.at(firstIndex + 1);
|
||||
auto C = pointsOnCurve.at(firstIndex + 2);
|
||||
auto D = pointsOnCurve.at(firstIndex + 3);
|
||||
if (pointsAreOnCircle(A, B, C, D, tolerance)) {
|
||||
passCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (passCount != TestCount) {
|
||||
// at least 1 test failed.
|
||||
return false;
|
||||
}
|
||||
Base::Vector3d avgCenter = sumCenter/ centers.size();
|
||||
|
||||
double avgCurve = sumCurvature/ centers.size();
|
||||
double errorCurve = 0;
|
||||
// sum the errors in curvature
|
||||
for (auto& cv: curvatures) {
|
||||
errorCurve += avgCurve - cv;
|
||||
// each group of 4 points lies on a circle. Since the groups of 4 overlap, all the points lie
|
||||
// on the same circle. https://en.wikipedia.org/wiki/Ptolemy%27s_theorem and
|
||||
// https://math.stackexchange.com/questions/3130053/how-to-check-if-a-set-of-points-in-cartesian-space-could-lie-on-the-circumferenc
|
||||
// so we can use any three points to make our circle.
|
||||
|
||||
auto gPoint0 = Base::convertTo<gp_Pnt>(pointsOnCurve.at(1));
|
||||
auto gPoint1 = Base::convertTo<gp_Pnt>(pointsOnCurve.at(3));
|
||||
auto gPoint2 = Base::convertTo<gp_Pnt>(pointsOnCurve.at(5)); //NOLINT readability-magic-numbers
|
||||
try {
|
||||
GC_MakeCircle mkCircle(gPoint0, gPoint1, gPoint2);
|
||||
if (!mkCircle.IsDone()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const Handle(Geom_Circle) circleFromParms = mkCircle.Value();
|
||||
radius = circleFromParms->Circ().Radius();
|
||||
center = Base::convertTo<Base::Vector3d>(circleFromParms->Circ().Location());
|
||||
return true;
|
||||
}
|
||||
catch (Standard_Failure& err) {
|
||||
Base::Console().Message("Geo::getCircleParms - failed to make a circle\n");
|
||||
}
|
||||
|
||||
double errorCenter{0};
|
||||
for (auto& observe : centers) {
|
||||
auto error = (Base::convertTo<Base::Vector3d>(observe)- avgCenter).Length();
|
||||
errorCenter += error;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//! returns true if the A, B, C and D all lie on the same circle according to Ptolemy's theorem
|
||||
//! we can skip the test for same plane, since the points are all on the XY plane(?not true
|
||||
//! for 3d dims?).
|
||||
bool GeometryUtils::pointsAreOnCircle(Base::Vector3d A,
|
||||
Base::Vector3d B,
|
||||
Base::Vector3d C,
|
||||
Base::Vector3d D,
|
||||
double tolerance)
|
||||
{
|
||||
auto AB = (B-A).Length();
|
||||
auto AC = (C-A).Length();
|
||||
auto AD = (D-A).Length();
|
||||
auto BC = (C-B).Length();
|
||||
auto BD = (D-B).Length();
|
||||
auto CD = (D-C).Length();
|
||||
|
||||
auto pieceLength = AB + BC + CD;
|
||||
auto wholeLength = AD;
|
||||
if (DU::fpCompare(pieceLength, wholeLength, tolerance)) {
|
||||
// these points are colinear
|
||||
return false;
|
||||
}
|
||||
|
||||
// calculate average error in curvature. we are only interested in the magnitude of the error
|
||||
errorCurve = fabs(errorCurve / curvatures.size());
|
||||
// calculate the average error in center of curvature
|
||||
errorCenter = errorCenter / curvatures.size();
|
||||
auto edgeLong = edgeLength(occEdge);
|
||||
double centerLimit = edgeLong * 0.01;
|
||||
|
||||
isArc = !c.IsClosed();
|
||||
bool isCircle(false);
|
||||
if ( errorCurve <= curveLimit &&
|
||||
errorCenter <= centerLimit) {
|
||||
isCircle = true;
|
||||
radius = 1.0/avgCurve;
|
||||
center = avgCenter;
|
||||
}
|
||||
|
||||
return isCircle;
|
||||
bool eq1 = DU::fpCompare(AB*CD + AC*BD, AD*BC, tolerance);
|
||||
bool eq2 = DU::fpCompare(AB*CD + AD*BC, AC*BD, tolerance);
|
||||
bool eq3 = DU::fpCompare(AC*BD + AD*BC, AB*CD, tolerance);
|
||||
return eq1 || eq2 || eq3;
|
||||
}
|
||||
|
||||
//! make a circle or arc of circle Edge from BSpline Edge
|
||||
// Note that the input edge has been inverted by GeometryObject, so +Y points down.
|
||||
TopoDS_Edge GeometryUtils::asCircle(TopoDS_Edge splineEdge, bool& arc)
|
||||
TopoDS_Edge GeometryUtils::asCircle(const TopoDS_Edge& splineEdge, bool& arc)
|
||||
{
|
||||
double radius{0};
|
||||
Base::Vector3d center;
|
||||
@@ -1582,11 +1619,16 @@ TopoDS_Edge GeometryUtils::asCircle(TopoDS_Edge splineEdge, bool& arc)
|
||||
if (!canMakeCircle) {
|
||||
throw Base::RuntimeError("GU::asCircle received non-circular edge!");
|
||||
}
|
||||
arc = isArc;
|
||||
|
||||
gp_Pnt gCenter = Base::convertTo<gp_Pnt>(center);
|
||||
gp_Dir gNormal{0, 0, 1};
|
||||
Handle(Geom_Circle) circleFromParms = GC_MakeCircle(gCenter, gNormal, radius);
|
||||
|
||||
if (!isArc) {
|
||||
return BRepBuilderAPI_MakeEdge(circleFromParms);
|
||||
}
|
||||
|
||||
// find the ends of the edge from the underlying curve
|
||||
BRepAdaptor_Curve curveAdapt(splineEdge);
|
||||
double firstParam = curveAdapt.FirstParameter();
|
||||
@@ -1594,40 +1636,42 @@ TopoDS_Edge GeometryUtils::asCircle(TopoDS_Edge splineEdge, bool& arc)
|
||||
gp_Pnt startPoint = curveAdapt.Value(firstParam);
|
||||
gp_Pnt endPoint = curveAdapt.Value(lastParam);
|
||||
|
||||
if (startPoint.IsEqual(endPoint, EWTOLERANCE)) { //more reliable than IsClosed flag
|
||||
arc = false;
|
||||
return BRepBuilderAPI_MakeEdge(circleFromParms);
|
||||
}
|
||||
|
||||
arc = true;
|
||||
double midRange = (lastParam + firstParam) / 2;
|
||||
gp_Pnt midPoint = curveAdapt.Value(midRange);
|
||||
|
||||
// this should be using circleFromParms as a base instead of points on the original spline.
|
||||
// could be problems with very small errors?? other versions of GC_MakeArcOfCircle have
|
||||
// poorly explained parameters.
|
||||
GC_MakeArcOfCircle mkArc(startPoint, midPoint, endPoint);
|
||||
auto circleArc = mkArc.Value();
|
||||
|
||||
if (!mkArc.IsDone()) {
|
||||
throw Base::RuntimeError("GU::asCircle failed to create arc");
|
||||
}
|
||||
return BRepBuilderAPI_MakeEdge(circleArc);
|
||||
}
|
||||
|
||||
|
||||
bool GeometryUtils::isLine(TopoDS_Edge occEdge)
|
||||
bool GeometryUtils::isLine(const TopoDS_Edge& occEdge)
|
||||
{
|
||||
BRepAdaptor_Curve c(occEdge);
|
||||
BRepAdaptor_Curve adapt(occEdge);
|
||||
|
||||
Handle(Geom_BSplineCurve) spline = c.BSpline();
|
||||
double f = c.FirstParameter();
|
||||
double l = c.LastParameter();
|
||||
gp_Pnt s = c.Value(f);
|
||||
gp_Pnt e = c.Value(l);
|
||||
Handle(Geom_BSplineCurve) spline = adapt.BSpline();
|
||||
double firstParm = adapt.FirstParameter();
|
||||
double lastParm = adapt.LastParameter();
|
||||
auto startPoint = Base::convertTo<Base::Vector3d>(adapt.Value(firstParm));
|
||||
auto endPoint = Base::convertTo<Base::Vector3d>(adapt.Value(lastParm));
|
||||
auto edgeLong = edgeLength(occEdge);
|
||||
|
||||
bool samePnt = s.IsEqual(e, FLT_EPSILON);
|
||||
if (samePnt) {
|
||||
constexpr double LimitFactor{0.001}; // 0.1% not sure about this value
|
||||
double tolerance = edgeLong * LimitFactor;
|
||||
if (startPoint.IsEqual(endPoint, tolerance)) {
|
||||
// either not a line or a zero length line?
|
||||
return false;
|
||||
}
|
||||
|
||||
Base::Vector3d vs = Base::convertTo<Base::Vector3d>(s);
|
||||
Base::Vector3d ve = Base::convertTo<Base::Vector3d>(e);
|
||||
double endLength = (vs - ve).Length();
|
||||
// in a line the sum of the lengths of the segments should equal the distance
|
||||
// from start to end
|
||||
double endPointLength = (endPoint - startPoint).Length();
|
||||
|
||||
int low = 0;
|
||||
int high = spline->NbPoles() - 1;
|
||||
TColgp_Array1OfPnt poles(low, high);
|
||||
@@ -1641,15 +1685,12 @@ bool GeometryUtils::isLine(TopoDS_Edge occEdge)
|
||||
lenTotal += (v2-v1).Length();
|
||||
}
|
||||
|
||||
if (DrawUtil::fpCompare(lenTotal, endLength)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return DrawUtil::fpCompare(lenTotal, endPointLength, tolerance);
|
||||
}
|
||||
|
||||
|
||||
//! make a line Edge from B-spline Edge
|
||||
TopoDS_Edge GeometryUtils::asLine(TopoDS_Edge occEdge)
|
||||
TopoDS_Edge GeometryUtils::asLine(const TopoDS_Edge& occEdge)
|
||||
{
|
||||
BRepAdaptor_Curve c(occEdge);
|
||||
|
||||
|
||||
@@ -315,7 +315,6 @@ class TechDrawExport BSpline: public BaseGeom
|
||||
bool isLine();
|
||||
bool isCircle();
|
||||
TopoDS_Edge asCircle(bool& isArc);
|
||||
// void getCircleParms(bool& isCircle, double& radius, Base::Vector3d& center, bool& isArc);
|
||||
bool intersectsArc(Base::Vector3d p1, Base::Vector3d p2);
|
||||
std::vector<BezierSegment> segments;
|
||||
};
|
||||
@@ -382,23 +381,23 @@ class TechDrawExport Vertex : public TechDraw::Tag
|
||||
Base::Vector3d point() const { return Base::Vector3d(pnt.x, pnt.y, 0.0); }
|
||||
void point(Base::Vector3d v){ pnt = Base::Vector3d(v.x, v.y); }
|
||||
|
||||
double x() {return pnt.x;}
|
||||
double y() {return pnt.y;}
|
||||
double x() const {return pnt.x;}
|
||||
double y() const {return pnt.y;}
|
||||
|
||||
// attribute setters and getters
|
||||
bool getHlrVisible() { return hlrVisible; }
|
||||
bool getHlrVisible() const { return hlrVisible; }
|
||||
void setHlrVisible(bool state) { hlrVisible = state; }
|
||||
int getRef3d() { return ref3D; }
|
||||
int getRef3d() const { return ref3D; }
|
||||
void setRef3d(int ref) { ref3D = ref; }
|
||||
TopoDS_Vertex getOCCVertex() { return occVertex; }
|
||||
void setOCCVertex(TopoDS_Vertex newVertex) { occVertex = newVertex; }
|
||||
bool getCosmetic() { return cosmetic; }
|
||||
void setOCCVertex(const TopoDS_Vertex& newVertex) { occVertex = newVertex; }
|
||||
bool getCosmetic() const { return cosmetic; }
|
||||
void setCosmetic (bool state) { cosmetic = state; }
|
||||
std::string getCosmeticTag() { return cosmeticTag; }
|
||||
void setCosmeticTag(std::string t) { cosmeticTag = t; }
|
||||
bool isCenter() {return m_center;}
|
||||
void setCosmeticTag(const std::string& t) { cosmeticTag = t; }
|
||||
bool isCenter() const {return m_center;}
|
||||
void isCenter(bool state) { m_center = state; }
|
||||
bool isReference() { return m_reference; }
|
||||
bool isReference() const { return m_reference; }
|
||||
void isReference(bool state) { m_reference = state; }
|
||||
|
||||
Part::TopoShape asTopoShape(double scale = 1.0);
|
||||
@@ -447,17 +446,22 @@ class TechDrawExport GeometryUtils
|
||||
static TopoDS_Edge edgeFromCircle(TechDraw::CirclePtr c);
|
||||
static TopoDS_Edge edgeFromCircleArc(TechDraw::AOCPtr c);
|
||||
|
||||
static bool isCircle(TopoDS_Edge occEdge);
|
||||
static bool getCircleParms(TopoDS_Edge occEdge, double& radius, Base::Vector3d& center, bool& isArc);
|
||||
static TopoDS_Edge asCircle(TopoDS_Edge splineEdge, bool& arc);
|
||||
static bool isLine(TopoDS_Edge occEdge);
|
||||
static TopoDS_Edge asLine(TopoDS_Edge occEdge);
|
||||
static bool isCircle(const TopoDS_Edge& occEdge);
|
||||
static bool getCircleParms(const TopoDS_Edge& occEdge, double& radius, Base::Vector3d& center, bool& isArc);
|
||||
static TopoDS_Edge asCircle(const TopoDS_Edge& splineEdge, bool& arc);
|
||||
static bool isLine(const TopoDS_Edge& occEdge);
|
||||
static TopoDS_Edge asLine(const TopoDS_Edge& occEdge);
|
||||
|
||||
static double edgeLength(TopoDS_Edge occEdge);
|
||||
|
||||
static TopoDS_Face makePerforatedFace(FacePtr bigCheese, const std::vector<FacePtr>& holesAll);
|
||||
static std::vector<FacePtr> findHolesInFace(const DrawViewPart* dvp, const std::string& bigCheeseSubRef);
|
||||
|
||||
static bool pointsAreOnCircle(Base::Vector3d A,
|
||||
Base::Vector3d B,
|
||||
Base::Vector3d C,
|
||||
Base::Vector3d D,
|
||||
double tolerance);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -210,11 +210,11 @@ DimensionGeometry TechDraw::validateDimSelection3d(
|
||||
|
||||
return DimensionGeometry::isInvalid;
|
||||
}
|
||||
bool TechDraw::validateSubnameList(StringVector subNames, GeometrySet acceptableGeometrySet)
|
||||
bool TechDraw::validateSubnameList(const StringVector& subNames, GeometrySet acceptableGeometrySet)
|
||||
{
|
||||
for (auto& sub : subNames) {
|
||||
std::string geometryType = DrawUtil::getGeomTypeFromName(ShapeFinder::getLastTerm(sub));
|
||||
if (acceptableGeometrySet.count(geometryType) == 0) {
|
||||
if (!acceptableGeometrySet.contains(geometryType)) {
|
||||
//this geometry type is not allowed
|
||||
return false;
|
||||
}
|
||||
@@ -223,13 +223,13 @@ bool TechDraw::validateSubnameList(StringVector subNames, GeometrySet acceptable
|
||||
}
|
||||
|
||||
//count how many of each "Edge", "Vertex, etc and compare totals to required minimum
|
||||
bool TechDraw::checkGeometryOccurrences(StringVector subNames, GeomCountMap keyedMinimumCounts)
|
||||
bool TechDraw::checkGeometryOccurrences(const StringVector& subNames, GeomCountMap keyedMinimumCounts)
|
||||
{
|
||||
//how many of each geometry descriptor are input
|
||||
GeomCountMap foundCounts;
|
||||
for (auto& sub : subNames) {
|
||||
std::string geometryType = DrawUtil::getGeomTypeFromName(ShapeFinder::getLastTerm(sub));
|
||||
std::map<std::string, int>::iterator it0(foundCounts.find(geometryType));
|
||||
auto it0(foundCounts.find(geometryType));
|
||||
if (it0 == foundCounts.end()) {
|
||||
//first occurrence of this geometryType
|
||||
foundCounts[geometryType] = 1;
|
||||
@@ -294,7 +294,7 @@ DimensionGeometry TechDraw::getGeometryConfiguration(ReferenceVector valid2dRefe
|
||||
|
||||
//return the first valid configuration contained in the already validated references
|
||||
DimensionGeometry TechDraw::getGeometryConfiguration3d(DrawViewPart* dvp,
|
||||
ReferenceVector valid3dReferences)
|
||||
const ReferenceVector& valid3dReferences)
|
||||
{
|
||||
//first we check for whole object references
|
||||
ReferenceVector wholeObjectRefs;
|
||||
@@ -360,7 +360,7 @@ GeomCountMap TechDraw::loadRequiredCounts(const StringVector& acceptableGeometry
|
||||
}
|
||||
|
||||
//! verify that Selection contains a valid Geometry for a single Edge Dimension
|
||||
DimensionGeometry TechDraw::isValidSingleEdge(ReferenceEntry ref)
|
||||
DimensionGeometry TechDraw::isValidSingleEdge(const ReferenceEntry& ref)
|
||||
{
|
||||
auto objFeat(dynamic_cast<TechDraw::DrawViewPart*>(ref.getObject()));
|
||||
if (!objFeat) {
|
||||
@@ -387,12 +387,12 @@ DimensionGeometry TechDraw::isValidSingleEdge(ReferenceEntry ref)
|
||||
}
|
||||
Base::Vector3d line = gen1->points.at(1) - gen1->points.at(0);
|
||||
if (fabs(line.y) < FLT_EPSILON) {
|
||||
return DimensionGeometry::isHorizontal;
|
||||
} else if (fabs(line.x) < FLT_EPSILON) {
|
||||
return DimensionGeometry::isHorizontal;
|
||||
} else {
|
||||
return DimensionGeometry::isDiagonal;
|
||||
return DimensionGeometry::isVertical;
|
||||
}
|
||||
if (fabs(line.x) < FLT_EPSILON) {
|
||||
return DimensionGeometry::isHorizontal;
|
||||
}
|
||||
return DimensionGeometry::isDiagonal;
|
||||
} else if (geom->getGeomType() == GeomType::CIRCLE || geom->getGeomType() == GeomType::ARCOFCIRCLE) {
|
||||
return DimensionGeometry::isCircle;
|
||||
} else if (geom->getGeomType() == GeomType::ELLIPSE || geom->getGeomType() == GeomType::ARCOFELLIPSE) {
|
||||
@@ -401,15 +401,14 @@ DimensionGeometry TechDraw::isValidSingleEdge(ReferenceEntry ref)
|
||||
TechDraw::BSplinePtr spline = std::static_pointer_cast<TechDraw::BSpline>(geom);
|
||||
if (spline->isCircle()) {
|
||||
return DimensionGeometry::isBSplineCircle;
|
||||
} else {
|
||||
return DimensionGeometry::isBSpline;
|
||||
}
|
||||
return DimensionGeometry::isBSpline;
|
||||
}
|
||||
return DimensionGeometry::isInvalid;
|
||||
}
|
||||
|
||||
//! verify that Selection contains a valid Geometry for a single Edge Dimension
|
||||
DimensionGeometry TechDraw::isValidSingleEdge3d(DrawViewPart* dvp, ReferenceEntry ref)
|
||||
DimensionGeometry TechDraw::isValidSingleEdge3d(DrawViewPart* dvp, const ReferenceEntry& ref)
|
||||
{
|
||||
(void)dvp;
|
||||
//the Name starts with "Edge"
|
||||
@@ -432,8 +431,9 @@ DimensionGeometry TechDraw::isValidSingleEdge3d(DrawViewPart* dvp, ReferenceEntr
|
||||
point1 = dvp->projectPoint(point1);
|
||||
Base::Vector3d line = point1 - point0;
|
||||
if (fabs(line.y) < FLT_EPSILON) {
|
||||
return DimensionGeometry::isHorizontal;
|
||||
} else if (fabs(line.x) < FLT_EPSILON) {
|
||||
return DimensionGeometry::isVertical;
|
||||
}
|
||||
if (fabs(line.x) < FLT_EPSILON) {
|
||||
return DimensionGeometry::isHorizontal;
|
||||
}
|
||||
// else if (fabs(line.z) < FLT_EPSILON) {
|
||||
@@ -449,16 +449,15 @@ DimensionGeometry TechDraw::isValidSingleEdge3d(DrawViewPart* dvp, ReferenceEntr
|
||||
} else if (adapt.GetType() == GeomAbs_BSplineCurve) {
|
||||
if (GeometryUtils::isCircle(occEdge)) {
|
||||
return DimensionGeometry::isBSplineCircle;
|
||||
} else {
|
||||
return DimensionGeometry::isBSpline;
|
||||
}
|
||||
return DimensionGeometry::isBSpline;
|
||||
}
|
||||
|
||||
return DimensionGeometry::isInvalid;
|
||||
}
|
||||
|
||||
//! verify that Selection contains a valid Geometry for a single Edge Dimension
|
||||
DimensionGeometry TechDraw::isValidSingleFace(ReferenceEntry ref)
|
||||
DimensionGeometry TechDraw::isValidSingleFace(const ReferenceEntry& ref)
|
||||
{
|
||||
auto objFeat(dynamic_cast<TechDraw::DrawViewPart*>(ref.getObject()));
|
||||
if (!objFeat) {
|
||||
@@ -480,7 +479,7 @@ DimensionGeometry TechDraw::isValidSingleFace(ReferenceEntry ref)
|
||||
}
|
||||
|
||||
//! verify that Selection contains a valid Geometry for a single Edge Dimension
|
||||
DimensionGeometry TechDraw::isValidSingleFace3d(DrawViewPart* dvp, ReferenceEntry ref)
|
||||
DimensionGeometry TechDraw::isValidSingleFace3d(DrawViewPart* dvp, const ReferenceEntry& ref)
|
||||
{
|
||||
(void)dvp;
|
||||
//the Name starts with "Edge"
|
||||
@@ -500,7 +499,7 @@ DimensionGeometry TechDraw::isValidSingleFace3d(DrawViewPart* dvp, ReferenceEntr
|
||||
|
||||
//! verify that the edge references can make a dimension. Currently only extent
|
||||
//! dimensions support more than 2 edges
|
||||
DimensionGeometry TechDraw::isValidMultiEdge(ReferenceVector refs)
|
||||
DimensionGeometry TechDraw::isValidMultiEdge(const ReferenceVector& refs)
|
||||
{
|
||||
//there has to be at least 2
|
||||
if (refs.size() < 2) {
|
||||
@@ -551,7 +550,7 @@ DimensionGeometry TechDraw::isValidMultiEdge(ReferenceVector refs)
|
||||
|
||||
//! verify that the edge references can make a dimension. Currently only extent
|
||||
//! dimensions support more than 2 edges
|
||||
DimensionGeometry TechDraw::isValidMultiEdge3d(DrawViewPart* dvp, ReferenceVector refs)
|
||||
DimensionGeometry TechDraw::isValidMultiEdge3d(DrawViewPart* dvp, const ReferenceVector& refs)
|
||||
{
|
||||
(void)dvp;
|
||||
//there has to be at least 2
|
||||
@@ -615,9 +614,9 @@ DimensionGeometry TechDraw::isValidMultiEdge3d(DrawViewPart* dvp, ReferenceVecto
|
||||
}
|
||||
|
||||
//! verify that the vertex references can make a dimension
|
||||
DimensionGeometry TechDraw::isValidVertexes(ReferenceVector refs)
|
||||
DimensionGeometry TechDraw::isValidVertexes(const ReferenceVector& refs)
|
||||
{
|
||||
TechDraw::DrawViewPart* dvp(dynamic_cast<TechDraw::DrawViewPart*>(refs.front().getObject()));
|
||||
auto* dvp(dynamic_cast<TechDraw::DrawViewPart*>(refs.front().getObject()));
|
||||
if (!dvp) {
|
||||
//probably redundant
|
||||
throw Base::RuntimeError("Logic error in isValidMultiEdge");
|
||||
@@ -650,7 +649,7 @@ DimensionGeometry TechDraw::isValidVertexes(ReferenceVector refs)
|
||||
}
|
||||
|
||||
//! verify that the vertex references can make a dimension
|
||||
DimensionGeometry TechDraw::isValidVertexes3d(DrawViewPart* dvp, ReferenceVector refs)
|
||||
DimensionGeometry TechDraw::isValidVertexes3d(DrawViewPart* dvp, const ReferenceVector& refs)
|
||||
{
|
||||
(void)dvp;
|
||||
const std::string matchToken{"Vertex"};
|
||||
@@ -672,8 +671,9 @@ DimensionGeometry TechDraw::isValidVertexes3d(DrawViewPart* dvp, ReferenceVector
|
||||
point1 = dvp->projectPoint(point1);
|
||||
Base::Vector3d line = point1 - point0;
|
||||
if (fabs(line.y) < FLT_EPSILON) {
|
||||
return DimensionGeometry::isHorizontal;
|
||||
} else if (fabs(line.x) < FLT_EPSILON) {
|
||||
return DimensionGeometry::isVertical;
|
||||
}
|
||||
if (fabs(line.x) < FLT_EPSILON) {
|
||||
return DimensionGeometry::isHorizontal;
|
||||
// } else if(fabs(line.z) < FLT_EPSILON) {
|
||||
// return isZLimited;
|
||||
@@ -691,7 +691,7 @@ DimensionGeometry TechDraw::isValidVertexes3d(DrawViewPart* dvp, ReferenceVector
|
||||
}
|
||||
|
||||
//! verify that the mixed bag (ex Vertex-Edge) of references can make a dimension
|
||||
DimensionGeometry TechDraw::isValidHybrid(ReferenceVector refs)
|
||||
DimensionGeometry TechDraw::isValidHybrid(const ReferenceVector& refs)
|
||||
{
|
||||
if (refs.empty()) {
|
||||
return DimensionGeometry::isInvalid;
|
||||
@@ -716,7 +716,7 @@ DimensionGeometry TechDraw::isValidHybrid(ReferenceVector refs)
|
||||
}
|
||||
|
||||
//! verify that the mixed bag (ex Vertex-Edge) of references can make a dimension
|
||||
DimensionGeometry TechDraw::isValidHybrid3d(DrawViewPart* dvp, ReferenceVector refs)
|
||||
DimensionGeometry TechDraw::isValidHybrid3d(DrawViewPart* dvp, const ReferenceVector& refs)
|
||||
{
|
||||
(void)dvp;
|
||||
//we can reuse the 2d check here.
|
||||
@@ -745,9 +745,11 @@ long int TechDraw::mapGeometryTypeToDimType(long int dimType, DimensionGeometry
|
||||
case DimensionGeometry::isAngle3Pt:
|
||||
return DrawViewDimension::Angle3Pt;
|
||||
default:
|
||||
break; // For all other cases, return dimType
|
||||
return dimType;
|
||||
}
|
||||
} else if (geometry2d != DimensionGeometry::isViewReference) {
|
||||
}
|
||||
|
||||
if (geometry2d != DimensionGeometry::isViewReference) {
|
||||
switch (geometry2d) {
|
||||
case DimensionGeometry::isDiagonal:
|
||||
return DrawViewDimension::Distance;
|
||||
@@ -763,6 +765,7 @@ long int TechDraw::mapGeometryTypeToDimType(long int dimType, DimensionGeometry
|
||||
break; // For all other cases, return dimType
|
||||
}
|
||||
}
|
||||
|
||||
return dimType;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,27 +74,27 @@ DimensionGeometry validateDimSelection3d(DrawViewPart* dvp,
|
||||
const std::vector<int>& minimumCounts, //how many of each geometry are needed for a good dimension
|
||||
const std::vector<DimensionGeometry>& acceptableDimensionGeometrys);//isVertical, isHorizontal, ...
|
||||
|
||||
bool validateSubnameList(StringVector subNames, GeometrySet acceptableGeometrySet);
|
||||
bool validateSubnameList(const StringVector& subNames, GeometrySet acceptableGeometrySet);
|
||||
|
||||
DimensionGeometry getGeometryConfiguration(ReferenceVector valid2dReferences);
|
||||
DimensionGeometry getGeometryConfiguration3d(DrawViewPart* dvp,
|
||||
ReferenceVector valid3dReferences);
|
||||
const ReferenceVector& valid3dReferences);
|
||||
|
||||
GeomCountMap loadRequiredCounts(const StringVector& acceptableGeometry,
|
||||
const std::vector<int>& minimumCouts);
|
||||
bool checkGeometryOccurrences(StringVector subNames, GeomCountMap keyedMinimumCounts);
|
||||
bool checkGeometryOccurrences(const StringVector& subNames, GeomCountMap keyedMinimumCounts);
|
||||
|
||||
DimensionGeometry isValidVertexes(ReferenceVector refs);
|
||||
DimensionGeometry isValidMultiEdge(ReferenceVector refs);
|
||||
DimensionGeometry isValidSingleEdge(ReferenceEntry ref);
|
||||
DimensionGeometry isValidSingleFace(ReferenceEntry ref);
|
||||
DimensionGeometry isValidHybrid(ReferenceVector refs);
|
||||
DimensionGeometry isValidVertexes(const ReferenceVector& refs);
|
||||
DimensionGeometry isValidMultiEdge(const ReferenceVector& refs);
|
||||
DimensionGeometry isValidSingleEdge(const ReferenceEntry& ref);
|
||||
DimensionGeometry isValidSingleFace(const ReferenceEntry& ref);
|
||||
DimensionGeometry isValidHybrid(const ReferenceVector& refs);
|
||||
|
||||
DimensionGeometry isValidVertexes3d(DrawViewPart* dvp, ReferenceVector refs);
|
||||
DimensionGeometry isValidMultiEdge3d(DrawViewPart* dvp, ReferenceVector refs);
|
||||
DimensionGeometry isValidSingleEdge3d(DrawViewPart* dvp, ReferenceEntry ref);
|
||||
DimensionGeometry isValidSingleFace3d(DrawViewPart* dvp, ReferenceEntry ref);
|
||||
DimensionGeometry isValidHybrid3d(DrawViewPart* dvp, ReferenceVector refs);
|
||||
DimensionGeometry isValidVertexes3d(DrawViewPart* dvp, const ReferenceVector& refs);
|
||||
DimensionGeometry isValidMultiEdge3d(DrawViewPart* dvp, const ReferenceVector& refs);
|
||||
DimensionGeometry isValidSingleEdge3d(DrawViewPart* dvp, const ReferenceEntry& ref);
|
||||
DimensionGeometry isValidSingleFace3d(DrawViewPart* dvp, const ReferenceEntry& ref);
|
||||
DimensionGeometry isValidHybrid3d(DrawViewPart* dvp, const ReferenceVector& refs);
|
||||
|
||||
long int mapGeometryTypeToDimType(long int dimType, DimensionGeometry geometry2d,
|
||||
DimensionGeometry geometry3d);
|
||||
|
||||
Reference in New Issue
Block a user