Slot DSH : implement tool parameters.

This commit is contained in:
Paddle
2023-11-03 18:36:20 +01:00
committed by abdullahtahiriyo
parent b4d4a00329
commit cb19b1036e

View File

@@ -20,6 +20,7 @@
* *
***************************************************************************/
#ifndef SKETCHERGUI_DrawSketchHandlerSlot_H
#define SKETCHERGUI_DrawSketchHandlerSlot_H
@@ -33,7 +34,8 @@
#include <Mod/Sketcher/App/SketchObject.h>
#include "DrawSketchHandler.h"
#include "DrawSketchDefaultWidgetController.h"
#include "DrawSketchControllableHandler.h"
#include "GeometryCreationMode.h"
#include "Utils.h"
#include "ViewProviderSketch.h"
@@ -44,333 +46,540 @@ namespace SketcherGui
extern GeometryCreationMode geometryCreationMode; // defined in CommandCreateGeo.cpp
class DrawSketchHandlerSlot: public DrawSketchHandler
class DrawSketchHandlerSlot;
using DSHSlotController =
DrawSketchDefaultWidgetController<DrawSketchHandlerSlot,
StateMachines::ThreeSeekEnd,
/*PAutoConstraintSize =*/2,
/*OnVieOnViewParametersT =*/OnViewParameters<5>,
/*WidgetParametersT =*/WidgetParameters<0>,
/*WidgetCheckboxesT =*/WidgetCheckboxes<0>,
/*WidgetComboboxesT =*/WidgetComboboxes<0>>;
using DSHSlotControllerBase = DSHSlotController::ControllerBase;
using DrawSketchHandlerSlotBase = DrawSketchControllableHandler<DSHSlotController>;
class DrawSketchHandlerSlot: public DrawSketchHandlerSlotBase
{
friend DSHSlotController;
friend DSHSlotControllerBase;
public:
DrawSketchHandlerSlot()
: Mode(STATUS_SEEK_First)
, SnapMode(SNAP_MODE_Free)
, SnapDir(SNAP_DIR_Horz)
, dx(0)
, dy(0)
, r(0)
, EditCurve(35)
: radius(1.0)
, length(0.0)
, angle(0.0)
, isHorizontal(false)
, isVertical(false)
, firstCurve(0)
{}
~DrawSketchHandlerSlot() override
{}
/// mode table
enum BoxMode
{
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
STATUS_End
};
enum SNAP_MODE
{
SNAP_MODE_Free,
SNAP_MODE_Straight
};
enum SNAP_DIR
{
SNAP_DIR_Horz,
SNAP_DIR_Vert
};
void mouseMove(Base::Vector2d onSketchPos) override
{
if (Mode == STATUS_SEEK_First) {
setPositionText(onSketchPos);
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(sugConstr1);
return;
}
}
else if (Mode == STATUS_SEEK_Second) {
dx = onSketchPos.x - StartPos.x;
dy = onSketchPos.y - StartPos.y;
if (QApplication::keyboardModifiers() == Qt::ControlModifier) {
SnapMode = SNAP_MODE_Straight;
}
else {
SnapMode = SNAP_MODE_Free;
}
double a = 0;
double rev = 0;
if (fabs(dx) > fabs(dy)) {
r = fabs(dx) / 4;
rev = Base::sgn(dx);
SnapDir = SNAP_DIR_Horz;
if (SnapMode == SNAP_MODE_Straight) {
dy = 0;
}
}
else {
r = fabs(dy) / 4;
a = 8;
rev = Base::sgn(dy);
SnapDir = SNAP_DIR_Vert;
if (SnapMode == SNAP_MODE_Straight) {
dx = 0;
}
}
// draw the arcs with each 16 segments
for (int i = 0; i < 17; i++) {
// first get the position at the arc
// if a is 0, the end points of the arc are at the y-axis, if it is 8, they are on
// the x-axis
double angle = (i + a) * M_PI / 16.0;
double rx = -r * rev * sin(angle);
double ry = r * rev * cos(angle);
// now apply the rotation matrix according to the angle between StartPos and
// onSketchPos
if (!(dx == 0 || dy == 0)) {
double rotAngle = atan(dy / dx);
if (a > 0) {
rotAngle = -atan(dx / dy);
}
double rxRot = rx * cos(rotAngle) - ry * sin(rotAngle);
double ryRot = rx * sin(rotAngle) + ry * cos(rotAngle);
rx = rxRot;
ry = ryRot;
}
EditCurve[i] = Base::Vector2d(StartPos.x + rx, StartPos.y + ry);
EditCurve[17 + i] = Base::Vector2d(StartPos.x + dx - rx, StartPos.y + dy - ry);
}
EditCurve[34] = EditCurve[0];
if (showCursorCoords()) {
SbString text;
std::string rString = lengthToDisplayFormat(r, 1);
std::string sqrtString = lengthToDisplayFormat(sqrt(dx * dx + dy * dy), 1);
text.sprintf(" (R%s L%s))", rString.c_str(), sqrtString.c_str());
setPositionText(onSketchPos, text);
}
drawEdit(EditCurve);
if (seekAutoConstraint(sugConstr2,
onSketchPos,
Base::Vector2d(dx, dy),
AutoConstraint::VERTEX_NO_TANGENCY)) {
renderSuggestConstraintsCursor(sugConstr2);
return;
}
}
applyCursor();
}
bool pressButton(Base::Vector2d onSketchPos) override
{
if (Mode == STATUS_SEEK_First) {
StartPos = onSketchPos;
Mode = STATUS_SEEK_Second;
}
else {
Mode = STATUS_End;
}
return true;
}
bool releaseButton(Base::Vector2d onSketchPos) override
{
Q_UNUSED(onSketchPos);
if (Mode == STATUS_End) {
unsetCursor();
resetPositionText();
int firstCurve = getHighestCurveIndex() + 1;
// add the geometry to the sketch
// first determine the rotation angle for the first arc
double start, end;
if (fabs(dx) > fabs(dy)) {
if (dx > 0) {
start = 0.5 * M_PI;
end = 1.5 * M_PI;
}
else {
start = 1.5 * M_PI;
end = 0.5 * M_PI;
}
}
else {
if (dy > 0) {
start = -M_PI;
end = 0;
}
else {
start = 0;
end = -M_PI;
}
}
try {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add slot"));
AutoConstraint lastCons = {Sketcher::None,
Sketcher::GeoEnum::GeoUndef,
Sketcher::PointPos::none};
if (!sugConstr2.empty()) {
lastCons = sugConstr2.back();
}
std::ostringstream snapCon = std::ostringstream("");
if (SnapMode == SNAP_MODE_Straight) {
snapCon << "conList.append(Sketcher.Constraint('";
if (SnapDir == SNAP_DIR_Horz) {
snapCon << "Horizontal";
}
else {
snapCon << "Vertical";
}
snapCon << "'," << firstCurve + 2 << "))\n";
// If horizontal/vertical already applied because of snap, do not duplicate with
// Autocontraint
if (lastCons.Type == Sketcher::Horizontal
|| lastCons.Type == Sketcher::Vertical) {
sugConstr2.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) {
sugConstr2.back().GeoId = firstCurve + 2;
}
}
Gui::Command::doCommand(
Gui::Command::Doc,
"geoList = []\n"
"geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(%f, %f, 0), "
"App.Vector(0, 0, 1), %f), %f, %f))\n"
"geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(%f, %f ,0), "
"App.Vector(0, 0, 1), %f), %f, %f))\n"
"geoList.append(Part.LineSegment(App.Vector(%f, %f, 0), App.Vector(%f, %f, "
"0)))\n"
"geoList.append(Part.LineSegment(App.Vector(%f, %f, 0), App.Vector(%f, %f, "
"0)))\n"
"%s.addGeometry(geoList, %s)\n"
"conList = []\n"
"conList.append(Sketcher.Constraint('Tangent', %i, 2, %i, 1))\n"
"conList.append(Sketcher.Constraint('Tangent', %i, 2, %i, 1))\n"
"conList.append(Sketcher.Constraint('Tangent', %i, 2, %i, 1))\n"
"conList.append(Sketcher.Constraint('Tangent', %i, 2, %i, 1))\n"
"conList.append(Sketcher.Constraint('Equal', %i, %i))\n"
"%s"
"%s.addConstraint(conList)\n"
"del geoList, conList\n",
StartPos.x,
StartPos.y, // center of the arc1
r, // radius arc1
start,
end, // start and end angle of arc1
StartPos.x + dx,
StartPos.y + dy, // center of the arc2
r, // radius arc2
end,
end + M_PI, // start and end angle of arc2
EditCurve[16].x,
EditCurve[16].y,
EditCurve[17].x,
EditCurve[17].y, // line1
EditCurve[33].x,
EditCurve[33].y,
EditCurve[34].x,
EditCurve[34].y, // line2
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str(), // the sketch
constructionModeAsBooleanText(), // geometry as construction or not
firstCurve,
firstCurve + 2, // tangent1
firstCurve + 2,
firstCurve + 1, // tangent2
firstCurve + 1,
firstCurve + 3, // tangent3
firstCurve + 3,
firstCurve, // tangent4
firstCurve,
firstCurve + 1, // equal constraint
snapCon.str().c_str(), // horizontal/vertical constraint if snapping
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str()); // the sketch
Gui::Command::commitCommand();
// add auto constraints at the center of the first arc
if (!sugConstr1.empty()) {
createAutoConstraints(sugConstr1,
getHighestCurveIndex() - 3,
Sketcher::PointPos::mid);
sugConstr1.clear();
}
// add auto constraints at the center of the second arc
if (!sugConstr2.empty()) {
createAutoConstraints(sugConstr2,
getHighestCurveIndex() - 2,
Sketcher::PointPos::mid);
sugConstr2.clear();
}
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
}
catch (const Base::Exception&) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add slot"));
Gui::Command::abortCommand();
tryAutoRecompute(static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
}
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode", true);
if (continuousMode) {
// This code enables the continuous creation mode.
Mode = STATUS_SEEK_First;
EditCurve.clear();
drawEdit(EditCurve);
EditCurve.resize(35);
applyCursor();
/* this is ok not to call to purgeHandler
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
}
else {
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in
// ViewProvider
}
SnapMode = SNAP_MODE_Straight;
}
return true;
}
~DrawSketchHandlerSlot() override = default;
private:
void updateDataAndDrawToPosition(Base::Vector2d onSketchPos) override
{
switch (state()) {
case SelectMode::SeekFirst: {
startPoint = onSketchPos;
if (seekAutoConstraint(sugConstraints[0], onSketchPos, Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(sugConstraints[0]);
return;
}
} break;
case SelectMode::SeekSecond: {
secondPoint = onSketchPos;
angle = GetPointAngle(startPoint, secondPoint);
checkHorizontalVertical();
length = (secondPoint - startPoint).Length();
radius = length / 5; // radius chosen at 1/5 of length
CreateAndDrawShapeGeometry();
if ((isHorizontal || isVertical)
&& seekAutoConstraint(sugConstraints[1],
onSketchPos,
secondPoint - startPoint,
AutoConstraint::VERTEX_NO_TANGENCY)) {
renderSuggestConstraintsCursor(sugConstraints[1]);
return;
}
else if (seekAutoConstraint(sugConstraints[1],
onSketchPos,
Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(sugConstraints[1]);
return;
}
} break;
case SelectMode::SeekThird: {
/*To follow the cursor, r should adapt depending on the position of the cursor. If
cursor is 'between' the center points, then its distance to that line and not
distance to the second center. A is "between" B and C if angle ?ABC and angle ?ACB
are both less than or equal to ninety degrees. An angle ?ABC is greater than ninety
degrees iff AB^2 + BC^2 < AC^2.*/
double L1 = (onSketchPos - startPoint)
.Length(); // distance between first center and onSketchPos
double L2 = (onSketchPos - secondPoint)
.Length(); // distance between second center and onSketchPos
if ((L1 * L1 + length * length > L2 * L2)
&& (L2 * L2 + length * length > L1 * L1)) {
// distance of onSketchPos to the line StartPos-SecondPos
radius = (abs((secondPoint.y - startPoint.y) * onSketchPos.x
- (secondPoint.x - startPoint.x) * onSketchPos.y
+ secondPoint.x * startPoint.y - secondPoint.y * startPoint.x))
/ length;
}
else {
radius = std::min(L1, L2);
}
CreateAndDrawShapeGeometry();
} break;
default:
break;
}
}
void executeCommands() override
{
firstCurve = getHighestCurveIndex() + 1;
try {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add slot"));
createShape(false);
commandAddShapeGeometryAndConstraints();
Gui::Command::commitCommand();
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add slot"));
Gui::Command::abortCommand();
THROWM(Base::RuntimeError,
QT_TRANSLATE_NOOP(
"Notifications",
"Tool execution aborted") "\n") // This prevents constraints from being
// applied on non existing geometry
}
}
void generateAutoConstraints() override
{
bool isHorizontalVertical = isHorizontal || isVertical;
// add auto constraints for the center of 1st arc
generateAutoConstraintsOnElement(sugConstraints[0],
getHighestCurveIndex() - 3,
Sketcher::PointPos::mid);
generateAutoConstraintsOnElement(
sugConstraints[1],
isHorizontalVertical ? getHighestCurveIndex() : getHighestCurveIndex() - 2,
isHorizontalVertical ? Sketcher::PointPos::none : Sketcher::PointPos::mid);
// Ensure temporary autoconstraints do not generate a redundancy and that the geometry
// parameters are accurate This is particularly important for adding widget mandated
// constraints.
removeRedundantAutoConstraints();
}
void createAutoConstraints() override
{
// execute python command to create autoconstraints
createGeneratedAutoConstraints(true);
sugConstraints[0].clear();
sugConstraints[1].clear();
isHorizontal = false;
isVertical = false;
}
std::string getToolName() const override
{
return "DSH_Slot";
}
QString getCrosshairCursorSVGName() const override
{
return QString::fromLatin1("Sketcher_Pointer_Slot");
}
protected:
BoxMode Mode;
SNAP_MODE SnapMode;
SNAP_DIR SnapDir;
Base::Vector2d StartPos;
double dx, dy, r;
std::vector<Base::Vector2d> EditCurve;
std::vector<AutoConstraint> sugConstr1, sugConstr2;
std::unique_ptr<QWidget> createWidget() const override
{
return std::make_unique<SketcherToolDefaultWidget>();
}
bool canGoToNextMode() override
{
if (state() == SelectMode::SeekSecond && length < Precision::Confusion()) {
// Prevent validation of null slot.
return false;
}
if (state() == SelectMode::SeekThird
&& (length < Precision::Confusion() || radius < Precision::Confusion())) {
// Prevent validation of null slot.
return false;
}
return true;
}
void angleSnappingControl() override
{
if (state() == SelectMode::SeekSecond) {
setAngleSnapping(true, startPoint);
}
else {
setAngleSnapping(false);
}
}
void createShape(bool onlyeditoutline) override
{
ShapeGeometry.clear();
if (length < Precision::Confusion() || radius < Precision::Confusion()) {
return;
}
auto arc1 = std::make_unique<Part::GeomArcOfCircle>();
arc1->setRadius(radius);
arc1->setRange(M_PI / 2 + angle, 1.5 * M_PI + angle, true);
arc1->setCenter(toVector3d(startPoint));
Sketcher::GeometryFacade::setConstruction(arc1.get(), isConstructionMode());
auto arc2 = std::make_unique<Part::GeomArcOfCircle>();
arc2->setRadius(radius);
arc2->setRange(1.5 * M_PI + angle, M_PI / 2 + angle, true);
arc2->setCenter(toVector3d(secondPoint));
Sketcher::GeometryFacade::setConstruction(arc2.get(), isConstructionMode());
Base::Vector3d p11 = arc1->getStartPoint();
Base::Vector3d p12 = arc1->getEndPoint();
Base::Vector3d p21 = arc2->getStartPoint();
Base::Vector3d p22 = arc2->getEndPoint();
ShapeGeometry.push_back(std::move(arc1));
ShapeGeometry.push_back(std::move(arc2));
addLineToShapeGeometry(p11, p22, isConstructionMode());
addLineToShapeGeometry(p12, p21, isConstructionMode());
if (!onlyeditoutline) {
addToShapeConstraints(Sketcher::Tangent,
firstCurve,
Sketcher::PointPos::start,
firstCurve + 2,
Sketcher::PointPos::start);
addToShapeConstraints(Sketcher::Tangent,
firstCurve,
Sketcher::PointPos::end,
firstCurve + 3,
Sketcher::PointPos::start);
addToShapeConstraints(Sketcher::Tangent,
firstCurve + 1,
Sketcher::PointPos::end,
firstCurve + 2,
Sketcher::PointPos::end);
addToShapeConstraints(Sketcher::Tangent,
firstCurve + 1,
Sketcher::PointPos::start,
firstCurve + 3,
Sketcher::PointPos::end);
addToShapeConstraints(Sketcher::Equal,
firstCurve,
Sketcher::PointPos::none,
firstCurve + 1);
}
}
void checkHorizontalVertical()
{
if (fmod(angle, M_PI) < Precision::Confusion()) {
isHorizontal = true;
isVertical = false;
}
else if (fmod(angle + M_PI / 2, M_PI) < Precision::Confusion()) {
isHorizontal = false;
isVertical = true;
}
}
private:
Base::Vector2d startPoint, secondPoint;
double radius, length, angle;
bool isHorizontal, isVertical;
int firstCurve;
};
template<>
auto DSHSlotControllerBase::getState(int labelindex) const
{
switch (labelindex) {
case OnViewParameter::First:
case OnViewParameter::Second:
return SelectMode::SeekFirst;
break;
case OnViewParameter::Third:
case OnViewParameter::Fourth:
return SelectMode::SeekSecond;
break;
case OnViewParameter::Fifth:
return SelectMode::SeekThird;
break;
default:
THROWM(Base::ValueError, "OnViewParameter index without an associated machine state")
}
}
template<>
void DSHSlotController::configureToolWidget()
{
onViewParameters[OnViewParameter::First]->setLabelType(Gui::SoDatumLabel::DISTANCEX);
onViewParameters[OnViewParameter::Second]->setLabelType(Gui::SoDatumLabel::DISTANCEY);
onViewParameters[OnViewParameter::Third]->setLabelType(
Gui::SoDatumLabel::DISTANCE,
Gui::EditableDatumLabel::Function::Dimensioning);
onViewParameters[OnViewParameter::Fourth]->setLabelType(
Gui::SoDatumLabel::ANGLE,
Gui::EditableDatumLabel::Function::Dimensioning);
onViewParameters[OnViewParameter::Fifth]->setLabelType(
Gui::SoDatumLabel::RADIUS,
Gui::EditableDatumLabel::Function::Dimensioning);
}
template<>
void DSHSlotControllerBase::doEnforceControlParameters(Base::Vector2d& onSketchPos)
{
switch (handler->state()) {
case SelectMode::SeekFirst: {
if (onViewParameters[OnViewParameter::First]->isSet) {
onSketchPos.x = onViewParameters[OnViewParameter::First]->getValue();
}
if (onViewParameters[OnViewParameter::Second]->isSet) {
onSketchPos.y = onViewParameters[OnViewParameter::Second]->getValue();
}
} break;
case SelectMode::SeekSecond: {
Base::Vector2d dir = onSketchPos - handler->startPoint;
if (dir.Length() < Precision::Confusion()) {
dir.x = 1.0; // if direction null, default to (1,0)
}
double length = dir.Length();
if (onViewParameters[OnViewParameter::Third]->isSet) {
length = onViewParameters[OnViewParameter::Third]->getValue();
if (length < Precision::Confusion()) {
unsetOnViewParameter(onViewParameters[OnViewParameter::Third].get());
return;
}
onSketchPos = handler->startPoint + length * dir.Normalize();
}
if (onViewParameters[OnViewParameter::Fourth]->isSet) {
double angle = onViewParameters[OnViewParameter::Fourth]->getValue() * M_PI / 180;
onSketchPos.x = handler->startPoint.x + cos(angle) * length;
onSketchPos.y = handler->startPoint.y + sin(angle) * length;
}
} break;
case SelectMode::SeekThird: {
if (onViewParameters[OnViewParameter::Fifth]->isSet) {
double radius = onViewParameters[OnViewParameter::Fifth]->getValue();
if (radius < Precision::Confusion()) {
unsetOnViewParameter(onViewParameters[OnViewParameter::Fifth].get());
return;
}
onSketchPos.x = handler->secondPoint.x + cos(handler->angle) * radius;
onSketchPos.y = handler->secondPoint.y + sin(handler->angle) * radius;
}
} break;
default:
break;
}
}
template<>
void DSHSlotController::adaptParameters(Base::Vector2d onSketchPos)
{
switch (handler->state()) {
case SelectMode::SeekFirst: {
if (!onViewParameters[OnViewParameter::First]->isSet) {
setOnViewParameterValue(OnViewParameter::First, onSketchPos.x);
}
if (!onViewParameters[OnViewParameter::Second]->isSet) {
setOnViewParameterValue(OnViewParameter::Second, onSketchPos.y);
}
bool sameSign = onSketchPos.x * onSketchPos.y > 0.;
onViewParameters[OnViewParameter::First]->setLabelAutoDistanceReverse(!sameSign);
onViewParameters[OnViewParameter::Second]->setLabelAutoDistanceReverse(sameSign);
onViewParameters[OnViewParameter::First]->setPoints(Base::Vector3d(),
toVector3d(onSketchPos));
onViewParameters[OnViewParameter::Second]->setPoints(Base::Vector3d(),
toVector3d(onSketchPos));
} break;
case SelectMode::SeekSecond: {
Base::Vector3d start = toVector3d(handler->startPoint);
Base::Vector3d end = toVector3d(handler->secondPoint);
Base::Vector3d vec = end - start;
if (!onViewParameters[OnViewParameter::Third]->isSet) {
onViewParameters[OnViewParameter::Third]->setSpinboxValue(vec.Length());
}
double range = (handler->secondPoint - handler->startPoint).Angle();
if (!onViewParameters[OnViewParameter::Fourth]->isSet) {
onViewParameters[OnViewParameter::Fourth]->setSpinboxValue(range * 180 / M_PI,
Base::Unit::Angle);
}
onViewParameters[OnViewParameter::Third]->setPoints(start, end);
onViewParameters[OnViewParameter::Fourth]->setPoints(start, Base::Vector3d());
onViewParameters[OnViewParameter::Fourth]->setLabelRange(range);
} break;
case SelectMode::SeekThird: {
if (!onViewParameters[OnViewParameter::Fifth]->isSet) {
setOnViewParameterValue(OnViewParameter::Fifth, handler->radius);
}
Base::Vector3d labelSecondPoint = Base::Vector3d();
labelSecondPoint.x = handler->secondPoint.x + cos(handler->angle) * handler->radius;
labelSecondPoint.y = handler->secondPoint.y + sin(handler->angle) * handler->radius;
onViewParameters[OnViewParameter::Fifth]->setPoints(toVector3d(handler->secondPoint),
labelSecondPoint);
} break;
default:
break;
}
}
template<>
void DSHSlotController::doChangeDrawSketchHandlerMode()
{
switch (handler->state()) {
case SelectMode::SeekFirst: {
if (onViewParameters[OnViewParameter::First]->isSet
&& onViewParameters[OnViewParameter::Second]->isSet) {
handler->setState(SelectMode::SeekSecond);
}
} break;
case SelectMode::SeekSecond: {
if (onViewParameters[OnViewParameter::Third]->isSet
&& onViewParameters[OnViewParameter::Fourth]->isSet) {
handler->setState(SelectMode::SeekThird);
}
} break;
case SelectMode::SeekThird: {
if (onViewParameters[OnViewParameter::Fifth]->isSet) {
handler->setState(SelectMode::End);
}
} break;
default:
break;
}
}
template<>
void DSHSlotController::addConstraints()
{
App::DocumentObject* obj = handler->sketchgui->getObject();
int firstCurve = handler->getHighestCurveIndex() - 3;
auto x0 = onViewParameters[OnViewParameter::First]->getValue();
auto y0 = onViewParameters[OnViewParameter::Second]->getValue();
auto x0set = onViewParameters[OnViewParameter::First]->isSet;
auto y0set = onViewParameters[OnViewParameter::Second]->isSet;
auto lengthSet = onViewParameters[OnViewParameter::Third]->isSet;
auto angleSet = onViewParameters[OnViewParameter::Fourth]->isSet;
auto radiusSet = onViewParameters[OnViewParameter::Fifth]->isSet;
using namespace Sketcher;
if (x0set && y0set && x0 == 0. && y0 == 0.) {
ConstraintToAttachment(GeoElementId(firstCurve, PointPos::mid),
GeoElementId::RtPnt,
x0,
handler->sketchgui->getObject());
}
else {
if (x0set) {
ConstraintToAttachment(GeoElementId(firstCurve, PointPos::mid),
GeoElementId::VAxis,
x0,
handler->sketchgui->getObject());
}
if (y0set) {
ConstraintToAttachment(GeoElementId(firstCurve, PointPos::mid),
GeoElementId::HAxis,
y0,
handler->sketchgui->getObject());
}
}
if (lengthSet) {
Gui::cmdAppObjectArgs(obj,
"addConstraint(Sketcher.Constraint('Distance',%d,%d,%d,%d,%f)) ",
firstCurve,
3,
firstCurve + 1,
3,
handler->length);
}
if (angleSet) {
handler->checkHorizontalVertical();
if (handler->isHorizontal) {
Gui::cmdAppObjectArgs(obj,
"addConstraint(Sketcher.Constraint('Horizontal',%d)) ",
firstCurve + 2);
}
else if (handler->isVertical) {
Gui::cmdAppObjectArgs(obj,
"addConstraint(Sketcher.Constraint('Vertical',%d)) ",
firstCurve + 2);
}
else {
Gui::cmdAppObjectArgs(obj,
"addConstraint(Sketcher.Constraint('Angle',%d,%d,%f)) ",
Sketcher::GeoEnum::HAxis,
firstCurve + 2,
handler->angle);
}
}
if (radiusSet) {
Gui::cmdAppObjectArgs(obj,
"addConstraint(Sketcher.Constraint('Radius',%d,%f)) ",
firstCurve,
handler->radius);
}
}
} // namespace SketcherGui