diff --git a/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp b/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp index 37f77b9ea8..f096f4aa06 100644 --- a/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp +++ b/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp @@ -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(sketchgui->getObject())); + tryAutoRecomputeIfNotSolve(static_cast(sketchgui->getObject())); } catch (const Base::Exception& e) { Base::Console().Error("Failed to add slot: %s\n", e.what()); Gui::Command::abortCommand(); - tryAutoRecompute(static_cast(sketchgui->getObject())); + tryAutoRecompute(static_cast(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 EditCurve; std::vector 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)