diff --git a/src/Mod/Fem/femcommands/commands.py b/src/Mod/Fem/femcommands/commands.py index 19fefd76e7..b2f6f7ea45 100644 --- a/src/Mod/Fem/femcommands/commands.py +++ b/src/Mod/Fem/femcommands/commands.py @@ -863,7 +863,7 @@ class _MeshRegion(CommandManager): super().__init__() self.menutext = Qt.QT_TRANSLATE_NOOP("FEM_MeshRegion", "FEM mesh refinement") self.tooltip = Qt.QT_TRANSLATE_NOOP("FEM_MeshRegion", "Creates a FEM mesh refinement") - self.is_active = "with_gmsh_femmesh" + self.is_active = "with_femmesh" self.do_activated = "add_obj_on_gui_selobj_set_edit" diff --git a/src/Mod/Fem/femmesh/netgentools.py b/src/Mod/Fem/femmesh/netgentools.py index 88fe25d187..f63a3a2f6e 100644 --- a/src/Mod/Fem/femmesh/netgentools.py +++ b/src/Mod/Fem/femmesh/netgentools.py @@ -111,7 +111,9 @@ NetgenTools.run_netgen(**{params}) "heal": self.obj.HealShape, "params": self.get_meshing_parameters(), "second_order": self.obj.SecondOrder, + "second_order_linear": self.obj.SecondOrderLinear, "result_file": self.result_file, + "mesh_region": self.get_mesh_region(), } def compute(self): @@ -121,12 +123,33 @@ NetgenTools.run_netgen(**{params}) return self.process @staticmethod - def run_netgen(brep_file, threads, heal, params, second_order, result_file): - + def run_netgen( + brep_file, + threads, + heal, + params, + second_order, + second_order_linear, + result_file, + mesh_region, + ): geom = occ.OCCGeometry(brep_file) ngcore.SetNumThreads(threads) + shape = geom.shape + for items, l in mesh_region: + for t, n in items: + if t == "Vertex": + shape.vertices.vertices[n - 1].maxh = l + elif t == "Edge": + shape.edges.edges[n - 1].maxh = l + elif t == "Face": + shape.faces.faces[n - 1].maxh = l + elif t == "Solid": + shape.solids.solids[n - 1].maxh = l + with ngcore.TaskManager(): + geom = occ.OCCGeometry(shape) if heal: geom.Heal() mesh = geom.GenerateMesh(mp=meshing.MeshingParameters(**params)) @@ -145,6 +168,8 @@ NetgenTools.run_netgen(**{params}) return None if second_order: + if second_order_linear: + mesh.SetGeometry(None) mesh.SecondOrder() coords = mesh.Coordinates() @@ -318,6 +343,22 @@ NetgenTools.run_netgen(**{params}) return params + def get_mesh_region(self): + from Part import Shape as PartShape + + result = [] + for reg in self.obj.MeshRegionList: + for s, sub_list in reg.References: + if s.isDerivedFrom("App::GeoFeature") and isinstance( + s.getPropertyOfGeometry(), PartShape + ): + geom = s.getPropertyOfGeometry() + sub_obj = [s.getSubObject(_) for _ in sub_list] + sub_sh = geom.findSubShape(sub_obj) + l = reg.CharacteristicLength.getValueAs("mm").Value + result.append((sub_sh, l)) + return result + @staticmethod def version(): result = "{}: {}\n" + "{}: {}\n" + "{}: {}\n" + "{}: {}" diff --git a/src/Mod/Fem/femobjects/mesh_netgen.py b/src/Mod/Fem/femobjects/mesh_netgen.py index de04357beb..21f9dd70ba 100644 --- a/src/Mod/Fem/femobjects/mesh_netgen.py +++ b/src/Mod/Fem/femobjects/mesh_netgen.py @@ -51,6 +51,16 @@ class MeshNetgen(base_fempythonobject.BaseFemPythonObject): def _get_properties(self): prop = [] + prop.append( + _PropHelper( + type="App::PropertyLinkList", + name="MeshRegionList", + group="Base", + doc="Refinements of the mesh", + value=[], + ) + ) + # mesh parameters prop.append( _PropHelper( type="App::PropertyString", @@ -403,6 +413,15 @@ class MeshNetgen(base_fempythonobject.BaseFemPythonObject): value=True, ) ) + prop.append( + _PropHelper( + type="App::PropertyBool", + name="SecondOrderLinear", + group="Mesh Parameters", + doc="Second order nodes are created by linear interpolation", + value=False, + ) + ) prop.append( _PropHelper( type="App::PropertyInteger", diff --git a/src/Mod/Fem/femviewprovider/view_mesh_netgen.py b/src/Mod/Fem/femviewprovider/view_mesh_netgen.py index 34a60d3698..b2835fe253 100644 --- a/src/Mod/Fem/femviewprovider/view_mesh_netgen.py +++ b/src/Mod/Fem/femviewprovider/view_mesh_netgen.py @@ -151,6 +151,10 @@ class VPMeshNetgen(view_base_femobject.VPBaseFemObject): FreeCAD.Console.PrintError(message + "\n") return True + def claimChildren(self): + reg_childs = self.Object.MeshRegionList + return reg_childs + def dumps(self): return None