Skip to content

Commit

Permalink
Merge pull request #6 from CadQuery/composition
Browse files Browse the repository at this point in the history
Broke the methods apart to make it cleaner if the user wants more meshing control
  • Loading branch information
jmwright authored Jan 29, 2025
2 parents 747e507 + 3595878 commit a47ce50
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 9 deletions.
35 changes: 33 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import cadquery_assembly_mesh_plugin.plugin
You can then tag faces in each of the assembly parts and create your asembly. To export the assembly to a mesh file, you do the following.

```python
your_assembly.assemblyToGmsh(mesh_path="tagged_mesh.msh")
your_assembly.saveToGmsh(mesh_path="tagged_mesh.msh")
```

Normal tag names lead to a physical group with the assembly part name prefixed. So a tag name of `inner-bottom` on an assembly part with the name `steel_plate` will be `steel_plate_inner-bottom`
Expand Down Expand Up @@ -54,11 +54,42 @@ assy = cq.Assembly()
assy.add(shell, name="shell", loc=cq.Location(cq.Vector(0, 0, 0)), color=cq.Color("red"))
assy.add(insert, name="insert", loc=cq.Location(cq.Vector(0, 0, 0)), color=cq.Color("blue"))

assy.assemblyToGmsh(mesh_path="tagged_mesh.msh")
assy.saveToGmsh(mesh_path="tagged_mesh.msh")
```

The resulting `.msh` file should have three physical groups named for tags in it. The `in_contact` group should include the faces from both the shell and the insert.

If you want more control over the mesh generation and export, you can use the `getTaggedGmsh` method and then finalize the mesh yourself.

```python
import cadquery as cq
import cadquery_assembly_mesh_plugin.plugin
import gmsh

shell = cq.Workplane("XY").box(50, 50, 50)
shell = shell.faces(">Z").workplane().rect(21, 21).cutThruAll()
shell.faces(">X[-2]").tag("inner-right")
shell.faces("<X[-2]").tag("~in_contact")

# Create the insert
insert = cq.Workplane("XY").box(20, 20, 50)
insert.faces("<X").tag("~in_contact")
insert.faces(">X").tag("outer-right")

assy = cq.Assembly()
assy.add(shell, name="shell", loc=cq.Location(cq.Vector(0, 0, 0)), color=cq.Color("red"))
assy.add(insert, name="insert", loc=cq.Location(cq.Vector(0, 0, 0)), color=cq.Color("blue"))

# Get a Gmsh object back with all the tagged faces as physical groups
gmsh = assy.getTaggedGmsh()

# Generate the mesh and write it to the file
gmsh.model.mesh.field.setAsBackgroundMesh(2)
gmsh.model.mesh.generate(3)
gmsh.write(mesh_path)
gmsh.finalize()
```

## Tests

These tests are also run in Github Actions, and the meshes which are generated can be viewed as artifacts on the successful `tests` Actions there.
Expand Down
21 changes: 17 additions & 4 deletions assembly_mesh_plugin/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
import gmsh


def assembly_to_gmsh(self, mesh_path="tagged_mesh.msh"):
def get_tagged_gmsh(self):
"""
Pack the assembly into a gmsh object, respecting assembly part names and face tags when creating
the physical groups.
Allows the user to get a gmsh object from the assembly, respecting assembly part names and face
tags, but have more control over how it is meshed.
"""

gmsh.initialize()
gmsh.option.setNumber("General.Terminal", 0)
gmsh.model.add("coil_assembly")
Expand Down Expand Up @@ -126,6 +125,18 @@ def assembly_to_gmsh(self, mesh_path="tagged_mesh.msh"):

gmsh.model.occ.synchronize()

return gmsh


def assembly_to_gmsh(self, mesh_path="tagged_mesh.msh"):
"""
Pack the assembly into a gmsh object, respecting assembly part names and face tags when creating
the physical groups.
"""

# Turn this assembly with potentially tagged faces into a gmsh object
gmsh = get_tagged_gmsh(self)

gmsh.model.mesh.field.setAsBackgroundMesh(2)

gmsh.model.mesh.generate(3)
Expand All @@ -136,3 +147,5 @@ def assembly_to_gmsh(self, mesh_path="tagged_mesh.msh"):

# Patch the new assembly functions into CadQuery's importers package
cq.Assembly.assemblyToGmsh = assembly_to_gmsh
cq.Assembly.saveToGmsh = assembly_to_gmsh # Alias name that works better on cq.Assembly
cq.Assembly.getTaggedGmsh = get_tagged_gmsh
6 changes: 3 additions & 3 deletions tests/smoke_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def test_basic_assembly():
assy = generate_simple_nested_boxes()

# Create a mesh that has all the faces tagged as physical groups
assy.assemblyToGmsh(mesh_path="tagged_mesh.msh")
assy.saveToGmsh(mesh_path="tagged_mesh.msh")


def test_basic_cross_section():
Expand All @@ -27,7 +27,7 @@ def test_basic_cross_section():
assy = generate_test_cross_section()

# Create a mesh that has all the faces in the correct physical groups
assy.assemblyToGmsh(mesh_path="tagged_cross_section.msh")
assy.saveToGmsh(mesh_path="tagged_cross_section.msh")


def test_planar_coil():
Expand All @@ -39,4 +39,4 @@ def test_planar_coil():
assy = generate_assembly()

# Create a mesh that has all the faces in the correct physical groups
assy.assemblyToGmsh(mesh_path="tagged_planar_coil.msh")
assy.saveToGmsh(mesh_path="tagged_planar_coil.msh")

0 comments on commit a47ce50

Please sign in to comment.