Skip to content

Commit 468fe30

Browse files
authored
Merge pull request #27 from CadQuery/materials
Added materials support by postfixing the material name onto the volume
2 parents cf112d1 + bcfabf4 commit 468fe30

5 files changed

Lines changed: 92 additions & 6 deletions

File tree

.github/workflows/tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,6 @@ jobs:
4040
- name: Install dependencies
4141
run: |
4242
python -m pip install .[dev]
43+
python -m pip install --upgrade git+https://github.com/CadQuery/cadquery.git
4344
- name: Run tests
4445
run: python -m pytest -v

assembly_mesh_plugin/plugin.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ def get_gmsh(self, imprint=True):
161161
tagged_faces = {}
162162
multi_material_groups = {}
163163
surface_groups = {}
164+
solid_materials = []
164165

165166
gmsh.initialize()
166167
gmsh.option.setNumber(
@@ -171,13 +172,23 @@ def get_gmsh(self, imprint=True):
171172
# Get all of the subshapes and their corresponding names/positions
172173
extract_subshape_names(self, self.name)
173174

174-
# Imprint the assembly
175-
imprinted_assembly, imprinted_solids_with_orginal_ids = (
176-
cq.occ_impl.assembly.imprint(self)
177-
)
178-
179175
# Handle the imprinted assembly
180176
if imprint:
177+
# Imprint the assembly
178+
imprinted_assembly, imprinted_solids_with_orginal_ids = (
179+
cq.occ_impl.assembly.imprint(self)
180+
)
181+
182+
# Collect the materials
183+
for imp_solid, solid_id in imprinted_solids_with_orginal_ids.items():
184+
# Track down the original assembly object so that we can retrieve materials, if present
185+
short_id = solid_id[0].split("/")[-1] if "/" in solid_id[0] else solid_id[0]
186+
subassy = self.objects[short_id]
187+
188+
# Save the assembly material associated with this solid
189+
if subassy.material:
190+
solid_materials.append(subassy.material.name)
191+
181192
for solid, name in imprinted_solids_with_orginal_ids.items():
182193
# Get just the name of the current assembly
183194
short_name = name[0].split("/")[-1]
@@ -202,12 +213,23 @@ def get_gmsh(self, imprint=True):
202213
# Add faces to the mesh and handle tagged faces
203214
add_faces_to_mesh(gmsh, solid, short_name, loc)
204215

216+
# Keep track of the materials
217+
if self.objects[name.split("/")[-1]].material:
218+
solid_materials.append(self.objects[name.split("/")[-1]].material.name)
219+
205220
# Step through each of the volumes and add physical groups for each
206221
for volume_id in volumes.keys():
207222
gmsh.model.occ.synchronize()
223+
224+
# Attach the name to the volume
208225
ps = gmsh.model.addPhysicalGroup(3, volumes[volume_id][0])
209226
gmsh.model.setPhysicalName(3, ps, f"{volume_map[volume_id]}")
210227

228+
# Attach the material to the volume, if the material is present
229+
if len(solid_materials) >= volume_id:
230+
ps1 = gmsh.model.addPhysicalGroup(3, volumes[volume_id][0])
231+
gmsh.model.setPhysicalName(3, ps1, f"mat:{solid_materials[volume_id - 1]}")
232+
211233
# Handle tagged surface groups
212234
for t_name, surf_group in surface_groups.items():
213235
gmsh.model.occ.synchronize()

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
66
name = "assembly_mesh_plugin"
77
version = "0.1.4"
88
dependencies = [
9-
"cadquery>=2.6.0",
9+
"cadquery>=2.7.0",
1010
"gmsh",
1111
]
1212
requires-python = ">=3.9"

tests/sample_assemblies.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,3 +315,20 @@ def generate_subshape_assembly():
315315
)
316316

317317
return assy
318+
319+
320+
def generate_materials_assembly():
321+
"""
322+
Generates a simple assembly with materials.
323+
"""
324+
325+
# Create the assembly children
326+
cube_1 = cq.Workplane().box(10, 10, 10)
327+
cube_2 = cq.Workplane().box(5, 5, 5)
328+
329+
# Put the assembly together
330+
assy = cq.Assembly(name="top-level")
331+
assy.add(cube_1, name="cube_1", material="copper")
332+
assy.add(cube_2, name="cube_2", loc=cq.Location(0, 0, 5), material="steel")
333+
334+
return assy

tests/test_meshes.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
generate_test_cross_section,
99
generate_assembly,
1010
generate_subshape_assembly,
11+
generate_materials_assembly,
1112
)
1213

1314

@@ -175,3 +176,48 @@ def _check_physical_groups():
175176

176177
# Ensure that there are physical groups
177178
_check_physical_groups()
179+
180+
181+
def test_mesh_materials():
182+
"""
183+
Tests to make sure that assembly materials are preserved in the mesh data.
184+
"""
185+
186+
# Create the basic assembly with materials
187+
assy = generate_materials_assembly()
188+
189+
#
190+
# Imprinted assembly
191+
#
192+
gmsh = assy.getGmsh(imprint=True)
193+
gmsh.model.mesh.generate(3)
194+
195+
phys_groups = gmsh.model.getPhysicalGroups(3)
196+
197+
# Make sure we got the correct names
198+
name = gmsh.model.getPhysicalName(3, 1)
199+
assert name == "cube_1"
200+
name = gmsh.model.getPhysicalName(3, 2)
201+
assert name == "mat:copper"
202+
name = gmsh.model.getPhysicalName(3, 3)
203+
assert name == "cube_2"
204+
name = gmsh.model.getPhysicalName(3, 4)
205+
assert name == "mat:steel"
206+
207+
#
208+
# Non-imprinted assembly
209+
#
210+
gmsh = assy.getGmsh(imprint=False)
211+
gmsh.model.mesh.generate(3)
212+
213+
phys_groups = gmsh.model.getPhysicalGroups(3)
214+
215+
# Make sure we got the correct names
216+
name = gmsh.model.getPhysicalName(3, 1)
217+
assert name == "cube_1"
218+
name = gmsh.model.getPhysicalName(3, 2)
219+
assert name == "mat:copper"
220+
name = gmsh.model.getPhysicalName(3, 3)
221+
assert name == "cube_2"
222+
name = gmsh.model.getPhysicalName(3, 4)
223+
assert name == "mat:steel"

0 commit comments

Comments
 (0)