Thanks, it got me started. I got it working but had to figure out a few things, like the fact that prop->type
and prop->subtype
are empty, no matter what type of value is set (list, single float, single int, string) so I cannot check data type which is a problem in cpp.
/*
This works but it's not safe to use as such because of data types
that could be different from float/double. prop->type yields nothing
so there's no way to check data type and choose appropriate casting.
However the type of data is read correctly by readfile.c when opening
the .blend file. It seems lost on the way to Cycles rendering.
Also, this only works for data read from the .blend file (settings new
custom values won't be updated in Cycles unless you save, reload
and run the render/preview again).
*/
ID *id = (ID *)b_ob->ptr.owner_id;
IDProperty *id_props = IDP_GetProperties(id, false);
IDProperty *prop = IDP_GetPropertyFromGroup(id_props, "custom_data");
std::cout << "Prop name: " << prop->name << std::endl;
std::cout << "Prop len: " << prop->len << std::endl;
std::cout << "Prop type: " << prop->type << std::endl;
std::cout << "Prop subtype: " << prop->subtype << std::endl;
std::cout << "Prop flag: " << prop->flag << std::endl;
std::cout << "Prop saved: " << prop->saved << std::endl;
double *values = (double*)prop->data.pointer;
for (unsigned int i = 0; i < prop->len; i++) {
auto value = *(values + i);
std::cout << "Custom value " << i << ": " << value << std::endl;
}
Here’s how I tested it, which also reveals a 6-digit limit in storing floats. I hope I’m doing something wrong and this is not by design, because then I don’t see the point of having to use double
.
import math.pi
obj = bpy.data.objects['Cube']
obj['custom_data'] = [452.01, 1/3, 0.5, 0.000515, 0.117, 897621545.1, 90654.008, math.pi*100]
Then
- hit “play” to start the script
- save your .blend file
- reopen the file from Blender (File > Open > …)
- start render or preview render
This is what cpp outputs in the console:
Prop name: custom_data
Prop len: 8
Prop total len: 8
Prop type:
Prop subtype:
Prop flag: 0
Prop saved: 0
Custom value 0: 452.01
Custom value 1: 0.333333
Custom value 2: 0.5
Custom value 3: 0.000515
Custom value 4: 0.117
Custom value 5: 8.97622e+08
Custom value 6: 90654
Custom value 7: 314.159
When you store an list of float in Python, it is stored as a double internally with two ints (?) so it took me a while to figure out why retrieving values with type float
in cpp yielded different results from what was set in Python.
I’ve been trying to rewrite in many ways the above loop to accomodate auto values. I also tried with sizeof to find the proper step for pointer iteration. The only way to have a result guaranteed under control so far is to call *IDP_GetPropertyTypeFromGroup()
instead of *IDP_GetPropertyFromGroup()
and to mention what type you want but this does not handle cases when say, a list of strings is set as custom_data instead of a list of floats.
Last thing, is there a way to tell Cycles (or Blender?) that an object should be updated? So far I can only load custom values that are saved within the .blend file. Modifying such values at runtime will not trigger an update.