Skip to content

Commit 8b05113

Browse files
authored
fix: carry material through the GN SDF remesh with Set Material (#20)
GN-generated geometry carries no material, so the input mesh's material was dropped on remesh and the result rendered default white -- a real user gotcha. build_remesh_via_sdf now re-applies the input material inside the tree via a GeometryNodeSetMaterial node on the GridToMesh output (the GN-native fix; verified to carry through on both builds: eval mesh materials=['Clay']). Added a material-present assertion (the source material must appear on the evaluated mesh) alongside the existing vertex-delta check, and a Materials gotcha note in the README. Verified headless on Blender 4.5.10 LTS and 5.1.1. Signed-off-by: fOuttaMyPaint <TMhospitalitystrategies@gmail.com>
1 parent 2f4630c commit 8b05113

2 files changed

Lines changed: 24 additions & 5 deletions

File tree

examples/gn-sdf-remesh/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ NODES modifier and evaluated via the depsgraph.
1111
socket, so wiring the grid there is an invalid link that yields no geometry). `Grid to Mesh`
1212
has the matching grid input.
1313

14+
**Materials gotcha:** geometry generated by Geometry Nodes carries **no** material, so the
15+
input mesh's material is dropped on remesh (the result renders with the default white). Re-apply
16+
it inside the tree with a **Set Material** node (`GeometryNodeSetMaterial`) on the remeshed
17+
output — this example does that and asserts the material survives onto the evaluated mesh.
18+
1419
## Run
1520

1621
```bash

examples/gn-sdf-remesh/gn_sdf_remesh.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
def get_eevee_engine_id():
2020
return 'BLENDER_EEVEE' if bpy.app.version >= (5, 0, 0) else 'BLENDER_EEVEE_NEXT'
2121

22-
def build_remesh_via_sdf(voxel_size=0.1, threshold=0.0):
22+
def build_remesh_via_sdf(voxel_size=0.1, threshold=0.0, material=None):
2323
tree = bpy.data.node_groups.new("SDFRemesh", 'GeometryNodeTree')
2424
tree.interface.new_socket(name="Geometry", in_out='INPUT', socket_type='NodeSocketGeometry')
2525
tree.interface.new_socket(name="Geometry", in_out='OUTPUT', socket_type='NodeSocketGeometry')
@@ -30,7 +30,15 @@ def build_remesh_via_sdf(voxel_size=0.1, threshold=0.0):
3030
grid_to_mesh.inputs["Threshold"].default_value = threshold
3131
tree.links.new(gi.outputs["Geometry"], mesh_to_sdf.inputs["Mesh"])
3232
link = tree.links.new(mesh_to_sdf.outputs["SDF Grid"], grid_to_mesh.inputs["Grid"])
33-
tree.links.new(grid_to_mesh.outputs["Mesh"], go.inputs["Geometry"])
33+
# GN-generated geometry carries no material, so the input mesh's material is dropped on
34+
# remesh. Re-apply it inside the tree with a Set Material node (the GN-native fix).
35+
out_socket = grid_to_mesh.outputs["Mesh"]
36+
if material is not None:
37+
set_mat = tree.nodes.new('GeometryNodeSetMaterial')
38+
set_mat.inputs["Material"].default_value = material
39+
tree.links.new(out_socket, set_mat.inputs["Geometry"])
40+
out_socket = set_mat.outputs["Geometry"]
41+
tree.links.new(out_socket, go.inputs["Geometry"])
3442
return tree, link.is_valid
3543

3644
def build():
@@ -89,13 +97,19 @@ def main():
8997

9098
obj = build()
9199
base = len(obj.data.vertices)
92-
tree, link_valid = build_remesh_via_sdf()
100+
src_mat = obj.data.materials[0] if obj.data.materials else None
101+
tree, link_valid = build_remesh_via_sdf(material=src_mat)
93102
obj.modifiers.new("sdf", 'NODES').node_group = tree
94103
dg = bpy.context.evaluated_depsgraph_get(); ev = obj.evaluated_get(dg)
95-
m = ev.to_mesh(); evc = len(m.vertices); ev.to_mesh_clear()
96-
print(f"link_valid={link_valid} base_vcount={base} eval_vcount={evc}")
104+
m = ev.to_mesh(); evc = len(m.vertices)
105+
mat_names = [mm.name for mm in m.materials if mm is not None]
106+
ev.to_mesh_clear()
107+
print(f"link_valid={link_valid} base_vcount={base} eval_vcount={evc} materials={mat_names}")
97108
if not (link_valid and evc > 0 and evc != base):
98109
print("ERROR: SDF remesh produced no/unchanged geometry", file=sys.stderr); return 3
110+
# the Set Material node must carry the input material onto the remeshed result
111+
if src_mat is not None and src_mat.name not in mat_names:
112+
print(f"ERROR: material '{src_mat.name}' dropped by remesh", file=sys.stderr); return 6
99113

100114
if args.output:
101115
if not render_still(obj, args.output, args.engine):

0 commit comments

Comments
 (0)