Skip to content

Commit 4e73484

Browse files
TMHSDigitalclaude
andauthored
fix: water-trough, gn-sdf-remesh and eval-mesh-datablock-name quality pass (#229)
* fix(showcase): water-trough quality pass — solid end boards that hold the water The ends were open U-bands and the water's end face showed where a board belongs; the piece read as a hammock. Ends are now solid boards on the hull's outer arc, and a containment budget casts rays outward from across each water end face (exit 18, --open-ends). --short-legs now stretches the legs to the floor instead of letting the piece re-ground, keeping its AABB still. Per-plank tone and grain, darker water at half fill, wider straps. The temp glTF export is removed after measuring. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> * fix(examples): gn-sdf-remesh still shows source and remesh side by side under edge cages Render path only. The check, its assertions and exit codes are unchanged. Both tori are grounded on their measured bottoms. docs/gallery/index.html also carries the water-trough card alt from the previous commit. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> * docs(examples): eval-mesh-datablock-name README says who hits it and why name tests never worked Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> * docs(showcase): conventions for contained vessels and still falsifier envelopes Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> --------- Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent dc2fcf2 commit 4e73484

16 files changed

Lines changed: 882 additions & 104 deletions

File tree

81 KB
Loading
-1.59 KB
Loading
-421 KB
Loading
-766 Bytes
Loading

‎docs/gallery/gn-sdf-remesh/index.html‎

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@
1616
<meta property="og:image" content="https://tmhsdigital.github.io/Blender-Developer-Tools/gallery/assets/gn-sdf-remesh-hero.webp" />
1717
<meta property="og:image:width" content="1280" />
1818
<meta property="og:image:height" content="720" />
19-
<meta property="og:image:alt" content="A glossy red torus with visibly blocky voxel faceting from the SDF remesh." />
19+
<meta property="og:image:alt" content="Two red tori side by side under pale edge cages: the source with even ring topology, and its SDF remesh covered in a dense irregular voxel grid." />
2020
<meta property="og:site_name" content="Blender Developer Tools" />
2121
<meta name="twitter:card" content="summary_large_image" />
2222
<meta name="twitter:title" content="gn-sdf-remesh — Examples — Blender Developer Tools" />
2323
<meta name="twitter:description" content="A Geometry Nodes SDF remesh (MeshToSDFGrid → GridToMesh at the SDF zero-level), with a Set Material node carrying the material through the remesh." />
2424
<meta name="twitter:image" content="https://tmhsdigital.github.io/Blender-Developer-Tools/gallery/assets/gn-sdf-remesh-hero.webp" />
25-
<meta name="twitter:image:alt" content="A glossy red torus with visibly blocky voxel faceting from the SDF remesh." />
25+
<meta name="twitter:image:alt" content="Two red tori side by side under pale edge cages: the source with even ring topology, and its SDF remesh covered in a dense irregular voxel grid." />
2626
<style>
2727
/* fonts are deployed by the landing build (docs/fonts/) */
2828
@font-face { font-family: 'Barlow Condensed'; font-weight: 600; font-display: swap;
@@ -268,8 +268,8 @@ <h1>gn-sdf-remesh</h1>
268268
<p>A Geometry Nodes SDF remesh (MeshToSDFGrid → GridToMesh at the SDF zero-level), with a Set Material node carrying the material through the remesh.</p>
269269
</header>
270270
<main id="main">
271-
<button class="detail-hero" id="heroZoom" type="button" aria-label="View full size: A glossy red torus with visibly blocky voxel faceting from the SDF remesh.">
272-
<img src="../assets/gn-sdf-remesh-hero.webp" alt="A glossy red torus with visibly blocky voxel faceting from the SDF remesh." width="1280" height="720" />
271+
<button class="detail-hero" id="heroZoom" type="button" aria-label="View full size: Two red tori side by side under pale edge cages: the source with even ring topology, and its SDF remesh covered in a dense irregular voxel grid.">
272+
<img src="../assets/gn-sdf-remesh-hero.webp" alt="Two red tori side by side under pale edge cages: the source with even ring topology, and its SDF remesh covered in a dense irregular voxel grid." width="1280" height="720" />
273273
</button>
274274
<p class="zoom-hint">Rendered headless by the example itself — click to zoom.</p>
275275
<div class="callout"><span class="tag">witnesses</span> An SDF grid is meshed with Grid to Mesh, not Volume to Mesh; GN geometry needs Set Material or it renders untextured.</div>
@@ -377,10 +377,56 @@ <h2>Source</h2>
377377
wall.rotation_euler = (<span class="n">1.5708</span>, <span class="n">0</span>, <span class="n">0</span>); bpy.context.collection.objects.link(wall)
378378
w = bpy.data.worlds.new(<span class="s">&quot;W&quot;</span>); w.use_nodes = <span class="k">True</span>
379379
w.node_tree.nodes[<span class="s">&quot;Background&quot;</span>].inputs[<span class="n">0</span>].default_value = (<span class="n">0.02</span>, <span class="n">0.021</span>, <span class="n">0.025</span>, <span class="n">1</span>); sc.world = w
380-
aim = bpy.data.objects.new(<span class="s">&quot;Aim&quot;</span>, <span class="k">None</span>); aim.location = (<span class="n">0</span>, <span class="n">0</span>, <span class="n">0.5</span>); bpy.context.collection.objects.link(aim)
381-
<span class="c"># off-axis and low: the remesh facets are the API evidence, and they only</span>
382-
<span class="c"># read when a raking key skims them from the side</span>
383-
cam = bpy.data.objects.new(<span class="s">&quot;cam&quot;</span>, bpy.data.cameras.new(<span class="s">&quot;cam&quot;</span>)); cam.location = (<span class="n">2.6</span>, -<span class="n">5.2</span>, <span class="n">1.5</span>)
380+
<span class="c"># Input beside output. Alone, the remeshed torus read as a glossy inner</span>
381+
<span class="c"># tube with blotchy highlights: nothing said &quot;remeshed&quot;. The source torus</span>
382+
<span class="c"># (a modifier-free copy of the same datablock) on the left and the SDF</span>
383+
<span class="c"># result on the right, each under a cage of its own edges, show the</span>
384+
<span class="c"># thing the check measures: UV-ring topology in, voxel-grid topology</span>
385+
<span class="c"># out. Render-path scaffolding only; the check ran before this.</span>
386+
obj.location.x = <span class="n">1.85</span>
387+
src = bpy.data.objects.new(<span class="s">&quot;SourceTorus&quot;</span>, obj.data.copy())
388+
src.location = (-<span class="n">1.85</span>, obj.location.y, obj.location.z)
389+
bpy.context.collection.objects.link(src)
390+
<span class="c"># build() centres the torus at z=0.55 with a 0.5 minor radius, so both</span>
391+
<span class="c"># hovered 5 cm over the floor. Ground each on its own measured bottom:</span>
392+
<span class="c"># the SDF surface is not exactly the source surface.</span>
393+
dg0 = bpy.context.evaluated_depsgraph_get()
394+
em = obj.evaluated_get(dg0).to_mesh()
395+
obj.location.z -= obj.location.z + min(v.co.z <span class="k">for</span> v <span class="k">in</span> em.vertices)
396+
obj.evaluated_get(dg0).to_mesh_clear()
397+
src.location.z = -min(v.co.z <span class="k">for</span> v <span class="k">in</span> src.data.vertices)
398+
cage_mat = bpy.data.materials.new(<span class="s">&quot;Cage&quot;</span>); cage_mat.use_nodes = <span class="k">True</span>
399+
cb = cage_mat.node_tree.nodes.get(<span class="s">&#x27;Principled BSDF&#x27;</span>)
400+
cb.inputs[<span class="s">&#x27;Base Color&#x27;</span>].default_value = (<span class="n">0.92</span>, <span class="n">0.82</span>, <span class="n">0.62</span>, <span class="n">1</span>)
401+
cb.inputs[<span class="s">&#x27;Roughness&#x27;</span>].default_value = <span class="n">0.4</span>
402+
cages = []
403+
dg = bpy.context.evaluated_depsgraph_get()
404+
<span class="k">for</span> host, remeshed <span class="k">in</span> ((src, <span class="k">False</span>), (obj, <span class="k">True</span>)):
405+
<span class="c"># The remeshed cage is the evaluated result frozen into a plain mesh:</span>
406+
<span class="c"># a live copy of the tree would re-apply its Set Material and paint</span>
407+
<span class="c"># the cage crimson.</span>
408+
data = (bpy.data.meshes.new_from_object(obj.evaluated_get(dg))
409+
<span class="k">if</span> remeshed <span class="k">else</span> obj.data.copy())
410+
cage = bpy.data.objects.new(host.name + <span class="s">&quot;Cage&quot;</span>, data)
411+
cage.data.materials.clear(); cage.data.materials.append(cage_mat)
412+
<span class="k">for</span> poly <span class="k">in</span> cage.data.polygons:
413+
poly.material_index = <span class="n">0</span>
414+
cage.location = host.location
415+
wire = cage.modifiers.new(<span class="s">&quot;cage&quot;</span>, <span class="s">&#x27;WIREFRAME&#x27;</span>)
416+
wire.thickness = <span class="n">0.012</span>; wire.offset = <span class="n">1.0</span>; wire.use_even_offset = <span class="k">True</span>
417+
wire.material_offset = <span class="n">0</span>
418+
bpy.context.collection.objects.link(cage)
419+
cages.append(cage)
420+
<span class="c"># Softer than 0.16: at that gloss every voxel facet threw its own hard</span>
421+
<span class="c"># glint and the highlight broke into blocks that read as artifacts.</span>
422+
<span class="k">for</span> m <span class="k">in</span> obj.data.materials:
423+
<span class="k">if</span> m <span class="k">is</span> <span class="k">not</span> <span class="k">None</span> <span class="k">and</span> m.node_tree <span class="k">is</span> <span class="k">not</span> <span class="k">None</span>:
424+
bsdf = m.node_tree.nodes.get(<span class="s">&#x27;Principled BSDF&#x27;</span>)
425+
<span class="k">if</span> bsdf <span class="k">is</span> <span class="k">not</span> <span class="k">None</span>:
426+
bsdf.inputs[<span class="s">&#x27;Roughness&#x27;</span>].default_value = <span class="n">0.32</span>
427+
aim = bpy.data.objects.new(<span class="s">&quot;Aim&quot;</span>, <span class="k">None</span>); aim.location = (<span class="n">0</span>, <span class="n">0</span>, <span class="n">0.45</span>); bpy.context.collection.objects.link(aim)
428+
<span class="c"># Raised so both donut holes read, and pulled back to hold the pair.</span>
429+
cam = bpy.data.objects.new(<span class="s">&quot;cam&quot;</span>, bpy.data.cameras.new(<span class="s">&quot;cam&quot;</span>)); cam.location = (<span class="n">1.5</span>, -<span class="n">10.8</span>, <span class="n">5.5</span>)
384430
bpy.context.collection.objects.link(cam); sc.camera = cam
385431
c = cam.constraints.new(<span class="s">&#x27;TRACK_TO&#x27;</span>); c.target = aim; c.track_axis = <span class="s">&#x27;TRACK_NEGATIVE_Z&#x27;</span>; c.up_axis = <span class="s">&#x27;UP_Y&#x27;</span>
386432
<span class="c"># low raking warm key so every facet catches a distinct glint, faint cool</span>
@@ -466,7 +512,7 @@ <h2>Source</h2>
466512
</main>
467513
<dialog class="lightbox" id="lightbox" aria-label="Full-size render">
468514
<button class="lightbox-close" type="button" autofocus>Close</button>
469-
<img src="../assets/gn-sdf-remesh-hero.webp" alt="A glossy red torus with visibly blocky voxel faceting from the SDF remesh." />
515+
<img src="../assets/gn-sdf-remesh-hero.webp" alt="Two red tori side by side under pale edge cages: the source with even ring topology, and its SDF remesh covered in a dense irregular voxel grid." />
470516
</dialog>
471517
<footer>
472518
<div class="statusbar">

‎docs/gallery/index.html‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ <h2><a href="turntable/">turntable</a></h2>
365365
</article>
366366
<article class="card" data-tags="geometry-nodes materials">
367367
<a class="card-media" href="gn-sdf-remesh/" tabindex="-1" aria-hidden="true">
368-
<img src="assets/gn-sdf-remesh-hero.webp" alt="A glossy red torus with visibly blocky voxel faceting from the SDF remesh." loading="lazy" decoding="async" />
368+
<img src="assets/gn-sdf-remesh-hero.webp" alt="Two red tori side by side under pale edge cages: the source with even ring topology, and its SDF remesh covered in a dense irregular voxel grid." loading="lazy" decoding="async" />
369369
</a>
370370
<div class="card-body">
371371
<h2><a href="gn-sdf-remesh/">gn-sdf-remesh</a></h2>
@@ -1058,7 +1058,7 @@ <h2><a href="anvil/">anvil</a></h2>
10581058
</article>
10591059
<article class="card" data-tags="mesh export showcase">
10601060
<a class="card-media" href="water-trough/" tabindex="-1" aria-hidden="true">
1061-
<img src="assets/water-trough-hero.webp" alt="A curved wooden water trough on crossed trestle legs, filled with dark green water." loading="lazy" decoding="async" />
1061+
<img src="assets/water-trough-hero.webp" alt="A staved wooden water trough with solid half-round end boards on crossed trestle legs, half full of dark water." loading="lazy" decoding="async" />
10621062
</a>
10631063
<div class="card-body">
10641064
<h2><a href="water-trough/">water-trough</a></h2>

0 commit comments

Comments
 (0)