0
$\begingroup$

I have a 3d numpy array containing results from a simulation which I want to render using Blender. When visualized using napari I get the expected result: enter image description here Using pyopenvdb’s copyFromArray function, I’ve attempted to import the same array within blender.

import bpy, os
import pyopenvdb as vdb
import numpy as np

# --- Scenario 3 -> .npy import of the actual array ---
actual_vol_path = '/Users/tomaubier/actual_volume.npy'
volume = np.load(actual_vol_path)

# numpy array to openvdb object
vecgrid = vdb.DoubleGrid()
vecgrid.name = 'density'
vecgrid.copyFromArray(volume)

# Saving the openvdb object
vdb_file_path = f'/Users/tomaubier/openvdb_volume.vdb'
vdb.write(vdb_file_path, grids=[vecgrid])

# Importing the volume within blender
bpy.ops.object.volume_import(filepath=vdb_file_path, files=[])

However this code gives me what looks like a array of shuffled values. enter image description here I then made up an arbitrary array defined as

# Making up a MWE volume
x = np.linspace(0, 5*np.pi, x_shape)
y = np.linspace(0, np.pi, y_shape)
z = np.linspace(0, .2*np.pi, z_shape)
X, Y, Z = np.meshgrid(x, y, z)
mwe_volume_presave = np.cos(X*Y*Z)

and got the expected result: enter image description here To check whether or not saving and loading the values in a .npy file could be at the root of this issue, I rendered the same dummy array after saving and loading it in a numpy file. As expected this test led to the same rendered output.

I currently don’t have any clues as to whats going on.. Do you guys have any ideas? If anyone wants to perform tests with the data I used, I've created a repo with the blender file and .npy array.

Best.

$\endgroup$
5
  • $\begingroup$ If you start Blender from the command line, you can use Python's print method to print values to the system command line. If I were you, I would try to look at a few coordinates where you know the values and see how they are loaded into Blender. This will give you good clues. I can also strongly recommend using VS Code as an external editor (and debugger!) to set breakpoints and check variables. I found this YouTube Video helpful: https://www.youtube.com/watch?v=YUytEtaVrrc $\endgroup$ Jan 2 at 16:43
  • $\begingroup$ Thanks for the suggestion, it seems way more usable that way indeed. $\endgroup$
    – Tom Aubier
    Jan 3 at 18:23
  • $\begingroup$ I was once again able to validate using a matplotlib imshow() that the volume forwarded to the copyFromArray function contained the expected values. The hypothesis stating that the issue arises from the numpy array to openvdb object conversion is still holding. I if you have any idea as to how I could debug this conversion process I would happily take your suggestions. Cheers $\endgroup$
    – Tom Aubier
    Jan 3 at 18:29
  • $\begingroup$ Hmm. If the problem is within the implementation of pyopenvdb, things get complicated. Depending on the size of your array, you could also try placing the points or vertices as individual geometry points on a container object in Blender (using a Python script) and then reconstructing your volume in a Geometry Node setup with a Points to Volume Node. Then you would have full control over your volume. I once did something similar to parse a 3D lookup table from a file. $\endgroup$ Jan 3 at 18:37
  • $\begingroup$ I see.. I might look into that. I'm not very familiar with Blender geometry nodes though, feel free share some examples if you have any on hand hehe! Thank anyways! $\endgroup$
    – Tom Aubier
    Jan 4 at 19:53

1 Answer 1

0
$\begingroup$

Thanks to Dxyk over on GitHub, a temporary fix was found by passing the numpy array through np.ascontiguousarray before calling copyFromArray.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .