diff --git a/src/Mod/Fem/FemGmshTools.py b/src/Mod/Fem/FemGmshTools.py
index 26fd8d728..22b3aef95 100644
--- a/src/Mod/Fem/FemGmshTools.py
+++ b/src/Mod/Fem/FemGmshTools.py
@@ -48,31 +48,73 @@ class FemGmshTools():
# part to mesh
self.part_obj = self.mesh_obj.Part
- # clmax, ElementSizeMax: float, 0.0 = 1e+22
- self.clmax = Units.Quantity(self.mesh_obj.ElementSizeMax).Value
+ # clmax, CharacteristicLengthMax: float, 0.0 = 1e+22
+ self.clmax = Units.Quantity(self.mesh_obj.CharacteristicLengthMax).Value
if self.clmax == 0.0:
self.clmax = 1e+22
- # clmin, ElementSizeMin: float
- self.clmin = Units.Quantity(self.mesh_obj.ElementSizeMin).Value
+ # clmin, CharacteristicLengthMin: float
+ self.clmin = Units.Quantity(self.mesh_obj.CharacteristicLengthMin).Value
- # order, ElementOrder: ['Auto', '1st', '2nd']
+ # order
+ # known_element_orders = ['Automatic', '1st', '2nd']
self.order = self.mesh_obj.ElementOrder
if self.order == '1st':
self.order = '1'
- elif self.order == 'Auto' or self.order == '2nd':
+ elif self.order == 'Automatic' or self.order == '2nd':
self.order = '2'
else:
print('Error in order')
- # dimension, ElementDimension: ['Auto', '1D', '2D', '3D']
+ # dimension
+ # known_element_dimensions = ['Automatic', '1D', '2D', '3D']
self.dimension = self.mesh_obj.ElementDimension
+ # Algorithm2D
+ # known_mesh_algorithm_2D = ['Automatic', 'MeshAdapt', 'Delaunay', 'Frontal', 'BAMG', 'DelQuad']
+ algo2D = self.mesh_obj.Algorithm2D
+ if algo2D == 'Automatic':
+ self.algorithm2D = '2'
+ elif algo2D == 'MeshAdapt':
+ self.algorithm2D = '1'
+ elif algo2D == 'Delaunay':
+ self.algorithm2D = '5'
+ elif algo2D == 'Frontal':
+ self.algorithm2D = '6'
+ elif algo2D == 'BAMG':
+ self.algorithm2D = '7'
+ elif algo2D == 'DelQuad':
+ self.algorithm2D = '8'
+ else:
+ self.algorithm2D = '2'
+
+ # Algorithm3D
+ # known_mesh_algorithm_3D = ['Automatic', 'Delaunay', 'New Delaunay', 'Frontal', 'Frontal Delaunay', 'Frontal Hex', 'MMG3D', 'R-tree']
+ algo3D = self.mesh_obj.Algorithm2D
+ if algo3D == 'Automatic':
+ self.algorithm3D = '1'
+ elif algo3D == 'Delaunay':
+ self.algorithm3D = '1'
+ elif algo3D == 'New Delaunay':
+ self.algorithm3D = '2'
+ elif algo3D == 'Frontal':
+ self.algorithm3D = '4'
+ elif algo3D == 'Frontal Delaunay':
+ self.algorithm3D = '5'
+ elif algo3D == 'Frontal Hex':
+ self.algorithm3D = '6'
+ elif algo3D == 'MMG3D':
+ self.algorithm3D = '7'
+ elif algo3D == 'R-tree':
+ self.algorithm3D = '9'
+ else:
+ self.algorithm3D = '1'
+
def create_mesh(self):
print("\nWe gone start GMSH FEM mesh run!")
print(' Part to mesh: Name --> ' + self.part_obj.Name + ', Label --> ' + self.part_obj.Label + ', ShapeType --> ' + self.part_obj.Shape.ShapeType)
- print(' ElementSizeMax: ' + str(self.clmax))
- print(' ElementSizeMin: ' + str(self.clmin))
+ print(' CharacteristicLengthMax: ' + str(self.clmax))
+ print(' CharacteristicLengthMin: ' + str(self.clmin))
print(' ElementOrder: ' + self.order)
self.get_dimension()
self.get_tmp_file_paths()
@@ -88,7 +130,7 @@ class FemGmshTools():
# Dimension
# GMSH uses the hightest availabe.
# A use case for not auto would be a surface (2D) mesh of a solid or other 3d shape
- if self.dimension == 'Auto':
+ if self.dimension == 'Automatic':
shty = self.part_obj.Shape.ShapeType
if shty == 'Solid' or shty == 'CompSolid':
# print('Found: ' + shty)
@@ -181,6 +223,23 @@ class FemGmshTools():
print(self.group_elements)
else:
print(' NO group meshing.')
+ self.ele_length_map = self.mesh_obj.CharacteristicLengthMap
+ self.ele_node_map = {}
+ if self.ele_length_map:
+ import FemMeshTools
+ print(self.ele_length_map)
+ self.ele_node_map = {}
+ for e in self.ele_length_map:
+ if not e.startswith('Solid'):
+ # Face, Edge, Vertex
+ ele_shape = self.part_obj.Shape.getElement(e)
+ else:
+ # Solid
+ ele_shape_index = int(e.lstrip('Solid')) - 1
+ ele_shape = self.part_obj.Shape.Solids[ele_shape_index]
+ ele_vertexes = FemMeshTools.get_vertexes_by_element(self.part_obj.Shape, ele_shape)
+ self.ele_node_map[e] = ele_vertexes
+ print(self.ele_node_map)
def write_part_file(self):
self.part_obj.Shape.exportBrep(self.temp_file_geometry)
@@ -190,7 +249,7 @@ class FemGmshTools():
geo.write('Merge "' + self.temp_file_geometry + '";\n')
geo.write("\n")
if self.analysis and self.group_elements:
- print(' We gone have found elements to make mesh groups for!')
+ print(' We gone have found elements to make mesh groups for.')
geo.write("// group data\n")
# we use the element name of FreeCAD which starts with 1 (example: 'Face1'), same as GMSH
for group in self.group_elements:
@@ -214,12 +273,44 @@ class FemGmshTools():
# print(ele_nr)
geo.write('Physical ' + physical_type + '("' + group + '") = {' + ele_nr + '};\n')
geo.write("\n")
+ if self.ele_length_map:
+ # we use the index FreeCAD which starts with 0, we need to add 1 for the index in GMSH
+ geo.write("// Characteristic Length according CharacteristicLengthMap\n")
+ for e in self.ele_length_map:
+ ele_nodes = (''.join((str(n + 1) + ', ') for n in self.ele_node_map[e])).rstrip(', ')
+ geo.write("// " + e + "\n")
+ geo.write("Characteristic Length { " + ele_nodes + " } = " + self.ele_length_map[e] + ";\n")
+ geo.write("\n")
geo.write("Mesh.CharacteristicLengthMax = " + str(self.clmax) + ";\n")
geo.write("Mesh.CharacteristicLengthMin = " + str(self.clmin) + ";\n")
geo.write("Mesh.ElementOrder = " + self.order + ";\n")
- geo.write("//Mesh.HighOrderOptimize = 1;\n") # but does not really work, in GUI it does
- geo.write("Mesh.Algorithm3D = 1;\n")
- geo.write("Mesh.Algorithm = 2;\n")
+ geo.write("\n")
+ geo.write("//optimize the mesh\n")
+ # GMSH tetra optimizer
+ if hasattr(self.mesh_obj, 'OptimizeStd') and self.mesh_obj.OptimizeStd is True:
+ geo.write("Mesh.Optimize = 1;\n")
+ else:
+ geo.write("Mesh.Optimize = 0;\n")
+ # Netgen optimizer in GMSH
+ if hasattr(self.mesh_obj, 'OptimizeNetgen') and self.mesh_obj.OptimizeNetgen is True:
+ geo.write("Mesh.OptimizeNetgen = 1;\n")
+ else:
+ geo.write("Mesh.OptimizeNetgen = 0;\n")
+ # hight order mesh optimizing
+ if hasattr(self.mesh_obj, 'OptimizeNetgen') and self.mesh_obj.OptimizeNetgen is True:
+ geo.write("Mesh.HighOrderOptimize = 1; //probably needs more lines off adjustment in geo file\n")
+ else:
+ geo.write("Mesh.HighOrderOptimize = 0; //probably needs more lines off adjustment in geo file\n")
+ geo.write("\n")
+ if hasattr(self.mesh_obj, 'RecombineAll') and self.mesh_obj.RecombineAll is True:
+ geo.write("//recombine\n")
+ geo.write("Mesh.RecombineAll = 1;\n")
+ geo.write("\n")
+ geo.write("//mesh algorithm\n")
+ geo.write("Mesh.Algorithm = " + self.algorithm2D + ";\n")
+ geo.write("Mesh.Algorithm3D = " + self.algorithm3D + ";\n")
+ geo.write("\n")
+ geo.write("//more\n")
geo.write("Mesh " + self.dimension + ";\n")
geo.write("Mesh.Format = 2;\n") # unv
if self.analysis and self.group_elements:
diff --git a/src/Mod/Fem/FemMeshTools.py b/src/Mod/Fem/FemMeshTools.py
index 42ace7d64..25141ccab 100644
--- a/src/Mod/Fem/FemMeshTools.py
+++ b/src/Mod/Fem/FemMeshTools.py
@@ -1162,6 +1162,49 @@ def find_element_in_shape(aShape, anElement):
FreeCAD.Console.PrintError('Compound is not supported.\n')
+def get_vertexes_by_element(aShape, anElement):
+ # we gone extent the method find_element_in_shape and return the vertexes
+ # import Part
+ ele_vertexes = []
+ ele_st = anElement.ShapeType
+ if ele_st == 'Solid' or ele_st == 'CompSolid':
+ for index, solid in enumerate(aShape.Solids):
+ if is_same_geometry(solid, anElement):
+ for vele in aShape.Solids[index].Vertexes:
+ for i, v in enumerate(aShape.Vertexes):
+ if vele.isSame(v): # use isSame, because orientation could be different
+ ele_vertexes.append(i)
+ # print(' ' + str(sorted(ele_vertexes)))
+ return ele_vertexes
+ FreeCAD.Console.PrintError('Error, Solid ' + str(anElement) + ' not found in: ' + str(aShape) + '\n')
+ elif ele_st == 'Face' or ele_st == 'Shell':
+ for index, face in enumerate(aShape.Faces):
+ if is_same_geometry(face, anElement):
+ for vele in aShape.Faces[index].Vertexes:
+ for i, v in enumerate(aShape.Vertexes):
+ if vele.isSame(v): # use isSame, because orientation could be different
+ ele_vertexes.append(i)
+ # print(' ' + str(sorted(ele_vertexes)))
+ return ele_vertexes
+ elif ele_st == 'Edge' or ele_st == 'Wire':
+ for index, edge in enumerate(aShape.Edges):
+ if is_same_geometry(edge, anElement):
+ for vele in aShape.Edges[index].Vertexes:
+ for i, v in enumerate(aShape.Vertexes):
+ if vele.isSame(v): # use isSame, because orientation could be different
+ ele_vertexes.append(i)
+ # print(' ' + str(sorted(ele_vertexes)))
+ return ele_vertexes
+ elif ele_st == 'Vertex':
+ for index, vertex in enumerate(aShape.Vertexes):
+ if is_same_geometry(vertex, anElement):
+ ele_vertexes.append(index)
+ # print(' ' + str(sorted(ele_vertexes)))
+ return ele_vertexes
+ elif ele_st == 'Compound':
+ FreeCAD.Console.PrintError('Compound is not supported.\n')
+
+
def is_same_geometry(shape1, shape2):
# the vertexes and the CenterOfMass are compared
# it is a hack, but I do not know any better !
diff --git a/src/Mod/Fem/Gui/Command.cpp b/src/Mod/Fem/Gui/Command.cpp
index 4ca785c73..b5480e208 100644
--- a/src/Mod/Fem/Gui/Command.cpp
+++ b/src/Mod/Fem/Gui/Command.cpp
@@ -975,7 +975,7 @@ CmdFemDefineNodesSet::CmdFemDefineNodesSet()
sToolTipText = QT_TR_NOOP("Create node set by Poly");
sWhatsThis = "Create node set by Poly";
sStatusTip = QT_TR_NOOP("Create node set by Poly");
- sPixmap = "fem-fem-mesh-create-node-by-poly";
+ sPixmap = "fem-femmesh-create-node-by-poly";
}
void CmdFemDefineNodesSet::activated(int)
@@ -1032,7 +1032,7 @@ CmdFemCreateNodesSet::CmdFemCreateNodesSet()
sToolTipText = QT_TR_NOOP("Creates a FEM mesh nodes set");
sWhatsThis = "Fem_CreateNodesSet";
sStatusTip = sToolTipText;
- sPixmap = "fem-fem-mesh-create-node-by-poly";
+ sPixmap = "fem-femmesh-create-node-by-poly";
}
void CmdFemCreateNodesSet::activated(int)
diff --git a/src/Mod/Fem/Gui/Resources/Fem.qrc b/src/Mod/Fem/Gui/Resources/Fem.qrc
index 1f914c089..79eec3a0b 100755
--- a/src/Mod/Fem/Gui/Resources/Fem.qrc
+++ b/src/Mod/Fem/Gui/Resources/Fem.qrc
@@ -25,10 +25,10 @@
icons/fem-control-solver.svg
icons/fem-cylinder.svg
icons/fem-data.png
- icons/fem-fem-mesh-create-node-by-poly.svg
- icons/fem-fem-mesh-from-shape.svg
- icons/fem-fem-mesh-gmsh-from-shape.svg
- icons/fem-fem-mesh-netgen-from-shape.svg
+ icons/fem-femmesh-create-node-by-poly.svg
+ icons/fem-femmesh-from-shape.svg
+ icons/fem-femmesh-gmsh-from-shape.svg
+ icons/fem-femmesh-netgen-from-shape.svg
icons/fem-femmesh-to-mesh.svg
icons/fem-frequency-analysis.svg
icons/fem-inp-editor.svg
diff --git a/src/Mod/Fem/Gui/Resources/icons/fem-fem-mesh-create-node-by-poly.svg b/src/Mod/Fem/Gui/Resources/icons/fem-femmesh-create-node-by-poly.svg
similarity index 99%
rename from src/Mod/Fem/Gui/Resources/icons/fem-fem-mesh-create-node-by-poly.svg
rename to src/Mod/Fem/Gui/Resources/icons/fem-femmesh-create-node-by-poly.svg
index 044191fe4..1d56b643c 100644
--- a/src/Mod/Fem/Gui/Resources/icons/fem-fem-mesh-create-node-by-poly.svg
+++ b/src/Mod/Fem/Gui/Resources/icons/fem-femmesh-create-node-by-poly.svg
@@ -15,7 +15,7 @@
id="svg2860"
sodipodi:version="0.32"
inkscape:version="0.48.3.1 r9886"
- sodipodi:docname="fem-fem-mesh-create-node-by-poly.svg"
+ sodipodi:docname="fem-femmesh-create-node-by-poly.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.1">
diff --git a/src/Mod/Fem/Gui/Resources/icons/fem-fem-mesh-gmsh-from-shape.svg b/src/Mod/Fem/Gui/Resources/icons/fem-femmesh-gmsh-from-shape.svg
similarity index 99%
rename from src/Mod/Fem/Gui/Resources/icons/fem-fem-mesh-gmsh-from-shape.svg
rename to src/Mod/Fem/Gui/Resources/icons/fem-femmesh-gmsh-from-shape.svg
index d9fd5d8cf..b869f01ca 100644
--- a/src/Mod/Fem/Gui/Resources/icons/fem-fem-mesh-gmsh-from-shape.svg
+++ b/src/Mod/Fem/Gui/Resources/icons/fem-femmesh-gmsh-from-shape.svg
@@ -15,7 +15,7 @@
id="svg2860"
sodipodi:version="0.32"
inkscape:version="0.48.5 r10040"
- sodipodi:docname="fem-fem-mesh-gmsh-from-shape.svg"
+ sodipodi:docname="fem-femmesh-gmsh-from-shape.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.1">
isDerivedFrom(ViewProviderFemPostFunction::getClassTypeId()));
@@ -244,7 +244,7 @@ void TaskPostFunction::applyPythonCode() {
//############################################################################################
TaskPostClip::TaskPostClip(ViewProviderDocumentObject* view, App::PropertyLink* function, QWidget* parent)
- : TaskPostBox(view,Gui::BitmapFactory().pixmap("fem-fem-mesh-create-node-by-poly"), tr("Choose implicit function"), parent) {
+ : TaskPostBox(view,Gui::BitmapFactory().pixmap("fem-femmesh-create-node-by-poly"), tr("Choose implicit function"), parent) {
assert(view->isDerivedFrom(ViewProviderFemPostClip::getClassTypeId()));
assert(function);
@@ -363,7 +363,7 @@ void TaskPostClip::on_InsideOut_toggled(bool val) {
//############################################################################################
TaskPostScalarClip::TaskPostScalarClip(ViewProviderDocumentObject* view, QWidget* parent) :
- TaskPostBox(view, Gui::BitmapFactory().pixmap("fem-fem-mesh-create-node-by-poly"), tr("Clip options"), parent) {
+ TaskPostBox(view, Gui::BitmapFactory().pixmap("fem-femmesh-create-node-by-poly"), tr("Clip options"), parent) {
assert(view->isDerivedFrom(ViewProviderFemPostScalarClip::getClassTypeId()));
@@ -455,7 +455,7 @@ void TaskPostScalarClip::on_InsideOut_toggled(bool val) {
//############################################################################################
TaskPostWarpVector::TaskPostWarpVector(ViewProviderDocumentObject* view, QWidget* parent) :
- TaskPostBox(view, Gui::BitmapFactory().pixmap("fem-fem-mesh-create-node-by-poly"), tr("Clip options"), parent) {
+ TaskPostBox(view, Gui::BitmapFactory().pixmap("fem-femmesh-create-node-by-poly"), tr("Clip options"), parent) {
assert(view->isDerivedFrom(ViewProviderFemPostWarpVector::getClassTypeId()));
@@ -540,7 +540,7 @@ void TaskPostWarpVector::on_Min_valueChanged(double v) {
//############################################################################################
TaskPostCut::TaskPostCut(ViewProviderDocumentObject* view, App::PropertyLink* function, QWidget* parent)
- : TaskPostBox(view,Gui::BitmapFactory().pixmap("fem-fem-mesh-create-node-by-poly"), tr("Choose implicit function"), parent) {
+ : TaskPostBox(view,Gui::BitmapFactory().pixmap("fem-femmesh-create-node-by-poly"), tr("Choose implicit function"), parent) {
assert(view->isDerivedFrom(ViewProviderFemPostCut::getClassTypeId()));
assert(function);
diff --git a/src/Mod/Fem/Gui/TaskTetParameter.cpp b/src/Mod/Fem/Gui/TaskTetParameter.cpp
index 2707b9e94..2ac5298a8 100644
--- a/src/Mod/Fem/Gui/TaskTetParameter.cpp
+++ b/src/Mod/Fem/Gui/TaskTetParameter.cpp
@@ -48,7 +48,7 @@ using namespace Gui;
TaskTetParameter::TaskTetParameter(Fem::FemMeshShapeNetgenObject *pcObject,QWidget *parent)
- : TaskBox(Gui::BitmapFactory().pixmap("fem-fem-mesh-create-node-by-poly"),
+ : TaskBox(Gui::BitmapFactory().pixmap("fem-femmesh-create-node-by-poly"),
tr("Tet Parameter"),
true,
parent),
diff --git a/src/Mod/Fem/Gui/ViewProviderFemMesh.cpp b/src/Mod/Fem/Gui/ViewProviderFemMesh.cpp
index 689a96ece..14b238ca5 100644
--- a/src/Mod/Fem/Gui/ViewProviderFemMesh.cpp
+++ b/src/Mod/Fem/Gui/ViewProviderFemMesh.cpp
@@ -183,7 +183,7 @@ App::PropertyFloatConstraint::Constraints ViewProviderFemMesh::floatRange = {1.0
ViewProviderFemMesh::ViewProviderFemMesh()
{
- sPixmap = "fem-fem-mesh-from-shape";
+ sPixmap = "fem-femmesh-from-shape";
ADD_PROPERTY(PointColor,(App::Color(0.7f,0.7f,0.7f)));
ADD_PROPERTY(PointSize,(5.0f));
diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp b/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp
index 9c73dacfc..fa8fedf2b 100644
--- a/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp
+++ b/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp
@@ -66,7 +66,7 @@ ViewProviderFemPostObject::ViewProviderFemPostObject() : m_blockPropertyChanges(
ADD_PROPERTY_TYPE(VectorMode,((long)0), "Coloring", App::Prop_None, "Select what to show for a vector field");
ADD_PROPERTY(Transperency, (0));
- sPixmap = "fem-fem-mesh-from-shape";
+ sPixmap = "fem-femmesh-from-shape";
//create the subnodes which do the visualization work
m_shapeHints = new SoShapeHints();
diff --git a/src/Mod/Fem/_CommandMeshGmshFromShape.py b/src/Mod/Fem/_CommandMeshGmshFromShape.py
index 5044fff6f..a11ce896a 100644
--- a/src/Mod/Fem/_CommandMeshGmshFromShape.py
+++ b/src/Mod/Fem/_CommandMeshGmshFromShape.py
@@ -38,7 +38,7 @@ class _CommandMeshGmshFromShape(FemCommands):
# the Fem_MeshGmshFromShape command definition
def __init__(self):
super(_CommandMeshGmshFromShape, self).__init__()
- self.resources = {'Pixmap': 'fem-fem-mesh-gmsh-from-shape',
+ self.resources = {'Pixmap': 'fem-femmesh-gmsh-from-shape',
'MenuText': QtCore.QT_TRANSLATE_NOOP("Fem_MeshGmshFromShape", "FEM mesh from shape by GMSH"),
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Fem_MeshGmshFromShape", "Create a FEM mesh from a shape by GMSH mesher")}
self.is_active = 'with_part_feature'
diff --git a/src/Mod/Fem/_CommandMeshNetgenFromShape.py b/src/Mod/Fem/_CommandMeshNetgenFromShape.py
index 877687a5b..f497fcb34 100644
--- a/src/Mod/Fem/_CommandMeshNetgenFromShape.py
+++ b/src/Mod/Fem/_CommandMeshNetgenFromShape.py
@@ -37,7 +37,7 @@ class _CommandMeshNetgenFromShape(FemCommands):
# the Fem_MeshNetgenFromShape command definition
def __init__(self):
super(_CommandMeshNetgenFromShape, self).__init__()
- self.resources = {'Pixmap': 'fem-fem-mesh-netgen-from-shape',
+ self.resources = {'Pixmap': 'fem-femmesh-netgen-from-shape',
'MenuText': QtCore.QT_TRANSLATE_NOOP("Fem_MeshFromShape", "FEM mesh from shape by Netgen"),
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Fem_MeshFromShape", "Create a FEM volume mesh from a solid or face shape by Netgen internal mesher")}
self.is_active = 'with_part_feature'
diff --git a/src/Mod/Fem/_FemMeshGmsh.py b/src/Mod/Fem/_FemMeshGmsh.py
index ea29ad8a3..5cfe46711 100644
--- a/src/Mod/Fem/_FemMeshGmsh.py
+++ b/src/Mod/Fem/_FemMeshGmsh.py
@@ -33,8 +33,10 @@ class _FemMeshGmsh():
"""
# they will be used from the task panel too, thus they need to be outside of the __init__
- known_element_dimensions = ['Auto', '1D', '2D', '3D']
- known_element_orders = ['Auto', '1st', '2nd']
+ known_element_dimensions = ['Automatic', '1D', '2D', '3D']
+ known_element_orders = ['Automatic', '1st', '2nd']
+ known_mesh_algorithm_2D = ['Automatic', 'MeshAdapt', 'Delaunay', 'Frontal', 'BAMG', 'DelQuad']
+ known_mesh_algorithm_3D = ['Automatic', 'Delaunay', 'New Delaunay', 'Frontal', 'Frontal Delaunay', 'Frontal Hex', 'MMG3D', 'R-tree']
def __init__(self, obj):
self.Type = "FemMeshGmsh"
@@ -44,19 +46,41 @@ class _FemMeshGmsh():
obj.addProperty("App::PropertyLink", "Part", "FEM Mesh", "Part object to mesh")
obj.Part = None
- obj.addProperty("App::PropertyLength", "ElementSizeMax", "FEM Mesh Params", "Max mesh element size (0.0 = infinity)")
- obj.ElementSizeMax = 0.0 # will be 1e+22
+ obj.addProperty("App::PropertyLength", "CharacteristicLengthMax", "FEM GMSH Mesh Params", "Max mesh element size (0.0 = infinity)")
+ obj.CharacteristicLengthMax = 0.0 # will be 1e+22
- obj.addProperty("App::PropertyLength", "ElementSizeMin", "FEM Mesh Params", "Min mesh element size")
- obj.ElementSizeMin = 0.0
+ obj.addProperty("App::PropertyLength", "CharacteristicLengthMin", "FEM GMSH Mesh Params", "Min mesh element size")
+ obj.CharacteristicLengthMin = 0.0
- obj.addProperty("App::PropertyEnumeration", "ElementDimension", "FEM Mesh Params", "Dimension of mesh elements (Auto = according ShapeType of part to mesh)")
+ obj.addProperty("App::PropertyEnumeration", "ElementDimension", "FEM GMSH Mesh Params", "Dimension of mesh elements (Auto = according ShapeType of part to mesh)")
obj.ElementDimension = _FemMeshGmsh.known_element_dimensions
- obj.ElementDimension = 'Auto' # according ShapeType of Part to mesh
+ obj.ElementDimension = 'Automatic' # according ShapeType of Part to mesh
- obj.addProperty("App::PropertyEnumeration", "ElementOrder", "FEM Mesh Params", "Order of mesh elements (Auto will be 2nd)")
+ obj.addProperty("App::PropertyEnumeration", "ElementOrder", "FEM GMSH Mesh Params", "Order of mesh elements (Auto will be 2nd)")
obj.ElementOrder = _FemMeshGmsh.known_element_orders
- obj.ElementOrder = 'Auto' # = 2nd
+ obj.ElementOrder = 'Automatic' # = 2nd
+
+ obj.addProperty("App::PropertyBool", "OptimizeStd", "FEM GMSH Mesh Params", "Optimize tetra elements")
+ obj.OptimizeStd = False
+
+ obj.addProperty("App::PropertyBool", "OptimizeNetgen", "FEM GMSH Mesh Params", "Optimize tetra elements by use of Netgen")
+ obj.OptimizeNetgen = False
+
+ obj.addProperty("App::PropertyBool", "HighOrderOptimize", "FEM GMSH Mesh Params", "Optimize hight order meshes")
+ obj.HighOrderOptimize = False
+
+ obj.addProperty("App::PropertyBool", "RecombineAll", "FEM GMSH Mesh Params", "Apply recombination algorithm to all surfaces")
+ obj.RecombineAll = False
+
+ obj.addProperty("App::PropertyEnumeration", "Algorithm2D", "FEM GMSH Mesh Params", "mesh algorithm 2D")
+ obj.Algorithm2D = _FemMeshGmsh.known_mesh_algorithm_2D
+ obj.Algorithm2D = 'Automatic' # ?
+
+ obj.addProperty("App::PropertyEnumeration", "Algorithm3D", "FEM GMSH Mesh Params", "mesh algorithm 3D")
+ obj.Algorithm3D = _FemMeshGmsh.known_mesh_algorithm_3D
+ obj.Algorithm3D = 'Automatic' # ?
+
+ obj.addProperty("App::PropertyMap", "CharacteristicLengthMap", "FEM GMSH Mesh Params", "Map of CharacteristicLength of Shape elements")
def execute(self, obj):
return
diff --git a/src/Mod/Fem/_FemSolverZ88.py b/src/Mod/Fem/_FemSolverZ88.py
index c9f05a46b..9ed12d117 100644
--- a/src/Mod/Fem/_FemSolverZ88.py
+++ b/src/Mod/Fem/_FemSolverZ88.py
@@ -27,7 +27,7 @@ __url__ = "http://www.freecadweb.org"
## @package FemSolverZ88
# \ingroup FEM
-import FreeCAD
+# import FreeCAD
import FemToolsZ88
@@ -42,15 +42,15 @@ class _FemSolverZ88():
obj.addProperty("App::PropertyString", "SolverType", "Base", "Type of the solver", 1) # the 1 set the property to ReadOnly
obj.SolverType = str(self.Type)
- fem_prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/General")
+ # fem_prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/General") # not needed ATM
- obj.addProperty("App::PropertyPath", "WorkingDir", "Fem", "Working directory for calculations")
- obj.WorkingDir = fem_prefs.GetString("WorkingDir", "")
+ obj.addProperty("App::PropertyPath", "WorkingDir", "Fem", "Working directory for calculations, will only be used it is left blank in preferences")
+ # the working directory is not set, the solver working directory is only used if the preferences working directory is left blank
obj.addProperty("App::PropertyEnumeration", "AnalysisType", "Fem", "Type of the analysis")
- obj.AnalysisType = FemToolsZ88.FemToolsZ88.known_analysis_types
- analysis_type = fem_prefs.GetInt("AnalysisType", 0)
- obj.AnalysisType = FemToolsZ88.FemToolsZ88.known_analysis_types[analysis_type]
+ known_analysis_types = FemToolsZ88.FemToolsZ88.known_analysis_types
+ obj.AnalysisType = known_analysis_types
+ obj.AnalysisType = known_analysis_types[0]
def execute(self, obj):
return
diff --git a/src/Mod/Fem/_TaskPanelFemMeshGmsh.py b/src/Mod/Fem/_TaskPanelFemMeshGmsh.py
index 0a9d0a42a..8aae5d848 100644
--- a/src/Mod/Fem/_TaskPanelFemMeshGmsh.py
+++ b/src/Mod/Fem/_TaskPanelFemMeshGmsh.py
@@ -78,14 +78,14 @@ class _TaskPanelFemMeshGmsh:
self.run_gmsh()
def get_mesh_params(self):
- self.clmax = self.mesh_obj.ElementSizeMax
- self.clmin = self.mesh_obj.ElementSizeMin
+ self.clmax = self.mesh_obj.CharacteristicLengthMax
+ self.clmin = self.mesh_obj.CharacteristicLengthMin
self.order = self.mesh_obj.ElementOrder
self.dimension = self.mesh_obj.ElementDimension
def set_mesh_params(self):
- self.mesh_obj.ElementSizeMax = self.clmax
- self.mesh_obj.ElementSizeMin = self.clmin
+ self.mesh_obj.CharacteristicLengthMax = self.clmax
+ self.mesh_obj.CharacteristicLengthMin = self.clmin
self.mesh_obj.ElementOrder = self.order
self.mesh_obj.ElementDimension = self.dimension
@@ -141,7 +141,12 @@ class _TaskPanelFemMeshGmsh:
import FemGmshTools
gmsh_mesh = FemGmshTools.FemGmshTools(self.obj, self.analysis)
self.console_log("Start GMSH ...")
- error = gmsh_mesh.create_mesh()
+ error = ''
+ try:
+ error = gmsh_mesh.create_mesh()
+ except:
+ import sys
+ print("Unexpected error when creating mesh: ", sys.exc_info()[0])
if error:
print(error)
self.console_log('GMSH had warnings ...')
diff --git a/src/Mod/Fem/_ViewProviderFemMeshGmsh.py b/src/Mod/Fem/_ViewProviderFemMeshGmsh.py
index 981bfeed6..34d4239aa 100644
--- a/src/Mod/Fem/_ViewProviderFemMeshGmsh.py
+++ b/src/Mod/Fem/_ViewProviderFemMeshGmsh.py
@@ -38,7 +38,7 @@ class _ViewProviderFemMeshGmsh:
vobj.Proxy = self
def getIcon(self):
- return ":/icons/fem-fem-mesh-from-shape.svg"
+ return ":/icons/fem-femmesh-from-shape.svg"
def attach(self, vobj):
self.ViewObject = vobj