Download src/Mod/TechDraw/Gui/CommandExtensionPack.cpp from AbdulElahGwaith/FreeCAD: direct link, hf CLI and curl.
- Browser
- Download file 96.5 kB
-
https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/TechDraw/Gui/CommandExtensionPack.cpp
- Command line
-
hf download hf://AbdulElahGwaith/FreeCAD/src/Mod/TechDraw/Gui/CommandExtensionPack.cpp
-
curl -L -o CommandExtensionPack.cpp https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/TechDraw/Gui/CommandExtensionPack.cpp
96.5 kB
| /*************************************************************************** | |
| * Copyright (c) 2021 edi * | |
| * * | |
| * This file is part of the FreeCAD CAx development system. * | |
| * * | |
| * This library is free software; you can redistribute it and/or * | |
| * modify it under the terms of the GNU Library General Public * | |
| * License as published by the Free Software Foundation; either * | |
| * version 2 of the License, or (at your option) any later version. * | |
| * * | |
| * This library is distributed in the hope that it will be useful, * | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
| * GNU Library General Public License for more details. * | |
| * * | |
| * You should have received a copy of the GNU Library General Public * | |
| * License along with this library; see the file COPYING.LIB. If not, * | |
| * write to the Free Software Foundation, Inc., 59 Temple Place, * | |
| * Suite 330, Boston, MA 02111-1307, USA * | |
| * * | |
| ***************************************************************************/ | |
| using namespace TechDrawGui; | |
| using namespace TechDraw; | |
| using DU = DrawUtil; | |
| namespace TechDrawGui | |
| { | |
| //TechDraw::LineFormat activeAttributes; // container holding global line attributes | |
| //internal helper functions | |
| TechDraw::LineFormat& _getActiveLineAttributes(); | |
| Base::Vector3d _circleCenter(Base::Vector3d p1, Base::Vector3d p2, Base::Vector3d p3); | |
| void _createThreadCircle(const std::string Name, TechDraw::DrawViewPart* objFeat, double factor); | |
| void _createThreadLines(const std::vector<std::string>& SubNames, TechDraw::DrawViewPart* objFeat, | |
| double factor); | |
| void _setLineAttributes(TechDraw::CosmeticEdge* cosEdge); | |
| void _setLineAttributes(TechDraw::CenterLine* cosEdge); | |
| void _setLineAttributes(TechDraw::CosmeticEdge* cosEdge, int style, float weight, Base::Color color); | |
| void _setLineAttributes(TechDraw::CenterLine* cosEdge, int style, float weight, Base::Color color); | |
| double _getAngle(Base::Vector3d center, Base::Vector3d point); | |
| std::vector<Base::Vector3d> _getVertexPoints(const std::vector<std::string>& SubNames, | |
| TechDraw::DrawViewPart* objFeat); | |
| bool _checkSel(Gui::Command* cmd, std::vector<Gui::SelectionObject>& selection, | |
| TechDraw::DrawViewPart*& objFeat, const std::string& message); | |
| std::string _createBalloon(Gui::Command* cmd, TechDraw::DrawViewPart* objFeat); | |
| //=========================================================================== | |
| // TechDraw_ExtensionHoleCircle | |
| //=========================================================================== | |
| void execHoleCircle(Gui::Command* cmd) | |
| { | |
| //create centerlines of a hole/bolt circle | |
| std::vector<Gui::SelectionObject> selection; | |
| TechDraw::DrawViewPart* objFeat{nullptr}; | |
| if (!_checkSel(cmd, selection, objFeat, QT_TRANSLATE_NOOP("Command","TechDraw hole circle"))) { | |
| return; | |
| } | |
| const std::vector<std::string> SubNames = selection[0].getSubNames(); | |
| std::vector<TechDraw::CirclePtr> Circles; | |
| for (const std::string& Name : SubNames) { | |
| int GeoId = TechDraw::DrawUtil::getIndexFromName(Name); | |
| std::string GeoType = TechDraw::DrawUtil::getGeomTypeFromName(Name); | |
| TechDraw::BaseGeomPtr geom = objFeat->getGeomByIndex(GeoId); | |
| if (GeoType == "Edge") { | |
| if (geom->getGeomType() == GeomType::CIRCLE || geom->getGeomType() == GeomType::ARCOFCIRCLE) { | |
| TechDraw::CirclePtr cgen = std::static_pointer_cast<TechDraw::Circle>(geom); | |
| Circles.push_back(cgen); | |
| } | |
| } | |
| } | |
| if (Circles.size() <= 2) { | |
| QMessageBox::warning(Gui::getMainWindow(), QObject::tr("TechDraw hole circle"), | |
| QObject::tr("Fewer than three circles selected")); | |
| return; | |
| } | |
| Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Bolt circle centerlines")); | |
| // make the bolt hole circle from 3 scaled and rotated points | |
| Base::Vector3d bigCenter = | |
| _circleCenter(Circles[0]->center, Circles[1]->center, Circles[2]->center); | |
| double bigRadius = (Circles[0]->center - bigCenter).Length(); | |
| // now convert the center & radius to canonical form | |
| bigCenter = CosmeticVertex::makeCanonicalPointInverted(objFeat, bigCenter); | |
| bigRadius = bigRadius / objFeat->getScale(); | |
| TechDraw::BaseGeomPtr bigCircle = | |
| std::make_shared<TechDraw::Circle>(bigCenter, bigRadius); | |
| std::string bigCircleTag = objFeat->addCosmeticEdge(bigCircle); | |
| TechDraw::CosmeticEdge* ceCircle = objFeat->getCosmeticEdge(bigCircleTag); | |
| _setLineAttributes(ceCircle); | |
| // make the center lines for the individual bolt holes | |
| constexpr double ExtendFactor{1.1}; | |
| for (const TechDraw::CirclePtr& oneCircle : Circles) { | |
| // convert the center to canonical form | |
| Base::Vector3d oneCircleCenter = CosmeticVertex::makeCanonicalPointInverted(objFeat, oneCircle->center); | |
| // oneCircle->radius is scaled. | |
| double oneRadius = oneCircle->radius / objFeat->getScale(); | |
| // what is magic number 2 (now ExtendFactor)? just a fudge factor to extend the line beyond the bolt | |
| // hole circle? should it be a function of hole diameter? maybe 110% of oneRadius? | |
| Base::Vector3d delta = (oneCircleCenter - bigCenter).Normalize() * (oneRadius * ExtendFactor); | |
| Base::Vector3d startPt = oneCircleCenter + delta; | |
| Base::Vector3d endPt = oneCircleCenter - delta; | |
| std::string oneLineTag = objFeat->addCosmeticEdge(startPt, endPt); | |
| TechDraw::CosmeticEdge* ceLine = objFeat->getCosmeticEdge(oneLineTag); | |
| _setLineAttributes(ceLine); | |
| } | |
| cmd->getSelection().clearSelection(); | |
| objFeat->refreshCEGeoms(); | |
| objFeat->requestPaint(); | |
| Gui::Command::commitCommand(); | |
| } | |
| }// namespace TechDrawGui | |
| DEF_STD_CMD_A(CmdTechDrawExtensionHoleCircle) | |
| CmdTechDrawExtensionHoleCircle::CmdTechDrawExtensionHoleCircle() | |
| : Command("TechDraw_ExtensionHoleCircle") | |
| { | |
| sAppModule = "TechDraw"; | |
| sGroup = QT_TR_NOOP("TechDraw"); | |
| sMenuText = QT_TR_NOOP("Bolt Circle Centerlines"); | |
| sToolTipText = QT_TR_NOOP("Adds centerlines to a circular pattern of three or more selected circles"); | |
| sWhatsThis = "TechDraw_ExtensionHoleCircle"; | |
| sStatusTip = sMenuText; | |
| sPixmap = "TechDraw_ExtensionHoleCircle"; | |
| } | |
| void CmdTechDrawExtensionHoleCircle::activated(int iMsg) | |
| { | |
| Q_UNUSED(iMsg); | |
| execHoleCircle(this); | |
| //Base::Console().message("HoleCircle started\n"); | |
| } | |
| bool CmdTechDrawExtensionHoleCircle::isActive() | |
| { | |
| bool havePage = DrawGuiUtil::needPage(this); | |
| bool haveView = DrawGuiUtil::needView(this); | |
| return (havePage && haveView); | |
| } | |
| //=========================================================================== | |
| // TechDraw_ExtensionCircleCenterLines | |
| //=========================================================================== | |
| void execCircleCenterLines(Gui::Command* cmd) | |
| { | |
| // create circle centerlines | |
| std::vector<Gui::SelectionObject> selection; | |
| TechDraw::DrawViewPart* objFeat{nullptr}; | |
| if (!_checkSel(cmd, selection, objFeat, QT_TRANSLATE_NOOP("Command","TechDraw circle centerlines"))) { | |
| return; | |
| } | |
| Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Circle Centerlines")); | |
| const std::vector<std::string> SubNames = selection[0].getSubNames(); | |
| for (const std::string& Name : SubNames) { | |
| int GeoId = TechDraw::DrawUtil::getIndexFromName(Name); | |
| TechDraw::BaseGeomPtr geom = objFeat->getGeomByIndex(GeoId); | |
| std::string GeoType = TechDraw::DrawUtil::getGeomTypeFromName(Name); | |
| if (GeoType == "Edge") { | |
| if (geom->getGeomType() == GeomType::CIRCLE || geom->getGeomType() == GeomType::ARCOFCIRCLE) { | |
| TechDraw::CirclePtr cgen = std::static_pointer_cast<TechDraw::Circle>(geom); | |
| // cgen->center is a scaled, rotated and inverted point | |
| Base::Vector3d center = CosmeticVertex::makeCanonicalPointInverted(objFeat, cgen->center); | |
| double radius = cgen->radius / objFeat->getScale(); | |
| // right, left, top, bottom are formed from a canonical point (center) | |
| // so they do not need to be changed to canonical form. | |
| Base::Vector3d right(center.x + radius + 2.0, center.y, 0.0); | |
| Base::Vector3d top(center.x, center.y + radius + 2.0, 0.0); | |
| Base::Vector3d left(center.x - radius - 2.0, center.y, 0.0); | |
| Base::Vector3d bottom(center.x, center.y - radius - 2.0, 0.0); | |
| std::string line1tag = objFeat->addCosmeticEdge(right, left); | |
| std::string line2tag = objFeat->addCosmeticEdge(top, bottom); | |
| TechDraw::CosmeticEdge* horiz = objFeat->getCosmeticEdge(line1tag); | |
| _setLineAttributes(horiz); | |
| TechDraw::CosmeticEdge* vert = objFeat->getCosmeticEdge(line2tag); | |
| _setLineAttributes(vert); | |
| } | |
| } | |
| } | |
| cmd->getSelection().clearSelection(); | |
| objFeat->refreshCEGeoms(); | |
| objFeat->requestPaint(); | |
| Gui::Command::commitCommand(); | |
| } | |
| DEF_STD_CMD_A(CmdTechDrawExtensionCircleCenterLines) | |
| CmdTechDrawExtensionCircleCenterLines::CmdTechDrawExtensionCircleCenterLines() | |
| : Command("TechDraw_ExtensionCircleCenterLines") | |
| { | |
| sAppModule = "TechDraw"; | |
| sGroup = QT_TR_NOOP("TechDraw"); | |
| sMenuText = QT_TR_NOOP("Circle Centerlines"); | |
| sToolTipText = QT_TR_NOOP("Adds centerlines to the selected circles and arcs"); | |
| sWhatsThis = "TechDraw_ExtensionCircleCenterLines"; | |
| sStatusTip = sMenuText; | |
| sPixmap = "TechDraw_ExtensionCircleCenterLines"; | |
| } | |
| void CmdTechDrawExtensionCircleCenterLines::activated(int iMsg) | |
| { | |
| Q_UNUSED(iMsg); | |
| execCircleCenterLines(this); | |
| } | |
| bool CmdTechDrawExtensionCircleCenterLines::isActive() | |
| { | |
| bool havePage = DrawGuiUtil::needPage(this); | |
| bool haveView = DrawGuiUtil::needView(this); | |
| return (havePage && haveView); | |
| } | |
| //=========================================================================== | |
| // TechDraw_ExtensionCircleCenterLinesGroup | |
| //=========================================================================== | |
| DEF_STD_CMD_ACL(CmdTechDrawExtensionCircleCenterLinesGroup) | |
| CmdTechDrawExtensionCircleCenterLinesGroup::CmdTechDrawExtensionCircleCenterLinesGroup() | |
| : Command("TechDraw_ExtensionCircleCenterLinesGroup") | |
| { | |
| sAppModule = "TechDraw"; | |
| sGroup = QT_TR_NOOP("TechDraw"); | |
| sMenuText = QT_TR_NOOP("Circle Centerlines"); | |
| sToolTipText = QT_TR_NOOP("Adds centerlines to selected circles and arcs"); | |
| sWhatsThis = "TechDraw_ExtensionCircleCenterLinesGroup"; | |
| sStatusTip = sMenuText; | |
| } | |
| void CmdTechDrawExtensionCircleCenterLinesGroup::activated(int iMsg) | |
| { | |
| Gui::TaskView::TaskDialog* dlg = Gui::Control().activeDialog(); | |
| if (dlg) { | |
| QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Task in progress"), | |
| QObject::tr("Close active task dialog and try again.")); | |
| return; | |
| } | |
| auto pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction); | |
| pcAction->setIcon(pcAction->actions().at(iMsg)->icon()); | |
| switch (iMsg) { | |
| case 0://circle centerlines | |
| execCircleCenterLines(this); | |
| break; | |
| case 1://bolt circle centerlines | |
| execHoleCircle(this); | |
| break; | |
| default: | |
| Base::Console().message("CMD::CVGrp - invalid iMsg: %d\n", iMsg); | |
| }; | |
| } | |
| Gui::Action* CmdTechDrawExtensionCircleCenterLinesGroup::createAction() | |
| { | |
| Gui::ActionGroup* pcAction = new Gui::ActionGroup(this, Gui::getMainWindow()); | |
| pcAction->setDropDownMenu(true); | |
| applyCommandData(this->className(), pcAction); | |
| QAction* p1 = pcAction->addAction(QString()); | |
| p1->setIcon(Gui::BitmapFactory().iconFromTheme("TechDraw_ExtensionCircleCenterLines")); | |
| p1->setObjectName(QStringLiteral("TechDraw_ExtensionCircleCenterLines")); | |
| p1->setWhatsThis(QStringLiteral("TechDraw_ExtensionCircleCenterLines")); | |
| QAction* p2 = pcAction->addAction(QString()); | |
| p2->setIcon(Gui::BitmapFactory().iconFromTheme("TechDraw_ExtensionHoleCircle")); | |
| p2->setObjectName(QStringLiteral("TechDraw_ExtensionHoleCircle")); | |
| p2->setWhatsThis(QStringLiteral("TechDraw_ExtensionHoleCircle")); | |
| _pcAction = pcAction; | |
| languageChange(); | |
| pcAction->setIcon(p1->icon()); | |
| int defaultId = 0; | |
| pcAction->setProperty("defaultAction", QVariant(defaultId)); | |
| return pcAction; | |
| } | |
| void CmdTechDrawExtensionCircleCenterLinesGroup::languageChange() | |
| { | |
| Command::languageChange(); | |
| if (!_pcAction) { | |
| return; | |
| } | |
| Gui::ActionGroup* pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction); | |
| QList<QAction*> action = pcAction->actions(); | |
| QAction* arc1 = action[0]; | |
| arc1->setText( | |
| QApplication::translate("CmdTechDrawExtensionCircleCenterLines", "Circle Centerlines")); | |
| arc1->setToolTip(QApplication::translate("CmdTechDrawExtensionCircleCenterLines", | |
| "Adds centerlines to selected circles and arcs:")); | |
| arc1->setStatusTip(arc1->text()); | |
| QAction* arc2 = action[1]; | |
| arc2->setText( | |
| QApplication::translate("CmdTechDrawExtensionHoleCircle", "Bolt Circle Centerlines")); | |
| arc2->setToolTip(QApplication::translate("CmdTechDrawExtensionHoleCircle", | |
| "Adds centerlines to a circular pattern of selected circles")); | |
| arc2->setStatusTip(arc2->text()); | |
| } | |
| bool CmdTechDrawExtensionCircleCenterLinesGroup::isActive() | |
| { | |
| bool havePage = DrawGuiUtil::needPage(this); | |
| bool haveView = DrawGuiUtil::needView(this, true); | |
| return (havePage && haveView); | |
| } | |
| //=========================================================================== | |
| // TechDraw_ExtensionThreadHoleSide | |
| //=========================================================================== | |
| void execThreadHoleSide(Gui::Command* cmd) | |
| { | |
| constexpr double ThreadFactor{1.176}; | |
| // add cosmetic thread to side view of hole | |
| std::vector<Gui::SelectionObject> selection; | |
| TechDraw::DrawViewPart* objFeat{nullptr}; | |
| if (!_checkSel(cmd, selection, objFeat, QT_TRANSLATE_NOOP("Command","TechDraw Thread Hole Side"))) { | |
| return; | |
| } | |
| Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Cosmetic Thread Hole Side")); | |
| const std::vector<std::string> SubNames = selection[0].getSubNames(); | |
| if (SubNames.size() >= 2) { | |
| _createThreadLines(SubNames, objFeat, ThreadFactor); | |
| } | |
| cmd->getSelection().clearSelection(); | |
| objFeat->refreshCEGeoms(); | |
| objFeat->requestPaint(); | |
| Gui::Command::commitCommand(); | |
| } | |
| DEF_STD_CMD_A(CmdTechDrawExtensionThreadHoleSide) | |
| CmdTechDrawExtensionThreadHoleSide::CmdTechDrawExtensionThreadHoleSide() | |
| : Command("TechDraw_ExtensionThreadHoleSide") | |
| { | |
| sAppModule = "TechDraw"; | |
| sGroup = QT_TR_NOOP("TechDraw"); | |
| sMenuText = QT_TR_NOOP("Cosmetic Thread Hole Side View"); | |
| sToolTipText = QT_TR_NOOP("Adds a cosmetic thread to the side view of a hole or circle"); | |
| sWhatsThis = "TechDraw_ExtensionThreadHoleSide"; | |
| sStatusTip = sMenuText; | |
| sPixmap = "TechDraw_ExtensionThreadHoleSide"; | |
| } | |
| void CmdTechDrawExtensionThreadHoleSide::activated(int iMsg) | |
| { | |
| Q_UNUSED(iMsg); | |
| execThreadHoleSide(this); | |
| } | |
| bool CmdTechDrawExtensionThreadHoleSide::isActive() | |
| { | |
| bool havePage = DrawGuiUtil::needPage(this); | |
| bool haveView = DrawGuiUtil::needView(this); | |
| return (havePage && haveView); | |
| } | |
| //=========================================================================== | |
| // TechDraw_ExtensionThreadBoltSide | |
| //=========================================================================== | |
| void execThreadBoltSide(Gui::Command* cmd) | |
| { | |
| constexpr double ThreadFactor{0.85}; | |
| // add cosmetic thread to side view of bolt | |
| std::vector<Gui::SelectionObject> selection; | |
| TechDraw::DrawViewPart* objFeat{nullptr}; | |
| if (!_checkSel(cmd, selection, objFeat, QT_TRANSLATE_NOOP("Command","TechDraw Thread Bolt Side"))) { | |
| return; | |
| } | |
| Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Cosmetic Thread Bolt Side")); | |
| const std::vector<std::string> SubNames = selection[0].getSubNames(); | |
| if (SubNames.size() >= 2) { | |
| _createThreadLines(SubNames, objFeat, ThreadFactor); | |
| } | |
| cmd->getSelection().clearSelection(); | |
| objFeat->refreshCEGeoms(); | |
| objFeat->requestPaint(); | |
| Gui::Command::commitCommand(); | |
| } | |
| DEF_STD_CMD_A(CmdTechDrawExtensionThreadBoltSide) | |
| CmdTechDrawExtensionThreadBoltSide::CmdTechDrawExtensionThreadBoltSide() | |
| : Command("TechDraw_ExtensionThreadBoltSide") | |
| { | |
| sAppModule = "TechDraw"; | |
| sGroup = QT_TR_NOOP("TechDraw"); | |
| sMenuText = QT_TR_NOOP("Cosmetic Thread Bolt Side View"); | |
| sToolTipText = QT_TR_NOOP("Adds a cosmetic thread to the side view of a " | |
| "bolt/screw/rod between two selected parallel lines"); | |
| sWhatsThis = "TechDraw_ExtensionThreadBoltSide"; | |
| sStatusTip = sMenuText; | |
| sPixmap = "TechDraw_ExtensionThreadBoltSide"; | |
| } | |
| void CmdTechDrawExtensionThreadBoltSide::activated(int iMsg) | |
| { | |
| Q_UNUSED(iMsg); | |
| execThreadBoltSide(this); | |
| } | |
| bool CmdTechDrawExtensionThreadBoltSide::isActive() | |
| { | |
| bool havePage = DrawGuiUtil::needPage(this); | |
| bool haveView = DrawGuiUtil::needView(this); | |
| return (havePage && haveView); | |
| } | |
| //=========================================================================== | |
| // TechDraw_ExtensionThreadHoleBottom | |
| //=========================================================================== | |
| void execThreadHoleBottom(Gui::Command* cmd) | |
| { | |
| constexpr double ThreadFactor{1.177}; // factor above is 1.176. should they be the same? | |
| // add cosmetic thread to bottom view of hole | |
| std::vector<Gui::SelectionObject> selection; | |
| TechDraw::DrawViewPart* objFeat{nullptr}; | |
| if (!_checkSel(cmd, selection, objFeat, QT_TRANSLATE_NOOP("Command","TechDraw Thread Hole Bottom"))) { | |
| return; | |
| } | |
| Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Cosmetic thread hole bottom")); | |
| const std::vector<std::string> SubNames = selection[0].getSubNames(); | |
| for (const std::string& Name : SubNames) { | |
| _createThreadCircle(Name, objFeat, ThreadFactor); | |
| } | |
| cmd->getSelection().clearSelection(); | |
| objFeat->refreshCEGeoms(); | |
| objFeat->requestPaint(); | |
| Gui::Command::commitCommand(); | |
| } | |
| DEF_STD_CMD_A(CmdTechDrawExtensionThreadHoleBottom) | |
| CmdTechDrawExtensionThreadHoleBottom::CmdTechDrawExtensionThreadHoleBottom() | |
| : Command("TechDraw_ExtensionThreadHoleBottom") | |
| { | |
| sAppModule = "TechDraw"; | |
| sGroup = QT_TR_NOOP("TechDraw"); | |
| sMenuText = QT_TR_NOOP("Cosmetic Thread Hole Bottom View"); | |
| sToolTipText = QT_TR_NOOP("Adds a cosmetic thread to the top or bottom view of selected holes or circles"); | |
| sWhatsThis = "TechDraw_ExtensionThreadHoleBottom"; | |
| sStatusTip = sMenuText; | |
| sPixmap = "TechDraw_ExtensionThreadHoleBottom"; | |
| } | |
| void CmdTechDrawExtensionThreadHoleBottom::activated(int iMsg) | |
| { | |
| Q_UNUSED(iMsg); | |
| execThreadHoleBottom(this); | |
| } | |
| bool CmdTechDrawExtensionThreadHoleBottom::isActive() | |
| { | |
| bool havePage = DrawGuiUtil::needPage(this); | |
| bool haveView = DrawGuiUtil::needView(this); | |
| return (havePage && haveView); | |
| } | |
| //=========================================================================== | |
| // TechDraw_ExtensionThreadBoltBottom | |
| //=========================================================================== | |
| void execThreadBoltBottom(Gui::Command* cmd) | |
| { | |
| constexpr double ThreadFactor{0.85}; | |
| // add cosmetic thread to bottom view of bolt | |
| std::vector<Gui::SelectionObject> selection; | |
| TechDraw::DrawViewPart* objFeat{nullptr}; | |
| if (!_checkSel(cmd, selection, objFeat, QT_TRANSLATE_NOOP("Command","TechDraw Thread Bolt Bottom"))) { | |
| return; | |
| } | |
| Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Cosmetic Thread Bolt Bottom")); | |
| const std::vector<std::string> SubNames = selection[0].getSubNames(); | |
| for (const std::string& Name : SubNames) { | |
| _createThreadCircle(Name, objFeat, ThreadFactor); | |
| } | |
| cmd->getSelection().clearSelection(); | |
| objFeat->refreshCEGeoms(); | |
| objFeat->requestPaint(); | |
| Gui::Command::commitCommand(); | |
| } | |
| DEF_STD_CMD_A(CmdTechDrawExtensionThreadBoltBottom) | |
| CmdTechDrawExtensionThreadBoltBottom::CmdTechDrawExtensionThreadBoltBottom() | |
| : Command("TechDraw_ExtensionThreadBoltBottom") | |
| { | |
| sAppModule = "TechDraw"; | |
| sGroup = QT_TR_NOOP("TechDraw"); | |
| sMenuText = QT_TR_NOOP("Cosmetic Thread Bolt Bottom View"); | |
| sToolTipText = | |
| QT_TR_NOOP("Adds a cosmetic thread to the top or bottom view of the selected bolts/screws/rods"); | |
| sWhatsThis = "TechDraw_ExtensionThreadBoltBottom"; | |
| sStatusTip = sMenuText; | |
| sPixmap = "TechDraw_ExtensionThreadBoltBottom"; | |
| } | |
| void CmdTechDrawExtensionThreadBoltBottom::activated(int iMsg) | |
| { | |
| Q_UNUSED(iMsg); | |
| execThreadBoltBottom(this); | |
| } | |
| bool CmdTechDrawExtensionThreadBoltBottom::isActive() | |
| { | |
| bool havePage = DrawGuiUtil::needPage(this); | |
| bool haveView = DrawGuiUtil::needView(this); | |
| return (havePage && haveView); | |
| } | |
| //=========================================================================== | |
| // TechDraw_ExtensionThreadsGroup | |
| //=========================================================================== | |
| DEF_STD_CMD_ACL(CmdTechDrawExtensionThreadsGroup) | |
| CmdTechDrawExtensionThreadsGroup::CmdTechDrawExtensionThreadsGroup() | |
| : Command("TechDraw_ExtensionThreadsGroup") | |
| { | |
| sAppModule = "TechDraw"; | |
| sGroup = QT_TR_NOOP("TechDraw"); | |
| sMenuText = QT_TR_NOOP("Cosmetic Thread Hole Side View"); | |
| sToolTipText = QT_TR_NOOP("Add a cosmetic thread to the side view of a selected hole between two selected parallel lines"); | |
| sWhatsThis = "TechDraw_ExtensionThreadsGroup"; | |
| sStatusTip = sMenuText; | |
| } | |
| void CmdTechDrawExtensionThreadsGroup::activated(int iMsg) | |
| { | |
| // Base::Console().message("CMD::TechDrawExtensionThreadsGroup - activated(%d)\n", iMsg); | |
| Gui::TaskView::TaskDialog* dlg = Gui::Control().activeDialog(); | |
| if (dlg) { | |
| QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Task in progress"), | |
| QObject::tr("Close active task dialog and try again.")); | |
| return; | |
| } | |
| auto pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction); | |
| pcAction->setIcon(pcAction->actions().at(iMsg)->icon()); | |
| switch (iMsg) { | |
| case 0://thread hole side view | |
| execThreadHoleSide(this); | |
| break; | |
| case 1://thread hole bottom view | |
| execThreadHoleBottom(this); | |
| break; | |
| case 2://thread bolt side view | |
| execThreadBoltSide(this); | |
| break; | |
| case 3://thread bolt bottom view | |
| execThreadBoltBottom(this); | |
| break; | |
| default: | |
| Base::Console().message("CMD::CVGrp - invalid iMsg: %d\n", iMsg); | |
| }; | |
| } | |
| Gui::Action* CmdTechDrawExtensionThreadsGroup::createAction() | |
| { | |
| Gui::ActionGroup* pcAction = new Gui::ActionGroup(this, Gui::getMainWindow()); | |
| pcAction->setDropDownMenu(true); | |
| applyCommandData(this->className(), pcAction); | |
| QAction* p1 = pcAction->addAction(QString()); | |
| p1->setIcon(Gui::BitmapFactory().iconFromTheme("TechDraw_ExtensionThreadHoleSide")); | |
| p1->setObjectName(QStringLiteral("TechDraw_ExtensionThreadHoleSide")); | |
| p1->setWhatsThis(QStringLiteral("TechDraw_ExtensionThreadHoleSide")); | |
| QAction* p2 = pcAction->addAction(QString()); | |
| p2->setIcon(Gui::BitmapFactory().iconFromTheme("TechDraw_ExtensionThreadHoleBottom")); | |
| p2->setObjectName(QStringLiteral("TechDraw_ExtensionThreadHoleBottom")); | |
| p2->setWhatsThis(QStringLiteral("TechDraw_ExtensionThreadHoleBottom")); | |
| QAction* p3 = pcAction->addAction(QString()); | |
| p3->setIcon(Gui::BitmapFactory().iconFromTheme("TechDraw_ExtensionThreadBoltSide")); | |
| p3->setObjectName(QStringLiteral("TechDraw_ExtensionThreadBoltSide")); | |
| p3->setWhatsThis(QStringLiteral("TechDraw_ExtensionThreadBoltSide")); | |
| QAction* p4 = pcAction->addAction(QString()); | |
| p4->setIcon(Gui::BitmapFactory().iconFromTheme("TechDraw_ExtensionThreadBoltBottom")); | |
| p4->setObjectName(QStringLiteral("TechDraw_ExtensionThreadBoltBottom")); | |
| p4->setWhatsThis(QStringLiteral("TechDraw_ExtensionThreadBoltBottom")); | |
| _pcAction = pcAction; | |
| languageChange(); | |
| pcAction->setIcon(p1->icon()); | |
| int defaultId = 0; | |
| pcAction->setProperty("defaultAction", QVariant(defaultId)); | |
| return pcAction; | |
| } | |
| void CmdTechDrawExtensionThreadsGroup::languageChange() | |
| { | |
| Command::languageChange(); | |
| if (!_pcAction) { | |
| return; | |
| } | |
| auto pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction); | |
| QList<QAction*> action = pcAction->actions(); | |
| QAction* arc1 = action[0]; | |
| arc1->setText(QApplication::translate("CmdTechDrawExtensionThreadHoleSide", | |
| "Cosmetic Thread Hole Side View")); | |
| arc1->setToolTip(QApplication::translate("CmdTechDrawExtensionThreadHoleSide", | |
| "Adds a cosmetic thread to the side view of a " | |
| "selected hole between two selected parallel lines")); | |
| arc1->setStatusTip(arc1->text()); | |
| QAction* arc2 = action[1]; | |
| arc2->setText(QApplication::translate("CmdTechDrawExtensionThreadHoleBottom", | |
| "Cosmetic Thread Hole Bottom View")); | |
| arc2->setToolTip( | |
| QApplication::translate("CmdTechDrawExtensionThreadHoleBottom", | |
| "Adds a cosmetic thread to the top or bottom view of holes or circles")); | |
| arc2->setStatusTip(arc2->text()); | |
| QAction* arc3 = action[2]; | |
| arc3->setText(QApplication::translate("CmdTechDrawExtensionThreadBoltSide", | |
| "Cosmetic Thread Bolt Side View")); | |
| arc3->setToolTip( | |
| QApplication::translate("CmdTechDrawExtensionThreadBoltSide", | |
| "Adds a cosmetic thread to the side view of a bolt/screw/rod " | |
| "between two selected parallel lines")); | |
| arc3->setStatusTip(arc3->text()); | |
| QAction* arc4 = action[3]; | |
| arc4->setText(QApplication::translate("CmdTechDrawExtensionThreadBoltBottom", | |
| "Cosmetic Thread Bolt Bottom View")); | |
| arc4->setToolTip(QApplication::translate( | |
| "CmdTechDrawExtensionThreadBoltBottom", | |
| "Adds a cosmetic thread to the top or bottom view of the selected bolts/screws/rods")); | |
| arc4->setStatusTip(arc4->text()); | |
| } | |
| bool CmdTechDrawExtensionThreadsGroup::isActive() | |
| { | |
| bool havePage = DrawGuiUtil::needPage(this); | |
| bool haveView = DrawGuiUtil::needView(this, true); | |
| return (havePage && haveView); | |
| } | |
| //=========================================================================== | |
| // TechDraw_ExtensionSelectLineAttributes | |
| //=========================================================================== | |
| DEF_STD_CMD_A(CmdTechDrawExtensionSelectLineAttributes) | |
| CmdTechDrawExtensionSelectLineAttributes::CmdTechDrawExtensionSelectLineAttributes() | |
| : Command("TechDraw_ExtensionSelectLineAttributes") | |
| { | |
| sAppModule = "TechDraw"; | |
| sGroup = QT_TR_NOOP("TechDraw"); | |
| sMenuText = QT_TR_NOOP("Select Line Attributes, Cascade Spacing and Delta Distance"); | |
| sToolTipText = QT_TR_NOOP( | |
| "Configures the default attributes for cosmetic lines and centerlines, including cascade spacing and delta distance"); | |
| sWhatsThis = "TechDraw_ExtensionSelectLineAttributes"; | |
| sStatusTip = sMenuText; | |
| sPixmap = "TechDraw_ExtensionSelectLineAttributes"; | |
| } | |
| void CmdTechDrawExtensionSelectLineAttributes::activated(int iMsg) | |
| { | |
| Q_UNUSED(iMsg); | |
| Gui::Control().showDialog(new TaskDlgSelectLineAttributes()); | |
| } | |
| bool CmdTechDrawExtensionSelectLineAttributes::isActive() | |
| { | |
| bool havePage = DrawGuiUtil::needPage(this); | |
| bool haveView = DrawGuiUtil::needView(this); | |
| return (havePage && haveView); | |
| } | |
| //=========================================================================== | |
| // TechDraw_ExtensionChangeLineAttributes | |
| //=========================================================================== | |
| DEF_STD_CMD_A(CmdTechDrawExtensionChangeLineAttributes) | |
| CmdTechDrawExtensionChangeLineAttributes::CmdTechDrawExtensionChangeLineAttributes() | |
| : Command("TechDraw_ExtensionChangeLineAttributes") | |
| { | |
| sAppModule = "TechDraw"; | |
| sGroup = QT_TR_NOOP("TechDraw"); | |
| sMenuText = QT_TR_NOOP("Change Line Attributes"); | |
| sToolTipText = QT_TR_NOOP("Changes the selected cosmetic lines and centerlines to the specified attributes"); | |
| sWhatsThis = "TechDraw_ExtensionChangeLineAttributes"; | |
| sStatusTip = sMenuText; | |
| sPixmap = "TechDraw_ExtensionChangeLineAttributes"; | |
| } | |
| void CmdTechDrawExtensionChangeLineAttributes::activated(int iMsg) | |
| { | |
| // change attributes (type, width, color) of a cosmetic or centerline | |
| Q_UNUSED(iMsg); | |
| std::vector<Gui::SelectionObject> selection; | |
| TechDraw::DrawViewPart* objFeat{nullptr}; | |
| if (!_checkSel(this, selection, objFeat, QT_TRANSLATE_NOOP("Command","TechDraw change line attributes"))) { | |
| return; | |
| } | |
| Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Change line attributes")); | |
| const std::vector<std::string> subNames = selection[0].getSubNames(); | |
| for (const std::string& name : subNames) { | |
| int num = DrawUtil::getIndexFromName(name); | |
| BaseGeomPtr baseGeo = objFeat->getGeomByIndex(num); | |
| if (baseGeo) { | |
| if (baseGeo->getCosmetic()) { | |
| if (baseGeo->source() == SourceType::COSMETICEDGE) { | |
| TechDraw::CosmeticEdge* cosEdgeTag = objFeat->getCosmeticEdgeBySelection(name); | |
| _setLineAttributes(cosEdgeTag); | |
| } | |
| else if (baseGeo->source() == SourceType::CENTERLINE) { | |
| TechDraw::CenterLine* centerLineTag = objFeat->getCenterLineBySelection(name); | |
| _setLineAttributes(centerLineTag); | |
| } | |
| } | |
| } | |
| } | |
| getSelection().clearSelection(); | |
| objFeat->refreshCEGeoms(); | |
| objFeat->requestPaint(); | |
| Gui::Command::commitCommand(); | |
| } | |
| bool CmdTechDrawExtensionChangeLineAttributes::isActive() | |
| { | |
| bool havePage = DrawGuiUtil::needPage(this); | |
| bool haveView = DrawGuiUtil::needView(this); | |
| return (havePage && haveView); | |
| } | |
| //=========================================================================== | |
| // TechDraw_ExtensionVertexAtIntersection | |
| //=========================================================================== | |
| DEF_STD_CMD_A(CmdTechDrawExtensionVertexAtIntersection) | |
| CmdTechDrawExtensionVertexAtIntersection::CmdTechDrawExtensionVertexAtIntersection() | |
| : Command("TechDraw_ExtensionVertexAtIntersection") | |
| { | |
| sAppModule = "TechDraw"; | |
| sGroup = QT_TR_NOOP("TechDraw"); | |
| sMenuText = QT_TR_NOOP("Cosmetic Intersection Vertices"); | |
| sToolTipText = | |
| QT_TR_NOOP("Adds cosmetic vertices at the intersections of selected edges"); | |
| sWhatsThis = "TechDraw_ExtensionVertexAtIntersection"; | |
| sStatusTip = sMenuText; | |
| sPixmap = "TechDraw_ExtensionVertexAtIntersection"; | |
| } | |
| void CmdTechDrawExtensionVertexAtIntersection::activated(int iMsg) | |
| { | |
| Q_UNUSED(iMsg); | |
| //Base::Console().message("VertexAtIntersection started\n"); | |
| std::vector<Gui::SelectionObject> selection; | |
| TechDraw::DrawViewPart* objFeat{nullptr}; | |
| if (!_checkSel(this, selection, objFeat, QT_TRANSLATE_NOOP("Command","TechDraw cosmetic intersection vertices"))) { | |
| return; | |
| } | |
| Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Cosmetic intersection vertices")); | |
| const std::vector<std::string> SubNames = selection[0].getSubNames(); | |
| if (SubNames.size() >= 2) { | |
| std::string GeoType1 = TechDraw::DrawUtil::getGeomTypeFromName(SubNames[0]); | |
| std::string GeoType2 = TechDraw::DrawUtil::getGeomTypeFromName(SubNames[1]); | |
| if (GeoType1 == "Edge" && GeoType2 == "Edge") { | |
| int GeoId1 = TechDraw::DrawUtil::getIndexFromName(SubNames[0]); | |
| TechDraw::BaseGeomPtr geom1 = objFeat->getGeomByIndex(GeoId1); | |
| int GeoId2 = TechDraw::DrawUtil::getIndexFromName(SubNames[1]); | |
| TechDraw::BaseGeomPtr geom2 = objFeat->getGeomByIndex(GeoId2); | |
| std::vector<Base::Vector3d> interPoints = geom1->intersection(geom2); | |
| for (auto pt : interPoints) { | |
| // geometry points are inverted | |
| Base::Vector3d temp = CosmeticVertex::makeCanonicalPointInverted(objFeat, pt); | |
| objFeat->addCosmeticVertex(temp, false); | |
| } | |
| } | |
| } | |
| getSelection().clearSelection(); | |
| objFeat->refreshCVGeoms(); | |
| objFeat->requestPaint(); | |
| Gui::Command::commitCommand(); | |
| } | |
| bool CmdTechDrawExtensionVertexAtIntersection::isActive() | |
| { | |
| bool havePage = DrawGuiUtil::needPage(this); | |
| bool haveView = DrawGuiUtil::needView(this); | |
| return (havePage && haveView); | |
| } | |
| //=========================================================================== | |
| // TechDraw_CosmeticCircle | |
| //=========================================================================== | |
| DEF_STD_CMD_A(CmdTechDrawCosmeticCircle) | |
| CmdTechDrawCosmeticCircle::CmdTechDrawCosmeticCircle() | |
| : Command("TechDraw_CosmeticCircle") | |
| { | |
| sAppModule = "TechDraw"; | |
| sGroup = QT_TR_NOOP("TechDraw"); | |
| sMenuText = QT_TR_NOOP("Cosmetic 1 Point Circle"); | |
| sToolTipText = QT_TR_NOOP("Adds a cosmetic circle based on a selected centerpoint"); | |
| sWhatsThis = "TechDraw_CosmeticCircle"; | |
| sStatusTip = sToolTipText; | |
| sPixmap = "actions/TechDraw_CosmeticCircle"; | |
| } | |
| bool CmdTechDrawCosmeticCircle::isActive() | |
| { | |
| bool havePage = DrawGuiUtil::needPage(this); | |
| bool haveView = DrawGuiUtil::needView(this, true); | |
| return (havePage && haveView); | |
| } | |
| void execCosmeticCircleCenter(Gui::Command* cmd) | |
| { | |
| TechDraw::DrawPage* page = DrawGuiUtil::findPage(cmd); | |
| if (!page) { | |
| return; | |
| } | |
| std::vector<Gui::SelectionObject> selection = cmd->getSelection().getSelectionEx(); | |
| TechDraw::DrawViewPart* baseFeat = nullptr; | |
| std::vector<std::string> subNames2D; | |
| std::vector< std::pair<Part::Feature*, std::string> > objs3D; | |
| if (selection.empty()) { | |
| QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong Selection"), | |
| QObject::tr("Selection is empty.")); | |
| return; | |
| } | |
| for (auto& so: selection) { | |
| if (so.getObject()->isDerivedFrom<TechDraw::DrawViewPart>()) { | |
| baseFeat = static_cast<TechDraw::DrawViewPart*> (so.getObject()); | |
| subNames2D = so.getSubNames(); | |
| } else if (so.getObject()->isDerivedFrom<Part::Feature>()) { | |
| std::vector<std::string> subNames3D = so.getSubNames(); | |
| for (auto& sub3D: subNames3D) { | |
| std::pair<Part::Feature*, std::string> temp; | |
| temp.first = static_cast<Part::Feature*>(so.getObject()); | |
| temp.second = sub3D; | |
| objs3D.push_back(temp); | |
| } | |
| } else { | |
| //garbage | |
| } | |
| } | |
| if (!baseFeat) { | |
| QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong Selection"), | |
| QObject::tr("You must select a base View for the circle.")); | |
| return; | |
| } | |
| std::vector<std::string> edgeNames; | |
| std::vector<std::string> vertexNames; | |
| for (auto& s: subNames2D) { | |
| std::string geomType = DrawUtil::getGeomTypeFromName(s); | |
| if (geomType == "Vertex") { | |
| vertexNames.push_back(s); | |
| } else if (geomType == "Edge") { | |
| edgeNames.push_back(s); | |
| } | |
| } | |
| //check if editing existing edge | |
| if (!edgeNames.empty() && (edgeNames.size() == 1)) { | |
| TechDraw::CosmeticEdge* ce = baseFeat->getCosmeticEdgeBySelection(edgeNames.front()); | |
| if (!ce | |
| || !(ce->m_geometry->getGeomType() == GeomType::CIRCLE | |
| || ce->m_geometry->getGeomType() == GeomType::ARCOFCIRCLE)) { | |
| QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong Selection"), | |
| QObject::tr("Selection is not a Cosmetic Circle or a Cosmetic Arc of Circle.")); | |
| return; | |
| } | |
| Gui::Control().showDialog(new TaskDlgCosmeticCircle(baseFeat, | |
| edgeNames.front())); | |
| return; | |
| } | |
| std::vector<Base::Vector3d> points; | |
| std::vector<bool> is3d; | |
| //get the 2D points | |
| if (!vertexNames.empty()) { | |
| for (auto& v2d: vertexNames) { | |
| int idx = DrawUtil::getIndexFromName(v2d); | |
| TechDraw::VertexPtr v = baseFeat->getProjVertexByIndex(idx); | |
| if (v) { | |
| points.push_back(v->point()); | |
| is3d.push_back(false); | |
| } | |
| } | |
| } | |
| //get the 3D points | |
| if (!objs3D.empty()) { | |
| for (auto& o3D: objs3D) { | |
| int idx = DrawUtil::getIndexFromName(o3D.second); | |
| Part::TopoShape s = o3D.first->Shape.getShape(); | |
| TopoDS_Vertex v = TopoDS::Vertex(s.getSubShape(TopAbs_VERTEX, idx)); | |
| Base::Vector3d p = DrawUtil::vertex2Vector(v); | |
| points.push_back(p); | |
| is3d.push_back(true); | |
| } | |
| } | |
| if (points.empty()) { | |
| QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong Selection"), | |
| QObject::tr("Please select a center for the circle.")); | |
| return; | |
| } | |
| bool centerIs3d = false; | |
| if (!is3d.empty()) { | |
| centerIs3d = is3d.front(); | |
| } | |
| Gui::Control().showDialog(new TaskDlgCosmeticCircle(baseFeat, | |
| points, | |
| centerIs3d)); | |
| } | |
| void CmdTechDrawCosmeticCircle::activated(int iMsg) | |
| { | |
| Q_UNUSED(iMsg); | |
| Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); | |
| if (dlg) { | |
| QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Task In Progress"), | |
| QObject::tr("Close active task dialog and try again.")); | |
| return; | |
| } | |
| execCosmeticCircleCenter(this); | |
| updateActive(); | |
| Gui::Selection().clearSelection(); | |
| } | |
| //=========================================================================== | |
| // TechDraw_ExtensionDrawCosmArc | |
| //=========================================================================== | |
| //! adds an anti-clockwise arc based on a center point, a radius/start angle point and an end angle | |
| //! point. Selection order is significant - center, start end. | |
| void execDrawCosmArc(Gui::Command* cmd) | |
| { | |
| //draw a cosmetic arc of circle | |
| std::vector<Gui::SelectionObject> selection; | |
| TechDraw::DrawViewPart* objFeat{nullptr}; | |
| if (!_checkSel(cmd, selection, objFeat, QT_TRANSLATE_NOOP("Command","TechDraw cosmetic arc"))) { | |
| return; | |
| } | |
| Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Cosmetic arc")); | |
| const std::vector<std::string> SubNames = selection[0].getSubNames(); | |
| std::vector<Base::Vector3d> vertexPoints; | |
| vertexPoints = _getVertexPoints(SubNames, objFeat); | |
| if (vertexPoints.size() >= 3) { | |
| // vertexPoints come from stored geometry, so are centered, scaled, rotated and inverted (CSRIz). | |
| // because the points are inverted, the start and end angles will be mirrored unless we invert the points | |
| // before calculating the angle. | |
| Base::Vector3d center = CosmeticVertex::makeCanonicalPoint(objFeat, DU::invertY(vertexPoints[0])); | |
| Base::Vector3d end1 = CosmeticVertex::makeCanonicalPoint(objFeat, DU::invertY(vertexPoints[1])); | |
| Base::Vector3d end2 = CosmeticVertex::makeCanonicalPoint(objFeat, DU::invertY(vertexPoints[2])); | |
| double arcRadius = (end1 - center).Length(); | |
| double angle1 = _getAngle(center, end1); | |
| double angle2 = _getAngle(center, end2); | |
| TechDraw::BaseGeomPtr baseGeo = std::make_shared<TechDraw::AOC>( | |
| center, arcRadius, angle1, angle2); | |
| TechDraw::AOCPtr aoc = std::static_pointer_cast<TechDraw::AOC>(baseGeo); | |
| // having done our calculations in sensible coordinates, we convert to inverted coords | |
| std::string arcTag = objFeat->addCosmeticEdge(baseGeo->inverted()); | |
| TechDraw::CosmeticEdge* arcEdge = objFeat->getCosmeticEdge(arcTag); | |
| _setLineAttributes(arcEdge); | |
| objFeat->refreshCEGeoms(); | |
| objFeat->requestPaint(); | |
| cmd->getSelection().clearSelection(); | |
| Gui::Command::commitCommand(); | |
| } | |
| } | |
| DEF_STD_CMD_A(CmdTechDrawExtensionDrawCosmArc) | |
| CmdTechDrawExtensionDrawCosmArc::CmdTechDrawExtensionDrawCosmArc() | |
| : Command("TechDraw_ExtensionDrawCosmArc") | |
| { | |
| sAppModule = "TechDraw"; | |
| sGroup = QT_TR_NOOP("TechDraw"); | |
| sMenuText = QT_TR_NOOP("Cosmetic Arc"); | |
| sToolTipText = QT_TR_NOOP("Adds a cosmetic counter clockwise arc based on three vertices, " | |
| "where the first selection is the center point and the second is the radius and start point"); | |
| sWhatsThis = "TechDraw_ExtensionDrawCosmArc"; | |
| sStatusTip = sMenuText; | |
| sPixmap = "TechDraw_ExtensionDrawCosmArc"; | |
| } | |
| void CmdTechDrawExtensionDrawCosmArc::activated(int iMsg) | |
| { | |
| Q_UNUSED(iMsg); | |
| //Base::Console().message("Cosmetic Arc started\n"); | |
| execDrawCosmArc(this); | |
| } | |
| bool CmdTechDrawExtensionDrawCosmArc::isActive() | |
| { | |
| bool havePage = DrawGuiUtil::needPage(this); | |
| bool haveView = DrawGuiUtil::needView(this); | |
| return (havePage && haveView); | |
| } | |
| //=========================================================================== | |
| // TechDraw_ExtensionDrawCosmCircle | |
| //=========================================================================== | |
| void execDrawCosmCircle(Gui::Command* cmd) | |
| { | |
| //draw a cosmetic circle | |
| std::vector<Gui::SelectionObject> selection; | |
| TechDraw::DrawViewPart* objFeat{nullptr}; | |
| if (!_checkSel(cmd, selection, objFeat, QT_TRANSLATE_NOOP("Command","TechDraw cosmetic circle"))) { | |
| return; | |
| } | |
| Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Cosmetic Circle")); | |
| const std::vector<std::string> SubNames = selection[0].getSubNames(); | |
| std::vector<Base::Vector3d> vertexPoints; | |
| vertexPoints = _getVertexPoints(SubNames, objFeat); | |
| if (vertexPoints.size() >= 2) { | |
| double circleRadius = (vertexPoints[1] - vertexPoints[0]).Length() / objFeat->getScale(); | |
| auto center = CosmeticVertex::makeCanonicalPointInverted(objFeat, vertexPoints[0]); | |
| TechDraw::BaseGeomPtr baseGeo = | |
| std::make_shared<TechDraw::Circle>(center, circleRadius); | |
| std::string circleTag = objFeat->addCosmeticEdge(baseGeo); | |
| TechDraw::CosmeticEdge* circleEdge = objFeat->getCosmeticEdge(circleTag); | |
| _setLineAttributes(circleEdge); | |
| objFeat->refreshCEGeoms(); | |
| objFeat->requestPaint(); | |
| cmd->getSelection().clearSelection(); | |
| Gui::Command::commitCommand(); | |
| } | |
| } | |
| DEF_STD_CMD_A(CmdTechDrawExtensionDrawCosmCircle) | |
| CmdTechDrawExtensionDrawCosmCircle::CmdTechDrawExtensionDrawCosmCircle() | |
| : Command("TechDraw_ExtensionDrawCosmCircle") | |
| { | |
| sAppModule = "TechDraw"; | |
| sGroup = QT_TR_NOOP("TechDraw"); | |
| sMenuText = QT_TR_NOOP("Cosmetic 2 Point Circle"); | |
| sToolTipText = QT_TR_NOOP("Adds a cosmetic circle based on two selected vertices, where the first is the center point and the second is the radius"); | |
| sWhatsThis = "TechDraw_ExtensionDrawCosmCircle"; | |
| sStatusTip = sToolTipText; | |
| sPixmap = "TechDraw_ExtensionDrawCosmCircle"; | |
| } | |
| void CmdTechDrawExtensionDrawCosmCircle::activated(int iMsg) | |
| { | |
| Q_UNUSED(iMsg); | |
| //Base::Console().message("Cosmetic Circle started\n"); | |
| execDrawCosmCircle(this); | |
| } | |
| bool CmdTechDrawExtensionDrawCosmCircle::isActive() | |
| { | |
| bool havePage = DrawGuiUtil::needPage(this); | |
| bool haveView = DrawGuiUtil::needView(this); | |
| return (havePage && haveView); | |
| } | |
| //=========================================================================== | |
| // TechDraw_ExtensionDrawCosmCircle3Points | |
| //=========================================================================== | |
| void execDrawCosmCircle3Points(Gui::Command* cmd) | |
| { | |
| //draw a cosmetic circle through 3 points | |
| std::vector<Gui::SelectionObject> selection; | |
| TechDraw::DrawViewPart* objFeat{nullptr}; | |
| if (!_checkSel(cmd, selection, objFeat, QT_TRANSLATE_NOOP("Command","TechDraw Cosmetic Circle 3 Points"))) { | |
| return; | |
| } | |
| Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Cosmetic Circle 3 Points")); | |
| const std::vector<std::string> SubNames = selection[0].getSubNames(); | |
| std::vector<Base::Vector3d> vertexPoints; | |
| vertexPoints = _getVertexPoints(SubNames, objFeat); | |
| if (vertexPoints.size() >= 3) { | |
| Base::Vector3d circleCenter = _circleCenter(vertexPoints[0], | |
| vertexPoints[1], | |
| vertexPoints[2]); | |
| double circleRadius = (vertexPoints[0] - circleCenter).Length() / objFeat->getScale(); | |
| circleCenter = CosmeticVertex::makeCanonicalPointInverted(objFeat, circleCenter); | |
| TechDraw::BaseGeomPtr theCircle = | |
| std::make_shared<TechDraw::Circle>(circleCenter, circleRadius); | |
| std::string circleTag = objFeat->addCosmeticEdge(theCircle); | |
| TechDraw::CosmeticEdge* circleEdge = objFeat->getCosmeticEdge(circleTag); | |
| _setLineAttributes(circleEdge); | |
| objFeat->refreshCEGeoms(); | |
| objFeat->requestPaint(); | |
| cmd->getSelection().clearSelection(); | |
| Gui::Command::commitCommand(); | |
| } | |
| } | |
| DEF_STD_CMD_A(CmdTechDrawExtensionDrawCosmCircle3Points) | |
| CmdTechDrawExtensionDrawCosmCircle3Points::CmdTechDrawExtensionDrawCosmCircle3Points() | |
| : Command("TechDraw_ExtensionDrawCosmCircle3Points") | |
| { | |
| sAppModule = "TechDraw"; | |
| sGroup = QT_TR_NOOP("TechDraw"); | |
| sMenuText = QT_TR_NOOP("Cosmetic 3 Point Circle"); | |
| sToolTipText = QT_TR_NOOP("Adds a cosmetic circle that passes through 3 selected perimeter points"); | |
| sWhatsThis = "TechDraw_ExtensionDrawCosmCircle3Points"; | |
| sStatusTip = sMenuText; | |
| sPixmap = "TechDraw_ExtensionDrawCosmCircle3Points"; | |
| } | |
| void CmdTechDrawExtensionDrawCosmCircle3Points::activated(int iMsg) | |
| { | |
| Q_UNUSED(iMsg); | |
| //Base::Console().message("Cosmetic Circle 3 Points started\n"); | |
| execDrawCosmCircle3Points(this); | |
| } | |
| bool CmdTechDrawExtensionDrawCosmCircle3Points::isActive() | |
| { | |
| bool havePage = DrawGuiUtil::needPage(this); | |
| bool haveView = DrawGuiUtil::needView(this); | |
| return (havePage && haveView); | |
| } | |
| //=========================================================================== | |
| // TechDraw_ExtensionDrawCirclesGroup | |
| //=========================================================================== | |
| DEF_STD_CMD_ACL(CmdTechDrawExtensionDrawCirclesGroup) | |
| CmdTechDrawExtensionDrawCirclesGroup::CmdTechDrawExtensionDrawCirclesGroup() | |
| : Command("TechDraw_ExtensionDrawCirclesGroup") | |
| { | |
| sAppModule = "TechDraw"; | |
| sGroup = QT_TR_NOOP("TechDraw"); | |
| sMenuText = QT_TR_NOOP("Cosmetic 1 Point Circle"); | |
| sToolTipText = QT_TR_NOOP("Adds a cosmetic circle based on two vertices, where the first selection is the centerpoint and the second is the radius"); | |
| sWhatsThis = "TechDraw_ExtensionDrawCirclesGroup"; | |
| sStatusTip = sMenuText; | |
| } | |
| void CmdTechDrawExtensionDrawCirclesGroup::activated(int iMsg) | |
| { | |
| // Base::Console().message("CMD::ExtensionDrawCirclesGroup - activated(%d)\n", iMsg); | |
| Gui::TaskView::TaskDialog* dlg = Gui::Control().activeDialog(); | |
| if (dlg) { | |
| QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Task in progress"), | |
| QObject::tr("Close active task dialog and try again.")); | |
| return; | |
| } | |
| auto pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction); | |
| pcAction->setIcon(pcAction->actions().at(iMsg)->icon()); | |
| switch (iMsg) { | |
| case 0: // 1 Point Circle | |
| execCosmeticCircleCenter(this); | |
| break; | |
| case 1: // 2 Point Circle | |
| execDrawCosmCircle(this); | |
| break; | |
| case 2: // 3 Point Circle | |
| execDrawCosmCircle3Points(this); | |
| break; | |
| case 3: // Cosmetic Arc | |
| execDrawCosmArc(this); | |
| break; | |
| default: | |
| Base::Console().message("CMD::CVGrp - invalid iMsg: %d\n", iMsg); | |
| }; | |
| } | |
| Gui::Action* CmdTechDrawExtensionDrawCirclesGroup::createAction() | |
| { | |
| Gui::ActionGroup* pcAction = new Gui::ActionGroup(this, Gui::getMainWindow()); | |
| pcAction->setDropDownMenu(true); | |
| applyCommandData(this->className(), pcAction); | |
| QAction* p1 = pcAction->addAction(QString()); | |
| p1->setIcon(Gui::BitmapFactory().iconFromTheme("actions/TechDraw_CosmeticCircle")); | |
| p1->setObjectName(QStringLiteral("TechDraw_CosmeticCircle")); | |
| p1->setWhatsThis(QStringLiteral("TechDraw_CosmeticCircle")); | |
| QAction* p2 = pcAction->addAction(QString()); | |
| p2->setIcon(Gui::BitmapFactory().iconFromTheme("TechDraw_ExtensionDrawCosmCircle")); | |
| p2->setObjectName(QStringLiteral("TechDraw_ExtensionDrawCosmCircle")); | |
| p2->setWhatsThis(QStringLiteral("TechDraw_ExtensionDrawCosmCircle")); | |
| QAction* p3 = pcAction->addAction(QString()); | |
| p3->setIcon(Gui::BitmapFactory().iconFromTheme("TechDraw_ExtensionDrawCosmCircle3Points")); | |
| p3->setObjectName(QStringLiteral("TechDraw_ExtensionDrawCosmCircle3Points")); | |
| p3->setWhatsThis(QStringLiteral("TechDraw_ExtensionDrawCosmCircle3Points")); | |
| QAction* p4 = pcAction->addAction(QString()); | |
| p4->setIcon(Gui::BitmapFactory().iconFromTheme("TechDraw_ExtensionDrawCosmArc")); | |
| p4->setObjectName(QStringLiteral("TechDraw_ExtensionDrawCosmArc")); | |
| p4->setWhatsThis(QStringLiteral("TechDraw_ExtensionDrawCosmArc")); | |
| _pcAction = pcAction; | |
| languageChange(); | |
| pcAction->setIcon(p1->icon()); | |
| int defaultId = 0; | |
| pcAction->setProperty("defaultAction", QVariant(defaultId)); | |
| return pcAction; | |
| } | |
| void CmdTechDrawExtensionDrawCirclesGroup::languageChange() | |
| { | |
| Command::languageChange(); | |
| if (!_pcAction) { | |
| return; | |
| } | |
| auto pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction); | |
| QList<QAction*> action = pcAction->actions(); | |
| QAction* p1 = action[0]; | |
| p1->setText(QApplication::translate("CmdTechDrawCosmeticCircle", | |
| "Cosmetic 1 Point Circle")); | |
| p1->setToolTip(QApplication::translate("CmdTechDrawCosmeticCircle", | |
| "Adds a cosmetic circle based on a selected centerpoint")); | |
| p1->setStatusTip(p1->text()); | |
| QAction* p2 = action[1]; | |
| p2->setText(QApplication::translate("CmdTechDrawExtensionDrawCosmCircle", | |
| "Cosmetic 2 Point Circle")); | |
| p2->setToolTip(QApplication::translate("CmdTechDrawExtensionDrawCosmCircle", | |
| "Adds a cosmetic circle based on two vertices, where " | |
| "the first selection is the centerpoint and the second is the radius")); | |
| p2->setStatusTip(p2->text()); | |
| QAction* p3 = action[2]; | |
| p3->setText(QApplication::translate("CmdTechDrawExtensionDrawCosmCircle3Points", | |
| "Cosmetic 3 Point Circle")); | |
| p3->setToolTip(QApplication::translate("CmdTechDrawExtensionDrawCosmCircle3Points", | |
| "Adds a cosmetic circle that passes through 3 selected perimeter points")); | |
| p3->setStatusTip(p3->text()); | |
| QAction* p4 = action[3]; | |
| p4->setText(QApplication::translate("CmdTechDrawExtensionDrawCosmArc", "Cosmetic Arc")); | |
| p4->setToolTip(QApplication::translate("CmdTechDrawExtensionDrawCosmArc", | |
| "Adds a cosmetic counter clockwise arc based on three vertices, " | |
| "where the first selection is the center point and the second is the radius and start point.")); | |
| p4->setStatusTip(p4->text()); | |
| } | |
| bool CmdTechDrawExtensionDrawCirclesGroup::isActive() | |
| { | |
| bool havePage = DrawGuiUtil::needPage(this); | |
| bool haveView = DrawGuiUtil::needView(this, true); | |
| return (havePage && haveView); | |
| } | |
| //=========================================================================== | |
| // TechDraw_ExtensionLineParallel | |
| //=========================================================================== | |
| void execLineParallelPerpendicular(Gui::Command* cmd, bool isParallel) | |
| { | |
| // create a line parallel or perpendicular to another line | |
| std::vector<Gui::SelectionObject> selection; | |
| TechDraw::DrawViewPart* objFeat{nullptr}; | |
| if (!_checkSel(cmd, selection, objFeat, QT_TRANSLATE_NOOP("Command","TechDraw Cosmetic Line Parallel/Perpendicular"))) { | |
| return; | |
| } | |
| Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Cosmetic Line Parallel/Perpendicular")); | |
| const std::vector<std::string> SubNames = selection[0].getSubNames(); | |
| if (SubNames.size() >= 2) { | |
| std::string GeoType1 = TechDraw::DrawUtil::getGeomTypeFromName(SubNames[0]); | |
| std::string GeoType2 = TechDraw::DrawUtil::getGeomTypeFromName(SubNames[1]); | |
| int EdgeId{-1}; | |
| int VertId{-1}; | |
| if (GeoType1 == "Edge" && GeoType2 == "Vertex") { | |
| EdgeId = TechDraw::DrawUtil::getIndexFromName(SubNames[0]); | |
| VertId = TechDraw::DrawUtil::getIndexFromName(SubNames[1]); | |
| } else if (GeoType2 == "Edge" && GeoType1 == "Vertex") { | |
| EdgeId = TechDraw::DrawUtil::getIndexFromName(SubNames[1]); | |
| VertId = TechDraw::DrawUtil::getIndexFromName(SubNames[0]); | |
| } else { | |
| // we don't have an edge + vertex as selection | |
| return; | |
| } | |
| TechDraw::BaseGeomPtr geom1 = objFeat->getGeomByIndex(EdgeId); | |
| TechDraw::GenericPtr lineGen = std::static_pointer_cast<TechDraw::Generic>(geom1); | |
| // ends are scaled and rotated | |
| Base::Vector3d lineStart = lineGen->points.at(0); | |
| lineStart = CosmeticVertex::makeCanonicalPointInverted(objFeat, lineStart); | |
| Base::Vector3d lineEnd = lineGen->points.at(1); | |
| lineEnd = CosmeticVertex::makeCanonicalPointInverted(objFeat, lineEnd); | |
| TechDraw::VertexPtr vert = objFeat->getProjVertexByIndex(VertId); | |
| Base::Vector3d vertexPoint(vert->point().x, vert->point().y, 0.0); | |
| vertexPoint = CosmeticVertex::makeCanonicalPointInverted(objFeat, vertexPoint); | |
| Base::Vector3d halfVector = (lineEnd - lineStart) / 2.0; | |
| if (!isParallel) { | |
| float dummy = halfVector.x; | |
| halfVector.x = -halfVector.y; | |
| halfVector.y = dummy; | |
| } | |
| Base::Vector3d startPoint = vertexPoint + halfVector; | |
| Base::Vector3d endPoint = vertexPoint - halfVector; | |
| TechDraw::BaseGeomPtr cLine = CosmeticEdge::makeLineFromCanonicalPoints(startPoint, endPoint); | |
| std::string lineTag = objFeat->addCosmeticEdge(cLine); | |
| TechDraw::CosmeticEdge* lineEdge = objFeat->getCosmeticEdge(lineTag); | |
| _setLineAttributes(lineEdge); | |
| objFeat->refreshCEGeoms(); | |
| objFeat->requestPaint(); | |
| cmd->getSelection().clearSelection(); | |
| } | |
| Gui::Command::commitCommand(); | |
| } | |
| DEF_STD_CMD_A(CmdTechDrawExtensionLineParallel) | |
| CmdTechDrawExtensionLineParallel::CmdTechDrawExtensionLineParallel() | |
| : Command("TechDraw_ExtensionLineParallel") | |
| { | |
| sAppModule = "TechDraw"; | |
| sGroup = QT_TR_NOOP("TechDraw"); | |
| sMenuText = QT_TR_NOOP("Cosmetic Parallel Line"); | |
| sToolTipText = QT_TR_NOOP("Adds a cosmetic circle to 3 selected vertices"); | |
| sWhatsThis = "TechDraw_ExtensionLineParallel"; | |
| sStatusTip = sMenuText; | |
| sPixmap = "TechDraw_ExtensionLineParallel"; | |
| } | |
| void CmdTechDrawExtensionLineParallel::activated(int iMsg) | |
| { | |
| Q_UNUSED(iMsg); | |
| execLineParallelPerpendicular(this, true); | |
| } | |
| bool CmdTechDrawExtensionLineParallel::isActive() | |
| { | |
| bool havePage = DrawGuiUtil::needPage(this); | |
| bool haveView = DrawGuiUtil::needView(this); | |
| return (havePage && haveView); | |
| } | |
| //=========================================================================== | |
| // TechDraw_ExtensionLinePerpendicular | |
| //=========================================================================== | |
| DEF_STD_CMD_A(CmdTechDrawExtensionLinePerpendicular) | |
| CmdTechDrawExtensionLinePerpendicular::CmdTechDrawExtensionLinePerpendicular() | |
| : Command("TechDraw_ExtensionLinePerpendicular") | |
| { | |
| sAppModule = "TechDraw"; | |
| sGroup = QT_TR_NOOP("TechDraw"); | |
| sMenuText = QT_TR_NOOP("Cosmetic Perpendicular Line"); | |
| sToolTipText = | |
| QT_TR_NOOP("Adds a cosmetic line perpendicular to the selected line through the selected vertex"); | |
| sWhatsThis = "TechDraw_ExtensionLinePerpendicular"; | |
| sStatusTip = sMenuText; | |
| sPixmap = "TechDraw_ExtensionLinePerpendicular"; | |
| } | |
| void CmdTechDrawExtensionLinePerpendicular::activated(int iMsg) | |
| { | |
| Q_UNUSED(iMsg); | |
| execLineParallelPerpendicular(this, false); | |
| } | |
| bool CmdTechDrawExtensionLinePerpendicular::isActive() | |
| { | |
| bool havePage = DrawGuiUtil::needPage(this); | |
| bool haveView = DrawGuiUtil::needView(this); | |
| return (havePage && haveView); | |
| } | |
| //=========================================================================== | |
| // TechDraw_ExtensionLinePPGroup | |
| //=========================================================================== | |
| DEF_STD_CMD_ACL(CmdTechDrawExtensionLinePPGroup) | |
| CmdTechDrawExtensionLinePPGroup::CmdTechDrawExtensionLinePPGroup() | |
| : Command("TechDraw_ExtensionLinePPGroup") | |
| { | |
| sAppModule = "TechDraw"; | |
| sGroup = QT_TR_NOOP("TechDraw"); | |
| sMenuText = QT_TR_NOOP("Cosmetic Parallel Line"); | |
| sToolTipText = QT_TR_NOOP("Adds a cosmetic line parallel to the selected line through the selected vertex"); | |
| sWhatsThis = "TechDraw_ExtensionLinePPGroup"; | |
| sStatusTip = sMenuText; | |
| } | |
| void CmdTechDrawExtensionLinePPGroup::activated(int iMsg) | |
| { | |
| // Base::Console().message("CMD::ExtensionLinePPGroup - activated(%d)\n", iMsg); | |
| Gui::TaskView::TaskDialog* dlg = Gui::Control().activeDialog(); | |
| if (dlg) { | |
| QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Task in progress"), | |
| QObject::tr("Close active task dialog and try again.")); | |
| return; | |
| } | |
| auto pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction); | |
| pcAction->setIcon(pcAction->actions().at(iMsg)->icon()); | |
| switch (iMsg) { | |
| case 0://create parallel line | |
| execLineParallelPerpendicular(this, true); | |
| break; | |
| case 1://create perpendicular line | |
| execLineParallelPerpendicular(this, false); | |
| break; | |
| default: | |
| Base::Console().message("CMD::CVGrp - invalid iMsg: %d\n", iMsg); | |
| }; | |
| } | |
| Gui::Action* CmdTechDrawExtensionLinePPGroup::createAction() | |
| { | |
| Gui::ActionGroup* pcAction = new Gui::ActionGroup(this, Gui::getMainWindow()); | |
| pcAction->setDropDownMenu(true); | |
| applyCommandData(this->className(), pcAction); | |
| QAction* p1 = pcAction->addAction(QString()); | |
| p1->setIcon(Gui::BitmapFactory().iconFromTheme("TechDraw_ExtensionLineParallel")); | |
| p1->setObjectName(QStringLiteral("TechDraw_ExtensionLineParallel")); | |
| p1->setWhatsThis(QStringLiteral("TechDraw_ExtensionLineParallel")); | |
| QAction* p2 = pcAction->addAction(QString()); | |
| p2->setIcon(Gui::BitmapFactory().iconFromTheme("TechDraw_ExtensionLinePerpendicular")); | |
| p2->setObjectName(QStringLiteral("TechDraw_ExtensionLinePerpendicular")); | |
| p2->setWhatsThis(QStringLiteral("TechDraw_ExtensionLinePerpendicular")); | |
| _pcAction = pcAction; | |
| languageChange(); | |
| pcAction->setIcon(p1->icon()); | |
| int defaultId = 0; | |
| pcAction->setProperty("defaultAction", QVariant(defaultId)); | |
| return pcAction; | |
| } | |
| void CmdTechDrawExtensionLinePPGroup::languageChange() | |
| { | |
| Command::languageChange(); | |
| if (!_pcAction) { | |
| return; | |
| } | |
| Gui::ActionGroup* pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction); | |
| QList<QAction*> action = pcAction->actions(); | |
| QAction* arc1 = action[0]; | |
| arc1->setText( | |
| QApplication::translate("CmdTechDrawExtensionLineParallel", "Cosmetic Parallel Line")); | |
| arc1->setToolTip( | |
| QApplication::translate("CmdTechDrawExtensionLineParallel", | |
| "Adds a cosmetic line parallel to the selected line through the selected vertex")); | |
| arc1->setStatusTip(arc1->text()); | |
| QAction* arc2 = action[1]; | |
| arc2->setText(QApplication::translate("CmdTechDrawExtensionLinePerpendicular", | |
| "Cosmetic Perpendicular Line")); | |
| arc2->setToolTip(QApplication::translate( | |
| "CmdTechDrawExtensionLinePerpendicular", | |
| "Adds a cosmetic line perpendicular to the selected line through the selected vertex")); | |
| arc2->setStatusTip(arc2->text()); | |
| } | |
| bool CmdTechDrawExtensionLinePPGroup::isActive() | |
| { | |
| bool havePage = DrawGuiUtil::needPage(this); | |
| bool haveView = DrawGuiUtil::needView(this, true); | |
| return (havePage && haveView); | |
| } | |
| //=========================================================================== | |
| // TechDraw_ExtensionLockUnlockView | |
| //=========================================================================== | |
| DEF_STD_CMD_A(CmdTechDrawExtensionLockUnlockView) | |
| CmdTechDrawExtensionLockUnlockView::CmdTechDrawExtensionLockUnlockView() | |
| : Command("TechDraw_ExtensionLockUnlockView") | |
| { | |
| sAppModule = "TechDraw"; | |
| sGroup = QT_TR_NOOP("TechDraw"); | |
| sMenuText = QT_TR_NOOP("Toggle View Lock"); | |
| sToolTipText = QT_TR_NOOP("Locks or unlocks the position of the selected views"); | |
| sWhatsThis = "TechDraw_ExtensionLockUnlockView"; | |
| sStatusTip = sMenuText; | |
| sPixmap = "TechDraw_ExtensionLockUnlockView"; | |
| } | |
| void CmdTechDrawExtensionLockUnlockView::activated(int iMsg) | |
| { | |
| Q_UNUSED(iMsg); | |
| std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx(); | |
| if (selection.empty()) { | |
| return; | |
| } | |
| Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Lock/Unlock View")); | |
| for (auto& sel : selection) { | |
| auto* obj = static_cast<TechDraw::DrawViewPart*>(sel.getObject()); | |
| if (obj->isDerivedFrom<TechDraw::DrawViewPart>()) { | |
| bool lockPosition = obj->LockPosition.getValue(); | |
| lockPosition = !lockPosition; | |
| obj->LockPosition.setValue(lockPosition); | |
| } | |
| } | |
| Gui::Command::commitCommand(); | |
| } | |
| bool CmdTechDrawExtensionLockUnlockView::isActive() | |
| { | |
| bool havePage = DrawGuiUtil::needPage(this); | |
| bool haveView = DrawGuiUtil::needView(this); | |
| return (havePage && haveView); | |
| } | |
| //=========================================================================== | |
| // TechDraw_ExtensionExtendLine | |
| //=========================================================================== | |
| void execExtendShortenLine(Gui::Command* cmd, bool extend) | |
| { | |
| // extend or shorten a cosmetic line or a centerline | |
| std::vector<Gui::SelectionObject> selection; | |
| TechDraw::DrawViewPart* objFeat{nullptr}; | |
| if (!_checkSel(cmd, selection, objFeat, QT_TRANSLATE_NOOP("Command","TechDraw Extend/Shorten Line"))) { | |
| return; | |
| } | |
| Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Extend/shorten line")); | |
| const std::vector<std::string> subNames = selection[0].getSubNames(); | |
| if (!subNames.empty()) { | |
| std::string name = subNames[0]; | |
| int num = DrawUtil::getIndexFromName(name); | |
| std::string geoType = TechDraw::DrawUtil::getGeomTypeFromName(name); | |
| if (geoType == "Edge") { | |
| TechDraw::BaseGeomPtr baseGeo = objFeat->getGeomByIndex(num); | |
| if (baseGeo) { | |
| if (baseGeo->getGeomType() == GeomType::GENERIC) { | |
| // start and end points are geometry points and are scaled, rotated and inverted | |
| // convert start and end to unscaled, unrotated. | |
| Base::Vector3d P0 = CosmeticVertex::makeCanonicalPointInverted(objFeat, baseGeo->getStartPoint()); | |
| Base::Vector3d P1 = CosmeticVertex::makeCanonicalPointInverted(objFeat, baseGeo->getEndPoint()); | |
| bool isCenterLine = false; | |
| TechDraw::CenterLine* centerEdge = nullptr; | |
| if (baseGeo->getCosmetic()) { | |
| std::string uniTag = baseGeo->getCosmeticTag(); | |
| int oldStyle = 1; | |
| float oldWeight = 1.0; | |
| Base::Color oldColor; | |
| std::vector<std::string> toDelete; | |
| toDelete.push_back(uniTag); | |
| if (baseGeo->source() == SourceType::COSMETICEDGE) { | |
| // cosmetic edge | |
| auto cosEdge = objFeat->getCosmeticEdge(uniTag); | |
| oldStyle = cosEdge->m_format.getLineNumber(); | |
| oldWeight = cosEdge->m_format.getWidth(); | |
| oldColor = cosEdge->m_format.getColor(); | |
| objFeat->removeCosmeticEdge(toDelete); | |
| } | |
| else if (baseGeo->source() == SourceType::CENTERLINE) { | |
| // centerline | |
| isCenterLine = true; | |
| centerEdge = objFeat->getCenterLine(uniTag); | |
| } | |
| Base::Vector3d direction = (P1 - P0).Normalize(); | |
| Base::Vector3d delta = direction * activeDimAttributes.getLineStretch(); | |
| Base::Vector3d startPt, endPt; | |
| if (extend) { | |
| // make it longer | |
| startPt = P0 - delta; | |
| endPt = P1 + delta; | |
| } | |
| else { | |
| // make it shorter | |
| startPt = P0 + delta; | |
| endPt = P1 - delta; | |
| } | |
| // startPt.y = -startPt.y; | |
| // endPt.y = -endPt.y; | |
| if (isCenterLine) { | |
| if (extend) { | |
| centerEdge->m_extendBy += activeDimAttributes.getLineStretch(); | |
| } else { | |
| centerEdge->m_extendBy -= activeDimAttributes.getLineStretch(); | |
| } | |
| objFeat->refreshCLGeoms(); | |
| } | |
| else { | |
| std::string lineTag = | |
| objFeat->addCosmeticEdge(startPt, endPt); | |
| TechDraw::CosmeticEdge* lineEdge = objFeat->getCosmeticEdge(lineTag); | |
| _setLineAttributes(lineEdge, oldStyle, oldWeight, oldColor); | |
| objFeat->refreshCEGeoms(); | |
| } | |
| objFeat->requestPaint(); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| Gui::Command::commitCommand(); | |
| } | |
| DEF_STD_CMD_A(CmdTechDrawExtensionExtendLine) | |
| CmdTechDrawExtensionExtendLine::CmdTechDrawExtensionExtendLine() | |
| : Command("TechDraw_ExtensionExtendLine") | |
| { | |
| sAppModule = "TechDraw"; | |
| sGroup = QT_TR_NOOP("TechDraw"); | |
| sMenuText = QT_TR_NOOP("Extend Line"); | |
| sToolTipText = QT_TR_NOOP("Extends a selected cosmetic line or centerline at both ends by the specified delta distance"); | |
| sWhatsThis = "TechDraw_ExtensionExtendLine"; | |
| sStatusTip = sToolTipText; | |
| sPixmap = "TechDraw_ExtensionExtendLine"; | |
| } | |
| void CmdTechDrawExtensionExtendLine::activated(int iMsg) | |
| { | |
| Q_UNUSED(iMsg); | |
| execExtendShortenLine(this, true); | |
| ///Base::Console().message("ExtendLine started\n"); | |
| } | |
| bool CmdTechDrawExtensionExtendLine::isActive() | |
| { | |
| bool havePage = DrawGuiUtil::needPage(this); | |
| bool haveView = DrawGuiUtil::needView(this); | |
| return (havePage && haveView); | |
| } | |
| //=========================================================================== | |
| // TechDraw_ExtensionShortenLine | |
| //=========================================================================== | |
| DEF_STD_CMD_A(CmdTechDrawExtensionShortenLine) | |
| CmdTechDrawExtensionShortenLine::CmdTechDrawExtensionShortenLine() | |
| : Command("TechDraw_ExtensionShortenLine") | |
| { | |
| sAppModule = "TechDraw"; | |
| sGroup = QT_TR_NOOP("TechDraw"); | |
| sMenuText = QT_TR_NOOP("Shorten Line"); | |
| sToolTipText = QT_TR_NOOP("Shortens a selected cosmetic line or centerline at both ends by the specified delta distance"); | |
| sWhatsThis = "TechDraw_ExtensionShortenLine"; | |
| sStatusTip = sMenuText; | |
| sPixmap = "TechDraw_ExtensionShortenLine"; | |
| } | |
| void CmdTechDrawExtensionShortenLine::activated(int iMsg) | |
| { | |
| Q_UNUSED(iMsg); | |
| execExtendShortenLine(this, false); | |
| ///Base::Console().message("ShortenLine started\n"); | |
| } | |
| bool CmdTechDrawExtensionShortenLine::isActive() | |
| { | |
| bool havePage = DrawGuiUtil::needPage(this); | |
| bool haveView = DrawGuiUtil::needView(this); | |
| return (havePage && haveView); | |
| } | |
| //=========================================================================== | |
| // TechDraw_ExtensionExtendShortenLineGroup | |
| //=========================================================================== | |
| DEF_STD_CMD_ACL(CmdTechDrawExtendShortenLineGroup) | |
| CmdTechDrawExtendShortenLineGroup::CmdTechDrawExtendShortenLineGroup() | |
| : Command("TechDraw_ExtensionExtendShortenLineGroup") | |
| { | |
| sAppModule = "TechDraw"; | |
| sGroup = QT_TR_NOOP("TechDraw"); | |
| sMenuText = QT_TR_NOOP("Extend Line"); | |
| sToolTipText = QT_TR_NOOP("Extends a selected cosmetic line or centerline at both ends by the specified delta distance"); | |
| sWhatsThis = "TechDraw_ExtensionExtendShortenLineGroup"; | |
| sStatusTip = sMenuText; | |
| } | |
| void CmdTechDrawExtendShortenLineGroup::activated(int iMsg) | |
| { | |
| // Base::Console().message("CMD::ExtendShortenLineGroup - activated(%d)\n", iMsg); | |
| Gui::TaskView::TaskDialog* dlg = Gui::Control().activeDialog(); | |
| if (dlg) { | |
| QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Task in progress"), | |
| QObject::tr("Close active task dialog and try again.")); | |
| return; | |
| } | |
| auto pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction); | |
| pcAction->setIcon(pcAction->actions().at(iMsg)->icon()); | |
| switch (iMsg) { | |
| case 0://extend a line | |
| execExtendShortenLine(this, true); | |
| break; | |
| case 1://shorten line | |
| execExtendShortenLine(this, false); | |
| break; | |
| default: | |
| Base::Console().message("CMD::CVGrp - invalid iMsg: %d\n", iMsg); | |
| }; | |
| } | |
| Gui::Action* CmdTechDrawExtendShortenLineGroup::createAction() | |
| { | |
| Gui::ActionGroup* pcAction = new Gui::ActionGroup(this, Gui::getMainWindow()); | |
| pcAction->setDropDownMenu(true); | |
| applyCommandData(this->className(), pcAction); | |
| QAction* p1 = pcAction->addAction(QString()); | |
| p1->setIcon(Gui::BitmapFactory().iconFromTheme("TechDraw_ExtensionExtendLine")); | |
| p1->setObjectName(QStringLiteral("TechDraw_ExtensionExtendLine")); | |
| p1->setWhatsThis(QStringLiteral("TechDraw_ExtensionExtendLine")); | |
| QAction* p2 = pcAction->addAction(QString()); | |
| p2->setIcon(Gui::BitmapFactory().iconFromTheme("TechDraw_ExtensionShortenLine")); | |
| p2->setObjectName(QStringLiteral("TechDraw_ExtensionShortenLine")); | |
| p2->setWhatsThis(QStringLiteral("TechDraw_ExtensionShortenLine")); | |
| _pcAction = pcAction; | |
| languageChange(); | |
| pcAction->setIcon(p1->icon()); | |
| int defaultId = 0; | |
| pcAction->setProperty("defaultAction", QVariant(defaultId)); | |
| return pcAction; | |
| } | |
| void CmdTechDrawExtendShortenLineGroup::languageChange() | |
| { | |
| Command::languageChange(); | |
| if (!_pcAction) { | |
| return; | |
| } | |
| Gui::ActionGroup* pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction); | |
| QList<QAction*> action = pcAction->actions(); | |
| QAction* arc1 = action[0]; | |
| arc1->setText(QApplication::translate("CmdTechDrawExtensionExtendLine", "Extend Line")); | |
| arc1->setToolTip(QApplication::translate( | |
| "CmdTechDrawExtensionExtendLine", "Extends a selected cosmetic line or centerline at both ends by the specified delta distance")); | |
| arc1->setStatusTip(arc1->text()); | |
| QAction* arc2 = action[1]; | |
| arc2->setText(QApplication::translate("CmdTechDrawExtensionShortenLine", "Shorten Line")); | |
| arc2->setToolTip(QApplication::translate( | |
| "CmdTechDrawExtensionShortenLine", "Shortens a selected cosmetic line or centerline at both ends by the specified delta distance")); | |
| arc2->setStatusTip(arc2->text()); | |
| } | |
| bool CmdTechDrawExtendShortenLineGroup::isActive() | |
| { | |
| bool havePage = DrawGuiUtil::needPage(this); | |
| bool haveView = DrawGuiUtil::needView(this, true); | |
| return (havePage && haveView); | |
| } | |
| //=========================================================================== | |
| // TechDraw_ExtensionAreaAnnotation | |
| //=========================================================================== | |
| DEF_STD_CMD_A(CmdTechDrawExtensionAreaAnnotation) | |
| CmdTechDrawExtensionAreaAnnotation::CmdTechDrawExtensionAreaAnnotation() | |
| : Command("TechDraw_ExtensionAreaAnnotation") | |
| { | |
| sAppModule = "TechDraw"; | |
| sGroup = QT_TR_NOOP("TechDraw"); | |
| sMenuText = QT_TR_NOOP("Area Annotation"); | |
| sToolTipText = QT_TR_NOOP("Calculates the area of multiple selected faces"); | |
| sWhatsThis = "TechDraw_ExtensionAreaAnnotation"; | |
| sStatusTip = sToolTipText; | |
| sPixmap = "TechDraw_ExtensionAreaAnnotation"; | |
| } | |
| void CmdTechDrawExtensionAreaAnnotation::activated(int iMsg) | |
| // calculate the area of selected faces, create output in a balloon | |
| { | |
| Q_UNUSED(iMsg); | |
| std::vector<Gui::SelectionObject> selection; | |
| TechDraw::DrawViewPart* objFeat{nullptr}; | |
| if (!_checkSel(this, selection, objFeat, QT_TRANSLATE_NOOP("Command","TechDraw Calculate Selected Area"))) { | |
| return; | |
| } | |
| // we must have at least 1 face in the selection | |
| const std::vector<std::string> subNamesAll = selection[0].getSubNames(); | |
| std::vector<std::string> subNames; | |
| for (auto& name : subNamesAll) { | |
| std::string geomType = DrawUtil::getGeomTypeFromName(name); | |
| if (geomType == "Face") { | |
| subNames.push_back(name); | |
| } | |
| } | |
| if (subNames.empty()) { | |
| QMessageBox::warning(Gui::getMainWindow(), | |
| QObject::tr("Incorrect selection"), | |
| QObject::tr("No faces in selection")); | |
| return; | |
| } | |
| // we have at least 1 face | |
| Base::Vector3d center; | |
| double totalArea = 0.0; | |
| for (const std::string& name : subNames) { | |
| TechDraw::FacePtr face = objFeat->getFace(name); | |
| if (!face) { | |
| continue; | |
| } | |
| GProp_GProps faceProps; | |
| BRepGProp::SurfaceProperties(face->toOccFace(), faceProps); | |
| double faceArea = faceProps.Mass(); | |
| totalArea += faceArea; | |
| center += faceArea*Base::convertTo<Base::Vector3d>(faceProps.CentreOfMass()); | |
| } | |
| if (totalArea > 0.0) { | |
| center /= totalArea; | |
| } | |
| // if area calculation was successful, start the command | |
| Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Calculate Face Area")); | |
| // at first we create the balloon | |
| std::string balloonName = _createBalloon(this, objFeat); | |
| TechDraw::DrawViewBalloon* balloon = nullptr; | |
| balloon = dynamic_cast<TechDraw::DrawViewBalloon*>( | |
| this->getDocument()->getObject(balloonName.c_str())); | |
| if (!balloon) { | |
| throw Base::TypeError("CmdTechDrawNewBalloon - balloon not found\n"); | |
| } | |
| // the balloon has been created successfully | |
| // calculate needed variables | |
| double scale = objFeat->getScale(); | |
| center = DrawUtil::invertY(center/scale); | |
| double scale2 = scale * scale; | |
| totalArea = totalArea / scale2;//convert from view scale to internal mm2 | |
| //make area unit-aware | |
| Base::Quantity asQuantity; | |
| asQuantity.setValue(totalArea); | |
| asQuantity.setUnit(Base::Unit::Area); | |
| QString qUserString = QString::fromStdString(asQuantity.getUserString()); | |
| if (qUserString.endsWith(QStringLiteral("^2"))) { | |
| qUserString.chop(2); | |
| qUserString.append(QStringLiteral("²")); | |
| } | |
| std::string sUserString = qUserString.toStdString(); | |
| // set the attributes in the data tab's fields | |
| // balloon->SourceView.setValue(objFeat); | |
| balloon->BubbleShape.setValue("Rectangle"); | |
| balloon->EndType.setValue("None"); | |
| balloon->KinkLength.setValue(0.0); | |
| balloon->X.setValue(center.x); | |
| balloon->Y.setValue(center.y); | |
| balloon->OriginX.setValue(center.x); | |
| balloon->OriginY.setValue(center.y); | |
| balloon->ScaleType.setValue("Page"); | |
| balloon->Text.setValue(sUserString); | |
| // look for the ballons's view provider | |
| TechDraw::DrawPage* page = objFeat->findParentPage(); | |
| Gui::Document* guiDoc = Gui::Application::Instance->getDocument(page->getDocument()); | |
| auto viewProvider = static_cast<ViewProviderBalloon*>(guiDoc->getViewProvider(balloon)); | |
| if (viewProvider) { | |
| // view provider successfully found, | |
| // set the attributes in the view tab's fields | |
| viewProvider->Fontsize.setValue(2.0); | |
| viewProvider->LineWidth.setValue(TechDraw::LineGroup::getDefaultWidth("Graphic")); | |
| viewProvider->LineVisible.setValue(false); | |
| viewProvider->Color.setValue(Base::Color(1.0, 0.0, 0.0)); | |
| } | |
| Gui::Command::commitCommand(); | |
| objFeat->touch(true); | |
| Gui::Command::updateActive(); | |
| } | |
| bool CmdTechDrawExtensionAreaAnnotation::isActive() | |
| { | |
| bool havePage = DrawGuiUtil::needPage(this); | |
| bool haveView = DrawGuiUtil::needView(this); | |
| return (havePage && haveView); | |
| } | |
| //=========================================================================== | |
| // TechDraw_ExtensionArcLengthAnnotation | |
| //=========================================================================== | |
| DEF_STD_CMD_A(CmdTechDrawExtensionArcLengthAnnotation) | |
| CmdTechDrawExtensionArcLengthAnnotation::CmdTechDrawExtensionArcLengthAnnotation() | |
| : Command("TechDraw_ExtensionArcLengthAnnotation") | |
| { | |
| sAppModule = "TechDraw"; | |
| sGroup = QT_TR_NOOP("TechDraw"); | |
| sMenuText = QT_TR_NOOP("Arc Length Annotation"); | |
| sToolTipText = QT_TR_NOOP("Inserts an annotation with the calculated arc length of the selected edges"); | |
| sWhatsThis = "TechDraw_ExtensionArcLengthAnnotation"; | |
| sStatusTip = sToolTipText; | |
| sPixmap = "TechDraw_ExtensionArcLengthAnnotation"; | |
| } | |
| void CmdTechDrawExtensionArcLengthAnnotation::activated(int iMsg) | |
| // Calculate the arc length of selected edge and create a balloon holding the datum | |
| { | |
| Q_UNUSED(iMsg); | |
| std::vector<Gui::SelectionObject> selection; | |
| TechDraw::DrawViewPart *objFeat{nullptr}; | |
| if (!_checkSel(this, selection, objFeat, QT_TRANSLATE_NOOP("Command", "TechDraw Calculate Selected Arc Length"))) { | |
| return; | |
| } | |
| // Collect all edges in the selection | |
| std::vector<std::string> subNames; | |
| for (auto &name : selection[0].getSubNames()) { | |
| if (DrawUtil::getGeomTypeFromName(name) == "Edge") { | |
| subNames.push_back(name); | |
| } | |
| } | |
| if (subNames.empty()) { | |
| QMessageBox::warning(Gui::getMainWindow(), | |
| QObject::tr("Incorrect selection"), | |
| QObject::tr("No edges in selection")); | |
| return; | |
| } | |
| // Now we have at least one edge | |
| std::vector<double> lengths(subNames.size()); | |
| double totalLength = 0.0; | |
| for (size_t iName = 0; iName < subNames.size(); ++iName) { | |
| lengths[iName] = totalLength; | |
| TechDraw::BaseGeomPtr edge = objFeat->getEdge(subNames[iName]); | |
| if (!edge) { | |
| continue; | |
| } | |
| GProp_GProps edgeProps; | |
| BRepGProp::LinearProperties(edge->getOCCEdge(), edgeProps); | |
| totalLength += edgeProps.Mass(); | |
| lengths[iName] = totalLength; | |
| } | |
| // We have calculated the length, let's start the command | |
| Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Calculate Edge Length")); | |
| // First we need to create the balloon | |
| std::string balloonName = _createBalloon(this, objFeat); | |
| auto balloon = dynamic_cast<TechDraw::DrawViewBalloon *>(getDocument()->getObject(balloonName.c_str())); | |
| if (!balloon) { | |
| throw Base::TypeError("CmdTechDrawNewBalloon - balloon not found\n"); | |
| } | |
| // Find the edge halving the selected path and the offset from its starting point | |
| double anchorLength = totalLength*0.5; | |
| size_t iLength = 0; | |
| while (iLength < lengths.size() && lengths[iLength] < anchorLength) { | |
| ++iLength; | |
| } | |
| if (iLength > 0) { | |
| anchorLength -= lengths[iLength - 1]; | |
| } | |
| // As reasonable anchor base point seems the "halving" edge endpoint | |
| BRepAdaptor_Curve curve(objFeat->getEdge(subNames[iLength])->getOCCEdge()); | |
| gp_Pnt midPoint; | |
| curve.D0(curve.LastParameter(), midPoint); | |
| // Now try to get the real path center which lies anchorLength from edge start point | |
| GCPnts_AbscissaPoint abscissa(Precision::Confusion(), curve, anchorLength, curve.FirstParameter()); | |
| if (abscissa.IsDone()) { | |
| curve.D0(abscissa.Parameter(), midPoint); | |
| } | |
| double scale = objFeat->getScale(); | |
| Base::Vector3d anchor = DrawUtil::invertY(Base::convertTo<Base::Vector3d>(midPoint)/scale); | |
| totalLength /= scale; | |
| // Use virtual dimension view helper to format resulting value | |
| TechDraw::DrawViewDimension helperDim; | |
| using Format = DimensionFormatter::Format; | |
| std::string valueStr = helperDim.formatValue(totalLength, | |
| QString::fromUtf8(helperDim.FormatSpec.getStrValue().data()), | |
| helperDim.isMultiValueSchema() ? Format::UNALTERED : Format::FORMATTED); | |
| balloon->Text.setValue("◠ " + valueStr); | |
| // Set balloon format to be referencing dimension-like | |
| int stdStyle = Preferences::getPreferenceGroup("Dimensions")->GetInt("StandardAndStyle", | |
| ViewProviderDimension::STD_STYLE_ISO_ORIENTED); | |
| bool asmeStyle = stdStyle == ViewProviderDimension::STD_STYLE_ASME_INLINED | |
| || stdStyle == ViewProviderDimension::STD_STYLE_ASME_REFERENCING; | |
| balloon->BubbleShape.setValue(asmeStyle ? "None" : "Line"); | |
| balloon->EndType.setValue(Preferences::getPreferenceGroup("Dimensions")->GetInt("ArrowStyle", 0)); | |
| balloon->OriginX.setValue(anchor.x); | |
| balloon->OriginY.setValue(anchor.y); | |
| // Set balloon label position a bit upwards and to the right, as QGSPage::createBalloon does | |
| double textOffset = 20.0/scale; | |
| balloon->X.setValue(anchor.x + textOffset); | |
| balloon->Y.setValue(anchor.y + textOffset); | |
| // Adjust the kink length accordingly to the standard used | |
| auto viewProvider = dynamic_cast<ViewProviderBalloon *>(Gui::Application::Instance->getViewProvider(balloon)); | |
| if (viewProvider) { | |
| balloon->KinkLength.setValue((asmeStyle ? 12.0 : 1.0)*viewProvider->LineWidth.getValue()); | |
| } | |
| // Close the command and update the view | |
| Gui::Command::commitCommand(); | |
| objFeat->touch(true); | |
| Gui::Command::updateActive(); | |
| } | |
| bool CmdTechDrawExtensionArcLengthAnnotation::isActive() | |
| { | |
| bool havePage = DrawGuiUtil::needPage(this); | |
| bool haveView = DrawGuiUtil::needView(this); | |
| return (havePage && haveView); | |
| } | |
| //=========================================================================== | |
| // internal helper routines | |
| //=========================================================================== | |
| namespace TechDrawGui | |
| { | |
| LineFormat& _getActiveLineAttributes() | |
| { | |
| return LineFormat::getCurrentLineFormat(); | |
| } | |
| std::string _createBalloon(Gui::Command* cmd, TechDraw::DrawViewPart* objFeat) | |
| // create a new balloon, return its name as string | |
| { | |
| std::string featName; | |
| TechDraw::DrawPage* page = objFeat->findParentPage(); | |
| Gui::Document* guiDoc = Gui::Application::Instance->getDocument(page->getDocument()); | |
| auto pageVP = freecad_cast<ViewProviderPage*>(guiDoc->getViewProvider(page)); | |
| if (pageVP) { | |
| QGSPage* scenePage = pageVP->getQGSPage(); | |
| featName = scenePage->getDrawPage()->getDocument()->getUniqueObjectName("Balloon"); | |
| std::string pageName = scenePage->getDrawPage()->getNameInDocument(); | |
| cmd->doCommand(cmd->Doc, | |
| "App.activeDocument().addObject('TechDraw::DrawViewBalloon', '%s')", | |
| featName.c_str()); | |
| cmd->doCommand(cmd->Doc, "App.activeDocument().%s.SourceView = (App.activeDocument().%s)", | |
| featName.c_str(), objFeat->getNameInDocument()); | |
| cmd->doCommand(cmd->Doc, "App.activeDocument().%s.addView(App.activeDocument().%s)", | |
| pageName.c_str(), featName.c_str()); | |
| } | |
| return featName; | |
| } | |
| bool _checkSel(Gui::Command* cmd, std::vector<Gui::SelectionObject>& selection, | |
| TechDraw::DrawViewPart*& objFeat, const std::string& message) | |
| { | |
| // check selection of getSelectionEx() and selection[0].getObject() | |
| selection = cmd->getSelection().getSelectionEx(); | |
| if (selection.empty()) { | |
| // message is translated in caller | |
| QMessageBox::warning(Gui::getMainWindow(), QString::fromUtf8(message.c_str()), | |
| QObject::tr("Selection is empty")); | |
| return false; | |
| } | |
| objFeat = dynamic_cast<TechDraw::DrawViewPart*>(selection[0].getObject()); | |
| if (!objFeat) { | |
| QMessageBox::warning(Gui::getMainWindow(), QString::fromUtf8(message.c_str()), | |
| QObject::tr("No object selected")); | |
| return false; | |
| } | |
| return true; | |
| } | |
| //! return the vertices in the selection as [Base::Vector3d] | |
| std::vector<Base::Vector3d> _getVertexPoints(const std::vector<std::string>& SubNames, | |
| TechDraw::DrawViewPart* objFeat) | |
| { | |
| std::vector<Base::Vector3d> vertexPoints; | |
| for (const std::string& Name : SubNames) { | |
| std::string GeoType = TechDraw::DrawUtil::getGeomTypeFromName(Name); | |
| if (GeoType == "Vertex") { | |
| int GeoId = TechDraw::DrawUtil::getIndexFromName(Name); | |
| TechDraw::VertexPtr vert = objFeat->getProjVertexByIndex(GeoId); | |
| vertexPoints.push_back(vert->point()); | |
| } | |
| } | |
| return vertexPoints; | |
| } | |
| //! get angle between x-axis and the vector from center to point. | |
| //! result is [0, 360] | |
| double _getAngle(Base::Vector3d center, Base::Vector3d point) | |
| { | |
| constexpr double DegreesHalfCircle{180.0}; | |
| Base::Vector3d vecCP = point - center; | |
| double angle = DU::angleWithX(vecCP) * DegreesHalfCircle / std::numbers::pi; | |
| return angle; | |
| } | |
| Base::Vector3d _circleCenter(Base::Vector3d p1, Base::Vector3d p2, Base::Vector3d p3) | |
| { | |
| Base::Vector2d v1(p1.x, p1.y); | |
| Base::Vector2d v2(p2.x, p2.y); | |
| Base::Vector2d v3(p3.x, p3.y); | |
| Base::Vector2d center = Part::Geom2dCircle::getCircleCenter(v1, v2, v3); | |
| return Base::Vector3d(center.x, center.y, 0.0); | |
| } | |
| void _createThreadCircle(const std::string Name, TechDraw::DrawViewPart* objFeat, double factor) | |
| { | |
| constexpr double ArcStartDegree{255.0}; | |
| constexpr double ArcEndDegree{165.0}; | |
| // create the 3/4 arc symbolizing a thread from top seen | |
| double scale = objFeat->getScale(); | |
| int GeoId = TechDraw::DrawUtil::getIndexFromName(Name); | |
| TechDraw::BaseGeomPtr geom = objFeat->getGeomByIndex(GeoId); | |
| std::string GeoType = TechDraw::DrawUtil::getGeomTypeFromName(Name); | |
| if (GeoType == "Edge" && geom->getGeomType() == GeomType::CIRCLE) { | |
| TechDraw::CirclePtr cgen = std::static_pointer_cast<TechDraw::Circle>(geom); | |
| // center is rotated and scaled | |
| Base::Vector3d center = CosmeticVertex::makeCanonicalPointInverted(objFeat, cgen->center); | |
| // radius is scaled | |
| float radius = cgen->radius * factor / scale; | |
| TechDraw::BaseGeomPtr threadArc = | |
| std::make_shared<TechDraw::AOC>(center, radius, ArcStartDegree, ArcEndDegree); | |
| std::string arcTag = objFeat->addCosmeticEdge(threadArc); | |
| TechDraw::CosmeticEdge* arc = objFeat->getCosmeticEdge(arcTag); | |
| _setLineAttributes(arc); | |
| } | |
| } | |
| void _createThreadLines(const std::vector<std::string>& SubNames, TechDraw::DrawViewPart* objFeat, | |
| double factor) | |
| { | |
| // create symbolizing lines of a thread from the side seen | |
| std::string GeoType0 = TechDraw::DrawUtil::getGeomTypeFromName(SubNames[0]); | |
| std::string GeoType1 = TechDraw::DrawUtil::getGeomTypeFromName(SubNames[1]); | |
| if ((GeoType0 == "Edge") && (GeoType1 == "Edge")) { | |
| int GeoId0 = TechDraw::DrawUtil::getIndexFromName(SubNames[0]); | |
| int GeoId1 = TechDraw::DrawUtil::getIndexFromName(SubNames[1]); | |
| TechDraw::BaseGeomPtr geom0 = objFeat->getGeomByIndex(GeoId0); | |
| TechDraw::BaseGeomPtr geom1 = objFeat->getGeomByIndex(GeoId1); | |
| if (geom0->getGeomType() != GeomType::GENERIC || geom1->getGeomType() != GeomType::GENERIC) { | |
| QMessageBox::warning(Gui::getMainWindow(), QObject::tr("TechDraw thread hole side"), | |
| QObject::tr("Select 2 straight lines")); | |
| return; | |
| } | |
| TechDraw::GenericPtr line0 = std::static_pointer_cast<TechDraw::Generic>(geom0); | |
| TechDraw::GenericPtr line1 = std::static_pointer_cast<TechDraw::Generic>(geom1); | |
| // start and end points are scaled,rotated and inverted (CSRIx). | |
| // convert start and end to unscaled, unrotated. | |
| Base::Vector3d start0 = CosmeticVertex::makeCanonicalPointInverted(objFeat, line0->getStartPoint()); | |
| Base::Vector3d start1 = CosmeticVertex::makeCanonicalPointInverted(objFeat, line1->getStartPoint()); | |
| Base::Vector3d end0 = CosmeticVertex::makeCanonicalPointInverted(objFeat, line0->getEndPoint()); | |
| Base::Vector3d end1 = CosmeticVertex::makeCanonicalPointInverted(objFeat, line1->getEndPoint()); | |
| if (DrawUtil::circulation(start0, end0, start1) | |
| != DrawUtil::circulation(end0, end1, start1)) { | |
| Base::Vector3d help1 = start1; | |
| Base::Vector3d help2 = end1; | |
| start1 = help2; | |
| end1 = help1; | |
| } | |
| float kernelDiam = (start1 - start0).Length(); | |
| float kernelFactor = (kernelDiam * factor - kernelDiam) / 2; | |
| Base::Vector3d delta = (start1 - start0).Normalize() * kernelFactor; | |
| std::string line0Tag = | |
| objFeat->addCosmeticEdge(start0 - delta, end0 - delta); | |
| std::string line1Tag = | |
| objFeat->addCosmeticEdge(start1 + delta, end1 + delta); | |
| TechDraw::CosmeticEdge* cosTag0 = objFeat->getCosmeticEdge(line0Tag); | |
| TechDraw::CosmeticEdge* cosTag1 = objFeat->getCosmeticEdge(line1Tag); | |
| _setLineAttributes(cosTag0); | |
| _setLineAttributes(cosTag1); | |
| } | |
| } | |
| void _setLineAttributes(TechDraw::CosmeticEdge* cosEdge) | |
| { | |
| // set line attributes of a cosmetic edge | |
| cosEdge->m_format.setStyle(_getActiveLineAttributes().getStyle()); | |
| cosEdge->m_format.setWidth(_getActiveLineAttributes().getWidth()); | |
| cosEdge->m_format.setColor(_getActiveLineAttributes().getColor()); | |
| cosEdge->m_format.setVisible(_getActiveLineAttributes().getVisible()); | |
| cosEdge->m_format.setLineNumber(_getActiveLineAttributes().getLineNumber()); | |
| } | |
| void _setLineAttributes(TechDraw::CenterLine* cosEdge) | |
| { | |
| // set line attributes of a cosmetic edge | |
| cosEdge->m_format.setStyle(_getActiveLineAttributes().getStyle()); | |
| cosEdge->m_format.setWidth(_getActiveLineAttributes().getWidth()); | |
| cosEdge->m_format.setColor(_getActiveLineAttributes().getColor()); | |
| cosEdge->m_format.setVisible(_getActiveLineAttributes().getVisible()); | |
| cosEdge->m_format.setLineNumber(_getActiveLineAttributes().getLineNumber()); | |
| } | |
| void _setLineAttributes(TechDraw::CosmeticEdge* cosEdge, int style, float weight, Base::Color color) | |
| { | |
| // set line attributes of a cosmetic edge | |
| cosEdge->m_format.setStyle(style); | |
| cosEdge->m_format.setWidth(weight); | |
| cosEdge->m_format.setColor(color); | |
| cosEdge->m_format.setVisible(_getActiveLineAttributes().getVisible()); | |
| cosEdge->m_format.setLineNumber(LineGenerator::fromQtStyle((Qt::PenStyle)style)); | |
| } | |
| void _setLineAttributes(TechDraw::CenterLine* cosEdge, int style, float weight, Base::Color color) | |
| { | |
| // set line attributes of a centerline | |
| cosEdge->m_format.setStyle(style); | |
| cosEdge->m_format.setWidth(weight); | |
| cosEdge->m_format.setColor(color); | |
| cosEdge->m_format.setVisible(_getActiveLineAttributes().getVisible()); | |
| cosEdge->m_format.setLineNumber(style);} | |
| }// namespace TechDrawGui | |
| //------------------------------------------------------------------------------ | |
| void CreateTechDrawCommandsExtensions() | |
| { | |
| Gui::CommandManager& rcCmdMgr = Gui::Application::Instance->commandManager(); | |
| rcCmdMgr.addCommand(new CmdTechDrawExtensionSelectLineAttributes()); | |
| rcCmdMgr.addCommand(new CmdTechDrawExtendShortenLineGroup()); | |
| rcCmdMgr.addCommand(new CmdTechDrawExtensionExtendLine()); | |
| rcCmdMgr.addCommand(new CmdTechDrawExtensionShortenLine()); | |
| rcCmdMgr.addCommand(new CmdTechDrawExtensionLockUnlockView()); | |
| rcCmdMgr.addCommand(new CmdTechDrawExtensionChangeLineAttributes()); | |
| rcCmdMgr.addCommand(new CmdTechDrawExtensionCircleCenterLinesGroup()); | |
| rcCmdMgr.addCommand(new CmdTechDrawExtensionCircleCenterLines()); | |
| rcCmdMgr.addCommand(new CmdTechDrawExtensionHoleCircle()); | |
| rcCmdMgr.addCommand(new CmdTechDrawExtensionVertexAtIntersection()); | |
| rcCmdMgr.addCommand(new CmdTechDrawExtensionDrawCirclesGroup()); | |
| rcCmdMgr.addCommand(new CmdTechDrawCosmeticCircle()); | |
| rcCmdMgr.addCommand(new CmdTechDrawExtensionDrawCosmCircle()); | |
| rcCmdMgr.addCommand(new CmdTechDrawExtensionDrawCosmArc()); | |
| rcCmdMgr.addCommand(new CmdTechDrawExtensionDrawCosmCircle3Points()); | |
| rcCmdMgr.addCommand(new CmdTechDrawExtensionLinePPGroup()); | |
| rcCmdMgr.addCommand(new CmdTechDrawExtensionLineParallel()); | |
| rcCmdMgr.addCommand(new CmdTechDrawExtensionLinePerpendicular()); | |
| rcCmdMgr.addCommand(new CmdTechDrawExtensionThreadsGroup()); | |
| rcCmdMgr.addCommand(new CmdTechDrawExtensionThreadHoleSide()); | |
| rcCmdMgr.addCommand(new CmdTechDrawExtensionThreadBoltSide()); | |
| rcCmdMgr.addCommand(new CmdTechDrawExtensionThreadHoleBottom()); | |
| rcCmdMgr.addCommand(new CmdTechDrawExtensionThreadBoltBottom()); | |
| rcCmdMgr.addCommand(new CmdTechDrawExtensionAreaAnnotation()); | |
| rcCmdMgr.addCommand(new CmdTechDrawExtensionArcLengthAnnotation()); | |
| } | |