diff options
-rw-r--r-- | intern/cycles/blender/blender_shader.cpp | 30 | ||||
-rw-r--r-- | intern/cycles/blender/blender_texture.cpp | 89 | ||||
-rw-r--r-- | intern/cycles/blender/blender_texture.h | 4 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_nodetree.c | 29 | ||||
-rw-r--r-- | source/blender/render/extern/include/RE_render_ext.h | 6 | ||||
-rw-r--r-- | source/blender/render/intern/source/pointdensity.c | 69 |
6 files changed, 117 insertions, 110 deletions
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index abf1fc25f7b..a06a6093c1c 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -803,19 +803,11 @@ static ShaderNode *add_node(Scene *scene, (InterpolationType)b_point_density_node.interpolation(); point_density->builtin_data = b_point_density_node.ptr.data; - /* Transformation form world space to texture space. */ - BL::Object b_ob(b_point_density_node.object()); - if(b_ob) { - float3 loc, size; - point_density_texture_space(b_point_density_node, loc, size); - point_density->tfm = - transform_translate(-loc) * transform_scale(size) * - transform_inverse(get_transform(b_ob.matrix_world())); - } + /* 1 - render settings, 0 - vewport settings. */ + int settings = background ? 1 : 0; /* TODO(sergey): Use more proper update flag. */ if(true) { - int settings = background ? 1 : 0; /* 1 - render settings, 0 - vewport settings. */ b_point_density_node.cache_point_density(b_scene, settings); scene->image_manager->tag_reload_image( point_density->filename, @@ -824,6 +816,24 @@ static ShaderNode *add_node(Scene *scene, EXTENSION_CLIP); } node = point_density; + + /* Transformation form world space to texture space. + * + * NOTE: Do this after the texture is cached, this is because getting + * min/max will need to access this cache. + */ + BL::Object b_ob(b_point_density_node.object()); + if(b_ob) { + float3 loc, size; + point_density_texture_space(b_scene, + b_point_density_node, + settings, + loc, + size); + point_density->tfm = + transform_translate(-loc) * transform_scale(size) * + transform_inverse(get_transform(b_ob.matrix_world())); + } } if(node) diff --git a/intern/cycles/blender/blender_texture.cpp b/intern/cycles/blender/blender_texture.cpp index 18f66560b10..55fc5352e3f 100644 --- a/intern/cycles/blender/blender_texture.cpp +++ b/intern/cycles/blender/blender_texture.cpp @@ -22,8 +22,8 @@ namespace { /* Point density helpers. */ -static void density_texture_space_invert(float3& loc, - float3& size) +void density_texture_space_invert(float3& loc, + float3& size) { if(size.x != 0.0f) size.x = 0.5f/size.x; if(size.y != 0.0f) size.y = 0.5f/size.y; @@ -32,87 +32,28 @@ static void density_texture_space_invert(float3& loc, loc = loc*size - make_float3(0.5f, 0.5f, 0.5f); } -static void density_object_texture_space(BL::Object b_ob, - float radius, - float3& loc, - float3& size) -{ - if(b_ob.type() == BL::Object::type_MESH) { - BL::Mesh b_mesh(b_ob.data()); - loc = get_float3(b_mesh.texspace_location()); - size = get_float3(b_mesh.texspace_size()); - } - else { - /* TODO(sergey): Not supported currently. */ - } - /* Adjust texture space to include density points on the boundaries. */ - size = size + make_float3(radius, radius, radius); - density_texture_space_invert(loc, size); -} - -static void density_particle_system_texture_space( - BL::Object b_ob, - BL::ParticleSystem b_particle_system, - float radius, - float3& loc, - float3& size) -{ - if(b_particle_system.settings().type() == BL::ParticleSettings::type_HAIR) { - /* TODO(sergey): Not supported currently. */ - return; - } - Transform tfm = get_transform(b_ob.matrix_world()); - Transform itfm = transform_inverse(tfm); - float3 min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX), - max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX); - float3 particle_size = make_float3(radius, radius, radius); - for(int i = 0; i < b_particle_system.particles.length(); ++i) { - BL::Particle particle = b_particle_system.particles[i]; - if(particle.alive_state() == BL::Particle::alive_state_ALIVE) { - float3 location = get_float3(particle.location()); - location = transform_point(&itfm, location); - min = ccl::min(min, location - particle_size); - max = ccl::max(max, location + particle_size); - } - } - /* Calculate texture space from the particle bounds. */ - loc = (min + max) * 0.5f; - size = (max - min) * 0.5f; - density_texture_space_invert(loc, size); -} - } /* namespace */ -void point_density_texture_space(BL::ShaderNodeTexPointDensity b_point_density_node, +void point_density_texture_space(BL::Scene b_scene, + BL::ShaderNodeTexPointDensity b_point_density_node, + int settings, float3& loc, float3& size) { - /* Fallback values. */ - loc = make_float3(0.0f, 0.0f, 0.0f); - size = make_float3(0.0f, 0.0f, 0.0f); BL::Object b_ob(b_point_density_node.object()); if(!b_ob) { + loc = make_float3(0.0f, 0.0f, 0.0f); + size = make_float3(0.0f, 0.0f, 0.0f); return; } - if(b_point_density_node.point_source() == - BL::ShaderNodeTexPointDensity::point_source_PARTICLE_SYSTEM) - { - BL::ParticleSystem b_particle_system( - b_point_density_node.particle_system()); - if(b_particle_system) { - density_particle_system_texture_space(b_ob, - b_particle_system, - b_point_density_node.radius(), - loc, - size); - } - } - else { - density_object_texture_space(b_ob, - b_point_density_node.radius(), - loc, - size); - } + float3 min, max; + b_point_density_node.calc_point_density_minmax(b_scene, + settings, + &min[0], + &max[0]); + loc = (min + max) * 0.5f; + size = (max - min) * 0.5f; + density_texture_space_invert(loc, size); } CCL_NAMESPACE_END diff --git a/intern/cycles/blender/blender_texture.h b/intern/cycles/blender/blender_texture.h index 74fbca02a9e..017b78b67e3 100644 --- a/intern/cycles/blender/blender_texture.h +++ b/intern/cycles/blender/blender_texture.h @@ -22,7 +22,9 @@ CCL_NAMESPACE_BEGIN -void point_density_texture_space(BL::ShaderNodeTexPointDensity b_point_density_node, +void point_density_texture_space(BL::Scene b_scene, + BL::ShaderNodeTexPointDensity b_point_density_node, + const int settings, float3& loc, float3& size); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 798f3cb9af3..14014186e0f 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3100,6 +3100,22 @@ void rna_ShaderNodePointDensity_density_calc(bNode *self, BKE_texture_pointdensity_free_data(pd); } +void rna_ShaderNodePointDensity_density_minmax(bNode *self, + Scene *scene, + int settings, + float r_min[3], + float r_max[3]) +{ + NodeShaderTexPointDensity *shader_point_density = self->storage; + PointDensity *pd = &shader_point_density->pd; + if (scene == NULL) { + zero_v3(r_min); + zero_v3(r_max); + return; + } + RE_minmac_point_density(scene, pd, settings == 1, r_min, r_max); +} + #else static EnumPropertyItem prop_image_layer_items[] = { @@ -4054,6 +4070,19 @@ static void def_sh_tex_pointdensity(StructRNA *srna) prop = RNA_def_float_array(func, "rgba_values", 1, NULL, 0, 0, "", "RGBA Values", 0, 0); RNA_def_property_flag(prop, PROP_DYNAMIC); RNA_def_function_output(func, prop); + + func = RNA_def_function(srna, "calc_point_density_minmax", "rna_ShaderNodePointDensity_density_minmax"); + 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"); + prop = RNA_def_property(func, "min", PROP_FLOAT, PROP_COORDS); + RNA_def_property_array(prop, 3); + RNA_def_property_flag(prop, PROP_THICK_WRAP); + RNA_def_function_output(func, prop); + prop = RNA_def_property(func, "max", PROP_FLOAT, PROP_COORDS); + RNA_def_property_array(prop, 3); + RNA_def_property_flag(prop, PROP_THICK_WRAP); + RNA_def_function_output(func, prop); } static void def_glossy(StructRNA *srna) diff --git a/source/blender/render/extern/include/RE_render_ext.h b/source/blender/render/extern/include/RE_render_ext.h index 81d1a00702d..d5af16d9b6e 100644 --- a/source/blender/render/extern/include/RE_render_ext.h +++ b/source/blender/render/extern/include/RE_render_ext.h @@ -67,6 +67,12 @@ void RE_cache_point_density(struct Scene *scene, struct PointDensity *pd, const bool use_render_params); +void RE_minmac_point_density(struct Scene *scene, + struct PointDensity *pd, + const bool use_render_params, + float r_min[3], + float r_max[3]); + void RE_sample_point_density(struct Scene *scene, struct PointDensity *pd, const int resolution, diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index b4dfbc4a59f..d98c47249ad 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -727,38 +727,28 @@ void RE_cache_point_density(Scene *scene, BLI_mutex_unlock(&sample_mutex); } -/* NOTE 1: Requires RE_cache_point_density() to be called first. - * NOTE 2: Frees point density structure after sampling. - */ -void RE_sample_point_density(Scene *scene, - PointDensity *pd, - const int resolution, +void RE_minmac_point_density(struct Scene *scene, + struct PointDensity *pd, const bool use_render_params, - float *values) + float r_min[3], + float r_max[3]) { - const size_t resolution2 = resolution * resolution; Object *object = pd->object; - size_t x, y, z; - float min[3], max[3], dim[3]; - - /* TODO(sergey): Implement some sort of assert() that point density - * was cached already. - */ - if (object == NULL) { - sample_dummy_point_density(resolution, values); - return; + zero_v3(r_min); + zero_v3(r_max); } - if (pd->source == TEX_PD_PSYS) { ParticleSystem *psys; if (pd->psys == 0) { - sample_dummy_point_density(resolution, values); + zero_v3(r_min); + zero_v3(r_max); return; } psys = BLI_findlink(&object->particlesystem, pd->psys - 1); if (psys == NULL) { - sample_dummy_point_density(resolution, values); + zero_v3(r_min); + zero_v3(r_max); return; } particle_system_minmax(scene, @@ -766,19 +756,48 @@ void RE_sample_point_density(Scene *scene, psys, pd->radius, use_render_params, - min, max); + r_min, r_max); } else { float radius[3] = {pd->radius, pd->radius, pd->radius}; float *loc, *size; BKE_object_obdata_texspace_get(pd->object, NULL, &loc, &size, NULL); - sub_v3_v3v3(min, loc, size); - add_v3_v3v3(max, loc, size); + sub_v3_v3v3(r_min, loc, size); + add_v3_v3v3(r_max, loc, size); /* Adjust texture space to include density points on the boundaries. */ - sub_v3_v3(min, radius); - add_v3_v3(max, radius); + sub_v3_v3(r_min, radius); + add_v3_v3(r_max, radius); + } +} + +/* NOTE 1: Requires RE_cache_point_density() to be called first. + * NOTE 2: Frees point density structure after sampling. + */ +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; + size_t x, y, z; + float min[3], max[3], dim[3]; + + /* TODO(sergey): Implement some sort of assert() that point density + * was cached already. + */ + + if (object == NULL) { + sample_dummy_point_density(resolution, values); + return; } + RE_minmac_point_density(scene, + pd, + use_render_params, + min, + max); sub_v3_v3v3(dim, max, min); if (dim[0] <= 0.0f || dim[1] <= 0.0f || dim[2] <= 0.0f) { sample_dummy_point_density(resolution, values); |