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);