[TD] fix centerline crashes and bugs
the PR fixes the following things: - change the way centerlines between 2 lines are calculated. The current implementation leads to many bugs and even crashes (e.g. when the 2 selected lines are parallel ones of a square). There are different forum threads from the last 1.5 years. The new endpoint line sorting is the one described here: https://forum.freecadweb.org/viewtopic.php?f=35&start=20&t=44255&sid=989a668890f954c13ef81e4a04ee6912#p501179 - as consequence the erroneous and misleading line end flipping can go and is removed (only used internally) - when creating a new centerline, you see it immediately - when creating a new or editing an existing centerline and press Cancel, the creation/editing is aborted - fix crash when the 2 selected lines are bot horizontal and one tries to create a vertical centerline - fix crash when changing the orientation of an existing centerline and the result would be invalid - cleanup the code a bit
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Exception.h>
|
||||
#include <Base/Matrix.h>
|
||||
#include <Base/Parameter.h>
|
||||
#include <Base/Reader.h>
|
||||
#include <Base/Tools.h>
|
||||
@@ -977,6 +978,20 @@ std::pair<Base::Vector3d, Base::Vector3d> CenterLine::calcEndPoints(DrawViewPart
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CenterLine::Circulation(Base::Vector3d A, Base::Vector3d B, Base::Vector3d C)
|
||||
{
|
||||
Base::Matrix4D CircMatrix(
|
||||
A.x, A.y, 1, 0,
|
||||
B.x, B.y, 1, 0,
|
||||
C.x, C.y, 1, 0,
|
||||
0, 0, 0, 1);
|
||||
|
||||
if (CircMatrix.determinant() > 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
std::pair<Base::Vector3d, Base::Vector3d> CenterLine::calcEndPoints2Lines(DrawViewPart* partFeat,
|
||||
std::vector<std::string> edgeNames,
|
||||
int mode, double ext,
|
||||
@@ -1018,17 +1033,21 @@ std::pair<Base::Vector3d, Base::Vector3d> CenterLine::calcEndPoints2Lines(DrawVi
|
||||
Base::Vector3d l2p1 = edges.back()->getStartPoint();
|
||||
Base::Vector3d l2p2 = edges.back()->getEndPoint();
|
||||
|
||||
if (flip) { //reverse line 2
|
||||
Base::Vector3d temp;
|
||||
temp = l2p1;
|
||||
l2p1 = l2p2;
|
||||
l2p2 = temp;
|
||||
// The centerline is drawn using the midpoints of the two lines that connect l1p1-l2p1 and l1p2-l2p2.
|
||||
// However, we don't know which point should be l1p1 to get a geometrically correct result.
|
||||
// Thus we test this by a circulation test.
|
||||
if (Circulation(l1p1, l1p2, l2p1) != Circulation(l1p2, l2p2, l2p1)) {
|
||||
Base::Vector3d temp; // reverse line 1
|
||||
temp = l1p1;
|
||||
l1p1 = l1p2;
|
||||
l1p2 = temp;
|
||||
}
|
||||
|
||||
Base::Vector3d p1 = (l1p1 + l2p1) / 2.0;
|
||||
Base::Vector3d p2 = (l1p2 + l2p2) / 2.0;
|
||||
Base::Vector3d mid = (p1 + p2) / 2.0;
|
||||
|
||||
//orientation
|
||||
if (mode == 0) { //Vertical
|
||||
p1.x = mid.x;
|
||||
p2.x = mid.x;
|
||||
|
||||
Reference in New Issue
Block a user