diff --git a/src/Gui/PreferencePackTemplates/Shortcuts.cfg b/src/Gui/PreferencePackTemplates/Shortcuts.cfg index 554404ab8b..56b0d5668f 100644 --- a/src/Gui/PreferencePackTemplates/Shortcuts.cfg +++ b/src/Gui/PreferencePackTemplates/Shortcuts.cfg @@ -843,6 +843,7 @@ + @@ -959,4 +960,4 @@ - \ No newline at end of file + diff --git a/src/Mod/TechDraw/Gui/CommandExtensionPack.cpp b/src/Mod/TechDraw/Gui/CommandExtensionPack.cpp index 20eba6de5a..1f0c4acb59 100644 --- a/src/Mod/TechDraw/Gui/CommandExtensionPack.cpp +++ b/src/Mod/TechDraw/Gui/CommandExtensionPack.cpp @@ -27,6 +27,8 @@ #include #include #include +#include +#include #endif #include @@ -52,13 +54,16 @@ #include #include #include +#include #include #include +#include #include "DrawGuiUtil.h" #include "QGSPage.h" #include "TaskSelectLineAttributes.h" #include "ViewProviderBalloon.h" +#include "ViewProviderDimension.h" #include "ViewProviderPage.h" @@ -1893,6 +1898,145 @@ bool CmdTechDrawExtensionAreaAnnotation::isActive() 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("Calculate the arc length of selected edges"); + sToolTipText = QT_TR_NOOP("Select several edges
\ + - click this tool"); + 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 selection; + TechDraw::DrawViewPart *objFeat; + if (!_checkSel(this, selection, objFeat, QT_TRANSLATE_NOOP("Command", "TechDraw calculate selected arc length"))) { + return; + } + + // Collect all edges in the selection + std::vector 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 lengths(subNames.size()); + double totalLength = 0.0; + size_t i; + for (i = 0; i < subNames.size(); ++i) { + lengths[i] = totalLength; + TechDraw::BaseGeomPtr edge = objFeat->getEdge(subNames[i]); + if (!edge) { + continue; + } + + GProp_GProps edgeProps; + BRepGProp::LinearProperties(edge->getOCCEdge(), edgeProps); + + totalLength += edgeProps.Mass(); + lengths[i] = 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(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; + i = 0; + while (i < lengths.size() && lengths[i] < anchorLength) { + ++i; + } + if (i) { + anchorLength -= lengths[i - 1]; + } + + // As reasonable anchor base point seems the "halving" edge endpoint + BRepAdaptor_Curve curve(objFeat->getEdge(subNames[i])->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(DrawUtil::toVector3d(midPoint)/scale); + totalLength /= scale; + + // Use virtual dimension view helper to format resulting value + TechDraw::DrawViewDimension helperDim; + std::string valueStr = helperDim.formatValue(totalLength, + QString::fromUtf8(helperDim.FormatSpec.getStrValue().data()), + helperDim.isMultiValueSchema() ? 0 : 1); + 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(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 //=========================================================================== @@ -2117,4 +2261,5 @@ void CreateTechDrawCommandsExtensions() rcCmdMgr.addCommand(new CmdTechDrawExtensionThreadHoleBottom()); rcCmdMgr.addCommand(new CmdTechDrawExtensionThreadBoltBottom()); rcCmdMgr.addCommand(new CmdTechDrawExtensionAreaAnnotation()); + rcCmdMgr.addCommand(new CmdTechDrawExtensionArcLengthAnnotation()); } diff --git a/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc b/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc index e19c7dad52..47b36b19a9 100644 --- a/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc +++ b/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc @@ -88,6 +88,7 @@ icons/TechDraw_Dimension.svg icons/TechDraw_DimensionRepair.svg icons/TechDraw_ExtensionAreaAnnotation.svg + icons/TechDraw_ExtensionArcLengthAnnotation.svg icons/TechDraw_ExtensionCascadeHorizDimension.svg icons/TechDraw_ExtensionCascadeObliqueDimension.svg icons/TechDraw_ExtensionCascadeVertDimension.svg diff --git a/src/Mod/TechDraw/Gui/Resources/icons/TechDraw_ExtensionArcLengthAnnotation.svg b/src/Mod/TechDraw/Gui/Resources/icons/TechDraw_ExtensionArcLengthAnnotation.svg new file mode 100644 index 0000000000..626721add0 --- /dev/null +++ b/src/Mod/TechDraw/Gui/Resources/icons/TechDraw_ExtensionArcLengthAnnotation.svg @@ -0,0 +1,85 @@ + + diff --git a/src/Mod/TechDraw/Gui/Workbench.cpp b/src/Mod/TechDraw/Gui/Workbench.cpp index 75d3bc62b9..79bc5b6f93 100644 --- a/src/Mod/TechDraw/Gui/Workbench.cpp +++ b/src/Mod/TechDraw/Gui/Workbench.cpp @@ -112,6 +112,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const *toolattrib << "TechDraw_ExtensionCascadeObliqueDimension"; *toolattrib << "Separator"; *toolattrib << "TechDraw_ExtensionAreaAnnotation"; + *toolattrib << "TechDraw_ExtensionArcLengthAnnotation"; *toolattrib << "TechDraw_ExtensionCustomizeFormat"; // extension: centerlines and threading @@ -337,6 +338,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const *extattribs << "TechDraw_ExtensionPosChainDimensionGroup"; *extattribs << "TechDraw_ExtensionCascadeDimensionGroup"; *extattribs << "TechDraw_ExtensionAreaAnnotation"; + *extattribs << "TechDraw_ExtensionArcLengthAnnotation"; *extattribs << "TechDraw_ExtensionCustomizeFormat"; Gui::ToolBarItem* extcenter = new Gui::ToolBarItem(root); @@ -447,6 +449,7 @@ Gui::ToolBarItem* Workbench::setupCommandBars() const *extattribs << "TechDraw_ExtensionPosChainDimensionGroup"; *extattribs << "TechDraw_ExtensionCascadeDimensionGroup"; *extattribs << "TechDraw_ExtensionAreaAnnotation"; + *extattribs << "TechDraw_ExtensionArcLengthAnnotation"; *extattribs << "TechDraw_ExtensionCustomizeFormat"; Gui::ToolBarItem* extcenter = new Gui::ToolBarItem(root);