diff options
19 files changed, 551 insertions, 19 deletions
diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt index fff9ed20bba..c6a2b919486 100644 --- a/intern/cycles/blender/CMakeLists.txt +++ b/intern/cycles/blender/CMakeLists.txt @@ -31,10 +31,12 @@ set(SRC blender_session.cpp blender_shader.cpp blender_sync.cpp + blender_texture.cpp CCL_api.h blender_sync.h blender_session.h + blender_texture.h blender_util.h ) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 8bb086df06a..fdb2afdb5e9 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -1236,7 +1236,8 @@ class CyclesTexture_PT_mapping(CyclesButtonsPanel, Panel): @classmethod def poll(cls, context): node = context.texture_node - return node and CyclesButtonsPanel.poll(context) + # TODO(sergey): perform a faster/nicer check? + return node and hasattr(node, 'texture_mapping') and CyclesButtonsPanel.poll(context) def draw(self, context): layout = self.layout diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 7342ed3b4f1..e1d5e1310d5 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -1016,6 +1016,18 @@ void BlenderSession::builtin_image_info(const string &builtin_name, void *builti is_float = true; } + else { + /* TODO(sergey): Check we're indeed in shader node tree. */ + PointerRNA ptr; + RNA_pointer_create(NULL, &RNA_Node, builtin_data, &ptr); + BL::Node b_node(ptr); + if(b_node.is_a(&RNA_ShaderNodeTexPointDensity)) { + BL::ShaderNodeTexPointDensity b_point_density_node(b_node); + channels = 4; + width = height = depth = b_point_density_node.resolution(); + is_float = true; + } + } } bool BlenderSession::builtin_image_pixels(const string &builtin_name, void *builtin_data, unsigned char *pixels) @@ -1158,6 +1170,17 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void fprintf(stderr, "Cycles error: unexpected smoke volume resolution, skipping\n"); } + else { + /* TODO(sergey): Check we're indeed in shader node tree. */ + PointerRNA ptr; + RNA_pointer_create(NULL, &RNA_Node, builtin_data, &ptr); + BL::Node b_node(ptr); + 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); + } + } return false; } diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 2b0e8acae38..6c54149164d 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -22,6 +22,7 @@ #include "scene.h" #include "shader.h" +#include "blender_texture.h" #include "blender_sync.h" #include "blender_util.h" @@ -736,6 +737,34 @@ static ShaderNode *add_node(Scene *scene, uvm->from_dupli = b_uvmap_node.from_dupli(); node = uvm; } + else if(b_node.is_a(&RNA_ShaderNodeTexPointDensity)) { + BL::ShaderNodeTexPointDensity b_point_density_node(b_node); + PointDensityTextureNode *point_density = new PointDensityTextureNode(); + point_density->filename = b_point_density_node.name(); + point_density->space = + PointDensityTextureNode::space_enum[(int)b_point_density_node.space()]; + point_density->interpolation = + (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())); + } + + /* TODO(sergey): Use more proper update flag. */ + if(true) { + scene->image_manager->tag_reload_image(point_density->filename, + point_density->builtin_data, + point_density->interpolation); + } + node = point_density; + } if(node) graph->add(node); diff --git a/intern/cycles/blender/blender_texture.cpp b/intern/cycles/blender/blender_texture.cpp new file mode 100644 index 00000000000..cb4dd1792d0 --- /dev/null +++ b/intern/cycles/blender/blender_texture.cpp @@ -0,0 +1,116 @@ +/* + * Copyright 2011-2015 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "blender_texture.h" + +CCL_NAMESPACE_BEGIN + +namespace { + +/* Point density helpers. */ + +static 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; + if(size.z != 0.0f) size.z = 0.5f/size.z; + + 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]; + 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, + 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) { + 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); + } +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/blender/blender_texture.h b/intern/cycles/blender/blender_texture.h new file mode 100644 index 00000000000..74fbca02a9e --- /dev/null +++ b/intern/cycles/blender/blender_texture.h @@ -0,0 +1,31 @@ +/* + * Copyright 2011-2015 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BLENDER_TEXTURE_H__ +#define __BLENDER_TEXTURE_H__ + +#include <stdlib.h> +#include "blender_sync.h" + +CCL_NAMESPACE_BEGIN + +void point_density_texture_space(BL::ShaderNodeTexPointDensity b_point_density_node, + float3& loc, + float3& size); + +CCL_NAMESPACE_END + +#endif /* __BLENDER_TEXTURE_H__ */ diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index cada125c6c2..c3def14787d 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -237,6 +237,7 @@ shader_node_categories = [ NodeItem("ShaderNodeTexMagic"), NodeItem("ShaderNodeTexChecker"), NodeItem("ShaderNodeTexBrick"), + NodeItem("ShaderNodeTexPointDensity"), ]), ShaderNewNodeCategory("SH_NEW_OP_COLOR", "Color", items=[ NodeItem("ShaderNodeMixRGB"), diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 4deaf26e2f5..0a6c21c2c60 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -782,6 +782,7 @@ struct ShadeResult; #define SH_NODE_COMBXYZ 189 #define SH_NODE_OUTPUT_LINESTYLE 190 #define SH_NODE_UVALONGSTROKE 191 +#define SH_NODE_TEX_POINTDENSITY 192 /* custom defines options for Material node */ #define SH_NODE_MAT_DIFF 1 diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h index 4e5214bc364..95918b9ca0b 100644 --- a/source/blender/blenkernel/BKE_texture.h +++ b/source/blender/blenkernel/BKE_texture.h @@ -115,6 +115,7 @@ void BKE_texture_envmap_free(struct EnvMap *env); struct EnvMap *BKE_texture_envmap_add(void); struct EnvMap *BKE_texture_envmap_copy(struct EnvMap *env); +void BKE_texture_pointdensity_init_data(struct PointDensity *pd); void BKE_texture_pointdensity_free_data(struct PointDensity *pd); void BKE_texture_pointdensity_free(struct PointDensity *pd); struct PointDensity *BKE_texture_pointdensity_add(void); diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 8ac0a8a31f6..8ea0a9df5f2 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -3591,6 +3591,7 @@ static void registerShaderNodes(void) register_node_type_sh_tex_magic(); register_node_type_sh_tex_checker(); register_node_type_sh_tex_brick(); + register_node_type_sh_tex_pointdensity(); } static void registerTextureNodes(void) diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 2ea903247b2..88a412d5e95 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -1470,11 +1470,8 @@ void BKE_texture_envmap_free(EnvMap *env) /* ------------------------------------------------------------------------- */ -PointDensity *BKE_texture_pointdensity_add(void) +void BKE_texture_pointdensity_init_data(PointDensity *pd) { - PointDensity *pd; - - pd = MEM_callocN(sizeof(PointDensity), "pointdensity"); pd->flag = 0; pd->radius = 0.3f; pd->falloff_type = TEX_PD_FALLOFF_STD; @@ -1498,7 +1495,12 @@ PointDensity *BKE_texture_pointdensity_add(void) pd->falloff_curve->cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE; curvemap_reset(pd->falloff_curve->cm, &pd->falloff_curve->clipr, pd->falloff_curve->preset, CURVEMAP_SLOPE_POSITIVE); curvemapping_changed(pd->falloff_curve, false); +} +PointDensity *BKE_texture_pointdensity_add(void) +{ + PointDensity *pd = MEM_callocN(sizeof(PointDensity), "pointdensity"); + BKE_texture_pointdensity_init_data(pd); return pd; } diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 7f35884cb65..fe0e959e976 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -937,6 +937,29 @@ static void node_shader_buts_tex_voronoi(uiLayout *layout, bContext *UNUSED(C), uiItemR(layout, ptr, "coloring", 0, "", ICON_NONE); } +static void node_shader_buts_tex_pointdensity(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + bNode *node = ptr->data; + NodeShaderTexPointDensity *shader_point_density = node->storage; + + uiItemR(layout, ptr, "point_source", UI_ITEM_R_EXPAND, NULL, ICON_NONE); + uiItemR(layout, ptr, "object", 0, NULL, ICON_NONE); + + if (node->id && shader_point_density->point_source == SHD_POINTDENSITY_SOURCE_PSYS) { + PointerRNA dataptr; + RNA_id_pointer_create((ID *)node->id, &dataptr); + uiItemPointerR(layout, ptr, "particle_system", &dataptr, "particle_systems", NULL, ICON_NONE); + } + + uiItemR(layout, ptr, "space", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "radius", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "interpolation", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "resolution", 0, NULL, ICON_NONE); + if (shader_point_density->point_source == SHD_POINTDENSITY_SOURCE_PSYS) { + uiItemR(layout, ptr, "color_source", 0, NULL, ICON_NONE); + } +} + static void node_shader_buts_tex_coord(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiItemR(layout, ptr, "object", 0, NULL, 0); @@ -1170,6 +1193,9 @@ static void node_shader_set_butfunc(bNodeType *ntype) case SH_NODE_TEX_VORONOI: ntype->draw_buttons = node_shader_buts_tex_voronoi; break; + case SH_NODE_TEX_POINTDENSITY: + ntype->draw_buttons = node_shader_buts_tex_pointdensity; + break; case SH_NODE_TEX_COORD: ntype->draw_buttons = node_shader_buts_tex_coord; break; diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index f17bf5af434..727c7b2117a 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -790,6 +790,17 @@ typedef struct NodeShaderVectTransform { int pad; } NodeShaderVectTransform; +typedef struct NodeShaderTexPointDensity { + short point_source, pad; + int particle_system; + float radius; + int resolution; + short space; + short interpolation; + short color_source; + short pad2; +} NodeShaderTexPointDensity; + /* TEX_output */ typedef struct TexNodeOutput { char name[64]; @@ -1090,4 +1101,22 @@ enum { #define CMP_NODE_PLANETRACKDEFORM_MBLUR_SAMPLES_MAX 64 +/* Point Density shader node */ + +enum { + SHD_POINTDENSITY_SOURCE_PSYS = 0, + SHD_POINTDENSITY_SOURCE_OBJECT = 1, +}; + +enum { + SHD_POINTDENSITY_SPACE_OBJECT = 0, + SHD_POINTDENSITY_SPACE_WORLD = 1, +}; + +enum { + SHD_POINTDENSITY_COLOR_PARTAGE = 1, + SHD_POINTDENSITY_COLOR_PARTSPEED = 2, + SHD_POINTDENSITY_COLOR_PARTVEL = 3, +}; + #endif diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 4df954b062b..068fb029182 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -38,6 +38,8 @@ #include "DNA_mesh_types.h" #include "DNA_node_types.h" #include "DNA_object_types.h" +#include "DNA_particle_types.h" +#include "DNA_scene_types.h" #include "DNA_text_types.h" #include "DNA_texture_types.h" @@ -61,6 +63,8 @@ #include "MEM_guardedalloc.h" +#include "RE_render_ext.h" + EnumPropertyItem node_socket_in_out_items[] = { { SOCK_IN, "IN", 0, "Input", "" }, { SOCK_OUT, "OUT", 0, "Output", "" }, @@ -2966,6 +2970,89 @@ static void rna_CompositorNodeScale_update(Main *bmain, Scene *scene, PointerRNA rna_Node_update(bmain, scene, ptr); } +static PointerRNA rna_ShaderNodePointDensity_psys_get(PointerRNA *ptr) +{ + bNode *node = ptr->data; + NodeShaderTexPointDensity *shader_point_density = node->storage; + Object *ob = (Object*)node->id; + ParticleSystem *psys = NULL; + PointerRNA value; + + if (ob && shader_point_density->particle_system) { + psys = BLI_findlink(&ob->particlesystem, shader_point_density->particle_system - 1); + } + + RNA_pointer_create(&ob->id, &RNA_ParticleSystem, psys, &value); + return value; +} + +static void rna_ShaderNodePointDensity_psys_set(PointerRNA *ptr, PointerRNA value) +{ + bNode *node = ptr->data; + NodeShaderTexPointDensity *shader_point_density = node->storage; + Object *ob = (Object*)node->id; + + if (ob && value.id.data == ob) { + shader_point_density->particle_system = BLI_findindex(&ob->particlesystem, value.data) + 1; + } + else { + shader_point_density->particle_system = 0; + } +} + +static int point_density_color_source_from_shader(NodeShaderTexPointDensity *shader_point_density) +{ + switch (shader_point_density->color_source) { + case SHD_POINTDENSITY_COLOR_PARTAGE: return TEX_PD_COLOR_PARTAGE; + case SHD_POINTDENSITY_COLOR_PARTSPEED: return TEX_PD_COLOR_PARTSPEED; + case SHD_POINTDENSITY_COLOR_PARTVEL: return TEX_PD_COLOR_PARTVEL; + default: + BLI_assert(!"Unknown color source"); + return TEX_PD_COLOR_CONSTANT; + } +} + +/* TODO(sergey): This functio nassumes 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) +{ + NodeShaderTexPointDensity *shader_point_density = self->storage; + PointDensity pd; + + *length = 4 * shader_point_density->resolution * + shader_point_density->resolution * + shader_point_density->resolution; + + if (*values == NULL) { + *values = MEM_mallocN(sizeof(float) * (*length), "point density dynamic array"); + } + + /* Create PointDensity structure from node for sampling. */ + BKE_texture_pointdensity_init_data(&pd); + pd.object = (Object *)self->id; + pd.radius = shader_point_density->radius; + if (shader_point_density->point_source == SHD_POINTDENSITY_SOURCE_PSYS) { + pd.source = TEX_PD_PSYS; + pd.psys = shader_point_density->particle_system; + pd.psys_cache_space = TEX_PD_OBJECTSPACE; + } + else { + BLI_assert(shader_point_density->point_source == SHD_POINTDENSITY_SOURCE_OBJECT); + pd.source = TEX_PD_OBJECT; + pd.ob_cache_space = TEX_PD_OBJECTSPACE; + } + pd.color_source = point_density_color_source_from_shader(shader_point_density); + + /* Single-threaded sampling of the voxel domain. */ + RE_sample_point_density(scene, &pd, + shader_point_density->resolution, + *values); + + /* We're done, time to clean up. */ + BKE_texture_pointdensity_free_data(&pd); +} + #else static EnumPropertyItem prop_image_layer_items[] = { @@ -3792,6 +3879,103 @@ static void def_sh_tex_wireframe(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } +static void def_sh_tex_pointdensity(StructRNA *srna) +{ + PropertyRNA *prop; + FunctionRNA *func; + + static EnumPropertyItem point_source_items[] = { + {SHD_POINTDENSITY_SOURCE_PSYS, "PARTICLE_SYSTEM", 0, "Particle System", + "Generate point density from a particle system"}, + {SHD_POINTDENSITY_SOURCE_OBJECT, "OBJECT", 0, "Object Vertices", + "Generate point density from an object's vertices"}, + {0, NULL, 0, NULL, NULL} + }; + + static const EnumPropertyItem prop_interpolation_items[] = { + {SHD_INTERP_CLOSEST, "Closest", 0, "Closest", + "No interpolation (sample closest texel)"}, + {SHD_INTERP_LINEAR, "Linear", 0, "Linear", + "Linear interpolation"}, + {SHD_INTERP_CUBIC, "Cubic", 0, "Cubic", + "Cubic interpolation (CPU only)"}, + {0, NULL, 0, NULL, NULL} + }; + + static EnumPropertyItem space_items[] = { + {SHD_POINTDENSITY_SPACE_OBJECT, "OBJECT", 0, "Object Space", ""}, + {SHD_POINTDENSITY_SPACE_WORLD, "WORLD", 0, "World Space", ""}, + {0, NULL, 0, NULL, NULL} + }; + + static EnumPropertyItem color_source_items[] = { + {SHD_POINTDENSITY_COLOR_PARTAGE, "PARTICLE_AGE", 0, "Particle Age", + "Lifetime mapped as 0.0 - 1.0 intensity"}, + {SHD_POINTDENSITY_COLOR_PARTSPEED, "PARTICLE_SPEED", 0, "Particle Speed", + "Particle speed (absolute magnitude of velocity) mapped as 0.0-1.0 intensity"}, + {SHD_POINTDENSITY_COLOR_PARTVEL, "PARTICLE_VELOCITY", 0, "Particle Velocity", + "XYZ velocity mapped to RGB colors"}, + {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"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Object", "Object to take point data from)"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + + RNA_def_struct_sdna_from(srna, "NodeShaderTexPointDensity", "storage"); + + prop = RNA_def_property(srna, "point_source", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, point_source_items); + RNA_def_property_ui_text(prop, "Point Source", "Point data to use as renderable point density"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "particle_system", PROP_POINTER, PROP_NONE); + RNA_def_property_ui_text(prop, "Particle System", "Particle System to render as points"); + RNA_def_property_struct_type(prop, "ParticleSystem"); + RNA_def_property_pointer_funcs(prop, "rna_ShaderNodePointDensity_psys_get", + "rna_ShaderNodePointDensity_psys_set", NULL, NULL); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "resolution", PROP_INT, PROP_NONE); + RNA_def_property_range(prop, 1, 32768); + RNA_def_property_ui_text(prop, "Resolution", "Resolution used by the texture holding the point density"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "radius", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "radius"); + RNA_def_property_range(prop, 0.001, FLT_MAX); + RNA_def_property_ui_text(prop, "Radius", "Radius from the shaded sample to look for points within"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "space", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, space_items); + RNA_def_property_ui_text(prop, "Space", "Coordinate system to calculate voxels in"); + RNA_def_property_update(prop, 0, "rna_Node_update"); + + prop = RNA_def_property(srna, "interpolation", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, prop_interpolation_items); + RNA_def_property_ui_text(prop, "Interpolation", "Texture interpolation"); + RNA_def_property_update(prop, 0, "rna_Node_update"); + + prop = RNA_def_property(srna, "color_source", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "color_source"); + RNA_def_property_enum_items(prop, color_source_items); + RNA_def_property_ui_text(prop, "Color Source", "Data to derive color results from"); + RNA_def_property_update(prop, 0, "rna_Node_update"); + + 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", "", ""); + /* 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); + RNA_def_function_output(func, prop); +} + static void def_glossy(StructRNA *srna) { PropertyRNA *prop; diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index c95daffe557..3fd1241f3fa 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -200,6 +200,7 @@ set(SRC shader/nodes/node_shader_tex_magic.c shader/nodes/node_shader_tex_musgrave.c shader/nodes/node_shader_tex_noise.c + shader/nodes/node_shader_tex_pointdensity.c shader/nodes/node_shader_tex_sky.c shader/nodes/node_shader_tex_voronoi.c shader/nodes/node_shader_tex_wave.c diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h index 595a3b12bc6..4c0047f1d58 100644 --- a/source/blender/nodes/NOD_shader.h +++ b/source/blender/nodes/NOD_shader.h @@ -75,6 +75,7 @@ void register_node_type_sh_sepxyz(void); void register_node_type_sh_combxyz(void); void register_node_type_sh_hue_sat(void); void register_node_type_sh_tex_brick(void); +void register_node_type_sh_tex_pointdensity(void); void register_node_type_sh_attribute(void); void register_node_type_sh_geometry(void); diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index b33bec51c2c..9e1a0c926fa 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -116,6 +116,7 @@ DefNode( ShaderNode, SH_NODE_TEX_MUSGRAVE, def_sh_tex_musgrave, "TE DefNode( ShaderNode, SH_NODE_TEX_VORONOI, def_sh_tex_voronoi, "TEX_VORONOI", TexVoronoi, "Voronoi Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_CHECKER, def_sh_tex_checker, "TEX_CHECKER", TexChecker, "Checker Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_BRICK, def_sh_tex_brick, "TEX_BRICK", TexBrick, "Brick Texture", "" ) +DefNode( ShaderNode, SH_NODE_TEX_POINTDENSITY, def_sh_tex_pointdensity,"TEX_POINTDENSITY", TexPointDensity, "Point Density", "" ) DefNode( ShaderNode, SH_NODE_TEX_COORD, def_sh_tex_coord, "TEX_COORD", TexCoord, "Texture Coordinate","" ) DefNode( ShaderNode, SH_NODE_VECT_TRANSFORM, def_sh_vect_transform, "VECT_TRANSFORM", VectorTransform, "Vector Transform", "" ) DefNode( ShaderNode, SH_NODE_SEPHSV, 0, "SEPHSV", SeparateHSV, "Separate HSV", "" ) diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_pointdensity.c b/source/blender/nodes/shader/nodes/node_shader_tex_pointdensity.c new file mode 100644 index 00000000000..6205b0fa11f --- /dev/null +++ b/source/blender/nodes/shader/nodes/node_shader_tex_pointdensity.c @@ -0,0 +1,76 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2015 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Sergey Sharybin. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "../node_shader_util.h" + +/* **************** OUTPUT ******************** */ + +static bNodeSocketTemplate sh_node_tex_pointdensity_in[] = { + {SOCK_VECTOR, 1, N_("Vector"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, + {-1, 0, ""} +}; + +static bNodeSocketTemplate sh_node_tex_pointdensity_out[] = { + {SOCK_RGBA, 0, N_("Color"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + {SOCK_FLOAT, 0, N_("Density"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + {-1, 0, ""} +}; + +static void node_shader_init_tex_pointdensity(bNodeTree *UNUSED(ntree), + bNode *node) +{ + NodeShaderTexPointDensity *point_density = + MEM_callocN(sizeof(NodeShaderTexPointDensity), "new pd node"); + point_density->resolution = 100; + point_density->radius = 0.3f; + point_density->space = SHD_POINTDENSITY_SPACE_OBJECT; + point_density->color_source = SHD_POINTDENSITY_COLOR_PARTAGE; + node->storage = point_density; +} + +/* node type definition */ +void register_node_type_sh_tex_pointdensity(void) +{ + static bNodeType ntype; + + sh_node_type_base(&ntype, + SH_NODE_TEX_POINTDENSITY, + "Point Density", + NODE_CLASS_TEXTURE, + 0); + node_type_compatibility(&ntype, NODE_NEW_SHADING); + node_type_socket_templates(&ntype, + sh_node_tex_pointdensity_in, + sh_node_tex_pointdensity_out); + node_type_init(&ntype, node_shader_init_tex_pointdensity); + node_type_storage(&ntype, + "NodeShaderTexPointDensity", + node_free_standard_storage, + node_copy_standard_storage); + + nodeRegisterType(&ntype); +} diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index a99cc3c72a2..d2ec5d80c91 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -152,6 +152,7 @@ static void pointdensity_cache_psys(Scene *scene, sim.scene = scene; sim.ob = ob; sim.psys = psys; + sim.psmd = psys_get_modifier(ob, psys); /* in case ob->imat isn't up-to-date */ invert_m4_m4(ob->imat, ob->obmat); @@ -530,6 +531,7 @@ static int pointdensity(PointDensity *pd, mul_v3_fl(vec, 1.0f / num); } + texres->tin = density; if (r_age != NULL) { *r_age = age; } @@ -537,24 +539,14 @@ static int pointdensity(PointDensity *pd, copy_v3_v3(r_vec, vec); } - texres->tin = density; - return retval; } -int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres) +static int pointdensity_color(PointDensity *pd, TexResult *texres, float age, const float vec[3]) { - PointDensity *pd = tex->pd; - float age = 0.0f; - float vec[3] = {0.0f, 0.0f, 0.0f}; - int retval = pointdensity(pd, texvec, texres, &age, vec); + int retval = 0; float col[4]; - BRICONT; - - if (pd->color_source == TEX_PD_COLOR_CONSTANT) - return retval; - retval |= TEX_RGB; switch (pd->color_source) { @@ -584,8 +576,7 @@ int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres) } case TEX_PD_COLOR_PARTVEL: texres->talpha = true; - mul_v3_fl(vec, pd->speed_scale); - copy_v3_v3(&texres->tr, vec); + mul_v3_v3fl(&texres->tr, vec, pd->speed_scale); texres->ta = texres->tin; break; case TEX_PD_COLOR_CONSTANT: @@ -593,6 +584,20 @@ int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres) texres->tr = texres->tg = texres->tb = texres->ta = 1.0f; break; } + + return retval; +} + +int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres) +{ + PointDensity *pd = tex->pd; + float age = 0.0f; + float vec[3] = {0.0f, 0.0f, 0.0f}; + int retval = pointdensity(pd, texvec, texres, &age, vec); + + BRICONT; + + retval |= pointdensity_color(pd, texres, age, vec); BRICONTRGB; return retval; @@ -698,6 +703,7 @@ void RE_sample_point_density(Scene *scene, PointDensity *pd, texvec[2] += dim[2] * (float)z / (float)resolution; pointdensity(pd, texvec, &texres, &age, vec); + pointdensity_color(pd, &texres, age, vec); copy_v3_v3(&values[index*4 + 0], &texres.tr); values[index*4 + 3] = texres.tin; |