Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,6 @@ jobs:
- name: Install dependencies
run: |
python -m pip install .[dev]
python -m pip install --upgrade git+https://github.com/CadQuery/cadquery.git
- name: Run tests
run: python -m pytest -v
32 changes: 27 additions & 5 deletions assembly_mesh_plugin/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ def get_gmsh(self, imprint=True):
tagged_faces = {}
multi_material_groups = {}
surface_groups = {}
solid_materials = []

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

# Imprint the assembly
imprinted_assembly, imprinted_solids_with_orginal_ids = (
cq.occ_impl.assembly.imprint(self)
)

# Handle the imprinted assembly
if imprint:
# Imprint the assembly
imprinted_assembly, imprinted_solids_with_orginal_ids = (
cq.occ_impl.assembly.imprint(self)
)

# Collect the materials
for imp_solid, solid_id in imprinted_solids_with_orginal_ids.items():
# Track down the original assembly object so that we can retrieve materials, if present
short_id = solid_id[0].split("/")[-1] if "/" in solid_id[0] else solid_id[0]
subassy = self.objects[short_id]

# Save the assembly material associated with this solid
if subassy.material:
solid_materials.append(subassy.material.name)

for solid, name in imprinted_solids_with_orginal_ids.items():
# Get just the name of the current assembly
short_name = name[0].split("/")[-1]
Expand All @@ -202,12 +213,23 @@ def get_gmsh(self, imprint=True):
# Add faces to the mesh and handle tagged faces
add_faces_to_mesh(gmsh, solid, short_name, loc)

# Keep track of the materials
if self.objects[name.split("/")[-1]].material:
solid_materials.append(self.objects[name.split("/")[-1]].material.name)

# Step through each of the volumes and add physical groups for each
for volume_id in volumes.keys():
gmsh.model.occ.synchronize()

# Attach the name to the volume
ps = gmsh.model.addPhysicalGroup(3, volumes[volume_id][0])
gmsh.model.setPhysicalName(3, ps, f"{volume_map[volume_id]}")

# Attach the material to the volume, if the material is present
if len(solid_materials) >= volume_id:
ps1 = gmsh.model.addPhysicalGroup(3, volumes[volume_id][0])
gmsh.model.setPhysicalName(3, ps1, f"mat:{solid_materials[volume_id - 1]}")

# Handle tagged surface groups
for t_name, surf_group in surface_groups.items():
gmsh.model.occ.synchronize()
Expand Down
17 changes: 17 additions & 0 deletions tests/sample_assemblies.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,3 +315,20 @@ def generate_subshape_assembly():
)

return assy


def generate_materials_assembly():
"""
Generates a simple assembly with materials.
"""

# Create the assembly children
cube_1 = cq.Workplane().box(10, 10, 10)
cube_2 = cq.Workplane().box(5, 5, 5)

# Put the assembly together
assy = cq.Assembly(name="top-level")
assy.add(cube_1, name="cube_1", material="copper")
assy.add(cube_2, name="cube_2", loc=cq.Location(0, 0, 5), material="steel")

return assy
46 changes: 46 additions & 0 deletions tests/test_meshes.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
generate_test_cross_section,
generate_assembly,
generate_subshape_assembly,
generate_materials_assembly,
)


Expand Down Expand Up @@ -175,3 +176,48 @@ def _check_physical_groups():

# Ensure that there are physical groups
_check_physical_groups()


def test_mesh_materials():
"""
Tests to make sure that assembly materials are preserved in the mesh data.
"""

# Create the basic assembly with materials
assy = generate_materials_assembly()

#
# Imprinted assembly
#
gmsh = assy.getGmsh(imprint=True)
gmsh.model.mesh.generate(3)

phys_groups = gmsh.model.getPhysicalGroups(3)

# Make sure we got the correct names
name = gmsh.model.getPhysicalName(3, 1)
assert name == "cube_1"
name = gmsh.model.getPhysicalName(3, 2)
assert name == "mat:copper"
name = gmsh.model.getPhysicalName(3, 3)
assert name == "cube_2"
name = gmsh.model.getPhysicalName(3, 4)
assert name == "mat:steel"

#
# Non-imprinted assembly
#
gmsh = assy.getGmsh(imprint=False)
gmsh.model.mesh.generate(3)

phys_groups = gmsh.model.getPhysicalGroups(3)

# Make sure we got the correct names
name = gmsh.model.getPhysicalName(3, 1)
assert name == "cube_1"
name = gmsh.model.getPhysicalName(3, 2)
assert name == "mat:copper"
name = gmsh.model.getPhysicalName(3, 3)
assert name == "cube_2"
name = gmsh.model.getPhysicalName(3, 4)
assert name == "mat:steel"
Loading