Is VDB advection possible with Grasshopper?


is there a way to work with VDB advection with Grasshopper? Maybe with Dendro, but are there any experiments with this topic already? All I can find about it is made with Houdini.

I would be happy to find some help.

Currently I don’t think there’s a solution for VDB advection. In principle, at least the basics with the signed distance field (i.e. SDF) are not that hard to do yourself “from scratch”, however you’d have to know how to program well in Python or C#, as well as know your way around the basics of computational geometry (e.g. relevant algorithms, etc.).
It would also be very hard to reach the quality and performance that Houdini can muster up to.
Dendro did conversions between VDBs and meshes, but nothing more, at least last time I checked (about a year ago).

Houdini is way more optimized to handle VDBs than Rhino - which doesn’t even support those right out of the box yet -, since it’s primarily used in the film industry for special effects.
Rhino is a CAD program and not really meant for doing these kinds of experiments, but it’s possible. It’s meant to do precise modelling with neat and tidy n.u.r.b.s. geometries for real life applications, like manufacturing, design, architecture, etc., but don’t let that hold you back! :wink:

1 Like

Interesting, thank you!

Does this make sense?

using System;
using System.Collections.Generic;
using Rhino.Geometry;

private void RunScript(List<Point3d> Pts, List<Vector3d> VField, double TimeStep, int Iterations, ref object A)
    if (Pts.Count != VField.Count)
        AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "The number of points and vectors must be equal.");

    List<Point3d> advectedPts = new List<Point3d>(Pts);

    for (int iter = 0; iter < Iterations; iter++)
        for (int i = 0; i < advectedPts.Count; i++)
            advectedPts[i] += VField[i] * TimeStep;

    A = advectedPts;

Or maybe this?

import Rhino.Geometry as rg
import ghpythonlib.treehelpers as th
import pyopenvdb as vdb
import numpy as np
import math

def mesh_to_vdb(mesh, voxel_size=1.0):
    points = [vdb.Vec3s(p.X, p.Y, p.Z) for p in mesh.Vertices]
    vertices = [(int(a), int(b), int(c)) for a, b, c in mesh.Faces]
    mesh_grid = vdb.FloatGrid.createLevelSetFromPolygons(points, vertices, voxel_size)
    return mesh_grid

def vdb_to_mesh(vdb_grid, iso_value=0.0, adaptivity=0.0):
    mesh = rg.Mesh()
    vertices, faces = vdb.convertLevelSetToTriangles(vdb_grid, iso_value, adaptivity)

    for v in vertices:
    for v in vertices:
        mesh.Vertices.Add(v.x(), v.y(), v.z())
    for f in faces:
        mesh.Faces.AddFace(f[0], f[1], f[2])
    return mesh

def advect_vdb(vdb_grid, vel_field, time_step, iterations=1):
    for _ in range(iterations):
        advect = vdb.GridAdvect(vdb_grid, vel_field)
    return vdb_grid

# Convert Rhino mesh to VDB
mesh_vdb = mesh_to_vdb(mesh, voxel_size)

# Advect VDB
mesh_vdb_advected = advect_vdb(mesh_vdb, velocity_field, time_step, iterations)

# Convert VDB back to Rhino mesh
mesh_output = vdb_to_mesh(mesh_vdb_advected, iso_value, adaptivity)

# Set the output
A = mesh_output

If yes, how can this be implemented?

Make sense in what sense?

Whether these codes are somehow suitable to do something like that :slight_smile:

That looks like a chatGPT output to me… As @diff-arch mentioned, your best bet is Houdini - it’s relatively easy to start playing with VDBs/meshes there are plenty of tutorials online too.

No they are not. I could provide various “grow” C#'s … but for realistic results (most notably elapsed time wise) stick to some other app.

Where did you get these? At first glance they look okay, but are weirdly incomplete and incoherent.

For instance, the C# example does the advection in a weird way and the composition of the SDF and gradient vectors is totally missing.

The Python script looks a little better, although this currently can’t work, since you cannot use CPython libraries (e.g. pyopenvdb, numpy, etc.) in GHPython, which uses an ancient version of IronPython. CPython support will come in Rhino 8 and hopefully Grasshopper in the future, but still has a long way to go.

@wkarnowka ROFLMAO :sweat_smile: :rofl: :joy:

Here’s a very crude try to replicate what Entagma do in their video, but in two dimensions and without scripting. You need Anemone for the looping though (and Human for the visuals).

I was lazy and didn’t watch the entire video, so my result might deviate from theirs, but the base principles should be very similar.
Keep in mind that this is an oversimplification of what they do in Houdini and since I did it quickly, the definition is rather inefficient and slow.
It should work similarly in three dimensions as well. (33.2 KB)

Interesting, thank you! I’ll take a closer look at it this weekend.

Btw, are these objects also made with Grasshopper? Does anyone know how to create such things?

Source: Chameleon | Food4Rhino

Partially, it seems like the Chameleon add-on creates a bridge between Grasshopper and ZBrush, so part of the process is done in the former and part in the latter.

I haven’t used Chameleon yet, but it seems that a base mesh is constructed in Rhino/Grasshopper and zoned (or partitioned) by adding colored regions to the mesh?
In ZBrush you can use groups and masks to only sculpt distinct parts of a bigger mesh, just like masks or selections work in something like Photoshop.
It seems like Chameleon lets you create these ZBrush groups from the mesh color data from within Grasshopper.
In ZBrush you can then go wild with deformers, NanoMesh, DynaMesh, etc. :wink:
It has a steep learning curve, but once you master the basics, it’s a great experience.
I haven’t used it in a while, since it’s too expensive for casual sculpting. I tend to use Blender for my sculpting needs now, which is also pretty neat. It gets constantly improved.