[Sketcher] Fix endpoint-to-endpoint/edge tangency substitution

Only substitute if the point(s) involved are `start`/`end`. Centers do
not make sense here.
This commit is contained in:
Ajinkya Dahale
2024-08-19 06:54:34 +05:30
parent 7c797b5a10
commit 6a1afdc4e2
3 changed files with 83 additions and 49 deletions

View File

@@ -3777,7 +3777,9 @@ bool CmdSketcherConstrainCoincidentUnified::substituteConstraintCombinationsPoin
if ((*it)->Type == Sketcher::Tangent && (*it)->FirstPos == Sketcher::PointPos::none
&& (*it)->SecondPos == Sketcher::PointPos::none && (*it)->Third == GeoEnum::GeoUndef
&& (((*it)->First == GeoId1 && (*it)->Second == GeoId2)
|| ((*it)->Second == GeoId1 && (*it)->First == GeoId2))) {
|| ((*it)->Second == GeoId1 && (*it)->First == GeoId2))
&& (PosId1 == Sketcher::PointPos::start
|| PosId1 == Sketcher::PointPos::end)) {
// NOTE: This function does not either open or commit a command as it is used for group
// addition it relies on such infrastructure being provided by the caller.
@@ -3813,6 +3815,12 @@ bool CmdSketcherConstrainCoincidentUnified::substituteConstraintCombinationsCoin
if ((*it)->Type == Sketcher::Tangent && (*it)->Third == GeoEnum::GeoUndef
&& (((*it)->First == GeoId1 && (*it)->Second == GeoId2)
|| ((*it)->Second == GeoId1 && (*it)->First == GeoId2))) {
if (!(PosId1 == Sketcher::PointPos::start
|| PosId1 == Sketcher::PointPos::end)
|| !(PosId2 == Sketcher::PointPos::start
|| PosId2 == Sketcher::PointPos::end)) {
continue;
}
if ((*it)->FirstPos == Sketcher::PointPos::none
&& (*it)->SecondPos == Sketcher::PointPos::none) {
@@ -6569,8 +6577,11 @@ bool CmdSketcherConstrainTangent::substituteConstraintCombinations(SketchObject*
++it, ++cid) {
if ((*it)->Type == Sketcher::Coincident
&& (((*it)->First == GeoId1 && (*it)->Second == GeoId2)
|| ((*it)->Second == GeoId1 && (*it)->First == GeoId2))) {
|| ((*it)->Second == GeoId1 && (*it)->First == GeoId2))
&& ((*it)->FirstPos == Sketcher::PointPos::start
|| (*it)->FirstPos == Sketcher::PointPos::end)
&& ((*it)->SecondPos == Sketcher::PointPos::start
|| (*it)->SecondPos == Sketcher::PointPos::end)) {
// save values because 'doEndpointTangency' changes the
// constraint property and thus invalidates this iterator
int first = (*it)->First;
@@ -6596,8 +6607,9 @@ bool CmdSketcherConstrainTangent::substituteConstraintCombinations(SketchObject*
}
else if ((*it)->Type == Sketcher::PointOnObject
&& (((*it)->First == GeoId1 && (*it)->Second == GeoId2)
|| ((*it)->Second == GeoId1 && (*it)->First == GeoId2))) {
|| ((*it)->Second == GeoId1 && (*it)->First == GeoId2))
&& ((*it)->FirstPos == Sketcher::PointPos::start
|| (*it)->FirstPos == Sketcher::PointPos::end)) {
Gui::Command::openCommand(
QT_TRANSLATE_NOOP("Command",
"Swap point on object and tangency with point to curve tangency"));

View File

@@ -666,19 +666,26 @@ protected:
}
// find if there is already a matching tangency
auto result = std::find_if(AutoConstraints.begin(),
AutoConstraints.end(),
[&](const auto& ace) {
return ace->Type == Sketcher::Tangent
&& ace->First == geoId1
&& ace->Second == ac.GeoId;
});
auto itOfTangentConstraint = AutoConstraints.end();
if ((posId1 == Sketcher::PointPos::start
|| posId1 == Sketcher::PointPos::end)
&& (ac.PosId == Sketcher::PointPos::start
|| ac.PosId == Sketcher::PointPos::end)) {
itOfTangentConstraint =
std::find_if(AutoConstraints.begin(),
AutoConstraints.end(),
[&](const auto& ace) {
return ace->Type == Sketcher::Tangent
&& ace->First == geoId1
&& ace->Second == ac.GeoId;
});
}
if (result
!= AutoConstraints.end()) { // modify tangency to endpoint-to-endpoint
(*result)->FirstPos = posId1;
(*result)->SecondPos = ac.PosId;
if (itOfTangentConstraint != AutoConstraints.end()) {
// modify tangency to endpoint-to-endpoint
(*itOfTangentConstraint)->FirstPos = posId1;
(*itOfTangentConstraint)->SecondPos = ac.PosId;
}
else {
auto c = std::make_unique<Sketcher::Constraint>();
@@ -699,21 +706,27 @@ protected:
std::swap(posId1, posId2);
}
auto result = std::find_if(AutoConstraints.begin(),
AutoConstraints.end(),
[&](const auto& ace) {
return ace->Type == Sketcher::Tangent
&& ace->First == geoId1
&& ace->Second == ac.GeoId;
});
auto itOfTangentConstraint = AutoConstraints.end();
if (posId1 == Sketcher::PointPos::start
|| posId1 == Sketcher::PointPos::end) {
itOfTangentConstraint =
std::find_if(AutoConstraints.begin(),
AutoConstraints.end(),
[&](const auto& ace) {
return ace->Type == Sketcher::Tangent
&& ace->First == geoId1
&& ace->Second == ac.GeoId;
});
}
// if tangency, convert to point-to-edge tangency
if (result != AutoConstraints.end()) {
(*result)->FirstPos = posId1;
if ((*result)->First != geoId1) {
std::swap((*result)->Second, (*result)->First);
if (itOfTangentConstraint != AutoConstraints.end()) {
if ((*itOfTangentConstraint)->First != geoId1) {
std::swap((*itOfTangentConstraint)->Second,
(*itOfTangentConstraint)->First);
}
(*itOfTangentConstraint)->FirstPos = posId1;
}
else {
auto c = std::make_unique<Sketcher::Constraint>();
@@ -735,11 +748,11 @@ protected:
c->ThirdPos = posId1;
AutoConstraints.push_back(std::move(c));
} break;
// In special case of Horizontal/Vertical constraint, geoId2 is normally unused
// and should be 'Constraint::GeoUndef' However it can be used as a way to
// require the function to apply these constraints on another geometry In this
// case the caller as to set geoId2, then it will be used as target instead of
// geoId2
// In special case of Horizontal/Vertical constraint, geoId2 is normally
// unused and should be 'Constraint::GeoUndef' However it can be used as a
// way to require the function to apply these constraints on another
// geometry In this case the caller as to set geoId2, then it will be used
// as target instead of geoId2
case Sketcher::Horizontal: {
auto c = std::make_unique<Sketcher::Constraint>();
c->Type = Sketcher::Horizontal;
@@ -777,9 +790,10 @@ protected:
|| geom2->getTypeId() == Part::GeomCircle::getClassTypeId()
|| geom2->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
// in all these cases an intermediate element is needed
/*makeTangentToEllipseviaNewPoint(Obj,
static_cast<const Part::GeomEllipse
*>(geom1), geom2, geoId1, geoId2);*/
// makeTangentToEllipseviaNewPoint(
// Obj,
// static_cast<const Part::GeomEllipse *>(geom1),
// geom2, geoId1, geoId2);
// NOTE: Temporarily deactivated
return;
}
@@ -803,11 +817,10 @@ protected:
|| geom2->getTypeId() == Part::GeomCircle::getClassTypeId()
|| geom2->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
// in all these cases an intermediate element is needed
// makeTangentToArcOfEllipseviaNewPoint(Obj,
// static_cast<const
// Part::GeomArcOfEllipse
// *>(geom1), geom2, geoId1,
// geoId2);
// makeTangentToArcOfEllipseviaNewPoint(
// Obj,
// static_cast<const Part::GeomArcOfEllipse*>(geom1), geom2,
// geoId1, geoId2);
// NOTE: Temporarily deactivated
return;
}
@@ -830,12 +843,18 @@ protected:
|| (ace->First == ac.GeoId && ace->Second == geoId1));
});
if (resultcoincident
!= AutoConstraints.end()) { // endpoint-to-endpoint tangency
if (resultcoincident != AutoConstraints.end()
&& ((*resultcoincident)->FirstPos == Sketcher::PointPos::start
|| (*resultcoincident)->FirstPos == Sketcher::PointPos::end)
&& ((*resultcoincident)->SecondPos == Sketcher::PointPos::start
|| (*resultcoincident)->SecondPos == Sketcher::PointPos::end)) {
// endpoint-to-endpoint tangency
(*resultcoincident)->Type = Sketcher::Tangent;
}
else if (resultpointonobject
!= AutoConstraints.end()) { // endpoint-to-edge tangency
else if (resultpointonobject != AutoConstraints.end()
&& ((*resultcoincident)->FirstPos == Sketcher::PointPos::start
|| (*resultcoincident)->FirstPos == Sketcher::PointPos::end)) {
// endpoint-to-edge tangency
(*resultpointonobject)->Type = Sketcher::Tangent;
}
else { // regular edge to edge tangency

View File

@@ -440,8 +440,8 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint>& suggested
int preSelPnt = getPreselectPoint();
int preSelCrv = getPreselectCurve();
int preSelCrs = getPreselectCross();
int GeoId = GeoEnum::GeoUndef;
int GeoId = GeoEnum::GeoUndef;
PointPos PosId = PointPos::none;
if (preSelPnt != -1) {
@@ -459,15 +459,18 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint>& suggested
}
}
}
else if (preSelCrs == 0) { // root point
else if (preSelCrs == 0) {
// root point
GeoId = Sketcher::GeoEnum::RtPnt;
PosId = PointPos::start;
}
else if (preSelCrs == 1) { // x axis
else if (preSelCrs == 1) {
// x axis
GeoId = Sketcher::GeoEnum::HAxis;
hitShapeDir = Base::Vector3d(1, 0, 0);
}
else if (preSelCrs == 2) { // y axis
else if (preSelCrs == 2) {
// y axis
GeoId = Sketcher::GeoEnum::VAxis;
hitShapeDir = Base::Vector3d(0, 1, 0);
}