Fem: Move MeshGmsh proxy from Fem::FemMeshObject to Fem::FemMeshShapeBaseObject - fixes #14897
This commit is contained in:
@@ -490,7 +490,7 @@ def makeMeshBoundaryLayer(doc, base_mesh, name="MeshBoundaryLayer"):
|
||||
def makeMeshGmsh(doc, name="MeshGmsh"):
|
||||
"""makeMeshGmsh(document, [name]):
|
||||
makes a Gmsh FEM mesh object"""
|
||||
obj = doc.addObject("Fem::FemMeshObjectPython", name)
|
||||
obj = doc.addObject("Fem::FemMeshShapeBaseObjectPython", name)
|
||||
from femobjects import mesh_gmsh
|
||||
|
||||
mesh_gmsh.MeshGmsh(obj)
|
||||
|
||||
@@ -762,10 +762,18 @@ class _MeshGmshFromShape(CommandManager):
|
||||
"ObjectsFem.makeMeshGmsh(FreeCAD.ActiveDocument, '" + mesh_obj_name + "')"
|
||||
)
|
||||
FreeCADGui.doCommand(
|
||||
"FreeCAD.ActiveDocument.ActiveObject.Part = FreeCAD.ActiveDocument.{}".format(
|
||||
"FreeCAD.ActiveDocument.ActiveObject.Shape = FreeCAD.ActiveDocument.{}".format(
|
||||
self.selobj.Name
|
||||
)
|
||||
)
|
||||
FreeCADGui.doCommand("FreeCAD.ActiveDocument.ActiveObject.ElementOrder = '2nd'")
|
||||
# SecondOrderLinear gives much better meshes in the regard of
|
||||
# nonpositive jacobians but on curved faces the constraint nodes
|
||||
# will no longer found thus standard will be False
|
||||
# https://forum.freecad.org/viewtopic.php?t=41738
|
||||
# https://forum.freecad.org/viewtopic.php?f=18&t=45260&start=20#p389494
|
||||
FreeCADGui.doCommand("FreeCAD.ActiveDocument.ActiveObject.SecondOrderLinear = False")
|
||||
|
||||
# Gmsh mesh object could be added without an active analysis
|
||||
# but if there is an active analysis move it in there
|
||||
import FemGui
|
||||
|
||||
@@ -57,7 +57,7 @@ class GmshTools:
|
||||
self.analysis = None
|
||||
|
||||
# part to mesh
|
||||
self.part_obj = self.mesh_obj.Part
|
||||
self.part_obj = self.mesh_obj.Shape
|
||||
|
||||
# clmax, CharacteristicLengthMax: float, 0.0 = 1e+22
|
||||
self.clmax = Units.Quantity(self.mesh_obj.CharacteristicLengthMax).Value
|
||||
@@ -982,7 +982,7 @@ doc.recompute()
|
||||
box_obj.ViewObject.Visibility = False
|
||||
|
||||
femmesh_obj = ObjectsFem.makeMeshGmsh(doc, box_obj.Name + "_Mesh")
|
||||
femmesh_obj.Part = box_obj
|
||||
femmesh_obj.Shape = box_obj
|
||||
doc.recompute()
|
||||
|
||||
from femmesh.gmshtools import GmshTools as gt
|
||||
@@ -1009,7 +1009,7 @@ for len in max_mesh_sizes:
|
||||
quantity_len = "{}".format(len)
|
||||
print("\n\n Start length = {}".format(quantity_len))
|
||||
femmesh_obj = ObjectsFem.makeMeshGmsh(doc, box_obj.Name + "_Mesh")
|
||||
femmesh_obj.Part = box_obj
|
||||
femmesh_obj.Shape = box_obj
|
||||
femmesh_obj.CharacteristicLengthMax = "{}".format(quantity_len)
|
||||
femmesh_obj.CharacteristicLengthMin = "{}".format(quantity_len)
|
||||
doc.recompute()
|
||||
|
||||
@@ -64,8 +64,6 @@ class MeshSetsGetter:
|
||||
if self.mesh_object:
|
||||
if hasattr(self.mesh_object, "Shape"):
|
||||
self.theshape = self.mesh_object.Shape
|
||||
elif hasattr(self.mesh_object, "Part"):
|
||||
self.theshape = self.mesh_object.Part
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"A finite mesh without a link to a Shape was given. "
|
||||
|
||||
@@ -31,6 +31,8 @@ __url__ = "https://www.freecad.org"
|
||||
|
||||
from . import base_fempythonobject
|
||||
|
||||
_PropHelper = base_fempythonobject._PropHelper
|
||||
|
||||
|
||||
class MeshGmsh(base_fempythonobject.BaseFemPythonObject):
|
||||
"""
|
||||
@@ -40,295 +42,267 @@ class MeshGmsh(base_fempythonobject.BaseFemPythonObject):
|
||||
Type = "Fem::FemMeshGmsh"
|
||||
|
||||
# they will be used from the task panel too, thus they need to be outside of the __init__
|
||||
known_element_dimensions = ["From Shape", "1D", "2D", "3D"]
|
||||
known_element_orders = ["1st", "2nd"]
|
||||
known_mesh_algorithm_2D = [
|
||||
"Automatic",
|
||||
"MeshAdapt",
|
||||
"Delaunay",
|
||||
"Frontal",
|
||||
"BAMG",
|
||||
"DelQuad",
|
||||
"Packing Parallelograms",
|
||||
]
|
||||
known_mesh_algorithm_3D = [
|
||||
"Automatic",
|
||||
"Delaunay",
|
||||
"New Delaunay",
|
||||
"Frontal",
|
||||
"MMG3D",
|
||||
"R-tree",
|
||||
"HXT",
|
||||
]
|
||||
known_mesh_RecombinationAlgorithms = [
|
||||
"Simple",
|
||||
"Blossom",
|
||||
"Simple full-quad",
|
||||
"Blossom full-quad",
|
||||
]
|
||||
known_mesh_HighOrderOptimizers = [
|
||||
"None",
|
||||
"Optimization",
|
||||
"Elastic+Optimization",
|
||||
"Elastic",
|
||||
"Fast curving",
|
||||
]
|
||||
known_mesh_SubdivisionAlgorithms = ["None", "All Quadrangles", "All Hexahedra", "Barycentric"]
|
||||
|
||||
def __init__(self, obj):
|
||||
super().__init__(obj)
|
||||
self.add_properties(obj)
|
||||
|
||||
for prop in self._get_properties():
|
||||
prop.add_to_object(obj)
|
||||
|
||||
def _get_properties(self):
|
||||
prop = []
|
||||
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyLinkList",
|
||||
name="MeshBoundaryLayerList",
|
||||
group="Base",
|
||||
doc="Mesh boundaries need inflation layers",
|
||||
value=[],
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyLinkList",
|
||||
name="MeshRegionList",
|
||||
group="Base",
|
||||
doc="Mesh refinments of the mesh",
|
||||
value=[],
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyLinkList",
|
||||
name="MeshGroupList",
|
||||
group="Base",
|
||||
doc="Mesh groups of the mesh",
|
||||
value=[],
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyLength",
|
||||
name="CharacteristicLengthMax",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Max mesh element size (0.0 means infinity)",
|
||||
value=0.0, # will be 1e+22
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyLength",
|
||||
name="CharacteristicLengthMin",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Min mesh element size",
|
||||
value=0.0,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
name="ElementDimension",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Dimension of mesh elements ('From Shape': according ShapeType of part to mesh)",
|
||||
value=["From Shape", "1D", "2D", "3D"],
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
name="ElementOrder",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Order of mesh elements",
|
||||
value=["1st", "2nd"],
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyBool",
|
||||
name="OptimizeStd",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Optimize tetrahedral elements",
|
||||
value=True,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyBool",
|
||||
name="OptimizeNetgen",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Optimize tetra elements by use of Netgen",
|
||||
value=False,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
name="HighOrderOptimize",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Optimization of high order meshes",
|
||||
value=[
|
||||
"None",
|
||||
"Optimization",
|
||||
"Elastic+Optimization",
|
||||
"Elastic",
|
||||
"Fast curving",
|
||||
],
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyBool",
|
||||
name="RecombineAll",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Apply recombination algorithm to all surfaces",
|
||||
value=False,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyBool",
|
||||
name="Recombine3DAll",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Apply recombination algorithm to all volumes",
|
||||
value=False,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
name="RecombinationAlgorithm",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Recombination algorithm",
|
||||
value=[
|
||||
"Simple",
|
||||
"Blossom",
|
||||
"Simple full-quad",
|
||||
"Blossom full-quad",
|
||||
],
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyBool",
|
||||
name="CoherenceMesh",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Removes all duplicate mesh vertices",
|
||||
value=True,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyFloat",
|
||||
name="GeometryTolerance",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Geometrical Tolerance (0.0 means GMSH std = 1e-08)",
|
||||
value=1e-06,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyBool",
|
||||
name="SecondOrderLinear",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Second order nodes are created by linear interpolation",
|
||||
value=False,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyIntegerConstraint",
|
||||
name="MeshSizeFromCurvature",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Number of elements per 2*pi radians, 0 to deactivate",
|
||||
value=(12, 0, 10000, 1),
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
name="Algorithm2D",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Mesh algorithm 2D",
|
||||
value=[
|
||||
"Automatic",
|
||||
"MeshAdapt",
|
||||
"Delaunay",
|
||||
"Frontal",
|
||||
"BAMG",
|
||||
"DelQuad",
|
||||
"Packing Parallelograms",
|
||||
],
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
name="Algorithm3D",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Mesh algorithm 3D",
|
||||
value=[
|
||||
"Automatic",
|
||||
"Delaunay",
|
||||
"New Delaunay",
|
||||
"Frontal",
|
||||
"MMG3D",
|
||||
"R-tree",
|
||||
"HXT",
|
||||
],
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyBool",
|
||||
name="GroupsOfNodes",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="For each group create not only the elements but the nodes too",
|
||||
value=False,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
name="SubdivisionAlgorithm",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Mesh subdivision algorithm",
|
||||
value=["None", "All Quadrangles", "All Hexahedra", "Barycentric"],
|
||||
)
|
||||
)
|
||||
|
||||
return prop
|
||||
|
||||
def onDocumentRestored(self, obj):
|
||||
# update old project with new properties
|
||||
for prop in self._get_properties():
|
||||
try:
|
||||
obj.getPropertyByName(prop.name)
|
||||
if prop.name == "Algorithm3D":
|
||||
# refresh the list of known 3D algorithms
|
||||
obj.Algorithm3D = prop.value
|
||||
elif prop.name == "HighOrderOptimize":
|
||||
# HighOrderOptimize was once App::PropertyBool, so check this
|
||||
if type(obj.HighOrderOptimize) is bool:
|
||||
value = obj.HighOrderOptimize
|
||||
obj.setPropertyStatus("HighOrderOptimize", "-LockDynamic")
|
||||
obj.removeProperty("HighOrderOptimize")
|
||||
prop.add_to_object(obj)
|
||||
obj.HighOrderOptimize = "Optimization" if value else "None"
|
||||
except:
|
||||
prop.add_to_object(obj)
|
||||
|
||||
# HighOrderOptimize
|
||||
# was once App::PropertyBool, so check this
|
||||
high_order_optimizer = ""
|
||||
if obj.HighOrderOptimize is True:
|
||||
high_order_optimizer = "Optimization"
|
||||
elif obj.HighOrderOptimize is False:
|
||||
high_order_optimizer = "None"
|
||||
obj.removeProperty("HighOrderOptimize")
|
||||
# add new HighOrderOptimize property
|
||||
self.add_properties(obj)
|
||||
# write the stored high_order_optimizer
|
||||
if high_order_optimizer:
|
||||
obj.HighOrderOptimize = high_order_optimizer
|
||||
|
||||
# Algorithm3D
|
||||
# refresh the list of known 3D algorithms for existing meshes
|
||||
# since some algos are meanwhile deprecated and new algos are available
|
||||
obj.Algorithm3D = MeshGmsh.known_mesh_algorithm_3D
|
||||
|
||||
def add_properties(self, obj):
|
||||
|
||||
# this method is called from onDocumentRestored
|
||||
# thus only add and or set a attribute
|
||||
# if the attribute does not exist
|
||||
|
||||
if not hasattr(obj, "MeshBoundaryLayerList"):
|
||||
obj.addProperty(
|
||||
"App::PropertyLinkList",
|
||||
"MeshBoundaryLayerList",
|
||||
"Base",
|
||||
"Mesh boundaries need inflation layers",
|
||||
# migrate old Part property to Shape property
|
||||
try:
|
||||
value_part = obj.getPropertyByName("Part")
|
||||
obj.setPropertyStatus("Part", "-LockDynamic")
|
||||
obj.removeProperty("Part")
|
||||
# old object is Fem::FemMeshObjectPython (does not have Shape property with global scope)
|
||||
prop = _PropHelper(
|
||||
type="App::PropertyLinkGlobal",
|
||||
name="Shape",
|
||||
group="FEM Mesh",
|
||||
doc="Geometry object, the mesh is made from. The geometry object has to have a Shape",
|
||||
value=value_part,
|
||||
)
|
||||
obj.setPropertyStatus("MeshBoundaryLayerList", "LockDynamic")
|
||||
obj.MeshBoundaryLayerList = []
|
||||
|
||||
if not hasattr(obj, "MeshRegionList"):
|
||||
obj.addProperty(
|
||||
"App::PropertyLinkList", "MeshRegionList", "Base", "Mesh refinments of the mesh"
|
||||
)
|
||||
obj.setPropertyStatus("MeshRegionList", "LockDynamic")
|
||||
obj.MeshRegionList = []
|
||||
|
||||
if not hasattr(obj, "MeshGroupList"):
|
||||
obj.addProperty(
|
||||
"App::PropertyLinkList", "MeshGroupList", "Base", "Mesh groups of the mesh"
|
||||
)
|
||||
obj.setPropertyStatus("MeshGroupList", "LockDynamic")
|
||||
obj.MeshGroupList = []
|
||||
|
||||
if not hasattr(obj, "Part"):
|
||||
obj.addProperty(
|
||||
"App::PropertyLink",
|
||||
"Part",
|
||||
"FEM Mesh",
|
||||
"Geometry object, the mesh is made from. The geometry object has to have a Shape.",
|
||||
)
|
||||
obj.setPropertyStatus("Part", "LockDynamic")
|
||||
obj.Part = None
|
||||
|
||||
if not hasattr(obj, "CharacteristicLengthMax"):
|
||||
obj.addProperty(
|
||||
"App::PropertyLength",
|
||||
"CharacteristicLengthMax",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Max mesh element size (0.0 = infinity)",
|
||||
)
|
||||
obj.setPropertyStatus("CharacteristicLengthMax", "LockDynamic")
|
||||
obj.CharacteristicLengthMax = 0.0 # will be 1e+22
|
||||
|
||||
if not hasattr(obj, "CharacteristicLengthMin"):
|
||||
obj.addProperty(
|
||||
"App::PropertyLength",
|
||||
"CharacteristicLengthMin",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Min mesh element size",
|
||||
)
|
||||
obj.setPropertyStatus("CharacteristicLengthMin", "LockDynamic")
|
||||
obj.CharacteristicLengthMin = 0.0
|
||||
|
||||
if not hasattr(obj, "ElementDimension"):
|
||||
obj.addProperty(
|
||||
"App::PropertyEnumeration",
|
||||
"ElementDimension",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Dimension of mesh elements (Auto = according ShapeType of part to mesh)",
|
||||
)
|
||||
obj.setPropertyStatus("ElementDimension", "LockDynamic")
|
||||
obj.ElementDimension = MeshGmsh.known_element_dimensions
|
||||
obj.ElementDimension = "From Shape" # according ShapeType of Part to mesh
|
||||
|
||||
if not hasattr(obj, "ElementOrder"):
|
||||
obj.addProperty(
|
||||
"App::PropertyEnumeration",
|
||||
"ElementOrder",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Order of mesh elements",
|
||||
)
|
||||
obj.setPropertyStatus("ElementOrder", "LockDynamic")
|
||||
obj.ElementOrder = MeshGmsh.known_element_orders
|
||||
obj.ElementOrder = "2nd"
|
||||
|
||||
if not hasattr(obj, "OptimizeStd"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"OptimizeStd",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Optimize tetrahedral elements",
|
||||
)
|
||||
obj.setPropertyStatus("OptimizeStd", "LockDynamic")
|
||||
obj.OptimizeStd = True
|
||||
|
||||
if not hasattr(obj, "OptimizeNetgen"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"OptimizeNetgen",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Optimize tetra elements by use of Netgen",
|
||||
)
|
||||
obj.setPropertyStatus("OptimizeNetgen", "LockDynamic")
|
||||
obj.OptimizeNetgen = False
|
||||
|
||||
if not hasattr(obj, "HighOrderOptimize"):
|
||||
obj.addProperty(
|
||||
"App::PropertyEnumeration",
|
||||
"HighOrderOptimize",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Optimization of high order meshes",
|
||||
)
|
||||
obj.setPropertyStatus("HighOrderOptimize", "LockDynamic")
|
||||
obj.HighOrderOptimize = MeshGmsh.known_mesh_HighOrderOptimizers
|
||||
obj.HighOrderOptimize = "None"
|
||||
|
||||
if not hasattr(obj, "RecombineAll"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"RecombineAll",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Apply recombination algorithm to all surfaces",
|
||||
)
|
||||
obj.setPropertyStatus("RecombineAll", "LockDynamic")
|
||||
obj.RecombineAll = False
|
||||
|
||||
if not hasattr(obj, "Recombine3DAll"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"Recombine3DAll",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Apply recombination algorithm to all volumes",
|
||||
)
|
||||
obj.setPropertyStatus("Recombine3DAll", "LockDynamic")
|
||||
obj.Recombine3DAll = False
|
||||
|
||||
if not hasattr(obj, "RecombinationAlgorithm"):
|
||||
obj.addProperty(
|
||||
"App::PropertyEnumeration",
|
||||
"RecombinationAlgorithm",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Recombination algorithm",
|
||||
)
|
||||
obj.setPropertyStatus("RecombinationAlgorithm", "LockDynamic")
|
||||
obj.RecombinationAlgorithm = MeshGmsh.known_mesh_RecombinationAlgorithms
|
||||
obj.RecombinationAlgorithm = "Simple"
|
||||
|
||||
if not hasattr(obj, "CoherenceMesh"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"CoherenceMesh",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Removes all duplicate mesh vertices",
|
||||
)
|
||||
obj.setPropertyStatus("CoherenceMesh", "LockDynamic")
|
||||
obj.CoherenceMesh = True
|
||||
|
||||
if not hasattr(obj, "GeometryTolerance"):
|
||||
obj.addProperty(
|
||||
"App::PropertyFloat",
|
||||
"GeometryTolerance",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Geometrical Tolerance (0.0 = GMSH std = 1e-08)",
|
||||
)
|
||||
obj.setPropertyStatus("GeometryTolerance", "LockDynamic")
|
||||
obj.GeometryTolerance = 1e-06
|
||||
|
||||
if not hasattr(obj, "SecondOrderLinear"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"SecondOrderLinear",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Second order nodes are created by linear interpolation",
|
||||
)
|
||||
obj.setPropertyStatus("SecondOrderLinear", "LockDynamic")
|
||||
obj.SecondOrderLinear = False
|
||||
# gives much better meshes in the regard of nonpositive jacobians
|
||||
# but
|
||||
# on curved faces the constraint nodes will no longer found
|
||||
# thus standard will be False
|
||||
# https://forum.freecad.org/viewtopic.php?t=41738
|
||||
# https://forum.freecad.org/viewtopic.php?f=18&t=45260&start=20#p389494
|
||||
|
||||
if not hasattr(obj, "MeshSizeFromCurvature"):
|
||||
obj.addProperty(
|
||||
"App::PropertyIntegerConstraint",
|
||||
"MeshSizeFromCurvature",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"number of elements per 2*pi radians, 0 to deactivate",
|
||||
)
|
||||
obj.setPropertyStatus("MeshSizeFromCurvature", "LockDynamic")
|
||||
obj.MeshSizeFromCurvature = (12, 0, 10000, 1)
|
||||
|
||||
if not hasattr(obj, "Algorithm2D"):
|
||||
obj.addProperty(
|
||||
"App::PropertyEnumeration",
|
||||
"Algorithm2D",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"mesh algorithm 2D",
|
||||
)
|
||||
obj.setPropertyStatus("Algorithm2D", "LockDynamic")
|
||||
obj.Algorithm2D = MeshGmsh.known_mesh_algorithm_2D
|
||||
obj.Algorithm2D = "Automatic"
|
||||
|
||||
if not hasattr(obj, "Algorithm3D"):
|
||||
obj.addProperty(
|
||||
"App::PropertyEnumeration",
|
||||
"Algorithm3D",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"mesh algorithm 3D",
|
||||
)
|
||||
obj.setPropertyStatus("Algorithm3D", "LockDynamic")
|
||||
obj.Algorithm3D = MeshGmsh.known_mesh_algorithm_3D
|
||||
obj.Algorithm3D = "Automatic"
|
||||
|
||||
if not hasattr(obj, "GroupsOfNodes"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"GroupsOfNodes",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"For each group create not only the elements but the nodes too.",
|
||||
)
|
||||
obj.setPropertyStatus("GroupsOfNodes", "LockDynamic")
|
||||
obj.GroupsOfNodes = False
|
||||
|
||||
if not hasattr(obj, "SubdivisionAlgorithm"):
|
||||
obj.addProperty(
|
||||
"App::PropertyEnumeration",
|
||||
"SubdivisionAlgorithm",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Mesh subdivision algorithm",
|
||||
)
|
||||
obj.setPropertyStatus("SubdivisionAlgorithm", "LockDynamic")
|
||||
obj.SubdivisionAlgorithm = MeshGmsh.known_mesh_SubdivisionAlgorithms
|
||||
obj.SubdivisionAlgorithm = "None"
|
||||
prop.add_to_object(obj)
|
||||
except:
|
||||
pass
|
||||
|
||||
@@ -85,7 +85,7 @@ class _TaskPanel:
|
||||
self.form = [self.refWidget, propWidget]
|
||||
analysis = obj.getParentGroup()
|
||||
self._mesh = membertools.get_single_member(analysis, "Fem::FemMeshObject")
|
||||
self._part = self._mesh.Part if self._mesh is not None else None
|
||||
self._part = self._mesh.Shape if self._mesh is not None else None
|
||||
self._partVisible = None
|
||||
self._meshVisible = None
|
||||
|
||||
|
||||
@@ -758,24 +758,24 @@ class Writer:
|
||||
obj = self.getSingleMember("Fem::FemMeshObject")
|
||||
bodyCount = 0
|
||||
prefix = ""
|
||||
if obj.Part.Shape.Solids:
|
||||
if obj.Shape.Shape.Solids:
|
||||
prefix = "Solid"
|
||||
bodyCount = len(obj.Part.Shape.Solids)
|
||||
elif obj.Part.Shape.Faces:
|
||||
bodyCount = len(obj.Shape.Shape.Solids)
|
||||
elif obj.Shape.Shape.Faces:
|
||||
prefix = "Face"
|
||||
bodyCount = len(obj.Part.Shape.Faces)
|
||||
elif obj.Part.Shape.Edges:
|
||||
bodyCount = len(obj.Shape.Shape.Faces)
|
||||
elif obj.Shape.Shape.Edges:
|
||||
prefix = "Edge"
|
||||
bodyCount = len(obj.Part.Shape.Edges)
|
||||
bodyCount = len(obj.Shape.Shape.Edges)
|
||||
return [prefix + str(i + 1) for i in range(bodyCount)]
|
||||
|
||||
def getMeshDimension(self):
|
||||
obj = self.getSingleMember("Fem::FemMeshObject")
|
||||
if obj.Part.Shape.Solids:
|
||||
if obj.Shape.Shape.Solids:
|
||||
return 3
|
||||
if obj.Part.Shape.Faces:
|
||||
if obj.Shape.Shape.Faces:
|
||||
return 2
|
||||
if obj.Part.Shape.Edges:
|
||||
if obj.Shape.Shape.Edges:
|
||||
return 1
|
||||
return None
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ import FreeCADGui
|
||||
|
||||
from femguiutils import selection_widgets
|
||||
|
||||
from femtools import femutils
|
||||
from femtools import membertools
|
||||
|
||||
|
||||
@@ -84,7 +83,7 @@ class _TaskPanel:
|
||||
if analysis is not None:
|
||||
self._mesh = membertools.get_single_member(analysis, "Fem::FemMeshObject")
|
||||
if self._mesh is not None:
|
||||
self._part = femutils.get_part_to_mesh(self._mesh)
|
||||
self._part = self._mesh.Shape
|
||||
self._partVisible = None
|
||||
self._meshVisible = None
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ import FreeCADGui
|
||||
|
||||
from femguiutils import selection_widgets
|
||||
|
||||
from femtools import femutils
|
||||
from femtools import membertools
|
||||
|
||||
|
||||
@@ -63,7 +62,7 @@ class _TaskPanel:
|
||||
if analysis is not None:
|
||||
self._mesh = membertools.get_single_member(analysis, "Fem::FemMeshObject")
|
||||
if self._mesh is not None:
|
||||
self._part = femutils.get_part_to_mesh(self._mesh)
|
||||
self._part = self._mesh.Shape
|
||||
self._partVisible = None
|
||||
self._meshVisible = None
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@ import FreeCAD
|
||||
import FreeCADGui
|
||||
from femguiutils import selection_widgets
|
||||
|
||||
from femtools import femutils
|
||||
from femtools import membertools
|
||||
|
||||
|
||||
@@ -66,7 +65,7 @@ class _TaskPanel:
|
||||
if analysis is not None:
|
||||
self._mesh = membertools.get_single_member(analysis, "Fem::FemMeshObject")
|
||||
if self._mesh is not None:
|
||||
self._part = femutils.get_part_to_mesh(self._mesh)
|
||||
self._part = self._mesh.Shape
|
||||
self._partVisible = None
|
||||
self._meshVisible = None
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ import FreeCAD
|
||||
import FreeCADGui
|
||||
|
||||
from femguiutils import selection_widgets
|
||||
from femtools import femutils
|
||||
from femtools import membertools
|
||||
|
||||
|
||||
@@ -64,7 +63,7 @@ class _TaskPanel:
|
||||
if analysis is not None:
|
||||
self._mesh = membertools.get_single_member(analysis, "Fem::FemMeshObject")
|
||||
if self._mesh is not None:
|
||||
self._part = femutils.get_part_to_mesh(self._mesh)
|
||||
self._part = self._mesh.Shape
|
||||
self._partVisible = None
|
||||
self._meshVisible = None
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ import FreeCAD
|
||||
import FreeCADGui
|
||||
|
||||
from femguiutils import selection_widgets
|
||||
from femtools import femutils
|
||||
from femtools import membertools
|
||||
|
||||
|
||||
@@ -64,7 +63,7 @@ class _TaskPanel:
|
||||
if analysis is not None:
|
||||
self._mesh = membertools.get_single_member(analysis, "Fem::FemMeshObject")
|
||||
if self._mesh is not None:
|
||||
self._part = femutils.get_part_to_mesh(self._mesh)
|
||||
self._part = self._mesh.Shape
|
||||
self._partVisible = None
|
||||
self._meshVisible = None
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ import FreeCAD
|
||||
import FreeCADGui
|
||||
from femguiutils import selection_widgets
|
||||
|
||||
from femtools import femutils
|
||||
from femtools import membertools
|
||||
|
||||
|
||||
@@ -62,7 +61,7 @@ class _TaskPanel:
|
||||
if analysis is not None:
|
||||
self._mesh = membertools.get_single_member(analysis, "Fem::FemMeshObject")
|
||||
if self._mesh is not None:
|
||||
self._part = femutils.get_part_to_mesh(self._mesh)
|
||||
self._part = self._mesh.Shape
|
||||
self._partVisible = None
|
||||
self._meshVisible = None
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ import FreeCADGui
|
||||
|
||||
from femguiutils import selection_widgets
|
||||
|
||||
from femtools import femutils
|
||||
from femtools import membertools
|
||||
|
||||
|
||||
@@ -63,7 +62,7 @@ class _TaskPanel:
|
||||
if analysis is not None:
|
||||
self._mesh = membertools.get_single_member(analysis, "Fem::FemMeshObject")
|
||||
if self._mesh is not None:
|
||||
self._part = femutils.get_part_to_mesh(self._mesh)
|
||||
self._part = self._mesh.Shape
|
||||
self._partVisible = None
|
||||
self._meshVisible = None
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@ import FreeCAD
|
||||
import FreeCADGui
|
||||
|
||||
import FemGui
|
||||
from femobjects import mesh_gmsh
|
||||
from femtools.femutils import is_of_type
|
||||
from femtools.femutils import getOutputWinColor
|
||||
|
||||
@@ -80,9 +79,9 @@ class _TaskPanel:
|
||||
self.form.pb_get_gmsh_version, QtCore.SIGNAL("clicked()"), self.get_gmsh_version
|
||||
)
|
||||
|
||||
self.form.cb_dimension.addItems(mesh_gmsh.MeshGmsh.known_element_dimensions)
|
||||
self.form.cb_dimension.addItems(self.mesh_obj.getEnumerationsOfProperty("ElementDimension"))
|
||||
|
||||
self.form.cb_order.addItems(mesh_gmsh.MeshGmsh.known_element_orders)
|
||||
self.form.cb_order.addItems(self.mesh_obj.getEnumerationsOfProperty("ElementOrder"))
|
||||
|
||||
self.get_mesh_params()
|
||||
self.get_active_analysis()
|
||||
@@ -195,7 +194,7 @@ class _TaskPanel:
|
||||
|
||||
gmsh_mesh = gmshtools.GmshTools(self.mesh_obj, self.analysis)
|
||||
QApplication.setOverrideCursor(Qt.WaitCursor)
|
||||
part = self.mesh_obj.Part
|
||||
part = self.mesh_obj.Shape
|
||||
if (
|
||||
self.mesh_obj.MeshRegionList
|
||||
and part.Shape.ShapeType == "Compound"
|
||||
|
||||
@@ -244,23 +244,6 @@ def make_dir(specific_path):
|
||||
|
||||
# ************************************************************************************************
|
||||
# other
|
||||
def get_part_to_mesh(mesh_obj):
|
||||
"""
|
||||
gmsh mesh object: the Attribute is Part
|
||||
netgen mesh object: the Attribute is Shape
|
||||
other mesh objects: do not have a Attribute which holds the part to mesh
|
||||
"""
|
||||
if is_derived_from(mesh_obj, "Fem::FemMeshGmsh"):
|
||||
return mesh_obj.Part
|
||||
elif is_derived_from(mesh_obj, "Fem::FemMeshShapeNetgenObject"):
|
||||
return mesh_obj.Shape
|
||||
else:
|
||||
return None
|
||||
# TODO: the Attributes should be named with the same name
|
||||
# should it be Shape or Part?
|
||||
# IMHO Part since the Attributes references the document object and not a Shape
|
||||
|
||||
|
||||
def getBoundBoxOfAllDocumentShapes(doc):
|
||||
"""Calculate bounding box containing all objects inside *doc*.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user