Sketcher: Slot tool: fix redundant horizontal (#24248)

* Sketcher: Slot tool: clean vertical/horizontal mess.

* Update DrawSketchHandlerSlot.h

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update DrawSketchHandlerSlot.h

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Clean removeRedundantHorizontalVertical

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
PaddleStroke
2025-09-26 22:05:55 +02:00
committed by GitHub
parent b9ab71e606
commit af4ed78c01
2 changed files with 73 additions and 112 deletions

View File

@@ -73,8 +73,6 @@ public:
: radius(1.0)
, length(0.0)
, angle(0.0)
, isHorizontal(false)
, isVertical(false)
, firstCurve(0)
{}
@@ -123,7 +121,6 @@ private:
secondPoint = onSketchPos;
angle = (secondPoint - startPoint).Angle();
checkHorizontalVertical();
length = (secondPoint - startPoint).Length();
const double scale = 0.2;
radius = length * scale; // radius chosen at 1/5 of length
@@ -197,6 +194,22 @@ private:
void generateAutoConstraints() override
{
// alignment constraints needs to apply to the line not the arc.
bool alignmentCstr = false;
for (auto& ac : sugConstraints[1]) {
if (ac.Type == Sketcher::Horizontal || ac.Type == Sketcher::Vertical
|| ac.Type == Sketcher::Perpendicular || ac.Type == Sketcher::Parallel) {
ac.GeoId = firstCurve + 2;
alignmentCstr = true;
}
}
if (avoidRedundants && alignmentCstr) {
removeRedundantHorizontalVertical(getSketchObject(),
sugConstraints[0],
sugConstraints[1]);
}
// add auto constraints for the center of 1st arc
generateAutoConstraintsOnElement(sugConstraints[0],
getHighestCurveIndex() - 3,
@@ -219,8 +232,6 @@ private:
sugConstraints[0].clear();
sugConstraints[1].clear();
isHorizontal = false;
isVertical = false;
}
std::string getToolName() const override
@@ -321,53 +332,12 @@ private:
firstCurve,
Sketcher::PointPos::none,
firstCurve + 1);
// Prevent duplicate with Autocontraint
AutoConstraint lastCons = {Sketcher::None,
Sketcher::GeoEnum::GeoUndef,
Sketcher::PointPos::none};
if (!sugConstraints[1].empty()) {
lastCons = sugConstraints[1].back();
}
if (isHorizontal || isVertical) {
addToShapeConstraints(isHorizontal ? Sketcher::Horizontal : Sketcher::Vertical,
firstCurve + 3);
if (lastCons.Type == Sketcher::Horizontal || lastCons.Type == Sketcher::Vertical) {
sugConstraints[1].pop_back();
}
}
else {
// If horizontal/vertical Autoconstraint suggested, applied it on first line
// (rather than last arc)
if (lastCons.Type == Sketcher::Horizontal || lastCons.Type == Sketcher::Vertical) {
sugConstraints[1].back().GeoId = firstCurve + 2;
}
}
}
}
void checkHorizontalVertical()
{
using std::numbers::pi;
isHorizontal = false;
isVertical = false;
if (fmod(fabs(angle), pi) < Precision::Confusion()) {
isHorizontal = true;
}
else if (fmod(fabs(angle + pi / 2), pi) < Precision::Confusion()) {
isVertical = true;
}
}
private:
Base::Vector2d startPoint, secondPoint;
double radius, length, angle;
bool isHorizontal, isVertical;
int firstCurve;
};
@@ -625,23 +595,16 @@ void DSHSlotController::addConstraints()
};
auto constraintAngle = [&]() {
if (!handler->isHorizontal && !handler->isVertical) {
ConstraintType lastType = handler->sugConstraints[1].empty()
? ConstraintType::None
: handler->sugConstraints[1].back().Type;
if (lastType != Sketcher::Horizontal && lastType != Sketcher::Vertical
&& lastType != Sketcher::Perpendicular && lastType != Sketcher::Parallel) {
Gui::cmdAppObjectArgs(obj,
"addConstraint(Sketcher.Constraint('Angle',%d,%d,%f)) ",
Sketcher::GeoEnum::HAxis,
firstCurve + 2,
handler->angle);
// Prevent duplicate with Autocontraint
AutoConstraint lastCons = {Sketcher::None,
Sketcher::GeoEnum::GeoUndef,
Sketcher::PointPos::none};
if (!handler->sugConstraints[1].empty()) {
lastCons = handler->sugConstraints[1].back();
if (lastCons.Type == Sketcher::Horizontal || lastCons.Type == Sketcher::Vertical) {
handler->AutoConstraints.pop_back();
}
}
}
};

View File

@@ -601,74 +601,72 @@ void SketcherGui::removeRedundantHorizontalVertical(Sketcher::SketchObject* pske
std::vector<AutoConstraint>& sug1,
std::vector<AutoConstraint>& sug2)
{
if (!sug1.empty() && !sug2.empty()) {
if (sug1.empty() || sug2.empty()) {
return;
}
bool rmvhorvert = false;
bool rmvhorvert = false;
// we look for:
// 1. Coincident to external on both endpoints
// 2. Coincident in one endpoint to origin and pointonobject/tangent to an axis on the other
auto detectredundant =
[psketch](std::vector<AutoConstraint>& sug, bool& ext, bool& orig, bool& axis) {
ext = false;
orig = false;
axis = false;
// we look for:
// 1. Coincident to external on both endpoints
// 2. Coincident in one endpoint to origin and pointonobject/tangent to an axis on the other
auto detectredundant =
[psketch](std::vector<AutoConstraint>& sug, bool& ext, bool& orig, bool& axis) {
ext = false;
orig = false;
axis = false;
for (std::vector<AutoConstraint>::const_iterator it = sug.begin(); it != sug.end();
++it) {
if ((*it).Type == Sketcher::Coincident && !ext) {
const std::map<int, Sketcher::PointPos> coincidents =
psketch->getAllCoincidentPoints((*it).GeoId, (*it).PosId);
for (auto& it : sug) {
if (it.Type == Sketcher::Coincident && !ext) {
const std::map<int, Sketcher::PointPos> coincidents =
psketch->getAllCoincidentPoints(it.GeoId, it.PosId);
if (!coincidents.empty()) {
// the keys are ordered, so if the first is negative, it is coincident
// with external
ext = coincidents.begin()->first < 0;
if (!coincidents.empty()) {
// the keys are ordered, so if the first is negative, it is coincident
// with external
ext = coincidents.begin()->first < 0;
std::map<int, Sketcher::PointPos>::const_iterator geoId1iterator;
std::map<int, Sketcher::PointPos>::const_iterator geoId1iterator;
geoId1iterator = coincidents.find(-1);
geoId1iterator = coincidents.find(-1);
if (geoId1iterator != coincidents.end()) {
if ((*geoId1iterator).second == Sketcher::PointPos::start) {
orig = true;
}
if (geoId1iterator != coincidents.end()) {
if ((*geoId1iterator).second == Sketcher::PointPos::start) {
orig = true;
}
}
else { // it may be that there is no constraint at all, but there is
// external geometry
ext = (*it).GeoId < 0;
orig = ((*it).GeoId == -1 && (*it).PosId == Sketcher::PointPos::start);
}
}
else if ((*it).Type == Sketcher::PointOnObject && !axis) {
axis = (((*it).GeoId == -1 && (*it).PosId == Sketcher::PointPos::none)
|| ((*it).GeoId == -2 && (*it).PosId == Sketcher::PointPos::none));
else { // it may be that there is no constraint at all, but there is
// external geometry
ext = it.GeoId < 0;
orig = (it.GeoId == -1 && it.PosId == Sketcher::PointPos::start);
}
}
};
bool firstext = false, secondext = false, firstorig = false, secondorig = false,
firstaxis = false, secondaxis = false;
detectredundant(sug1, firstext, firstorig, firstaxis);
detectredundant(sug2, secondext, secondorig, secondaxis);
rmvhorvert =
((firstext && secondext) || // coincident with external on both endpoints
(firstorig && secondaxis) || // coincident origin and point on object on other
(secondorig && firstaxis));
if (rmvhorvert) {
for (std::vector<AutoConstraint>::reverse_iterator it = sug2.rbegin();
it != sug2.rend();
++it) {
if ((*it).Type == Sketcher::Horizontal || (*it).Type == Sketcher::Vertical) {
sug2.erase(std::next(it).base());
it = sug2.rbegin(); // erase invalidates the iterator
else if (it.Type == Sketcher::PointOnObject && !axis) {
axis = ((it.GeoId == -1 && it.PosId == Sketcher::PointPos::none)
|| (it.GeoId == -2 && it.PosId == Sketcher::PointPos::none));
}
}
};
bool firstext = false, secondext = false, firstorig = false, secondorig = false,
firstaxis = false, secondaxis = false;
detectredundant(sug1, firstext, firstorig, firstaxis);
detectredundant(sug2, secondext, secondorig, secondaxis);
rmvhorvert = ((firstext && secondext) || // coincident with external on both endpoints
(firstorig && secondaxis) || // coincident origin and point on object on other
(secondorig && firstaxis));
if (rmvhorvert) {
for (std::vector<AutoConstraint>::reverse_iterator it = sug2.rbegin(); it != sug2.rend();
++it) {
if ((*it).Type == Sketcher::Horizontal || (*it).Type == Sketcher::Vertical) {
sug2.erase(std::next(it).base());
it = sug2.rbegin(); // erase invalidates the iterator
}
}
}
}