Skip to content

Commit

Permalink
Sketcher_Dimension: Enable the user to select what angle he wants.
Browse files Browse the repository at this point in the history
  • Loading branch information
PaddleStroke committed Sep 12, 2023
1 parent 4bc2b1b commit 4b69642
Showing 1 changed file with 81 additions and 0 deletions.
81 changes: 81 additions & 0 deletions src/Mod/Sketcher/Gui/CommandConstraints.cpp
Expand Up @@ -1159,6 +1159,7 @@ class DrawSketchHandlerDimension : public DrawSketchHandler
, selEllipseAndCo({})
, initialSelection(std::move(SubNames))
, numberOfConstraintsCreated(0)
, angleReversed(false)
{
}
~DrawSketchHandlerDimension() override
Expand All @@ -1177,6 +1178,7 @@ class DrawSketchHandlerDimension : public DrawSketchHandler
enum class SpecialConstraint {
LineOr2PointsDistance,
Block,
LinesAngle,
None
};

Expand Down Expand Up @@ -1252,6 +1254,9 @@ class DrawSketchHandlerDimension : public DrawSketchHandler
if (specialConstraint == SpecialConstraint::LineOr2PointsDistance)
updateDistanceType(onSketchPos);

if (specialConstraint == SpecialConstraint::LinesAngle)
updateAngle(onSketchPos);

//Move constraints
if (numberOfConstraintsCreated > 0) {
bool oneMoved = false;
Expand Down Expand Up @@ -1372,6 +1377,8 @@ class DrawSketchHandlerDimension : public DrawSketchHandler

int numberOfConstraintsCreated;

bool angleReversed;

Sketcher::SketchObject* Obj;

void handleInitialSelection()
Expand Down Expand Up @@ -2094,6 +2101,8 @@ class DrawSketchHandlerDimension : public DrawSketchHandler
}

void createAngleConstrain(int GeoId1, int GeoId2, Base::Vector2d onSketchPos) {
specialConstraint = SpecialConstraint::LinesAngle;

const Part::Geometry* geom1 = Obj->getGeometry(GeoId1);
const Part::Geometry* geom2 = Obj->getGeometry(GeoId2);
if (geom1->getTypeId() == Part::GeomLineSegment::getClassTypeId() &&
Expand Down Expand Up @@ -2171,6 +2180,13 @@ class DrawSketchHandlerDimension : public DrawSketchHandler
std::swap(PosId1, PosId2);
}

if (angleReversed) {
ActAngle = M_PI - ActAngle;
std::swap(GeoId1, GeoId2);
std::swap(PosId1, PosId2);
PosId1 = (PosId1 == Sketcher::PointPos::start) ? Sketcher::PointPos::end : Sketcher::PointPos::start;
}

Gui::cmdAppObjectArgs(Obj, "addConstraint(Sketcher.Constraint('Angle',%d,%d,%d,%d,%f)) ",
GeoId1, static_cast<int>(PosId1), GeoId2, static_cast<int>(PosId2), ActAngle);

Expand Down Expand Up @@ -2359,6 +2375,70 @@ class DrawSketchHandlerDimension : public DrawSketchHandler
}
}

void updateAngle(Base::Vector2d onSketchPos)
{
const std::vector< Sketcher::Constraint* >& vals = Obj->Constraints.getValues();
Sketcher::Constraint* cstr = vals[vals.size() - 1];
int geoId1 = cstr->First;
int geoId2 = cstr->Second;
Sketcher::PointPos posId1 = cstr->FirstPos;
Sketcher::PointPos posId2 = cstr->SecondPos;

const Part::Geometry* geom1 = Obj->getGeometry(geoId1);
const Part::Geometry* geom2 = Obj->getGeometry(geoId2);
if (geom1->getTypeId() != Part::GeomLineSegment::getClassTypeId() ||
geom2->getTypeId() != Part::GeomLineSegment::getClassTypeId()) {
return;
}

const auto* lineSeg1 = static_cast<const Part::GeomLineSegment*>(geom1);
const auto* lineSeg2 = static_cast<const Part::GeomLineSegment*>(geom2);

Base::Vector3d p1[2], p2[2];
p1[0] = lineSeg1->getStartPoint();
p1[1] = lineSeg1->getEndPoint();
p2[0] = lineSeg2->getStartPoint();
p2[1] = lineSeg2->getEndPoint();

// Get the intersection point in 2d of the two lines if possible
Base::Line2d line1(Base::Vector2d(p1[0].x, p1[0].y), Base::Vector2d(p1[1].x, p1[1].y));
Base::Line2d line2(Base::Vector2d(p2[0].x, p2[0].y), Base::Vector2d(p2[1].x, p2[1].y));
Base::Vector2d intersection = Base::Vector2d(0., 0.);
line1.Intersect(line2, intersection);

Base::Vector2d ap1 = (posId1 == Sketcher::PointPos::start) ? Base::Vector2d(p1[0].x, p1[0].y) : Base::Vector2d(p1[1].x, p1[1].y);
Base::Vector2d ap2 = (posId2 == Sketcher::PointPos::start) ? Base::Vector2d(p2[0].x, p2[0].y) : Base::Vector2d(p2[1].x, p2[1].y);

//calculate the angle between intersection-onsketchpos and intersection-ap1.
Base::Vector2d vector0 = onSketchPos - intersection;
Base::Vector2d vector1 = ap1 - intersection;
Base::Vector2d vector2 = ap2 - intersection;

Base::Vector2d ap3 = intersection + vector1 + vector2;

auto isLeftOfLine = [](Base::Vector2d a, Base::Vector2d b, Base::Vector2d c) {
return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x) > 0;
};

bool sign1 = isLeftOfLine(intersection, ap1, ap3);
bool sign2 = isLeftOfLine(intersection, ap2, ap3);

bool sign3 = isLeftOfLine(intersection, ap1, onSketchPos);
bool sign4 = isLeftOfLine(intersection, ap2, onSketchPos);

bool reverse = true;
if ((sign1 == sign3 && sign2 == sign4) || (sign1 != sign3 && sign2 != sign4)) {
reverse = false;
}

if (reverse) {
bool angleReversedBackup = !angleReversed;
restartCommand(QT_TRANSLATE_NOOP("Command", "Add Angle constraint"));
angleReversed = angleReversedBackup;
createAngleConstrain(selLine[0].GeoId, selLine[1].GeoId, onSketchPos);
}
}

void restartCommand(const char* cstrName) {
specialConstraint = SpecialConstraint::None;
Gui::Command::abortCommand();
Expand All @@ -2367,6 +2447,7 @@ class DrawSketchHandlerDimension : public DrawSketchHandler
Gui::Command::openCommand(cstrName);

numberOfConstraintsCreated = 0;
angleReversed = false;
}
};

Expand Down

0 comments on commit 4b69642

Please sign in to comment.