diff --git a/src/Mod/Fem/Gui/CMakeLists.txt b/src/Mod/Fem/Gui/CMakeLists.txt
index c1cb70c6a5..f03da1ec3b 100755
--- a/src/Mod/Fem/Gui/CMakeLists.txt
+++ b/src/Mod/Fem/Gui/CMakeLists.txt
@@ -404,6 +404,7 @@ INSTALL(FILES ${FemGuiIcon_SVG} DESTINATION "${CMAKE_INSTALL_DATADIR}/Mod/Fem/Re
# Python modules ui files, they are copied as they are, thus the need not to be added to Fem.qrc
# see https://forum.freecadweb.org/viewtopic.php?f=10&t=25833
SET(FemGuiPythonUI_SRCS
+ Resources/ui/ConstraintTie.ui
Resources/ui/ElectrostaticPotential.ui
Resources/ui/ElementFluid1D.ui
Resources/ui/ElementGeometry1D.ui
diff --git a/src/Mod/Fem/Gui/Resources/Fem.qrc b/src/Mod/Fem/Gui/Resources/Fem.qrc
index 6bf8909ae7..a728e690b4 100755
--- a/src/Mod/Fem/Gui/Resources/Fem.qrc
+++ b/src/Mod/Fem/Gui/Resources/Fem.qrc
@@ -25,6 +25,7 @@
icons/fem-constraint-pulley.svg
icons/fem-constraint-selfweight.svg
icons/fem-constraint-temperature.svg
+ icons/fem-constraint-tie.svg
icons/fem-constraint-transform.svg
icons/fem-element-fluid-1d.svg
icons/fem-element-geometry-1d.svg
@@ -110,6 +111,7 @@
translations/Fem_vi.qm
translations/Fem_zh-CN.qm
translations/Fem_zh-TW.qm
+ ui/ConstraintTie.ui
ui/ElectrostaticPotential.ui
ui/ElementFluid1D.ui
ui/ElementGeometry1D.ui
diff --git a/src/Mod/Fem/Gui/Resources/icons/fem-constraint-tie.svg b/src/Mod/Fem/Gui/Resources/icons/fem-constraint-tie.svg
new file mode 100644
index 0000000000..c927434c82
--- /dev/null
+++ b/src/Mod/Fem/Gui/Resources/icons/fem-constraint-tie.svg
@@ -0,0 +1,1283 @@
+
+
diff --git a/src/Mod/Fem/Gui/Resources/ui/ConstraintTie.ui b/src/Mod/Fem/Gui/Resources/ui/ConstraintTie.ui
new file mode 100644
index 0000000000..6f8a27596e
--- /dev/null
+++ b/src/Mod/Fem/Gui/Resources/ui/ConstraintTie.ui
@@ -0,0 +1,110 @@
+
+
+ Form
+
+
+
+ 0
+ 0
+ 350
+ 500
+
+
+
+ Tie parameter
+
+
+ -
+
+
+
+ 16777215
+ 1677215
+
+
+
+ Parameter
+
+
+
-
+
+
+ QFormLayout::AllNonFixedFieldsGrow
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 80
+ 20
+
+
+
+ Qt::LeftToRight
+
+
+ 0.0
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 1.000000000000000
+
+
+ 1000000000.000000000000000
+
+
+ mm
+
+
+ 2
+
+
+ 0.000000000000000
+
+
+
+ -
+
+
+ Tolerance:
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+ Gui::InputField
+ QLineEdit
+
+
+
+
+
+
diff --git a/src/Mod/Fem/Gui/Workbench.cpp b/src/Mod/Fem/Gui/Workbench.cpp
index 53ea055994..ef8287b98d 100755
--- a/src/Mod/Fem/Gui/Workbench.cpp
+++ b/src/Mod/Fem/Gui/Workbench.cpp
@@ -110,6 +110,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
<< "FEM_ConstraintDisplacement"
<< "FEM_ConstraintPlaneRotation"
<< "FEM_ConstraintContact"
+ << "FEM_ConstraintTie"
<< "FEM_ConstraintTransform"
<< "Separator"
<< "FEM_ConstraintForce"
@@ -220,6 +221,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
<< "FEM_ConstraintDisplacement"
<< "FEM_ConstraintPlaneRotation"
<< "FEM_ConstraintContact"
+ << "FEM_ConstraintTie"
<< "FEM_ConstraintTransform"
<< "Separator"
<< "FEM_ConstraintForce"
diff --git a/src/Mod/Fem/femcommands/commands.py b/src/Mod/Fem/femcommands/commands.py
index 897b981239..80606fc6ef 100644
--- a/src/Mod/Fem/femcommands/commands.py
+++ b/src/Mod/Fem/femcommands/commands.py
@@ -245,6 +245,29 @@ class _ConstraintSelfWeight(CommandManager):
self.add_obj_on_gui_noset_edit(self.__class__.__name__.lstrip("_"))
+class _ConstraintTie(CommandManager):
+ "The FEM_ConstraintTie command definition"
+
+ def __init__(self):
+ super(_ConstraintTie, self).__init__()
+ self.resources = {
+ "Pixmap": "fem-constraint-tie",
+ "MenuText": QtCore.QT_TRANSLATE_NOOP(
+ "FEM_ConstraintTie",
+ "Constraint tie"
+ ),
+ "Accel": "C, T",
+ "ToolTip": QtCore.QT_TRANSLATE_NOOP(
+ "FEM_ConstraintTie",
+ "Creates a FEM constraint tie"
+ )
+ }
+ self.is_active = "with_analysis"
+
+ def Activated(self):
+ self.add_obj_on_gui_set_edit(self.__class__.__name__.lstrip("_"))
+
+
class _ElementFluid1D(CommandManager):
"The FEM_ElementFluid1D command definition"
@@ -1134,6 +1157,10 @@ FreeCADGui.addCommand(
"FEM_ConstraintSelfWeight",
_ConstraintSelfWeight()
)
+FreeCADGui.addCommand(
+ "FEM_ConstraintTie",
+ _ConstraintTie()
+)
FreeCADGui.addCommand(
"FEM_ElementFluid1D",
_ElementFluid1D()
diff --git a/src/Mod/Fem/femguiobjects/_ViewProviderFemConstraintTie.py b/src/Mod/Fem/femguiobjects/_ViewProviderFemConstraintTie.py
index 8350d24e27..7006e83a01 100644
--- a/src/Mod/Fem/femguiobjects/_ViewProviderFemConstraintTie.py
+++ b/src/Mod/Fem/femguiobjects/_ViewProviderFemConstraintTie.py
@@ -33,7 +33,7 @@ import FreeCADGui
import FemGui # needed to display the icons in TreeView
# for the panel
-from PySide import QtCore
+from PySide import QtCore, QtGui
from . import FemSelectionWidgets
False if FemGui.__name__ else True # flake8, dummy FemGui usage
@@ -68,9 +68,31 @@ class _ViewProviderFemConstraintTie:
return
def setEdit(self, vobj, mode=0):
+ # hide all meshes
+ for o in FreeCAD.ActiveDocument.Objects:
+ if o.isDerivedFrom("Fem::FemMeshObject"):
+ o.ViewObject.hide()
+ # show task panel
+ taskd = _TaskPanelFemConstraintTie(self.Object)
+ taskd.obj = vobj.Object
+ FreeCADGui.Control.showDialog(taskd)
return True
def unsetEdit(self, vobj, mode=0):
+ FreeCADGui.Control.closeDialog()
+ return True
+
+ def doubleClicked(self, vobj):
+ guidoc = FreeCADGui.getDocument(vobj.Object.Document)
+ # check if another VP is in edit mode
+ # https://forum.freecadweb.org/viewtopic.php?t=13077#p104702
+ if not guidoc.getInEdit():
+ guidoc.setEdit(vobj.Object.Name)
+ else:
+ from PySide.QtGui import QMessageBox
+ message = "Active Task Dialog found! Please close this one before opening a new one!"
+ QMessageBox.critical(None, "Error in tree view", message)
+ FreeCAD.Console.PrintError(message + "\n")
return True
def __getstate__(self):
@@ -78,3 +100,79 @@ class _ViewProviderFemConstraintTie:
def __setstate__(self, state):
return None
+
+
+class _TaskPanelFemConstraintTie:
+ """The TaskPanel for editing References property of FemConstraintTie objects"""
+
+ def __init__(self, obj):
+
+ self.obj = obj
+
+ # parameter widget
+ self.parameterWidget = FreeCADGui.PySideUic.loadUi(
+ FreeCAD.getHomePath() + "Mod/Fem/Resources/ui/ConstraintTie.ui"
+ )
+ QtCore.QObject.connect(
+ self.parameterWidget.if_tolerance,
+ QtCore.SIGNAL("valueChanged(Base::Quantity)"),
+ self.tolerance_changed
+ )
+ self.init_parameter_widget()
+
+ # geometry selection widget
+ self.selectionWidget = FemSelectionWidgets.GeometryElementsSelection(
+ obj.References,
+ ["Face"]
+ )
+
+ # form made from param and selection widget
+ self.form = [self.parameterWidget, self.selectionWidget]
+
+ def accept(self):
+ # check values
+ items = len(self.selectionWidget.references)
+ FreeCAD.Console.PrintMessage(
+ "Task panel: found references: {}\n{}\n"
+ .format(items, self.selectionWidget.references)
+ )
+
+ if items != 2:
+ msgBox = QtGui.QMessageBox()
+ msgBox.setIcon(QtGui.QMessageBox.Question)
+ msgBox.setText(
+ "Constraint Tie requires exactly two faces\n\nfound references: {}"
+ .format(items)
+ )
+ msgBox.setWindowTitle("FreeCAD FEM Constraint Tie")
+ retryButton = msgBox.addButton(QtGui.QMessageBox.Retry)
+ ignoreButton = msgBox.addButton(QtGui.QMessageBox.Ignore)
+ msgBox.exec_()
+
+ if msgBox.clickedButton() == retryButton:
+ return False
+ elif msgBox.clickedButton() == ignoreButton:
+ pass
+ self.obj.Tolerance = self.tolerance
+ self.obj.References = self.selectionWidget.references
+ self.recompute_and_set_back_all()
+ return True
+
+ def reject(self):
+ self.recompute_and_set_back_all()
+ return True
+
+ def recompute_and_set_back_all(self):
+ doc = FreeCADGui.getDocument(self.obj.Document)
+ doc.Document.recompute()
+ self.selectionWidget.setback_listobj_visibility()
+ if self.selectionWidget.sel_server:
+ FreeCADGui.Selection.removeObserver(self.selectionWidget.sel_server)
+ doc.resetEdit()
+
+ def init_parameter_widget(self):
+ self.tolerance = self.obj.Tolerance
+ self.parameterWidget.if_tolerance.setText(self.tolerance.UserString)
+
+ def tolerance_changed(self, base_quantity_value):
+ self.tolerance = base_quantity_value