[TD]fix pathological centerline for points

This commit is contained in:
wandererfan
2023-07-06 15:56:05 -04:00
committed by WandererFan
parent dbd4fbb460
commit 6a0d3dedfb
3 changed files with 121 additions and 26 deletions

View File

@@ -159,7 +159,7 @@ CenterLine* CenterLine::CenterLineBuilder(DrawViewPart* partFeat,
int mode,
bool flip)
{
// Base::Console().Message("CL::CLBuilder()\n - subNames: %d", subNames.size());
// Base::Console().Message("CL::CLBuilder()\n - subNames: %d\n", subNames.size());
std::pair<Base::Vector3d, Base::Vector3d> ends;
std::vector<std::string> faces;
std::vector<std::string> edges;
@@ -405,7 +405,6 @@ std::pair<Base::Vector3d, Base::Vector3d> CenterLine::calcEndPoints(DrawViewPart
if (faceBox.IsVoid()) {
Base::Console().Error("CL::calcEndPoints - faceBox is void!\n");
// return result;
throw Base::IndexError("CenterLine wrong number of faces.");
}
@@ -527,7 +526,6 @@ std::pair<Base::Vector3d, Base::Vector3d> CenterLine::calcEndPoints2Lines(DrawVi
// if the proposed end points prevent the creation of a vertical or horizontal centerline, we need
// to prevent the "orientation" code below from creating identical endpoints. This would create a
// zero length edge and cause problems later.
// this should probably be prevented in the creation task?
bool inhibitVertical = false;
bool inhibitHorizontal = false;
if (DU::fpCompare(p1.y, p2.y, EWTOLERANCE)) {
@@ -586,7 +584,7 @@ std::pair<Base::Vector3d, Base::Vector3d> CenterLine::calcEndPoints2Points(DrawV
double rotate, bool flip)
{
// Base::Console().Message("CL::calc2Points()\n");
// Base::Console().Message("CL::calc2Points() - mode: %d\n", mode);
if (vertNames.empty()) {
Base::Console().Warning("CL::calcEndPoints2Points - no points!\n");
return std::pair<Base::Vector3d, Base::Vector3d>();
@@ -606,17 +604,41 @@ std::pair<Base::Vector3d, Base::Vector3d> CenterLine::calcEndPoints2Points(DrawV
}
}
if (points.size() != 2) {
//this should fail harder. maybe be in a try/catch.
// Base::Console().Message("CL::calcEndPoints2Points - wrong number of points!\n");
// return result;
throw Base::IndexError("CenterLine wrong number of points.");
}
Base::Vector3d v1 = points.front()->point();
Base::Vector3d v2 = points.back()->point();
Base::Vector3d mid = (v1 + v2) / 2.0;
Base::Vector3d dir = v2 - v1;
// if the proposed end points prevent the creation of a vertical or horizontal centerline, we need
// to prevent the "orientation" code below from creating identical endpoints. This would create a
// zero length edge and cause problems later.
bool inhibitVertical = false;
bool inhibitHorizontal = false;
if (DU::fpCompare(v1.y, v2.y, EWTOLERANCE)) {
// proposed end points are aligned horizontally, can not draw horizontal CL
inhibitHorizontal = true;
}
if (DU::fpCompare(v1.x, v2.x, EWTOLERANCE)) {
// proposed end points are aligned vertically, can not draw vertical CL
inhibitVertical = true;
}
if (mode == 0 && !inhibitVertical) {
//Vertical
v1.x = mid.x;
v2.x = mid.x;
} else if (mode == 1 && !inhibitHorizontal) {
//Horizontal
v1.y = mid.y;
v2.y = mid.y;
} else if (mode == 2) { //Aligned
// no op
}
double length = dir.Length();
dir.Normalize();
Base::Vector3d clDir(dir.y, -dir.x, dir.z);
@@ -630,17 +652,6 @@ std::pair<Base::Vector3d, Base::Vector3d> CenterLine::calcEndPoints2Points(DrawV
p2 = temp;
}
if (mode == 0) { //Vertical
p1.x = mid.x;
p2.x = mid.x;
} else if (mode == 1) { //Horizontal
p1.y = mid.y;
p2.y = mid.y;
} else if (mode == 2) { //Aligned
// no op
}
//extend
p1 = p1 + (clDir * ext);
p2 = p2 - (clDir * ext);

View File

@@ -192,8 +192,14 @@ void TaskCenterLine::setUiPrimary()
int precision = Base::UnitsApi::getDecimals();
ui->qsbRotate->setDecimals(precision);
int orientation = checkPathologicalEdges(m_mode);
setUiOrientation(orientation);
if (m_type == 1) {
int orientation = checkPathologicalEdges(m_mode);
setUiOrientation(orientation);
}
if (m_type == 2) {
int orientation = checkPathologicalVertices(m_mode);
setUiOrientation(orientation);
}
}
void TaskCenterLine::setUiEdit()
@@ -238,6 +244,9 @@ void TaskCenterLine::setUiEdit()
void TaskCenterLine::onOrientationChanged()
{
if (!m_cl) {
return;
}
if (ui->rbVertical->isChecked())
m_cl->m_mode = CenterLine::CLMODE::VERTICAL;
else if (ui->rbHorizontal->isChecked())
@@ -254,30 +263,50 @@ void TaskCenterLine::onOrientationChanged()
void TaskCenterLine::onShiftHorizChanged()
{
if (!m_cl) {
return;
}
m_cl->m_hShift = ui->qsbHorizShift->rawValue();
m_partFeat->recomputeFeature();
}
void TaskCenterLine::onShiftVertChanged()
{
if (!m_cl) {
return;
}
m_cl->m_vShift = ui->qsbVertShift->rawValue();
m_partFeat->recomputeFeature();
}
void TaskCenterLine::onRotationChanged()
{
if (!m_cl) {
return;
}
m_cl->m_rotate = ui->qsbRotate->rawValue();
m_partFeat->recomputeFeature();
}
void TaskCenterLine::onExtendChanged()
{
if (!m_cl) {
return;
}
m_cl->m_extendBy = ui->qsbExtend->rawValue();
m_partFeat->recomputeFeature();
}
void TaskCenterLine::onColorChanged()
{
if (!m_cl) {
return;
}
App::Color ac;
ac.setValue<QColor>(ui->cpLineColor->color());
m_cl->m_format.m_color.setValue<QColor>(ui->cpLineColor->color());
@@ -286,12 +315,20 @@ void TaskCenterLine::onColorChanged()
void TaskCenterLine::onWeightChanged()
{
if (!m_cl) {
return;
}
m_cl->m_format.m_weight = ui->dsbWeight->value().getValue();
m_partFeat->recomputeFeature();
}
void TaskCenterLine::onStyleChanged()
{
if (!m_cl) {
return;
}
m_cl->m_format.m_style = ui->cboxStyle->currentIndex() + 1;
m_partFeat->recomputeFeature();
}
@@ -326,12 +363,47 @@ int TaskCenterLine::checkPathologicalEdges(int inMode)
return inMode;
}
// check that we are not trying to create an impossible centerline (ex a vertical centerline
// between 2 vertices aligned vertically)
int TaskCenterLine::checkPathologicalVertices(int inMode)
{
if (m_type != 2) {
// not a vertex based centerline, this doesn't apply
return inMode;
}
TechDraw::VertexPtr vert1 = m_partFeat->getVertex(m_subNames.front());
Base::Vector3d point1 = vert1->point();
TechDraw::VertexPtr vert2 = m_partFeat->getVertex(m_subNames.back());
Base::Vector3d point2 = vert2->point();
if (DU::fpCompare(point1.x, point2.x, EWTOLERANCE)) {
// points are aligned vertically, CL must be horizontal
return CenterLine::CLMODE::HORIZONTAL;
}
if (DU::fpCompare(point1.y, point2.y, EWTOLERANCE)) {
// points are aligned horizontally, CL must be vertical
return CenterLine::CLMODE::VERTICAL;
}
// not pathological case, just return the input mode
return inMode;
}
//******************************************************************************
void TaskCenterLine::createCenterLine()
{
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Create CenterLine"));
m_mode = checkPathologicalEdges(m_mode);
// check for illogical parameters
if (m_type == 1) {
// between lines
m_mode = checkPathologicalEdges(m_mode);
} else if (m_type == 2) {
// between points
m_mode = checkPathologicalVertices(m_mode);
}
CenterLine* cl = CenterLine::CenterLineBuilder(m_partFeat, m_subNames, m_mode, false);
@@ -367,6 +439,7 @@ void TaskCenterLine::createCenterLine()
void TaskCenterLine::updateOrientation()
{
// Base::Console().Message("TCL::updateOrientation()\n");
if (!m_cl) {
return;
}
@@ -375,10 +448,20 @@ void TaskCenterLine::updateOrientation()
// https://forum.freecad.org/viewtopic.php?f=35&t=44255&start=20#p503220
// The centerline creation can fail if m_type is edge and both selected edges are vertical or horizontal.
int orientation = m_cl->m_mode;
if (!m_edgeName.empty() && !m_cl->m_edges.empty()) {
// we have an existing centerline, not a freshly created one, and it is a centerline between edges
m_subNames = m_cl->m_edges;
orientation = checkPathologicalEdges(orientation);
if (m_type == 1) {
// between lines
if (!m_edgeName.empty() && !m_cl->m_edges.empty()) {
// we have an existing centerline, not a freshly created one, and it is a centerline between edges
m_subNames = m_cl->m_edges;
orientation = checkPathologicalEdges(orientation);
}
} else if (m_type == 2) {
// between points
if (!m_edgeName.empty() && !m_cl->m_verts.empty()) {
// we have an existing centerline, not a freshly created one, and it is a centerline between points
m_subNames = m_cl->m_verts;
orientation = checkPathologicalVertices(orientation);
}
}
setUiOrientation(orientation);

View File

@@ -89,6 +89,7 @@ protected:
double getExtendBy();
int checkPathologicalEdges(int inMode);
int checkPathologicalVertices(int inMode);
void setUiOrientation(int orientation);
private: