[sketch] rework the slot command
In practical work it turned out that the slot command is not as convenient as it should because one cannot snap to a proper endpoint and one is restricted to work perpendicular to the sketch axes
This PR fixes this by setting the second snap point to the center of the second arc and removing the perpendicularity.
Benefits:
when you want to get the slot at a line, edge or sketch axis, set the two center points accordingly. The line does not have to be parallel to one of the sketch axes
when you want to define the slot using 2 points in the sketch you can do this now
This commit is contained in:
committed by
abdullahtahiriyo
parent
d58940756e
commit
582317a405
@@ -6979,16 +6979,16 @@ namespace SketcherGui {
|
||||
/**
|
||||
* Create Slot
|
||||
*/
|
||||
class DrawSketchHandlerSlot: public DrawSketchHandler
|
||||
class DrawSketchHandlerSlot : public DrawSketchHandler
|
||||
{
|
||||
public:
|
||||
DrawSketchHandlerSlot()
|
||||
: Mode(STATUS_SEEK_First)
|
||||
, lx(0), ly(0), r(0), a(0)
|
||||
, EditCurve(36)
|
||||
: Mode(STATUS_SEEK_First)
|
||||
, dx(0), dy(0), r(0)
|
||||
, EditCurve(35)
|
||||
{
|
||||
}
|
||||
virtual ~DrawSketchHandlerSlot(){}
|
||||
virtual ~DrawSketchHandlerSlot() {}
|
||||
/// mode table
|
||||
enum BoxMode {
|
||||
STATUS_SEEK_First, /**< enum value ----. */
|
||||
@@ -6996,7 +6996,7 @@ public:
|
||||
STATUS_End
|
||||
};
|
||||
|
||||
virtual void activated(ViewProviderSketch *)
|
||||
virtual void activated(ViewProviderSketch*)
|
||||
{
|
||||
setCrosshairCursor("Sketcher_Pointer_Slot");
|
||||
}
|
||||
@@ -7004,48 +7004,57 @@ public:
|
||||
virtual void mouseMove(Base::Vector2d onSketchPos)
|
||||
{
|
||||
|
||||
if (Mode==STATUS_SEEK_First) {
|
||||
if (Mode == STATUS_SEEK_First) {
|
||||
setPositionText(onSketchPos);
|
||||
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f,0.f))) {
|
||||
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f, 0.f))) {
|
||||
renderSuggestConstraintsCursor(sugConstr1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (Mode==STATUS_SEEK_Second) {
|
||||
float dx = onSketchPos.x - StartPos.x;
|
||||
float dy = onSketchPos.y - StartPos.y;
|
||||
else if (Mode == STATUS_SEEK_Second) {
|
||||
dx = onSketchPos.x - StartPos.x;
|
||||
dy = onSketchPos.y - StartPos.y;
|
||||
|
||||
lx = 0; ly = 0; a = 0;
|
||||
double a = 0;
|
||||
double rev = 0;
|
||||
if (fabs(dx) > fabs(dy)) {
|
||||
lx = dx;
|
||||
r = dy;
|
||||
r = fabs(dx) / 4;
|
||||
rev = Base::sgn(dx);
|
||||
}
|
||||
else {
|
||||
ly = dy;
|
||||
r = dx;
|
||||
r = fabs(dy) / 4;
|
||||
a = 8;
|
||||
rev = Base::sgn(dy);
|
||||
}
|
||||
|
||||
// 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 = -fabs(r) * rev * sin(angle);
|
||||
double ry = fabs(r) * rev * cos(angle);
|
||||
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[18 + i] = Base::Vector2d(StartPos.x - rx + lx, StartPos.y - ry + ly);
|
||||
EditCurve[17 + i] = Base::Vector2d(StartPos.x + dx - rx, StartPos.y + dy - ry);
|
||||
}
|
||||
EditCurve[17] = EditCurve[16] + Base::Vector2d(lx,ly);
|
||||
EditCurve[35] = EditCurve[0] ;
|
||||
EditCurve[34] = EditCurve[0];
|
||||
|
||||
SbString text;
|
||||
text.sprintf(" (%.1fR %.1fL)", r,lx);
|
||||
text.sprintf(" (%.1fR %.1fL)", r, sqrt(dx * dx + dy * dy));
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f,0.f),
|
||||
AutoConstraint::CURVE)) {
|
||||
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f, 0.f))) {
|
||||
renderSuggestConstraintsCursor(sugConstr2);
|
||||
return;
|
||||
}
|
||||
@@ -7055,7 +7064,7 @@ public:
|
||||
|
||||
virtual bool pressButton(Base::Vector2d onSketchPos)
|
||||
{
|
||||
if (Mode==STATUS_SEEK_First){
|
||||
if (Mode == STATUS_SEEK_First) {
|
||||
StartPos = onSketchPos;
|
||||
Mode = STATUS_SEEK_Second;
|
||||
}
|
||||
@@ -7068,25 +7077,33 @@ public:
|
||||
virtual bool releaseButton(Base::Vector2d onSketchPos)
|
||||
{
|
||||
Q_UNUSED(onSketchPos);
|
||||
if (Mode==STATUS_End){
|
||||
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(lx) > fabs(ly)) {
|
||||
start = M_PI / 2;
|
||||
end = -M_PI / 2;
|
||||
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 {
|
||||
start = 0;
|
||||
end = M_PI;
|
||||
}
|
||||
if (ly > 0 || lx < 0) {
|
||||
double temp = start;
|
||||
start = end;
|
||||
end = temp;
|
||||
if (dy > 0) {
|
||||
start = -M_PI;
|
||||
end = 0;
|
||||
}
|
||||
else {
|
||||
start = 0;
|
||||
end = -M_PI;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -7094,67 +7111,65 @@ public:
|
||||
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.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, 1, %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, 2))\n"
|
||||
"conList.append(Sketcher.Constraint('%s', %i))\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.addConstraint(conList)\n",
|
||||
StartPos.x, StartPos.y, // center of the arc1
|
||||
fabs(r), // radius arc1
|
||||
start, end, // start and end angle of arc1
|
||||
StartPos.x + lx, StartPos.y + ly, // center of the arc2
|
||||
fabs(r), // radius arc2
|
||||
end, start, // start and end angle of arc2
|
||||
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[0].x, EditCurve[0].y, EditCurve[34].x, EditCurve[34].y, // line2
|
||||
EditCurve[33].x, EditCurve[33].y, EditCurve[34].x, EditCurve[34].y, // line2
|
||||
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str(), // the sketch
|
||||
geometryCreationMode == Construction ? "True" : "False", // geometry as construction or not
|
||||
firstCurve, firstCurve + 3, // tangent1
|
||||
firstCurve, firstCurve + 2, // tangent2
|
||||
firstCurve + 2, firstCurve + 1, // tangent3
|
||||
firstCurve + 3, firstCurve + 1, // tangent4
|
||||
(fabs(lx) > fabs(ly)) ? "Horizontal" : "Vertical", firstCurve + 2, // vertical or horizontal constraint
|
||||
firstCurve, firstCurve + 1, // equal constraint
|
||||
firstCurve, firstCurve + 2, // tangent1
|
||||
firstCurve + 2, firstCurve + 1, // tangent2
|
||||
firstCurve + 1, firstCurve + 3, // tangent3
|
||||
firstCurve + 3, firstCurve, // tangent4
|
||||
firstCurve, firstCurve + 1, // equal constraint
|
||||
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str()); // the sketch
|
||||
|
||||
Gui::Command::commitCommand();
|
||||
|
||||
// add auto constraints at the start of the first side
|
||||
// add auto constraints at the center of the first arc
|
||||
if (sugConstr1.size() > 0) {
|
||||
createAutoConstraints(sugConstr1, getHighestCurveIndex() - 3 , Sketcher::mid);
|
||||
createAutoConstraints(sugConstr1, getHighestCurveIndex() - 3, Sketcher::mid);
|
||||
sugConstr1.clear();
|
||||
}
|
||||
|
||||
// add auto constraints at the end of the second side
|
||||
// add auto constraints at the center of the second arc
|
||||
if (sugConstr2.size() > 0) {
|
||||
createAutoConstraints(sugConstr2, getHighestCurveIndex() - 2, Sketcher::end);
|
||||
createAutoConstraints(sugConstr2, getHighestCurveIndex() - 2, Sketcher::mid);
|
||||
sugConstr2.clear();
|
||||
}
|
||||
|
||||
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
|
||||
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
Base::Console().Error("Failed to add slot: %s\n", e.what());
|
||||
Gui::Command::abortCommand();
|
||||
|
||||
tryAutoRecompute(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
|
||||
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);
|
||||
bool continuousMode = hGrp->GetBool("ContinuousCreationMode", true);
|
||||
|
||||
if (continuousMode) {
|
||||
// This code enables the continuous creation mode.
|
||||
Mode = STATUS_SEEK_First;
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
EditCurve.resize(36);
|
||||
EditCurve.resize(35);
|
||||
applyCursor();
|
||||
/* this is ok not to call to purgeHandler
|
||||
* in continuous creation mode because the
|
||||
@@ -7170,7 +7185,7 @@ public:
|
||||
protected:
|
||||
BoxMode Mode;
|
||||
Base::Vector2d StartPos;
|
||||
double lx, ly, r, a;
|
||||
double dx, dy, r;
|
||||
std::vector<Base::Vector2d> EditCurve;
|
||||
std::vector<AutoConstraint> sugConstr1, sugConstr2;
|
||||
};
|
||||
@@ -7178,17 +7193,17 @@ protected:
|
||||
DEF_STD_CMD_AU(CmdSketcherCreateSlot)
|
||||
|
||||
CmdSketcherCreateSlot::CmdSketcherCreateSlot()
|
||||
: Command("Sketcher_CreateSlot")
|
||||
: Command("Sketcher_CreateSlot")
|
||||
{
|
||||
sAppModule = "Sketcher";
|
||||
sGroup = QT_TR_NOOP("Sketcher");
|
||||
sMenuText = QT_TR_NOOP("Create slot");
|
||||
sToolTipText = QT_TR_NOOP("Create a slot in the sketch");
|
||||
sWhatsThis = "Sketcher_CreateSlot";
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "Sketcher_CreateSlot";
|
||||
sAccel = "";
|
||||
eType = ForEdit;
|
||||
sAppModule = "Sketcher";
|
||||
sGroup = QT_TR_NOOP("Sketcher");
|
||||
sMenuText = QT_TR_NOOP("Create slot");
|
||||
sToolTipText = QT_TR_NOOP("Create a slot in the sketch");
|
||||
sWhatsThis = "Sketcher_CreateSlot";
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "Sketcher_CreateSlot";
|
||||
sAccel = "";
|
||||
eType = ForEdit;
|
||||
}
|
||||
|
||||
void CmdSketcherCreateSlot::activated(int iMsg)
|
||||
|
||||
Reference in New Issue
Block a user