Cycles: Support heat volume attribute

Similar to velocity, it was kind of supported by the mesh manager but
was missing a code in BlenderSession to get actual values.

In Cycles Heat is an attribute which goes from -1 to 1, where -1 is
the coldest ever temperature, 1 is the hottest ever one.
This commit is contained in:
Sergey Sharybin 2016-04-15 12:02:31 +02:00
parent a52b4378b2
commit f951cc36e2
2 changed files with 79 additions and 7 deletions

View File

@ -1113,7 +1113,8 @@ void BlenderSession::builtin_image_info(const string &builtin_name, void *builti
return;
if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY) ||
builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_FLAME))
builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_FLAME) ||
builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT))
channels = 1;
else if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_COLOR))
channels = 4;
@ -1125,6 +1126,13 @@ void BlenderSession::builtin_image_info(const string &builtin_name, void *builti
int3 resolution = get_int3(b_domain.domain_resolution());
int amplify = (b_domain.use_high_resolution())? b_domain.amplify() + 1: 1;
/* Velocity and heat data is always low-resolution. */
if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY) ||
builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT))
{
amplify = 1;
}
width = resolution.x * amplify;
height = resolution.y * amplify;
depth = resolution.z * amplify;
@ -1248,8 +1256,10 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void
int3 resolution = get_int3(b_domain.domain_resolution());
int length, amplify = (b_domain.use_high_resolution())? b_domain.amplify() + 1: 1;
/* Velocity data is always low-resolution. */
if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY)) {
/* Velocity and heat data is always low-resolution. */
if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY) ||
builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT))
{
amplify = 1;
}
@ -1260,7 +1270,6 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void
if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY)) {
SmokeDomainSettings_density_grid_get_length(&b_domain.ptr, &length);
if(length == num_pixels) {
SmokeDomainSettings_density_grid_get(&b_domain.ptr, pixels);
return true;
@ -1270,7 +1279,6 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void
/* this is in range 0..1, and interpreted by the OpenGL smoke viewer
* as 1500..3000 K with the first part faded to zero density */
SmokeDomainSettings_flame_grid_get_length(&b_domain.ptr, &length);
if(length == num_pixels) {
SmokeDomainSettings_flame_grid_get(&b_domain.ptr, pixels);
return true;
@ -1279,7 +1287,6 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void
else if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_COLOR)) {
/* the RGB is "premultiplied" by density for better interpolation results */
SmokeDomainSettings_color_grid_get_length(&b_domain.ptr, &length);
if(length == num_pixels*4) {
SmokeDomainSettings_color_grid_get(&b_domain.ptr, pixels);
return true;
@ -1287,12 +1294,18 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void
}
else if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY)) {
SmokeDomainSettings_velocity_grid_get_length(&b_domain.ptr, &length);
if(length == num_pixels*3) {
SmokeDomainSettings_velocity_grid_get(&b_domain.ptr, pixels);
return true;
}
}
else if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT)) {
SmokeDomainSettings_heat_grid_get_length(&b_domain.ptr, &length);
if(length == num_pixels) {
SmokeDomainSettings_heat_grid_get(&b_domain.ptr, pixels);
return true;
}
}
else {
fprintf(stderr,
"Cycles error: unknown volume attribute %s, skipping\n",

View File

@ -191,6 +191,29 @@ static int rna_SmokeModifier_velocity_grid_get_length(PointerRNA *ptr, int lengt
return length[0];
}
static int rna_SmokeModifier_heat_grid_get_length(
PointerRNA *ptr,
int length[RNA_MAX_ARRAY_DIMENSION])
{
#ifdef WITH_SMOKE
SmokeDomainSettings *sds = (SmokeDomainSettings *)ptr->data;
float *heat = NULL;
int size = 0;
/* Heat data is always low-resolution. */
if (sds->fluid) {
size = sds->res[0] * sds->res[1] * sds->res[2];
heat = smoke_get_heat(sds->fluid);
}
length[0] = (heat) ? size : 0;
#else
(void)ptr;
length[0] = 0;
#endif
return length[0];
}
static void rna_SmokeModifier_density_grid_get(PointerRNA *ptr, float *values)
{
#ifdef WITH_SMOKE
@ -293,6 +316,34 @@ static void rna_SmokeModifier_flame_grid_get(PointerRNA *ptr, float *values)
#endif
}
static void rna_SmokeModifier_heat_grid_get(PointerRNA *ptr, float *values)
{
#ifdef WITH_SMOKE
SmokeDomainSettings *sds = (SmokeDomainSettings *)ptr->data;
int length[RNA_MAX_ARRAY_DIMENSION];
int size = rna_SmokeModifier_heat_grid_get_length(ptr, length);
float *heat;
BLI_rw_mutex_lock(sds->fluid_mutex, THREAD_LOCK_READ);
heat = smoke_get_heat(sds->fluid);
if (heat != NULL) {
/* scale heat values from -2.0-2.0 to -1.0-1.0. */
for (int i = 0; i < size; i++) {
values[i] = heat[i] * 0.5f;
}
}
else {
memset(values, 0, size * sizeof(float));
}
BLI_rw_mutex_unlock(sds->fluid_mutex);
#else
UNUSED_VARS(ptr, values);
#endif
}
static void rna_SmokeFlow_density_vgroup_get(PointerRNA *ptr, char *value)
{
SmokeFlowSettings *flow = (SmokeFlowSettings *)ptr->data;
@ -563,6 +614,14 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
RNA_def_property_float_funcs(prop, "rna_SmokeModifier_color_grid_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Color Grid", "Smoke color grid");
prop = RNA_def_property(srna, "heat_grid", PROP_FLOAT, PROP_NONE);
RNA_def_property_array(prop, 32);
RNA_def_property_flag(prop, PROP_DYNAMIC);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_dynamic_array_funcs(prop, "rna_SmokeModifier_heat_grid_get_length");
RNA_def_property_float_funcs(prop, "rna_SmokeModifier_heat_grid_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Heat Grid", "Smoke heat grid");
prop = RNA_def_property(srna, "cell_size", PROP_FLOAT, PROP_XYZ); /* can change each frame when using adaptive domain */
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "cell_size", "Cell Size");