SD5 is an addon that adds the libfive library to Blender. Libfive allows the user to create any geometry defined by math. The resulting geometry is meshed using manifold dual contouring and added to the scene. This allows complex interactions between Blender systems and arbitrary math defined meshes, such as controlling shapes with empties and letting them update in real-time.
The addon is made interactive by using a post depsgraph handler that runs scripts starting with “SD5_” and expects sd5.name and sd5.mesh to be correctly defined.
For more information please go to the github page or grab the addon zip on the releases page.
Please note that I made this addon primarily for myself so it is not as user friendly as can be. But if you know a bit of Python it shouldn’t be a problem.
Hi Snowdaw,
I try to use your addon but don’t work for me B4.3.1RC
Traceback:
Erreur: Python : Traceback (most recent call last):
File "\Texte", line 8, in <module>
File "C:\Users\Patrick\AppData\Roaming\Blender Foundation\Blender\4.3\scripts\addons\SD5\utils.py", line 6, in set_control
s = s.move(control.location)
^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'location'
This error happens when the name given to the set_control function does not correspond to an object.
I assume you pasted the example code from the github, but forgot to create the three empties/objects the example uses: “C_Sphere”, “C_Box” and “Bounds”.
Would the Libfive library also allow implementing SDF curves that are faster than when using the native SDF to Mesh functionality of Blender’s Geo Nodes?
This is a bit of a tricky question. I think you are referring to the SDF to Mesh geometry node used by the SDF presets geometry nodes and the Prototyper addon.
The short answer would be yes.
Performance & meshing
The volume to mesh node uses marching cubes, which is bad at preserving sharp edges so you need a high resolution to get an acceptable mesh. And even then be disappointed by the result.
Libfive uses manifold dual contouring, which produces a more accurate mesh than marching cubes. So you wouldn’t need as high resolution and thus get more performance. Libfive also uses multithreading to speed up the meshing. So it is probably on par or faster than the Blender volume to mesh node.
The curves the SDF presets geometry nodes use aren’t actually curves, but rather a lot of spheres blended together. This combined with marching cubes needing higher resolution leads to bad performance.
I could implement the same system to get an easy curve that works good enough. The fun thing is that because shapes are defined by math, you have a lot of freedom and most things are possible. I’ll try to make an example script.
Ok I managed to get a very interesting result. I hadn’t read everything…
Now to continue my experiments I will need more explanations about the language and the limits of the real-time procedural process.
Thks a lot for your work.
It seems like it can’t find the SD5 library in 4.3.1. I can install it in the Python folder, but just wanted to see what you think before doing so.
import SD5.utils as sd5
s = sd5.sphere(2)
sd5.name = "SD5_Demo"
sd5.mesh = s.get_mesh()
Error: Python: Traceback (most recent call last):
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1126, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
ModuleNotFoundError: No module named 'SD5'
I added a video to the first post to show the initial setup. For better visualization I suggest changing your axis empty for the bounds to a cube empty so you can see where it stops generating the mesh.
It could be that the normals are set incorrectly because the bounds are clipped.
A quick fix for inverting the normals is adding a geometry nodes modifier with the Flip Faces node.
This error happens if the unzipped folder isn’t called SD5. Downloading the repository as zip instead of downloading the zip file in the releases tab probably caused this. Github automatically adds the branch name to the folder.
I should fix this because it’s an easy mistake to make.
For anyone else having this problem: Please use the zip from the releases tab.
This is done by creating a curve a like normal. Then create an mesh without vertices and put the geometry nodes seen in the screenshot on the mesh object.
This is because we can’t get the data we want directly from the curve in edit mode. So we convert the relevant data to a mesh object with geometry nodes and sample that in the shape_on_curve function.
This is just a simple and quick example I threw together:
I thought about this a bunch and even tried to make a more streamlined interface using geometry nodes. While it works to some extent, it’s just not as flexible as the Python API for creating complex shapes and interactions.
The addon is still quite rudimentary and I would like to add more helper functions for people to learn from how the system works. After more functions have been added putting a nicer UI on top of that is possible. But I don’t really see the point of just having a custom window where you input the same values as you would in the script. Also creating a UI that accounts for every possible case would just create something that looks like the script again.
Having said that, you can make your own UI in a way using geometry nodes. This is how I would do it if I wanted to have more control from the viewport.
Here is an example where I blend two shapes together using a dial gizmo node.
This uses the example with controls on the github, but the “C_Box” is a mesh object instead of an empty. It has one vertex, could be more but that could visually get in the way. The object has the following geometry nodes setup. This just gets the value from the dial gizmo, clamps it and then stores it on the vertex as an attribute called “blend”.
Here is the script with a function that reads single values (not vectors) from depsgraph evaluated meshes and uses it for the blend value.
import bpy
import sd5
# Add a new sphere and box
s = sd5.sphere(1)
b = sd5.box([-1,-1,-1], [1,1,1])
# Move the shapes
s = sd5.set_control(s, "C_Sphere")
b = sd5.set_control(b, "C_Box")
def get_attribute_value(obj_name, attr_name):
# Get the object
obj = bpy.data.objects.get(obj_name)
# Get the depsgraph
depsgraph = bpy.context.evaluated_depsgraph_get()
# Get the depsgraph evaluated version of the mesh
# This means that the geometry nodes are applied
obj = obj.evaluated_get(depsgraph)
# Get the attributes
attr = obj.data.attributes
# Return the value of the first vertex with attr_name
return attr[attr_name].data[0].value
# Blend the shapes together
s = sd5.blend(s, b, get_attribute_value("C_Box", "blend"))
# Set the name of the output object and get the mesh from within the bounds empty
# Note that these two variables need to be set for the script to work
sd5.name = "SD5_Demo"
sd5.mesh = sd5.mesh_from_bounds(s, 6, "Bounds")
I hope this helps understand how you can create your own UI for the things you need.