Cycles: Fix for point density always using render settings for modifiers

This commit is contained in:
Sergey Sharybin 2015-10-08 12:09:28 +05:00
parent 7980891a13
commit 5d0a99b6ee
4 changed files with 88 additions and 19 deletions

View File

@ -1194,7 +1194,8 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void
if(b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
int length;
b_point_density_node.calc_point_density(b_scene, &length, &pixels);
int settings = background ? 1 : 0; /* 1 - render settings, 0 - vewport settings. */
b_point_density_node.calc_point_density(b_scene, settings, &length, &pixels);
}
}

View File

@ -3019,7 +3019,11 @@ static int point_density_color_source_from_shader(NodeShaderTexPointDensity *sha
/* TODO(sergey): This function assumes allocated array was passed,
* works fine with Cycles via C++ RNA, but fails with call from python.
*/
void rna_ShaderNodePointDensity_density_calc(bNode *self, Scene *scene, int *length, float **values)
void rna_ShaderNodePointDensity_density_calc(bNode *self,
Scene *scene,
int settings,
int *length,
float **values)
{
NodeShaderTexPointDensity *shader_point_density = self->storage;
PointDensity pd;
@ -3051,6 +3055,7 @@ void rna_ShaderNodePointDensity_density_calc(bNode *self, Scene *scene, int *len
/* Single-threaded sampling of the voxel domain. */
RE_sample_point_density(scene, &pd,
shader_point_density->resolution,
settings == 1,
*values);
/* We're done, time to clean up. */
@ -3934,6 +3939,13 @@ static void def_sh_tex_pointdensity(StructRNA *srna)
{0, NULL, 0, NULL, NULL}
};
/* TODO(sergey): Use some mnemonic names for the hardcoded values here. */
static EnumPropertyItem calc_mode_items[] = {
{0, "VIEWPORT", 0, "Viewport", "Canculate density using viewport settings"},
{1, "RENDER", 0, "Render", "Canculate duplis using render settings"},
{0, NULL, 0, NULL, NULL}
};
prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "id");
RNA_def_property_struct_type(prop, "Object");
@ -3986,6 +3998,7 @@ static void def_sh_tex_pointdensity(StructRNA *srna)
func = RNA_def_function(srna, "calc_point_density", "rna_ShaderNodePointDensity_density_calc");
RNA_def_function_ui_description(func, "Calculate point density");
RNA_def_pointer(func, "scene", "Scene", "", "");
RNA_def_enum(func, "settings", calc_mode_items, 1, "", "Calculate density for rendering");
/* TODO, See how array size of 0 works, this shouldnt be used. */
prop = RNA_def_float_array(func, "rgba_values", 1, NULL, 0, 0, "", "RGBA Values", 0, 0);
RNA_def_property_flag(prop, PROP_DYNAMIC);

View File

@ -63,7 +63,11 @@ void RE_sample_material_color(
struct PointDensity;
void RE_sample_point_density(struct Scene *scene, struct PointDensity *pd, int resolution, float *values);
void RE_sample_point_density(struct Scene *scene,
struct PointDensity *pd,
const int resolution,
const bool use_render_params,
float *values);
void RE_init_texture_rng(void);
void RE_exit_texture_rng(void);

View File

@ -121,7 +121,8 @@ static void pointdensity_cache_psys(Scene *scene,
ParticleSystem *psys,
float viewmat[4][4],
float winmat[4][4],
int winx, int winy)
int winx, int winy,
const bool use_render_params)
{
DerivedMesh *dm;
ParticleKey state;
@ -140,9 +141,20 @@ static void pointdensity_cache_psys(Scene *scene,
}
/* Just to create a valid rendering context for particles */
psys_render_set(ob, psys, viewmat, winmat, winx, winy, 0);
if (use_render_params) {
psys_render_set(ob, psys, viewmat, winmat, winx, winy, 0);
}
dm = mesh_create_derived_render(scene, ob, CD_MASK_BAREMESH | CD_MASK_MTFACE | CD_MASK_MCOL);
if (use_render_params) {
dm = mesh_create_derived_render(scene,
ob,
CD_MASK_BAREMESH | CD_MASK_MTFACE | CD_MASK_MCOL);
}
else {
dm = mesh_get_derived_final(scene,
ob,
CD_MASK_BAREMESH | CD_MASK_MTFACE | CD_MASK_MCOL);
}
if ( !psys_check_enabled(ob, psys)) {
psys_render_restore(ob, psys);
@ -240,17 +252,32 @@ static void pointdensity_cache_psys(Scene *scene,
psys->lattice_deform_data = NULL;
}
psys_render_restore(ob, psys);
if (use_render_params) {
psys_render_restore(ob, psys);
}
}
static void pointdensity_cache_object(Scene *scene, PointDensity *pd, Object *ob)
static void pointdensity_cache_object(Scene *scene,
PointDensity *pd,
Object *ob,
const bool use_render_params)
{
int i;
DerivedMesh *dm;
MVert *mvert = NULL;
dm = mesh_create_derived_render(scene, ob, CD_MASK_BAREMESH | CD_MASK_MTFACE | CD_MASK_MCOL);
if (use_render_params) {
dm = mesh_create_derived_render(scene,
ob,
CD_MASK_BAREMESH | CD_MASK_MTFACE | CD_MASK_MCOL);
}
else {
dm = mesh_get_derived_final(scene,
ob,
CD_MASK_BAREMESH | CD_MASK_MTFACE | CD_MASK_MCOL);
}
mvert = dm->getVertArray(dm); /* local object space */
pd->totpoints = dm->getNumVerts(dm);
@ -290,7 +317,8 @@ static void cache_pointdensity_ex(Scene *scene,
PointDensity *pd,
float viewmat[4][4],
float winmat[4][4],
int winx, int winy)
int winx, int winy,
const bool use_render_params)
{
if (pd == NULL) {
return;
@ -314,18 +342,28 @@ static void cache_pointdensity_ex(Scene *scene,
return;
}
pointdensity_cache_psys(scene, pd, ob, psys, viewmat, winmat, winx, winy);
pointdensity_cache_psys(scene,
pd,
ob,
psys,
viewmat, winmat,
winx, winy,
use_render_params);
}
else if (pd->source == TEX_PD_OBJECT) {
Object *ob = pd->object;
if (ob && ob->type == OB_MESH)
pointdensity_cache_object(scene, pd, ob);
pointdensity_cache_object(scene, pd, ob, use_render_params);
}
}
void cache_pointdensity(Render *re, PointDensity *pd)
{
cache_pointdensity_ex(re->scene, pd, re->viewmat, re->winmat, re->winx, re->winy);
cache_pointdensity_ex(re->scene,
pd,
re->viewmat, re->winmat,
re->winx, re->winy,
true);
}
void free_pointdensity(PointDensity *pd)
@ -621,6 +659,7 @@ static void particle_system_minmax(Scene *scene,
Object *object,
ParticleSystem *psys,
float radius,
const bool use_render_params,
float min[3], float max[3])
{
const float size[3] = {radius, radius, radius};
@ -639,7 +678,9 @@ static void particle_system_minmax(Scene *scene,
}
unit_m4(mat);
psys_render_set(object, psys, mat, mat, 1, 1, 0);
if (use_render_params) {
psys_render_set(object, psys, mat, mat, 1, 1, 0);
}
sim.scene = scene;
sim.ob = object;
@ -669,11 +710,16 @@ static void particle_system_minmax(Scene *scene,
psys->lattice_deform_data = NULL;
}
psys_render_restore(object, psys);
if (use_render_params) {
psys_render_restore(object, psys);
}
}
void RE_sample_point_density(Scene *scene, PointDensity *pd,
int resolution, float *values)
void RE_sample_point_density(Scene *scene,
PointDensity *pd,
const int resolution,
const bool use_render_params,
float *values)
{
const size_t resolution2 = resolution * resolution;
Object *object = pd->object;
@ -696,7 +742,12 @@ void RE_sample_point_density(Scene *scene, PointDensity *pd,
sample_dummy_point_density(resolution, values);
return;
}
particle_system_minmax(scene, object, psys, pd->radius, min, max);
particle_system_minmax(scene,
object,
psys,
pd->radius,
use_render_params,
min, max);
}
else {
float radius[3] = {pd->radius, pd->radius, pd->radius};
@ -719,7 +770,7 @@ void RE_sample_point_density(Scene *scene, PointDensity *pd,
unit_m4(mat);
BLI_mutex_lock(&sample_mutex);
cache_pointdensity_ex(scene, pd, mat, mat, 1, 1);
cache_pointdensity_ex(scene, pd, mat, mat, 1, 1, use_render_params);
for (z = 0; z < resolution; ++z) {
for (y = 0; y < resolution; ++y) {
for (x = 0; x < resolution; ++x) {