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:
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user