Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release/scripts/startup/bl_ui/properties_texture.py17
-rw-r--r--source/blender/editors/space_node/drawnode.c18
-rw-r--r--source/blender/makesdna/DNA_node_types.h9
-rw-r--r--source/blender/makesdna/DNA_texture_types.h29
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c56
-rw-r--r--source/blender/makesrna/intern/rna_texture.c24
-rw-r--r--source/blender/render/intern/source/pointdensity.c451
7 files changed, 457 insertions, 147 deletions
diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py
index 1f0107f2a0e..caf19a9e469 100644
--- a/release/scripts/startup/bl_ui/properties_texture.py
+++ b/release/scripts/startup/bl_ui/properties_texture.py
@@ -830,12 +830,21 @@ class TEXTURE_PT_pointdensity(TextureButtonsPanel, Panel):
col.separator()
+ col.label(text="Color Source:")
if pd.point_source == 'PARTICLE_SYSTEM':
- col.label(text="Color Source:")
- col.prop(pd, "color_source", text="")
- if pd.color_source in {'PARTICLE_SPEED', 'PARTICLE_VELOCITY'}:
+ col.prop(pd, "particle_color_source", text="")
+ if pd.particle_color_source in {'PARTICLE_SPEED', 'PARTICLE_VELOCITY'}:
col.prop(pd, "speed_scale")
- if pd.color_source in {'PARTICLE_SPEED', 'PARTICLE_AGE'}:
+ if pd.particle_color_source in {'PARTICLE_SPEED', 'PARTICLE_AGE'}:
+ layout.template_color_ramp(pd, "color_ramp", expand=True)
+ else:
+ col.prop(pd, "vertex_color_source", text="")
+ if pd.vertex_color_source == 'VERTEX_COLOR':
+ if pd.object and pd.object.data:
+ col.prop_search(pd, "vertex_attribute_name", pd.object.data, "vertex_colors", text="")
+ if pd.vertex_color_source == 'VERTEX_WEIGHT':
+ if pd.object:
+ col.prop_search(pd, "vertex_attribute_name", pd.object, "vertex_groups", text="")
layout.template_color_ramp(pd, "color_ramp", expand=True)
col = split.column()
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 1460a3a35c8..b2f3306fb62 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -961,6 +961,11 @@ static void node_shader_buts_tex_pointdensity(uiLayout *layout, bContext *UNUSED
{
bNode *node = ptr->data;
NodeShaderTexPointDensity *shader_point_density = node->storage;
+ Object *ob = (Object *)node->id;
+ PointerRNA ob_ptr, obdata_ptr;
+
+ RNA_id_pointer_create((ID *)ob, &ob_ptr);
+ RNA_id_pointer_create(ob ? (ID *)ob->data : NULL, &obdata_ptr);
uiItemR(layout, ptr, "point_source", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
uiItemR(layout, ptr, "object", 0, NULL, ICON_NONE);
@@ -976,7 +981,18 @@ static void node_shader_buts_tex_pointdensity(uiLayout *layout, bContext *UNUSED
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);
+ uiItemR(layout, ptr, "particle_color_source", 0, NULL, ICON_NONE);
+ }
+ else {
+ uiItemR(layout, ptr, "vertex_color_source", 0, NULL, ICON_NONE);
+ if (shader_point_density->ob_color_source == SHD_POINTDENSITY_COLOR_VERTWEIGHT) {
+ if (ob_ptr.data)
+ uiItemPointerR(layout, ptr, "vertex_attribute_name", &ob_ptr, "vertex_groups", "", ICON_NONE);
+ }
+ if (shader_point_density->ob_color_source == SHD_POINTDENSITY_COLOR_VERTCOL) {
+ if (obdata_ptr.data)
+ uiItemPointerR(layout, ptr, "vertex_attribute_name", &obdata_ptr, "vertex_colors", "", ICON_NONE);
+ }
}
}
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index cf5d2dfc815..c75a019a28e 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -807,7 +807,8 @@ typedef struct NodeShaderTexPointDensity {
short space;
short interpolation;
short color_source;
- short pad2;
+ short ob_color_source;
+ char vertex_attribute_name[64]; /* vertex attribute layer for color source, MAX_CUSTOMDATA_LAYER_NAME */
PointDensity pd;
} NodeShaderTexPointDensity;
@@ -1142,4 +1143,10 @@ enum {
SHD_POINTDENSITY_COLOR_PARTVEL = 3,
};
+enum {
+ SHD_POINTDENSITY_COLOR_VERTCOL = 0,
+ SHD_POINTDENSITY_COLOR_VERTWEIGHT = 1,
+ SHD_POINTDENSITY_COLOR_VERTNOR = 2,
+};
+
#endif
diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h
index 2843d010c9d..995d7645dc0 100644
--- a/source/blender/makesdna/DNA_texture_types.h
+++ b/source/blender/makesdna/DNA_texture_types.h
@@ -143,15 +143,18 @@ typedef struct PointDensity {
float falloff_softness;
float radius;
short source;
- short color_source;
- int totpoints;
+ short pad0;
+
+ short color_source; /* psys_color_source */
+ short ob_color_source;
- int pdpad;
+ int totpoints;
struct Object *object; /* for 'Object' or 'Particle system' type - source object */
int psys; /* index+1 in ob.particlesystem, non-ID pointer not allowed */
short psys_cache_space; /* cache points in worldspace, object space, ... ? */
short ob_cache_space; /* cache points in worldspace, object space, ... ? */
+ char vertex_attribute_name[64]; /* vertex attribute layer for color source, MAX_CUSTOMDATA_LAYER_NAME */
void *point_tree; /* the acceleration tree containing points */
float *point_data; /* dynamically allocated extra for extra information, like particle age */
@@ -160,10 +163,10 @@ typedef struct PointDensity {
short noise_depth;
short noise_influence;
short noise_basis;
- short pdpad3[3];
+ short pad1[3];
float noise_fac;
- float speed_scale, falloff_speed_scale, pdpad2;
+ float speed_scale, falloff_speed_scale, pad2;
struct ColorBand *coba; /* for time -> color */
struct CurveMapping *falloff_curve; /* falloff density curve */
@@ -594,13 +597,21 @@ enum {
#define TEX_PD_NOISE_TIME 3
/* color_source */
-#define TEX_PD_COLOR_CONSTANT 0
-#define TEX_PD_COLOR_PARTAGE 1
-#define TEX_PD_COLOR_PARTSPEED 2
-#define TEX_PD_COLOR_PARTVEL 3
+enum {
+ TEX_PD_COLOR_CONSTANT = 0,
+ /* color_source: particles */
+ TEX_PD_COLOR_PARTAGE = 1,
+ TEX_PD_COLOR_PARTSPEED = 2,
+ TEX_PD_COLOR_PARTVEL = 3,
+ /* color_source: vertices */
+ TEX_PD_COLOR_VERTCOL = 1,
+ TEX_PD_COLOR_VERTWEIGHT = 2,
+ TEX_PD_COLOR_VERTNOR = 3,
+};
#define POINT_DATA_VEL 1
#define POINT_DATA_LIFE 2
+#define POINT_DATA_COLOR 4
/******************** Voxel Data *****************************/
/* flag */
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index a701cf6182d..ccbabb2b238 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -3030,12 +3030,30 @@ static void rna_ShaderNodePointDensity_psys_set(PointerRNA *ptr, PointerRNA valu
}
}
-static int point_density_color_source_from_shader(NodeShaderTexPointDensity *shader_point_density)
+static int point_density_particle_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;
+ 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;
+ }
+}
+
+static int point_density_vertex_color_source_from_shader(NodeShaderTexPointDensity *shader_point_density)
+{
+ switch (shader_point_density->ob_color_source) {
+ case SHD_POINTDENSITY_COLOR_VERTCOL:
+ return TEX_PD_COLOR_VERTCOL;
+ case SHD_POINTDENSITY_COLOR_VERTWEIGHT:
+ return TEX_PD_COLOR_VERTWEIGHT;
+ case SHD_POINTDENSITY_COLOR_VERTNOR:
+ return TEX_PD_COLOR_VERTNOR;
default:
BLI_assert(!"Unknown color source");
return TEX_PD_COLOR_CONSTANT;
@@ -3064,13 +3082,17 @@ void rna_ShaderNodePointDensity_density_cache(bNode *self,
pd->source = TEX_PD_PSYS;
pd->psys = shader_point_density->particle_system;
pd->psys_cache_space = TEX_PD_OBJECTSPACE;
+ pd->color_source = point_density_particle_color_source_from_shader(shader_point_density);
}
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->ob_color_source = point_density_vertex_color_source_from_shader(shader_point_density);
+ BLI_strncpy(pd->vertex_attribute_name,
+ shader_point_density->vertex_attribute_name,
+ sizeof(pd->vertex_attribute_name));
}
- pd->color_source = point_density_color_source_from_shader(shader_point_density);
/* Single-threaded sampling of the voxel domain. */
RE_point_density_cache(scene,
@@ -4002,7 +4024,7 @@ static void def_sh_tex_pointdensity(StructRNA *srna)
{0, NULL, 0, NULL, NULL}
};
- static EnumPropertyItem color_source_items[] = {
+ static EnumPropertyItem particle_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",
@@ -4012,6 +4034,14 @@ static void def_sh_tex_pointdensity(StructRNA *srna)
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem vertex_color_source_items[] = {
+ {SHD_POINTDENSITY_COLOR_VERTCOL, "VERTEX_COLOR", 0, "Vertex Color", "Vertex color layer"},
+ {SHD_POINTDENSITY_COLOR_VERTWEIGHT, "VERTEX_WEIGHT", 0, "Vertex Weight", "Vertex group weight"},
+ {SHD_POINTDENSITY_COLOR_VERTNOR, "VERTEX_NORMAL", 0, "Vertex Normal",
+ "XYZ normal vector mapped to RGB colors"},
+ {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"},
@@ -4062,12 +4092,22 @@ static void def_sh_tex_pointdensity(StructRNA *srna)
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);
+ prop = RNA_def_property(srna, "particle_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_enum_items(prop, particle_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");
+ prop = RNA_def_property(srna, "vertex_color_source", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "ob_color_source");
+ RNA_def_property_enum_items(prop, vertex_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");
+
+ prop = RNA_def_property(srna, "vertex_attribute_name", PROP_STRING, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Vertex Attribute Name", "Vertex attribute to use for color");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
func = RNA_def_function(srna, "cache_point_density", "rna_ShaderNodePointDensity_density_cache");
RNA_def_function_ui_description(func, "Cache point density data for later calculation");
RNA_def_pointer(func, "scene", "Scene", "", "");
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index b44482dc2c1..ad1ca12d4ea 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -1668,7 +1668,7 @@ static void rna_def_texture_pointdensity(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
- static EnumPropertyItem color_source_items[] = {
+ static EnumPropertyItem particle_color_source_items[] = {
{TEX_PD_COLOR_CONSTANT, "CONSTANT", 0, "Constant", ""},
{TEX_PD_COLOR_PARTAGE, "PARTICLE_AGE", 0, "Particle Age", "Lifetime mapped as 0.0 - 1.0 intensity"},
{TEX_PD_COLOR_PARTSPEED, "PARTICLE_SPEED", 0, "Particle Speed",
@@ -1677,6 +1677,14 @@ static void rna_def_texture_pointdensity(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem vertex_color_source_items[] = {
+ {TEX_PD_COLOR_CONSTANT, "CONSTANT", 0, "Constant", ""},
+ {TEX_PD_COLOR_VERTCOL, "VERTEX_COLOR", 0, "Vertex Color", "Vertex color layer"},
+ {TEX_PD_COLOR_VERTWEIGHT, "VERTEX_WEIGHT", 0, "Vertex Weight", "Vertex group weight"},
+ {TEX_PD_COLOR_VERTNOR, "VERTEX_NORMAL", 0, "Vertex Normal", "XYZ normal vector mapped to RGB colors"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
static EnumPropertyItem turbulence_influence_items[] = {
{TEX_PD_NOISE_STATIC, "STATIC", 0, "Static",
"Noise patterns will remain unchanged, faster and suitable for stills"},
@@ -1742,12 +1750,22 @@ static void rna_def_texture_pointdensity(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Softness", "Softness of the 'soft' falloff option");
RNA_def_property_update(prop, 0, "rna_Texture_update");
- prop = RNA_def_property(srna, "color_source", PROP_ENUM, PROP_NONE);
+ prop = RNA_def_property(srna, "particle_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_enum_items(prop, particle_color_source_items);
RNA_def_property_ui_text(prop, "Color Source", "Data to derive color results from");
RNA_def_property_update(prop, 0, "rna_Texture_update");
+ prop = RNA_def_property(srna, "vertex_color_source", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "ob_color_source");
+ RNA_def_property_enum_items(prop, vertex_color_source_items);
+ RNA_def_property_ui_text(prop, "Color Source", "Data to derive color results from");
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
+
+ prop = RNA_def_property(srna, "vertex_attribute_name", PROP_STRING, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Vertex Attribute Name", "Vertex attribute to use for color");
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
+
prop = RNA_def_property(srna, "speed_scale", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "speed_scale");
RNA_def_property_range(prop, 0.001, 100.0);
diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c
index 91ae29afea3..59aaad661c9 100644
--- a/source/blender/render/intern/source/pointdensity.c
+++ b/source/blender/render/intern/source/pointdensity.c
@@ -43,6 +43,12 @@
#include "BLT_translation.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+#include "DNA_particle_types.h"
+#include "DNA_texture_types.h"
+
+#include "BKE_deform.h"
#include "BKE_DerivedMesh.h"
#include "BKE_lattice.h"
#include "BKE_main.h"
@@ -52,10 +58,6 @@
#include "BKE_texture.h"
#include "BKE_colortools.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_texture_types.h"
-#include "DNA_particle_types.h"
-
#include "render_types.h"
#include "texture.h"
#include "pointdensity.h"
@@ -89,29 +91,78 @@ static int point_data_used(PointDensity *pd)
pd_bitflag |= POINT_DATA_LIFE;
}
}
+ else if (pd->source == TEX_PD_OBJECT) {
+ if (ELEM(pd->ob_color_source, TEX_PD_COLOR_VERTCOL, TEX_PD_COLOR_VERTWEIGHT, TEX_PD_COLOR_VERTNOR)) {
+ pd_bitflag |= POINT_DATA_COLOR;
+ }
+ }
return pd_bitflag;
}
+static void point_data_pointers(PointDensity *pd,
+ float **r_data_velocity, float **r_data_life, float **r_data_color)
+{
+ const int data_used = point_data_used(pd);
+ const int totpoint = pd->totpoints;
+ float *data = pd->point_data;
+ int offset = 0;
+
+ if (data_used & POINT_DATA_VEL) {
+ if (r_data_velocity)
+ *r_data_velocity = data + offset;
+ offset += 3 * totpoint;
+ }
+ else {
+ if (r_data_velocity)
+ *r_data_velocity = NULL;
+ }
+
+ if (data_used & POINT_DATA_LIFE) {
+ if (r_data_life)
+ *r_data_life = data + offset;
+ offset += totpoint;
+ }
+ else {
+ if (r_data_life)
+ *r_data_life = NULL;
+ }
+
+ if (data_used & POINT_DATA_COLOR) {
+ if (r_data_color)
+ *r_data_color = data + offset;
+ offset += 3 * totpoint;
+ }
+ else {
+ if (r_data_color)
+ *r_data_color = NULL;
+ }
+}
/* additional data stored alongside the point density BVH,
* accessible by point index number to retrieve other information
* such as particle velocity or lifetime */
-static void alloc_point_data(PointDensity *pd, int total_particles, int point_data_used)
+static void alloc_point_data(PointDensity *pd)
{
+ const int totpoints = pd->totpoints;
+ int data_used = point_data_used(pd);
int data_size = 0;
- if (point_data_used & POINT_DATA_VEL) {
+ if (data_used & POINT_DATA_VEL) {
/* store 3 channels of velocity data */
data_size += 3;
}
- if (point_data_used & POINT_DATA_LIFE) {
+ if (data_used & POINT_DATA_LIFE) {
/* store 1 channel of lifetime data */
data_size += 1;
}
+ if (data_used & POINT_DATA_COLOR) {
+ /* store 3 channels of RGB data */
+ data_size += 3;
+ }
if (data_size) {
- pd->point_data = MEM_mallocN(sizeof(float) * data_size * total_particles,
+ pd->point_data = MEM_callocN(sizeof(float) * data_size * totpoints,
"particle point data");
}
}
@@ -132,8 +183,9 @@ static void pointdensity_cache_psys(Scene *scene,
ParticleData *pa = NULL;
float cfra = BKE_scene_frame_get(scene);
int i /*, childexists*/ /* UNUSED */;
- int total_particles, offset = 0;
- int data_used = point_data_used(pd);
+ int total_particles;
+ int data_used;
+ float *data_vel, *data_life;
float partco[3];
/* init everything */
@@ -141,6 +193,8 @@ static void pointdensity_cache_psys(Scene *scene,
return;
}
+ data_used = point_data_used(pd);
+
/* Just to create a valid rendering context for particles */
if (use_render_params) {
psys_render_set(ob, psys, viewmat, winmat, winx, winy, 0);
@@ -174,11 +228,9 @@ static void pointdensity_cache_psys(Scene *scene,
psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
pd->point_tree = BLI_bvhtree_new(total_particles, 0.0, 4, 6);
- alloc_point_data(pd, total_particles, data_used);
pd->totpoints = total_particles;
- if (data_used & POINT_DATA_VEL) {
- offset = pd->totpoints * 3;
- }
+ alloc_point_data(pd);
+ point_data_pointers(pd, &data_vel, &data_life, NULL);
#if 0 /* UNUSED */
if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
@@ -235,13 +287,13 @@ static void pointdensity_cache_psys(Scene *scene,
BLI_bvhtree_insert(pd->point_tree, i, partco, 1);
- if (data_used & POINT_DATA_VEL) {
- pd->point_data[i * 3 + 0] = state.vel[0];
- pd->point_data[i * 3 + 1] = state.vel[1];
- pd->point_data[i * 3 + 2] = state.vel[2];
+ if (data_vel) {
+ data_vel[i*3 + 0] = state.vel[0];
+ data_vel[i*3 + 1] = state.vel[1];
+ data_vel[i*3 + 2] = state.vel[2];
}
- if (data_used & POINT_DATA_LIFE) {
- pd->point_data[offset + i] = state.time;
+ if (data_life) {
+ data_life[i] = state.time;
}
}
@@ -259,39 +311,127 @@ static void pointdensity_cache_psys(Scene *scene,
}
+static void pointdensity_cache_vertex_color(PointDensity *pd, Object *UNUSED(ob), DerivedMesh *dm, float *data_color)
+{
+ const MLoop *mloop = dm->getLoopArray(dm);
+ const int totloop = dm->getNumLoops(dm);
+ const MLoopCol *mcol;
+ char layername[MAX_CUSTOMDATA_LAYER_NAME];
+ int i;
+
+ BLI_assert(data_color);
+
+ if (!CustomData_has_layer(&dm->loopData, CD_MLOOPCOL))
+ return;
+ CustomData_validate_layer_name(&dm->loopData, CD_MLOOPCOL, pd->vertex_attribute_name, layername);
+ mcol = CustomData_get_layer_named(&dm->loopData, CD_MLOOPCOL, layername);
+ if (!mcol)
+ return;
+
+ /* Stores the number of MLoops using the same vertex, so we can normalize colors. */
+ int *mcorners = MEM_callocN(sizeof(int) * pd->totpoints, "point density corner count");
+
+ for (i = 0; i < totloop; i++) {
+ int v = mloop[i].v;
+ rgb_uchar_to_float(&data_color[v*3], &mcol[i].r);
+ ++mcorners[v];
+ }
+
+ /* Normalize colors by averaging over mcorners.
+ * All the corners share the same vertex, ie. occupy the same point in space.
+ */
+ for (i = 0; i < pd->totpoints; i++) {
+ if (mcorners[i] > 0)
+ mul_v3_fl(&data_color[i*3], 1.0f / mcorners[i]);
+ }
+
+ MEM_freeN(mcorners);
+}
+
+static void pointdensity_cache_vertex_weight(PointDensity *pd, Object *ob, DerivedMesh *dm, float *data_color)
+{
+ const int totvert = dm->getNumVerts(dm);
+ const MDeformVert *mdef, *dv;
+ int mdef_index;
+ int i;
+
+ BLI_assert(data_color);
+
+ mdef = CustomData_get_layer(&dm->vertData, CD_MDEFORMVERT);
+ if (!mdef)
+ return;
+ mdef_index = defgroup_name_index(ob, pd->vertex_attribute_name);
+ if (mdef_index < 0)
+ mdef_index = ob->actdef - 1;
+ if (mdef_index < 0)
+ return;
+
+ for (i = 0, dv = mdef; i < totvert; ++i, ++dv, data_color += 3) {
+ MDeformWeight *dw;
+ int j;
+
+ for (j = 0, dw = dv->dw; j < dv->totweight; ++j, ++dw) {
+ if (dw->def_nr == mdef_index) {
+ copy_v3_fl(data_color, dw->weight);
+ break;
+ }
+ }
+ }
+}
+
+static void pointdensity_cache_vertex_normal(PointDensity *pd, Object *UNUSED(ob), DerivedMesh *dm, float *data_color)
+{
+ MVert *mvert = dm->getVertArray(dm), *mv;
+ int i;
+
+ BLI_assert(data_color);
+
+ for (i = 0, mv = mvert; i < pd->totpoints; i++, mv++, data_color += 3) {
+ normal_short_to_float_v3(data_color, mv->no);
+ }
+}
+
static void pointdensity_cache_object(Scene *scene,
PointDensity *pd,
Object *ob,
const bool use_render_params)
{
+ float *data_color;
int i;
DerivedMesh *dm;
- MVert *mvert = NULL;
+ CustomDataMask mask = CD_MASK_BAREMESH | CD_MASK_MTFACE | CD_MASK_MCOL;
+ MVert *mvert = NULL, *mv;
+
+ switch (pd->ob_color_source) {
+ case TEX_PD_COLOR_VERTCOL:
+ mask |= CD_MASK_MLOOPCOL;
+ break;
+ case TEX_PD_COLOR_VERTWEIGHT:
+ mask |= CD_MASK_MDEFORMVERT;
+ break;
+ }
if (use_render_params) {
- dm = mesh_create_derived_render(scene,
- ob,
- CD_MASK_BAREMESH | CD_MASK_MTFACE | CD_MASK_MCOL);
+ dm = mesh_create_derived_render(scene, ob, mask);
}
else {
- dm = mesh_get_derived_final(scene,
- ob,
- CD_MASK_BAREMESH | CD_MASK_MTFACE | CD_MASK_MCOL);
-
+ dm = mesh_get_derived_final(scene, ob, mask);
}
- mvert = dm->getVertArray(dm); /* local object space */
+ mvert = dm->getVertArray(dm); /* local object space */
pd->totpoints = dm->getNumVerts(dm);
if (pd->totpoints == 0) {
return;
}
pd->point_tree = BLI_bvhtree_new(pd->totpoints, 0.0, 4, 6);
+ alloc_point_data(pd);
+ point_data_pointers(pd, NULL, NULL, &data_color);
- for (i = 0; i < pd->totpoints; i++, mvert++) {
+ for (i = 0, mv = mvert; i < pd->totpoints; i++, mv++) {
float co[3];
- copy_v3_v3(co, mvert->co);
+ copy_v3_v3(co, mv->co);
switch (pd->ob_cache_space) {
case TEX_PD_OBJECTSPACE:
@@ -308,6 +448,18 @@ static void pointdensity_cache_object(Scene *scene,
BLI_bvhtree_insert(pd->point_tree, i, co, 1);
}
+
+ switch (pd->ob_color_source) {
+ case TEX_PD_COLOR_VERTCOL:
+ pointdensity_cache_vertex_color(pd, ob, dm, data_color);
+ break;
+ case TEX_PD_COLOR_VERTWEIGHT:
+ pointdensity_cache_vertex_weight(pd, ob, dm, data_color);
+ break;
+ case TEX_PD_COLOR_VERTNOR:
+ pointdensity_cache_vertex_normal(pd, ob, dm, data_color);
+ break;
+ }
BLI_bvhtree_balance(pd->point_tree);
dm->release(dm);
@@ -423,80 +575,99 @@ void free_pointdensities(Render *re)
typedef struct PointDensityRangeData {
float *density;
float squared_radius;
- const float *point_data;
+ float *point_data_life;
+ float *point_data_velocity;
+ float *point_data_color;
float *vec;
+ float *col;
float softness;
short falloff_type;
short noise_influence;
float *age;
- int point_data_used;
- int offset;
struct CurveMapping *density_curve;
float velscale;
} PointDensityRangeData;
+static float density_falloff(PointDensityRangeData *pdr, int index, float squared_dist)
+{
+ const float dist = (pdr->squared_radius - squared_dist) / pdr->squared_radius * 0.5f;
+ float density = 0.0f;
+
+ switch (pdr->falloff_type) {
+ case TEX_PD_FALLOFF_STD:
+ density = dist;
+ break;
+ case TEX_PD_FALLOFF_SMOOTH:
+ density = 3.0f * dist * dist - 2.0f * dist * dist * dist;
+ break;
+ case TEX_PD_FALLOFF_SOFT:
+ density = pow(dist, pdr->softness);
+ break;
+ case TEX_PD_FALLOFF_CONSTANT:
+ density = pdr->squared_radius;
+ break;
+ case TEX_PD_FALLOFF_ROOT:
+ density = sqrtf(dist);
+ break;
+ case TEX_PD_FALLOFF_PARTICLE_AGE:
+ if (pdr->point_data_life)
+ density = dist * MIN2(pdr->point_data_life[index], 1.0f);
+ else
+ density = dist;
+ break;
+ case TEX_PD_FALLOFF_PARTICLE_VEL:
+ if (pdr->point_data_velocity)
+ density = dist * len_v3(&pdr->point_data_velocity[index * 3]) * pdr->velscale;
+ else
+ density = dist;
+ break;
+ }
+
+ if (pdr->density_curve && dist != 0.0f) {
+ curvemapping_initialize(pdr->density_curve);
+ density = curvemapping_evaluateF(pdr->density_curve, 0, density / dist) * dist;
+ }
+
+ return density;
+}
+
static void accum_density(void *userdata, int index, const float co[3], float squared_dist)
{
PointDensityRangeData *pdr = (PointDensityRangeData *)userdata;
- const float dist = (pdr->squared_radius - squared_dist) / pdr->squared_radius * 0.5f;
float density = 0.0f;
UNUSED_VARS(co);
- if (pdr->point_data_used & POINT_DATA_VEL) {
- pdr->vec[0] += pdr->point_data[index * 3 + 0]; // * density;
- pdr->vec[1] += pdr->point_data[index * 3 + 1]; // * density;
- pdr->vec[2] += pdr->point_data[index * 3 + 2]; // * density;
- }
- if (pdr->point_data_used & POINT_DATA_LIFE) {
- *pdr->age += pdr->point_data[pdr->offset + index]; // * density;
- }
-
- if (pdr->falloff_type == TEX_PD_FALLOFF_STD)
- density = dist;
- else if (pdr->falloff_type == TEX_PD_FALLOFF_SMOOTH)
- density = 3.0f * dist * dist - 2.0f * dist * dist * dist;
- else if (pdr->falloff_type == TEX_PD_FALLOFF_SOFT)
- density = pow(dist, pdr->softness);
- else if (pdr->falloff_type == TEX_PD_FALLOFF_CONSTANT)
- density = pdr->squared_radius;
- else if (pdr->falloff_type == TEX_PD_FALLOFF_ROOT)
- density = sqrtf(dist);
- else if (pdr->falloff_type == TEX_PD_FALLOFF_PARTICLE_AGE) {
- if (pdr->point_data_used & POINT_DATA_LIFE)
- density = dist * MIN2(pdr->point_data[pdr->offset + index], 1.0f);
- else
- density = dist;
+ if (pdr->point_data_velocity) {
+ pdr->vec[0] += pdr->point_data_velocity[index * 3 + 0]; // * density;
+ pdr->vec[1] += pdr->point_data_velocity[index * 3 + 1]; // * density;
+ pdr->vec[2] += pdr->point_data_velocity[index * 3 + 2]; // * density;
}
- else if (pdr->falloff_type == TEX_PD_FALLOFF_PARTICLE_VEL) {
- if (pdr->point_data_used & POINT_DATA_VEL)
- density = dist * len_v3(pdr->point_data + index * 3) * pdr->velscale;
- else
- density = dist;
+ if (pdr->point_data_life) {
+ *pdr->age += pdr->point_data_life[index]; // * density;
}
-
- if (pdr->density_curve && dist != 0.0f) {
- curvemapping_initialize(pdr->density_curve);
- density = curvemapping_evaluateF(pdr->density_curve, 0, density / dist) * dist;
+ if (pdr->point_data_color) {
+ add_v3_v3(pdr->col, &pdr->point_data_color[index * 3]); // * density;
}
+ density = density_falloff(pdr, index, squared_dist);
+
*pdr->density += density;
}
static void init_pointdensityrangedata(PointDensity *pd, PointDensityRangeData *pdr,
- float *density, float *vec, float *age, struct CurveMapping *density_curve, float velscale)
+ float *density, float *vec, float *age, float *col, struct CurveMapping *density_curve, float velscale)
{
pdr->squared_radius = pd->radius * pd->radius;
pdr->density = density;
- pdr->point_data = pd->point_data;
pdr->falloff_type = pd->falloff_type;
pdr->vec = vec;
pdr->age = age;
+ pdr->col = col;
pdr->softness = pd->falloff_softness;
pdr->noise_influence = pd->noise_influence;
- pdr->point_data_used = point_data_used(pd);
- pdr->offset = (pdr->point_data_used & POINT_DATA_VEL) ? pd->totpoints * 3 : 0;
+ point_data_pointers(pd, &pdr->point_data_velocity, &pdr->point_data_life, &pdr->point_data_color);
pdr->density_curve = density_curve;
pdr->velscale = velscale;
}
@@ -505,13 +676,14 @@ static void init_pointdensityrangedata(PointDensity *pd, PointDensityRangeData *
static int pointdensity(PointDensity *pd,
const float texvec[3],
TexResult *texres,
+ float r_vec[3],
float *r_age,
- float r_vec[3])
+ float r_col[3])
{
int retval = TEX_INT;
PointDensityRangeData pdr;
float density = 0.0f, age = 0.0f, time = 0.0f;
- float vec[3] = {0.0f, 0.0f, 0.0f}, co[3];
+ float vec[3] = {0.0f, 0.0f, 0.0f}, col[3] = {0.0f, 0.0f, 0.0f}, co[3];
float turb, noise_fac;
int num = 0;
@@ -520,7 +692,7 @@ static int pointdensity(PointDensity *pd,
if ((!pd) || (!pd->point_tree))
return 0;
- init_pointdensityrangedata(pd, &pdr, &density, vec, &age,
+ init_pointdensityrangedata(pd, &pdr, &density, vec, &age, col,
(pd->flag & TEX_PD_FALLOFF_CURVE ? pd->falloff_curve : NULL),
pd->falloff_speed_scale * 0.001f);
noise_fac = pd->noise_fac * 0.5f; /* better default */
@@ -534,10 +706,13 @@ static int pointdensity(PointDensity *pd,
if (num > 0) {
age /= num;
mul_v3_fl(vec, 1.0f / num);
+ mul_v3_fl(col, 1.0f / num);
}
/* reset */
- density = vec[0] = vec[1] = vec[2] = 0.0f;
+ density = 0.0f;
+ zero_v3(vec);
+ zero_v3(col);
}
if (pd->flag & TEX_PD_TURBULENCE) {
@@ -570,6 +745,7 @@ static int pointdensity(PointDensity *pd,
if (num > 0) {
age /= num;
mul_v3_fl(vec, 1.0f / num);
+ mul_v3_fl(col, 1.0f / num);
}
texres->tin = density;
@@ -579,51 +755,88 @@ static int pointdensity(PointDensity *pd,
if (r_vec != NULL) {
copy_v3_v3(r_vec, vec);
}
+ if (r_col != NULL) {
+ copy_v3_v3(r_col, col);
+ }
return retval;
}
-static int pointdensity_color(PointDensity *pd, TexResult *texres, float age, const float vec[3])
+static int pointdensity_color(PointDensity *pd, TexResult *texres, float age, const float vec[3], const float col[3])
{
- int retval = 0;
- float col[4];
-
- retval |= TEX_RGB;
+ int retval = TEX_RGB;
- switch (pd->color_source) {
- case TEX_PD_COLOR_PARTAGE:
- if (pd->coba) {
- if (do_colorband(pd->coba, age, col)) {
- texres->talpha = true;
- copy_v3_v3(&texres->tr, col);
- texres->tin *= col[3];
- texres->ta = texres->tin;
+ if (pd->source == TEX_PD_PSYS) {
+ float rgba[4];
+
+ switch (pd->color_source) {
+ case TEX_PD_COLOR_PARTAGE:
+ if (pd->coba) {
+ if (do_colorband(pd->coba, age, rgba)) {
+ texres->talpha = true;
+ copy_v3_v3(&texres->tr, rgba);
+ texres->tin *= rgba[3];
+ texres->ta = texres->tin;
+ }
}
+ break;
+ case TEX_PD_COLOR_PARTSPEED:
+ {
+ float speed = len_v3(vec) * pd->speed_scale;
+
+ if (pd->coba) {
+ if (do_colorband(pd->coba, speed, rgba)) {
+ texres->talpha = true;
+ copy_v3_v3(&texres->tr, rgba);
+ texres->tin *= rgba[3];
+ texres->ta = texres->tin;
+ }
+ }
+ break;
}
- break;
- case TEX_PD_COLOR_PARTSPEED:
- {
- float speed = len_v3(vec) * pd->speed_scale;
-
- if (pd->coba) {
- if (do_colorband(pd->coba, speed, col)) {
- texres->talpha = true;
+ case TEX_PD_COLOR_PARTVEL:
+ texres->talpha = true;
+ mul_v3_v3fl(&texres->tr, vec, pd->speed_scale);
+ texres->ta = texres->tin;
+ break;
+ case TEX_PD_COLOR_CONSTANT:
+ default:
+ texres->tr = texres->tg = texres->tb = texres->ta = 1.0f;
+ retval = TEX_INT;
+ break;
+ }
+ }
+ else {
+ float rgba[4];
+
+ switch (pd->ob_color_source) {
+ case TEX_PD_COLOR_VERTCOL:
+ texres->talpha = true;
+ copy_v3_v3(&texres->tr, col);
+ texres->ta = texres->tin;
+ break;
+ case TEX_PD_COLOR_VERTWEIGHT:
+ texres->talpha = true;
+ if (pd->coba && do_colorband(pd->coba, col[0], rgba)) {
+ copy_v3_v3(&texres->tr, rgba);
+ texres->tin *= rgba[3];
+ }
+ else {
copy_v3_v3(&texres->tr, col);
- texres->tin *= col[3];
- texres->ta = texres->tin;
}
- }
- break;
+ texres->ta = texres->tin;
+ break;
+ case TEX_PD_COLOR_VERTNOR:
+ texres->talpha = true;
+ copy_v3_v3(&texres->tr, col);
+ texres->ta = texres->tin;
+ break;
+ case TEX_PD_COLOR_CONSTANT:
+ default:
+ texres->tr = texres->tg = texres->tb = texres->ta = 1.0f;
+ retval = TEX_INT;
+ break;
}
- case TEX_PD_COLOR_PARTVEL:
- texres->talpha = true;
- mul_v3_v3fl(&texres->tr, vec, pd->speed_scale);
- texres->ta = texres->tin;
- break;
- case TEX_PD_COLOR_CONSTANT:
- default:
- texres->tr = texres->tg = texres->tb = texres->ta = 1.0f;
- break;
}
return retval;
@@ -634,16 +847,12 @@ 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);
+ float col[3] = {0.0f, 0.0f, 0.0f};
+ int retval = pointdensity(pd, texvec, texres, vec, &age, col);
- BRICONT;
-
- if (pd->color_source == TEX_PD_COLOR_CONSTANT)
- return retval;
-
- retval |= pointdensity_color(pd, texres, age, vec);
+ retval |= pointdensity_color(pd, texres, age, vec, col);
BRICONTRGB;
-
+
return retval;
#if 0
@@ -803,7 +1012,7 @@ static void point_density_sample_func(void *data_v, const int iter)
for (size_t x = 0; x < resolution; ++x) {
size_t index = z * resolution2 + y * resolution + x;
float texvec[3];
- float age, vec[3];
+ float age, vec[3], col[3];
TexResult texres;
copy_v3_v3(texvec, min);
@@ -811,8 +1020,8 @@ static void point_density_sample_func(void *data_v, const int iter)
texvec[1] += dim[1] * (float)y / (float)resolution;
texvec[2] += dim[2] * (float)z / (float)resolution;
- pointdensity(pd, texvec, &texres, &age, vec);
- pointdensity_color(pd, &texres, age, vec);
+ pointdensity(pd, texvec, &texres, vec, &age, col);
+ pointdensity_color(pd, &texres, age, vec, col);
copy_v3_v3(&values[index*4 + 0], &texres.tr);
values[index*4 + 3] = texres.tin;