diff --git a/src/Mod/Fem/Gui/Resources/ui/ElementGeometry1D.ui b/src/Mod/Fem/Gui/Resources/ui/ElementGeometry1D.ui
index 00387d2881..0c3559333b 100644
--- a/src/Mod/Fem/Gui/Resources/ui/ElementGeometry1D.ui
+++ b/src/Mod/Fem/Gui/Resources/ui/ElementGeometry1D.ui
@@ -20,46 +20,16 @@
Cross section parameter
-
- 9
-
-
- 9
-
-
- 9
-
-
- 9
-
-
- 6
-
-
-
+
-
2
-
+
-
- 9
-
-
- 9
-
-
- 9
-
-
- 9
-
-
- 6
-
-
@@ -121,23 +91,8 @@
-
+
-
- 9
-
-
- 9
-
-
- 9
-
-
- 9
-
-
- 6
-
-
@@ -173,7 +128,7 @@
-
+
-
@@ -236,6 +191,284 @@
+
+
+ -
+
+
+ QFormLayout::AllNonFixedFieldsGrow
+
+
-
+
+
+ Axis1 Length:
+
+
+
+ -
+
+
+ Qt::AlignLeft|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 1.000000000000000
+
+
+ 1000000000.000000000000000
+
+
+ 0.000000000000000
+
+
+ mm
+
+
+ 2
+
+
+ 0.000000000000000
+
+
+
+ -
+
+
+ Axis2 Length:
+
+
+
+ -
+
+
+ Qt::AlignLeft|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 1.000000000000000
+
+
+ 1000000000.000000000000000
+
+
+ 0.000000000000000
+
+
+ mm
+
+
+ 2
+
+
+ 0.000000000000000
+
+
+
+
+
+
+
+
+
+ -
+
+
+ QFormLayout::AllNonFixedFieldsGrow
+
+
-
+
+
+ Height:
+
+
+
+ -
+
+
+ Qt::AlignLeft|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 1.000000000000000
+
+
+ 1000000000.000000000000000
+
+
+ 0.000000000000000
+
+
+ mm
+
+
+ 2
+
+
+ 0.000000000000000
+
+
+
+ -
+
+
+ Width:
+
+
+
+ -
+
+
+ Qt::AlignLeft|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 1.000000000000000
+
+
+ 1000000000.000000000000000
+
+
+ mm
+
+
+ 2
+
+
+ 0.000000000000000
+
+
+ 0.000000000000000
+
+
+
+ -
+
+
+ T1 Thickness:
+
+
+
+ -
+
+
+ Qt::AlignLeft|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 1.000000000000000
+
+
+ 1000000000.000000000000000
+
+
+ 0.000000000000000
+
+
+ mm
+
+
+ 2
+
+
+ 0.000000000000000
+
+
+
+ -
+
+
+ T2 Thickness:
+
+
+
+ -
+
+
+ Qt::AlignLeft|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 1.000000000000000
+
+
+ 1000000000.000000000000000
+
+
+ 0.000000000000000
+
+
+ mm
+
+
+ 2
+
+
+ 0.000000000000000
+
+
+
+ -
+
+
+ T3 Thickness:
+
+
+
+ -
+
+
+ Qt::AlignLeft|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 1.000000000000000
+
+
+ 1000000000.000000000000000
+
+
+ 0.000000000000000
+
+
+ mm
+
+
+ 2
+
+
+ 0.000000000000000
+
+
+
+ -
+
+
+ T4 Thickness:
+
+
+
+ -
+
+
+ Qt::AlignLeft|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 1.000000000000000
+
+
+ 1000000000.000000000000000
+
+
+ 0.000000000000000
+
+
+ mm
+
+
+ 2
+
+
+ 0.000000000000000
+
+
+
+
+
+
+
@@ -266,7 +499,7 @@
- cb_crosssectiontype
+ cb_cross_section_type
currentIndexChanged(int)
widget_stack
setCurrentIndex(int)
diff --git a/src/Mod/Fem/ObjectsFem.py b/src/Mod/Fem/ObjectsFem.py
index bd0eb7d301..ad8963d760 100644
--- a/src/Mod/Fem/ObjectsFem.py
+++ b/src/Mod/Fem/ObjectsFem.py
@@ -351,7 +351,7 @@ def makeElementFluid1D(doc, name="ElementFluid1D"):
def makeElementGeometry1D(
- doc, sectiontype="Rectangular", width=10.0, height=25.0, name="ElementGeometry1D"
+ doc, sectiontype="Rectangular", width=10.0, height=25.0, thickness=2.0, name="ElementGeometry1D"
):
"""makeElementGeometry1D(document, [width], [height], [name]):
creates a 1D geometry element object to define a cross section"""
@@ -359,17 +359,22 @@ def makeElementGeometry1D(
from femobjects import element_geometry1D
element_geometry1D.ElementGeometry1D(obj)
- sec_types = element_geometry1D.ElementGeometry1D.known_beam_types
- if sectiontype not in sec_types:
- FreeCAD.Console.PrintError("Section type is unknown. Set to " + sec_types[0] + " \n")
- obj.SectionType = sec_types[0]
- else:
- obj.SectionType = sectiontype
+
+ obj.SectionType = sectiontype
obj.RectWidth = width
obj.RectHeight = height
obj.CircDiameter = height
obj.PipeDiameter = height
- obj.PipeThickness = width
+ obj.PipeThickness = thickness
+ obj.Axis1Length = width
+ obj.Axis2Length = height
+ obj.BoxHeight = height
+ obj.BoxWidth = width
+ obj.BoxT1 = thickness
+ obj.BoxT2 = thickness
+ obj.BoxT3 = thickness
+ obj.BoxT4 = thickness
+
if FreeCAD.GuiUp:
from femviewprovider import view_element_geometry1D
diff --git a/src/Mod/Fem/femobjects/element_geometry1D.py b/src/Mod/Fem/femobjects/element_geometry1D.py
index 6ab731e37d..4d30631b8c 100644
--- a/src/Mod/Fem/femobjects/element_geometry1D.py
+++ b/src/Mod/Fem/femobjects/element_geometry1D.py
@@ -29,7 +29,11 @@ __url__ = "https://www.freecad.org"
# \ingroup FEM
# \brief element geometry 1D object
+from FreeCAD import Base
from . import base_femelement
+from . import base_fempythonobject
+
+_PropHelper = base_fempythonobject._PropHelper
class ElementGeometry1D(base_femelement.BaseFemElement):
@@ -38,55 +42,150 @@ class ElementGeometry1D(base_femelement.BaseFemElement):
"""
Type = "Fem::ElementGeometry1D"
- known_beam_types = ["Rectangular", "Circular", "Pipe"]
def __init__(self, obj):
super().__init__(obj)
- obj.addProperty(
- "App::PropertyLength",
- "RectWidth",
- "RectBeamSection",
- "set width of the rectangular beam elements",
- )
- obj.setPropertyStatus("RectWidth", "LockDynamic")
+ def _get_properties(self):
+ prop = super()._get_properties()
- obj.addProperty(
- "App::PropertyLength",
- "RectHeight",
- "RectBeamSection",
- "set height of therectangular beam elements",
+ prop.append(
+ _PropHelper(
+ type="App::PropertyLength",
+ name="RectWidth",
+ group="RectBeamSection",
+ doc="Set width of the rectangular beam elements",
+ value=0.0,
+ )
)
- obj.setPropertyStatus("RectHeight", "LockDynamic")
-
- obj.addProperty(
- "App::PropertyLength",
- "CircDiameter",
- "CircBeamSection",
- "set diameter of the circular beam elements",
+ prop.append(
+ _PropHelper(
+ type="App::PropertyLength",
+ name="RectHeight",
+ group="RectBeamSection",
+ doc="Set height of there ctangular beam elements",
+ value=0.0,
+ )
)
- obj.setPropertyStatus("CircDiameter", "LockDynamic")
-
- obj.addProperty(
- "App::PropertyLength",
- "PipeDiameter",
- "PipeBeamSection",
- "set outer diameter of the pipe beam elements",
+ prop.append(
+ _PropHelper(
+ type="App::PropertyLength",
+ name="CircDiameter",
+ group="CircBeamSection",
+ doc="Set diameter of the circular beam elements",
+ value=0.0,
+ )
)
- obj.setPropertyStatus("PipeDiameter", "LockDynamic")
-
- obj.addProperty(
- "App::PropertyLength",
- "PipeThickness",
- "PipeBeamSection",
- "set thickness of the pipe beam elements",
+ prop.append(
+ _PropHelper(
+ type="App::PropertyLength",
+ name="PipeDiameter",
+ group="PipeBeamSection",
+ doc="Set outer diameter of the pipe beam elements",
+ value=0.0,
+ )
)
- obj.setPropertyStatus("PipeThickness", "LockDynamic")
-
- obj.addProperty(
- "App::PropertyEnumeration", "SectionType", "BeamSection", "select beam section type"
+ prop.append(
+ _PropHelper(
+ type="App::PropertyLength",
+ name="PipeThickness",
+ group="PipeBeamSection",
+ doc="Set thickness of the pipe beam elements",
+ value=0.0,
+ )
+ )
+ prop.append(
+ _PropHelper(
+ type="App::PropertyLength",
+ name="Axis1Length",
+ group="EllipticalBeamSection",
+ doc="Set first principal axis length of the elliptical beam elements",
+ value=0.0,
+ )
+ )
+ prop.append(
+ _PropHelper(
+ type="App::PropertyLength",
+ name="Axis2Length",
+ group="EllipticalBeamSection",
+ doc="Set second principal axis length of the elliptical beam elements",
+ value=0.0,
+ )
+ )
+ prop.append(
+ _PropHelper(
+ type="App::PropertyLength",
+ name="BoxWidth",
+ group="BoxBeamSection",
+ doc="Set width of the box beam elements",
+ value=0.0,
+ )
+ )
+ prop.append(
+ _PropHelper(
+ type="App::PropertyLength",
+ name="BoxHeight",
+ group="BoxBeamSection",
+ doc="Set height of the box beam elements",
+ value=0.0,
+ )
+ )
+ prop.append(
+ _PropHelper(
+ type="App::PropertyLength",
+ name="BoxT1",
+ group="BoxBeamSection",
+ doc="Set thickness parameter t1 of the box beam elements",
+ value=0.0,
+ )
+ )
+ prop.append(
+ _PropHelper(
+ type="App::PropertyLength",
+ name="BoxT2",
+ group="BoxBeamSection",
+ doc="Set thickness parameter t2 of the box beam elements",
+ value=0.0,
+ )
+ )
+ prop.append(
+ _PropHelper(
+ type="App::PropertyLength",
+ name="BoxT3",
+ group="BoxBeamSection",
+ doc="Set thickness parameter t3 of the box beam elements",
+ value=0.0,
+ )
+ )
+ prop.append(
+ _PropHelper(
+ type="App::PropertyLength",
+ name="BoxT4",
+ group="BoxBeamSection",
+ doc="Set thickness parameter t4 of the box beam elements",
+ value=0.0,
+ )
+ )
+ prop.append(
+ _PropHelper(
+ type="App::PropertyEnumeration",
+ name="SectionType",
+ group="BeamSection",
+ doc="Select beam section type",
+ value=["Rectangular", "Circular", "Pipe", "Elliptical", "Box"],
+ )
)
- obj.setPropertyStatus("SectionType", "LockDynamic")
- obj.SectionType = ElementGeometry1D.known_beam_types
- obj.SectionType = "Rectangular"
+ return prop
+
+ def onDocumentRestored(self, obj):
+ # update old project with new properties
+ for prop in self._get_properties():
+ try:
+ obj.getPropertyByName(prop.name)
+ except Base.PropertyError:
+ prop.add_to_object(obj)
+
+ if prop.name == "SectionType":
+ # refresh the list of known section types for old projects
+ obj.SectionType = prop.value
diff --git a/src/Mod/Fem/femsolver/calculix/write_femelement_geometry.py b/src/Mod/Fem/femsolver/calculix/write_femelement_geometry.py
index c7ee293538..12f672e2b2 100644
--- a/src/Mod/Fem/femsolver/calculix/write_femelement_geometry.py
+++ b/src/Mod/Fem/femsolver/calculix/write_femelement_geometry.py
@@ -45,7 +45,6 @@ def write_femelement_geometry(f, ccxwriter):
section_nor = "{:.13G}, {:.13G}, {:.13G}\n".format(
beam_axis_m[0], beam_axis_m[1], beam_axis_m[2]
)
- print(section_nor)
if beamsec_obj.SectionType == "Rectangular":
# see meshtools.get_beam_main_axis_m(beam_direction, defined_angle)
# the method get_beam_main_axis_m() which calculates the beam_axis_m vector
@@ -66,12 +65,29 @@ def write_femelement_geometry(f, ccxwriter):
section_type = ", SECTION=CIRC"
section_geo = f"{diameter:.13G}\n"
section_def = f"*BEAM SECTION, {elsetdef}{material}{section_type}\n"
+ elif beamsec_obj.SectionType == "Elliptical":
+ axis1 = beamsec_obj.Axis1Length.getValueAs("mm").Value
+ axis2 = beamsec_obj.Axis2Length.getValueAs("mm").Value
+ section_type = ", SECTION=CIRC"
+ section_geo = f"{axis1:.13G},{axis2:.13G}\n"
+ section_def = f"*BEAM SECTION, {elsetdef}{material}{section_type}\n"
elif beamsec_obj.SectionType == "Pipe":
radius = 0.5 * beamsec_obj.PipeDiameter.getValueAs("mm").Value
thickness = beamsec_obj.PipeThickness.getValueAs("mm").Value
section_type = ", SECTION=PIPE"
section_geo = f"{radius:.13G},{thickness:.13G}\n"
section_def = f"*BEAM SECTION, {elsetdef}{material}{section_type}\n"
+ elif beamsec_obj.SectionType == "Box":
+ box_width = beamsec_obj.BoxWidth.getValueAs("mm").Value
+ box_height = beamsec_obj.BoxHeight.getValueAs("mm").Value
+ box_t1 = beamsec_obj.BoxT1.getValueAs("mm").Value
+ box_t2 = beamsec_obj.BoxT2.getValueAs("mm").Value
+ box_t3 = beamsec_obj.BoxT3.getValueAs("mm").Value
+ box_t4 = beamsec_obj.BoxT4.getValueAs("mm").Value
+ section_type = ", SECTION=BOX"
+ section_geo = f"{box_width:.13G},{box_height:.13G},{box_t1:.13G},{box_t2:.13G},{box_t3:.13G},{box_t4:.13G}\n"
+ section_def = f"*BEAM SECTION, {elsetdef}{material}{section_type}\n"
+
f.write(section_def)
f.write(section_geo)
f.write(section_nor)
diff --git a/src/Mod/Fem/femtaskpanels/task_element_geometry1D.py b/src/Mod/Fem/femtaskpanels/task_element_geometry1D.py
index 08f3a39d1d..dffaae01fc 100644
--- a/src/Mod/Fem/femtaskpanels/task_element_geometry1D.py
+++ b/src/Mod/Fem/femtaskpanels/task_element_geometry1D.py
@@ -52,7 +52,7 @@ class _TaskPanel(base_femtaskpanel._BaseTaskPanel):
FreeCAD.getHomePath() + "Mod/Fem/Resources/ui/ElementGeometry1D.ui"
)
QtCore.QObject.connect(
- self.parameter_widget.cb_crosssectiontype,
+ self.parameter_widget.cb_cross_section_type,
QtCore.SIGNAL("activated(int)"),
self.sectiontype_changed,
)
@@ -81,10 +81,51 @@ class _TaskPanel(base_femtaskpanel._BaseTaskPanel):
QtCore.SIGNAL("valueChanged(Base::Quantity)"),
self.pipe_thickness_changed,
)
-
- self.parameter_widget.cb_crosssectiontype.addItems(
- element_geometry1D.ElementGeometry1D.known_beam_types
+ QtCore.QObject.connect(
+ self.parameter_widget.qsb_elliptical_axis1,
+ QtCore.SIGNAL("valueChanged(Base::Quantity)"),
+ self.elliptical_axis1_changed,
)
+ QtCore.QObject.connect(
+ self.parameter_widget.qsb_elliptical_axis2,
+ QtCore.SIGNAL("valueChanged(Base::Quantity)"),
+ self.elliptical_axis2_changed,
+ )
+ QtCore.QObject.connect(
+ self.parameter_widget.qsb_box_height,
+ QtCore.SIGNAL("valueChanged(Base::Quantity)"),
+ self.box_height_changed,
+ )
+ QtCore.QObject.connect(
+ self.parameter_widget.qsb_box_width,
+ QtCore.SIGNAL("valueChanged(Base::Quantity)"),
+ self.box_width_changed,
+ )
+ QtCore.QObject.connect(
+ self.parameter_widget.qsb_box_t1,
+ QtCore.SIGNAL("valueChanged(Base::Quantity)"),
+ self.box_t1_changed,
+ )
+ QtCore.QObject.connect(
+ self.parameter_widget.qsb_box_t2,
+ QtCore.SIGNAL("valueChanged(Base::Quantity)"),
+ self.box_t2_changed,
+ )
+ QtCore.QObject.connect(
+ self.parameter_widget.qsb_box_t3,
+ QtCore.SIGNAL("valueChanged(Base::Quantity)"),
+ self.box_t3_changed,
+ )
+ QtCore.QObject.connect(
+ self.parameter_widget.qsb_box_t4,
+ QtCore.SIGNAL("valueChanged(Base::Quantity)"),
+ self.box_t4_changed,
+ )
+
+ self.parameter_widget.cb_cross_section_type.addItems(
+ obj.getEnumerationsOfProperty("SectionType")
+ )
+
self.get_beamsection_props()
self.update_parameter_widget()
@@ -113,6 +154,14 @@ class _TaskPanel(base_femtaskpanel._BaseTaskPanel):
self.circ_diameter = self.obj.CircDiameter
self.pipe_diameter = self.obj.PipeDiameter
self.pipe_thickness = self.obj.PipeThickness
+ self.axis1_length = self.obj.Axis1Length
+ self.axis2_length = self.obj.Axis2Length
+ self.box_height = self.obj.BoxHeight
+ self.box_width = self.obj.BoxWidth
+ self.box_t1 = self.obj.BoxT1
+ self.box_t2 = self.obj.BoxT2
+ self.box_t3 = self.obj.BoxT3
+ self.box_t4 = self.obj.BoxT4
def set_beamsection_props(self):
self.obj.SectionType = self.section_type
@@ -121,15 +170,17 @@ class _TaskPanel(base_femtaskpanel._BaseTaskPanel):
self.obj.CircDiameter = self.circ_diameter
self.obj.PipeDiameter = self.pipe_diameter
self.obj.PipeThickness = self.pipe_thickness
+ self.obj.Axis1Length = self.axis1_length
+ self.obj.Axis2Length = self.axis2_length
+ self.obj.BoxHeight = self.box_height
+ self.obj.BoxWidth = self.box_width
+ self.obj.BoxT1 = self.box_t1
+ self.obj.BoxT2 = self.box_t2
+ self.obj.BoxT3 = self.box_t3
+ self.obj.BoxT4 = self.box_t4
def update_parameter_widget(self):
"fills the widgets"
- self.rect_height = self.obj.RectHeight
- self.rect_width = self.obj.RectWidth
- self.circ_diameter = self.obj.CircDiameter
- self.pipe_diameter = self.obj.PipeDiameter
- self.pipe_thickness = self.obj.PipeThickness
-
FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_rec_height).bind(
self.obj, "RectHeight"
)
@@ -153,16 +204,42 @@ class _TaskPanel(base_femtaskpanel._BaseTaskPanel):
)
self.parameter_widget.qsb_pipe_thickness.setProperty("value", self.pipe_thickness)
- index_crosssectiontype = self.parameter_widget.cb_crosssectiontype.findText(
+ FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_elliptical_axis1).bind(
+ self.obj, "Axis1Length"
+ )
+ self.parameter_widget.qsb_elliptical_axis1.setProperty("value", self.axis1_length)
+ FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_elliptical_axis2).bind(
+ self.obj, "Axis2Length"
+ )
+ self.parameter_widget.qsb_elliptical_axis2.setProperty("value", self.axis2_length)
+
+ FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_box_height).bind(
+ self.obj, "BoxHeight"
+ )
+ self.parameter_widget.qsb_box_height.setProperty("value", self.box_height)
+ FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_box_width).bind(self.obj, "BoxWidth")
+ self.parameter_widget.qsb_box_width.setProperty("value", self.box_width)
+
+ FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_box_t1).bind(self.obj, "BoxT1")
+ self.parameter_widget.qsb_box_t1.setProperty("value", self.box_t1)
+
+ FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_box_t2).bind(self.obj, "BoxT2")
+ self.parameter_widget.qsb_box_t2.setProperty("value", self.box_t2)
+ FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_box_t3).bind(self.obj, "BoxT3")
+ self.parameter_widget.qsb_box_t3.setProperty("value", self.box_t3)
+ FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_box_t4).bind(self.obj, "BoxT4")
+ self.parameter_widget.qsb_box_t4.setProperty("value", self.box_t4)
+
+ index_cross_section_type = self.parameter_widget.cb_cross_section_type.findText(
self.section_type
)
- self.parameter_widget.cb_crosssectiontype.setCurrentIndex(index_crosssectiontype)
+ self.parameter_widget.cb_cross_section_type.setCurrentIndex(index_cross_section_type)
def sectiontype_changed(self, index):
if index < 0:
return
- self.parameter_widget.cb_crosssectiontype.setCurrentIndex(index)
- self.section_type = self.parameter_widget.cb_crosssectiontype.itemText(index)
+ self.parameter_widget.cb_cross_section_type.setCurrentIndex(index)
+ self.section_type = self.parameter_widget.cb_cross_section_type.itemText(index)
def rec_height_changed(self, base_quantity_value):
self.rect_height = base_quantity_value
@@ -178,3 +255,27 @@ class _TaskPanel(base_femtaskpanel._BaseTaskPanel):
def pipe_thickness_changed(self, base_quantity_value):
self.pipe_thickness = base_quantity_value
+
+ def elliptical_axis1_changed(self, base_quantity_value):
+ self.axis1_length = base_quantity_value
+
+ def elliptical_axis2_changed(self, base_quantity_value):
+ self.axis2_length = base_quantity_value
+
+ def box_height_changed(self, base_quantity_value):
+ self.box_height = base_quantity_value
+
+ def box_width_changed(self, base_quantity_value):
+ self.box_width = base_quantity_value
+
+ def box_t1_changed(self, base_quantity_value):
+ self.box_t1 = base_quantity_value
+
+ def box_t2_changed(self, base_quantity_value):
+ self.box_t2 = base_quantity_value
+
+ def box_t3_changed(self, base_quantity_value):
+ self.box_t3 = base_quantity_value
+
+ def box_t4_changed(self, base_quantity_value):
+ self.box_t4 = base_quantity_value