From ce7a3ecaa2bd92138965a298e7bb0d97585281e3 Mon Sep 17 00:00:00 2001 From: wmayer Date: Sat, 29 Mar 2014 12:03:17 +0100 Subject: [PATCH] + fixes #0001490: Implement a perimeter circle (3 point circle) similar to solidworks in sketcher (mdinger) --- src/Mod/Complete/Gui/Workbench.cpp | 3 +- src/Mod/PartDesign/Gui/Workbench.cpp | 3 +- src/Mod/Sketcher/Gui/CommandCreateGeo.cpp | 301 +++++++++++++++++ src/Mod/Sketcher/Gui/Resources/Makefile.am | 1 + src/Mod/Sketcher/Gui/Resources/Sketcher.qrc | 1 + .../icons/Sketcher_Create3PointCircle.svg | 305 ++++++++++++++++++ src/Mod/Sketcher/Gui/ViewProviderSketch.cpp | 1 + src/Mod/Sketcher/Gui/Workbench.cpp | 3 +- 8 files changed, 615 insertions(+), 3 deletions(-) create mode 100644 src/Mod/Sketcher/Gui/Resources/icons/Sketcher_Create3PointCircle.svg diff --git a/src/Mod/Complete/Gui/Workbench.cpp b/src/Mod/Complete/Gui/Workbench.cpp index d08cd8b3a..3d7ce8438 100644 --- a/src/Mod/Complete/Gui/Workbench.cpp +++ b/src/Mod/Complete/Gui/Workbench.cpp @@ -243,6 +243,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const << "Sketcher_CreateArc" << "Sketcher_Create3PointArc" << "Sketcher_CreateCircle" + << "Sketcher_Create3PointCircle" << "Sketcher_CreateLine" << "Sketcher_CreatePolyline" << "Sketcher_CreateRectangle" @@ -504,7 +505,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const << "Separator" << "Sketcher_CreatePoint" << "Sketcher_CompCreateArc" - << "Sketcher_CreateCircle" + << "Sketcher_CompCreateCircle" << "Sketcher_CreateLine" << "Sketcher_CreatePolyline" << "Sketcher_CreateRectangle" diff --git a/src/Mod/PartDesign/Gui/Workbench.cpp b/src/Mod/PartDesign/Gui/Workbench.cpp index 17c7b295b..d1488d4e5 100644 --- a/src/Mod/PartDesign/Gui/Workbench.cpp +++ b/src/Mod/PartDesign/Gui/Workbench.cpp @@ -169,6 +169,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const << "Sketcher_CreateArc" << "Sketcher_Create3PointArc" << "Sketcher_CreateCircle" + << "Sketcher_Create3PointCircle" << "Sketcher_CreateLine" << "Sketcher_CreatePolyline" << "Sketcher_CreateRectangle" @@ -261,7 +262,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const geom->setCommand("Sketcher geometries"); *geom << "Sketcher_CreatePoint" << "Sketcher_CompCreateArc" - << "Sketcher_CreateCircle" + << "Sketcher_CompCreateCircle" << "Sketcher_CreateLine" << "Sketcher_CreatePolyline" << "Sketcher_CreateRectangle" diff --git a/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp b/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp index e349b1a1d..9dea50deb 100644 --- a/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp +++ b/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp @@ -1781,6 +1781,305 @@ bool CmdSketcherCreateCircle::isActive(void) } +// ====================================================================================== + +/* XPM */ +static const char *cursor_create3pointcircle[]={ +"32 32 3 1", +"+ c white", +"# c red", +". c None", +"......+.........................", +"......+.........................", +"......+.........................", +"......+.........................", +"......+.........................", +"................................", +"+++++...+++++...................", +"................................", +"......+........#######..........", +"......+......##.......##........", +"......+.....#...........#.......", +"......+....#.............#......", +"......+...#...............#.....", +".........#.................#....", +".......###.................###..", +".......#.#.................#.#..", +".......###.................###..", +".......#.....................#..", +".......#.........###.........#..", +".......#.........#.#.........#..", +".......#.........###.........#..", +".......#.....................#..", +".......#.....................#..", +"........#...................#...", +"........#...................#...", +".........#.................#....", +"..........#...............#.....", +"...........#.............#......", +"............#...........#.......", +".............##..###..##........", +"...............###.###..........", +".................###............"}; + +class DrawSketchHandler3PointCircle : public DrawSketchHandler +{ +public: + DrawSketchHandler3PointCircle() + : Mode(STATUS_SEEK_First),EditCurve(2),N(32.0){} + virtual ~DrawSketchHandler3PointCircle(){} + /// mode table + enum SelectMode { + STATUS_SEEK_First, /**< enum value ----. */ + STATUS_SEEK_Second, /**< enum value ----. */ + STATUS_SEEK_Third, /**< enum value ----. */ + STATUS_End + }; + + virtual void activated(ViewProviderSketch *sketchgui) + { + setCursor(QPixmap(cursor_create3pointcircle),7,7); + } + + virtual void mouseMove(Base::Vector2D onSketchPos) + { + if (Mode == STATUS_SEEK_First) { + setPositionText(onSketchPos); + if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2D(0.f,0.f), + AutoConstraint::CURVE)) { + // Disable tangent snap on 1st point + if (sugConstr1.back().Type == Sketcher::Tangent) + sugConstr1.pop_back(); + else + renderSuggestConstraintsCursor(sugConstr1); + return; + } + } + else if (Mode == STATUS_SEEK_Second || Mode == STATUS_SEEK_Third) { + if (Mode == STATUS_SEEK_Second) + CenterPoint = EditCurve[N+1] = (onSketchPos - FirstPoint)/2 + FirstPoint; + else + CenterPoint = EditCurve[N+1] = GetCircleCenter(FirstPoint, SecondPoint, onSketchPos); + radius = (onSketchPos - CenterPoint).Length(); + double lineAngle = GetPointAngle(CenterPoint, onSketchPos); + + // Build a N point circle + for (int i=1; i < N; i++) { + // Start at current angle + double angle = i*2*M_PI/N + lineAngle; // N point closed circle has N segments + EditCurve[i] = Base::Vector2D(CenterPoint.fX + radius*cos(angle), + CenterPoint.fY + radius*sin(angle)); + } + // Beginning and end of curve should be exact + EditCurve[0] = EditCurve[N] = onSketchPos; + + // Display radius and start angle + // This lineAngle will report counter-clockwise from +X, not relatively + SbString text; + text.sprintf(" (%.1fR,%.1fdeg)", (float) radius, (float) lineAngle * 180 / M_PI); + setPositionText(onSketchPos, text); + + sketchgui->drawEdit(EditCurve); + if (Mode == STATUS_SEEK_Second) { + if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2D(0.f,0.f), + AutoConstraint::CURVE)) { + // Disable tangent snap on 2nd point + if (sugConstr2.back().Type == Sketcher::Tangent) + sugConstr2.pop_back(); + else + renderSuggestConstraintsCursor(sugConstr2); + return; + } + } + else { + if (seekAutoConstraint(sugConstr3, onSketchPos, Base::Vector2D(0.0,0.0), + AutoConstraint::CURVE)) { + renderSuggestConstraintsCursor(sugConstr3); + return; + } + } + } + applyCursor(); + } + + virtual bool pressButton(Base::Vector2D onSketchPos) + { + if (Mode == STATUS_SEEK_First) { + // N point curve + center + endpoint + EditCurve.resize(N+2); + FirstPoint = onSketchPos; + + Mode = STATUS_SEEK_Second; + } + else if (Mode == STATUS_SEEK_Second) { + SecondPoint = onSketchPos; + + Mode = STATUS_SEEK_Third; + } + else { + EditCurve.resize(N); + + sketchgui->drawEdit(EditCurve); + applyCursor(); + Mode = STATUS_End; + } + + return true; + } + + virtual bool releaseButton(Base::Vector2D onSketchPos) + { + // Need to look at. rx might need fixing. + if (Mode==STATUS_End) { + unsetCursor(); + resetPositionText(); + Gui::Command::openCommand("Add sketch circle"); + Gui::Command::doCommand(Gui::Command::Doc, + "App.ActiveDocument.%s.addGeometry(Part.Circle" + "(App.Vector(%f,%f,0),App.Vector(0,0,1),%f))", + sketchgui->getObject()->getNameInDocument(), + CenterPoint.fX, CenterPoint.fY, + radius); + + Gui::Command::commitCommand(); + Gui::Command::updateActive(); + + // Auto Constraint first picked point + if (sugConstr1.size() > 0) { + createAutoConstraints(sugConstr1, getHighestCurveIndex(), Sketcher::none); + sugConstr1.clear(); + } + + // Auto Constraint second picked point + if (sugConstr2.size() > 0) { + createAutoConstraints(sugConstr2, getHighestCurveIndex(), Sketcher::none); + sugConstr2.clear(); + } + + // Auto Constraint third picked point + if (sugConstr3.size() > 0) { + createAutoConstraints(sugConstr3, getHighestCurveIndex(), Sketcher::none); + sugConstr3.clear(); + } + + EditCurve.clear(); + sketchgui->drawEdit(EditCurve); + sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider + } + return true; + } +protected: + SelectMode Mode; + std::vector EditCurve; + Base::Vector2D CenterPoint, FirstPoint, SecondPoint; + double radius, N; // N should be even + std::vector sugConstr1, sugConstr2, sugConstr3; +}; + +DEF_STD_CMD_A(CmdSketcherCreate3PointCircle); + +CmdSketcherCreate3PointCircle::CmdSketcherCreate3PointCircle() + : Command("Sketcher_Create3PointCircle") +{ + sAppModule = "Sketcher"; + sGroup = QT_TR_NOOP("Sketcher"); + sMenuText = QT_TR_NOOP("Create circle by three points"); + sToolTipText = QT_TR_NOOP("Create a circle by 3 perimeter points"); + sWhatsThis = sToolTipText; + sStatusTip = sToolTipText; + sPixmap = "Sketcher_Create3PointCircle"; + eType = ForEdit; +} + +void CmdSketcherCreate3PointCircle::activated(int iMsg) +{ + ActivateHandler(getActiveGuiDocument(),new DrawSketchHandler3PointCircle() ); +} + +bool CmdSketcherCreate3PointCircle::isActive(void) +{ + return isCreateGeoActive(getActiveGuiDocument()); +} + + +DEF_STD_CMD_ACL(CmdSketcherCompCreateCircle); + +CmdSketcherCompCreateCircle::CmdSketcherCompCreateCircle() + : Command("Sketcher_CompCreateCircle") +{ + sAppModule = "Sketcher"; + sGroup = QT_TR_NOOP("Sketcher"); + sMenuText = QT_TR_NOOP("Create circle"); + sToolTipText = QT_TR_NOOP("Create a circle in the sketcher"); + sWhatsThis = sToolTipText; + sStatusTip = sToolTipText; + eType = ForEdit; +} + +void CmdSketcherCompCreateCircle::activated(int iMsg) +{ + if (iMsg==0) + ActivateHandler(getActiveGuiDocument(),new DrawSketchHandlerCircle()); + else if (iMsg==1) + ActivateHandler(getActiveGuiDocument(),new DrawSketchHandler3PointCircle()); + else + return; + + // Since the default icon is reset when enabing/disabling the command we have + // to explicitly set the icon of the used command. + Gui::ActionGroup* pcAction = qobject_cast(_pcAction); + QList a = pcAction->actions(); + + assert(iMsg < a.size()); + pcAction->setIcon(a[iMsg]->icon()); +} + +Gui::Action * CmdSketcherCompCreateCircle::createAction(void) +{ + Gui::ActionGroup* pcAction = new Gui::ActionGroup(this, Gui::getMainWindow()); + pcAction->setDropDownMenu(true); + applyCommandData(pcAction); + + QAction* arc1 = pcAction->addAction(QString()); + arc1->setIcon(Gui::BitmapFactory().pixmapFromSvg("Sketcher_CreateCircle", QSize(24,24))); + QAction* arc2 = pcAction->addAction(QString()); + arc2->setIcon(Gui::BitmapFactory().pixmapFromSvg("Sketcher_Create3PointCircle", QSize(24,24))); + + _pcAction = pcAction; + languageChange(); + + pcAction->setIcon(arc1->icon()); + int defaultId = 0; + pcAction->setProperty("defaultAction", QVariant(defaultId)); + + return pcAction; +} + +void CmdSketcherCompCreateCircle::languageChange() +{ + Command::languageChange(); + + if (!_pcAction) + return; + Gui::ActionGroup* pcAction = qobject_cast(_pcAction); + QList a = pcAction->actions(); + + QAction* arc1 = a[0]; + arc1->setText(QApplication::translate("CmdSketcherCompCreateCircle", "Center and rim point")); + arc1->setToolTip(QApplication::translate("Sketcher_CreateCircle", "Create a circle by its center and by a rim point")); + arc1->setStatusTip(QApplication::translate("Sketcher_CreateCircle", "Create a circle by its center and by a rim point")); + QAction* arc2 = a[1]; + arc2->setText(QApplication::translate("CmdSketcherCompCreateCircle", "3 rim points")); + arc2->setToolTip(QApplication::translate("Sketcher_Create3PointCircle", "Create a circle by 3 rim points")); + arc2->setStatusTip(QApplication::translate("Sketcher_Create3PointCircle", "Create a circle by 3 rim points")); +} + +bool CmdSketcherCompCreateCircle::isActive(void) +{ + return isCreateGeoActive(getActiveGuiDocument()); +} + + // ====================================================================================== /* XPM */ @@ -2543,6 +2842,8 @@ void CreateSketcherCommandsCreateGeo(void) rcCmdMgr.addCommand(new CmdSketcherCreate3PointArc()); rcCmdMgr.addCommand(new CmdSketcherCompCreateArc()); rcCmdMgr.addCommand(new CmdSketcherCreateCircle()); + rcCmdMgr.addCommand(new CmdSketcherCreate3PointCircle()); + rcCmdMgr.addCommand(new CmdSketcherCompCreateCircle()); rcCmdMgr.addCommand(new CmdSketcherCreateLine()); rcCmdMgr.addCommand(new CmdSketcherCreatePolyline()); rcCmdMgr.addCommand(new CmdSketcherCreateRectangle()); diff --git a/src/Mod/Sketcher/Gui/Resources/Makefile.am b/src/Mod/Sketcher/Gui/Resources/Makefile.am index 2bb55a36f..b5db31a24 100644 --- a/src/Mod/Sketcher/Gui/Resources/Makefile.am +++ b/src/Mod/Sketcher/Gui/Resources/Makefile.am @@ -63,6 +63,7 @@ icons/Constraint_PointOnObject.svg \ icons/Sketcher_CreateArc.svg \ icons/Sketcher_Create3PointArc.svg \ icons/Sketcher_CreateCircle.svg \ + icons/Sketcher_Create3PointCircle.svg \ icons/Sketcher_CreateLine.svg \ icons/Sketcher_CreatePoint.svg \ icons/Sketcher_CreatePolyline.svg \ diff --git a/src/Mod/Sketcher/Gui/Resources/Sketcher.qrc b/src/Mod/Sketcher/Gui/Resources/Sketcher.qrc index 391f5d02e..ce2e844fd 100644 --- a/src/Mod/Sketcher/Gui/Resources/Sketcher.qrc +++ b/src/Mod/Sketcher/Gui/Resources/Sketcher.qrc @@ -53,6 +53,7 @@ icons/Sketcher_CreateArc.svg icons/Sketcher_Create3PointArc.svg icons/Sketcher_CreateCircle.svg + icons/Sketcher_Create3PointCircle.svg icons/Sketcher_CreateLine.svg icons/Sketcher_CreatePoint.svg icons/Sketcher_CreatePolyline.svg diff --git a/src/Mod/Sketcher/Gui/Resources/icons/Sketcher_Create3PointCircle.svg b/src/Mod/Sketcher/Gui/Resources/icons/Sketcher_Create3PointCircle.svg new file mode 100644 index 000000000..e07fdab34 --- /dev/null +++ b/src/Mod/Sketcher/Gui/Resources/icons/Sketcher_Create3PointCircle.svg @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp index c2cf2fc19..27280d6c4 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp @@ -760,6 +760,7 @@ bool ViewProviderSketch::mouseButtonPressed(int Button, bool pressed, const SbVe << "Sketcher_CreateArc" << "Sketcher_Create3PointArc" << "Sketcher_CreateCircle" + << "Sketcher_Create3PointCircle" << "Sketcher_CreateLine" << "Sketcher_CreatePolyline" << "Sketcher_CreateRectangle" diff --git a/src/Mod/Sketcher/Gui/Workbench.cpp b/src/Mod/Sketcher/Gui/Workbench.cpp index 933d643bf..34374fbf4 100644 --- a/src/Mod/Sketcher/Gui/Workbench.cpp +++ b/src/Mod/Sketcher/Gui/Workbench.cpp @@ -64,6 +64,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const << "Sketcher_CreateArc" << "Sketcher_Create3PointArc" << "Sketcher_CreateCircle" + << "Sketcher_Create3PointCircle" << "Sketcher_CreateLine" << "Sketcher_CreatePolyline" << "Sketcher_CreateRectangle" @@ -123,7 +124,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const geom->setCommand("Sketcher geometries"); *geom << "Sketcher_CreatePoint" << "Sketcher_CompCreateArc" - << "Sketcher_CreateCircle" + << "Sketcher_CompCreateCircle" << "Sketcher_CreateLine" << "Sketcher_CreatePolyline" << "Sketcher_CreateRectangle"