Python Volume access
-
Hello,
I'm trying to read a VolumeObject from Python, just trying to visualize the voxel count for now. When I acces a volume interface, like this...
def GetDParameter(self, node, id, flags): paramId = id[0].id if paramId == c4d.UNITY_VOLUME_VoxelCount: volume = self.get_volume_object(node) if volume == None: return False vi = volume.GetVolume() data = vi.GetActiveVoxelCount() return (True, data, flags | c4d.DESCFLAGS_GET_PARAM_GET) return False
It works, but I always hit this debug breakpoint. Removing that code stops the critical stop.
Do I need to dispose the interface in any way?/Volumes/Branches/build_osx/osx-4-release/depot/release/20.0/frameworks/kernel.framework/source/memory/systemallocator.cpp(487): CRITICAL: Stop: Damaged block (or from a different allocator
Also, how to iterate the volume using a GridIterator?
There's nothing like the step methods from C++ SDK, how do I do the loop? -
Hi @rsodre, there are few examples of volume usage in python in Github repository.
Especially gridaccessor_read_r20.py which demonstrate how to read data for a given voxel.
So here on a volume builder, the next script is working as expected, note that it's very important to import maxon and volume from maxon.frameworks.
import c4d import maxon from maxon.frameworks import volume def main(): # Checks if there is an active object if op is None: raise RuntimeError("Failed to retrieve op.") # Checks if the active object is a Volume builder if not op.IsInstanceOf(c4d.Ovolumebuilder): raise TypeError("op is not a c4d.Ovolumebuilder.") # Gets the C4D Volume Object from the cache cache = op.GetCache() if cache is None: raise RuntimeError("Failed to retrieve the cache of the volume builder.") # Checks if the cache is a C4D Volume Object if not cache.IsInstanceOf(c4d.Ovolume): raise TypeError("cache is not a c4d.Ovolume.") # Gets the Volume object linked to this Ovolume object. volume = cache.GetVolume() if volume is None: raise RuntimeError("Failed to retrieve the maxon.frameworks.volume.VolumeRef.") print(volume.GetActiveVoxelCount()) if __name__ == '__main__': main()
Unfortunately, there is no GridIterator in Python available.
So even if you import maxon, and the volume module you still have the issue, I would say that maybe your volumeobject is not correctly built, but without more code, it's hard to reproduce your issue.
Cheers,
Maxime. -
I'll devour hat repository, thanks!
I'm getting the volume from a VolumeBuilder's cache.
My code so far is here (very early WIP) -
Hi @m_adam.
About the critical stop, it happens even with your code.
I run C4D R20.059 from XCode 10.3What should the coordinate in
access.GetValue(vec)
be?
If I try the voxel coordinate, it always returns the same value, testing everything insidevolume.GetGetActiveVoxelDim()
If I try world coordinates, all values are negative (inside and outside) the volume.From the docs,
volume. GetWorldBoundingBox()
should return amaxon.Range
, but this type is not documented anywhere. In practice, it returns a type that is unknown...
UnknownDataType(net.maxon.parametrictype.range<net.maxon.parametrictype.vec<3,float64>>)
I need to extract a normalized SDF from the volume.
Pretty basic but I can't figure out how just with api descriptions. -
Hi @rsodre, unfortunately, due to a bug solved in R21, it's not possible in R20 to run Cinema 4D as debug mode and call MAXON_CPYTHON_FUNCTION in release mode.
The issue is that the Python volume framework does use the MAXON_CPYTHON_FUNCTION, so this leads to the behavior that the memory model is not the same.
So I guess if you try your code in regular Cinema 4D (without Xcode and not running c4d in debug mode), it will work without issue, could you confirm?
GetValue
works in the global space of the volume grid. This grid can be retrieved from avolumeRef
withGetGridTransform
.
However, since it's amaxon.Matrix64
this is a bit problematic sincemaxon.Matrix64
andmaxon.Vector
doesn't support * operator. So you have to translate them in c4d type (manually) then reconvert it back to a Maxon datatype (this will be done on the fly).Correct,
maxon.Range
is not yet implemented in Python so a UnknownDataType is returned so C++.While I'm happy to assist you on Python Maxon API, I have to admit that the Maxon API regarding Python is far from being feature complete, and regarding your knowledge I advise you to do what you want in C++, it will be far way easier with the GridAccessor.
Cheers,
Maxime. -