[Bf-blender-cvs] [2f15a1f] master: Point density: Add utility function to sample density outside of render pipeline

Sergey Sharybin noreply at git.blender.org
Sat Jul 18 23:00:45 CEST 2015


Commit: 2f15a1f66e3092158d330db97a33dc8d087ca053
Author: Sergey Sharybin
Date:   Sat Jul 18 21:42:39 2015 +0200
Branches: master
https://developer.blender.org/rB2f15a1f66e3092158d330db97a33dc8d087ca053

Point density: Add utility function to sample density outside of render pipeline

Not currently used, it's a preparation for the further work.

Should not be functional changes.

===================================================================

M	source/blender/render/extern/include/RE_render_ext.h
M	source/blender/render/intern/source/pointdensity.c
M	source/blenderplayer/bad_level_call_stubs/stubs.c

===================================================================

diff --git a/source/blender/render/extern/include/RE_render_ext.h b/source/blender/render/extern/include/RE_render_ext.h
index 6adbb6d..9d8a1a6 100644
--- a/source/blender/render/extern/include/RE_render_ext.h
+++ b/source/blender/render/extern/include/RE_render_ext.h
@@ -59,6 +59,12 @@ void RE_free_sample_material(struct Material *mat);
 void RE_sample_material_color(struct Material *mat, float color[3], float *alpha, const float volume_co[3], const float surface_co[3],
                               int face_index, short hit_quad, struct DerivedMesh *orcoDm, struct Object *ob);
 
+/* pointdensity.c */
+
+struct PointDensity;
+
+void RE_sample_point_density(struct Scene *scene, struct PointDensity *pd, int resolution, float *values);
+
 void RE_init_texture_rng(void);
 void RE_exit_texture_rng(void);
 #endif /* __RE_RENDER_EXT_H__ */
diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c
index 3a1f1fb..a99cc3c 100644
--- a/source/blender/render/intern/source/pointdensity.c
+++ b/source/blender/render/intern/source/pointdensity.c
@@ -45,6 +45,7 @@
 #include "BKE_DerivedMesh.h"
 #include "BKE_lattice.h"
 #include "BKE_main.h"
+#include "BKE_object.h"
 #include "BKE_particle.h"
 #include "BKE_scene.h"
 #include "BKE_texture.h"
@@ -58,12 +59,15 @@
 #include "texture.h"
 #include "pointdensity.h"
 
+#include "RE_render_ext.h"
+
 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
 /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
 /* only to be used here in this file, it's for speed */
 extern struct Render R;
 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
 
+static ThreadMutex sample_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 static int point_data_used(PointDensity *pd)
 {
@@ -456,14 +460,16 @@ static void init_pointdensityrangedata(PointDensity *pd, PointDensityRangeData *
 }
 
 
-int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres)
+static int pointdensity(PointDensity *pd,
+                        const float texvec[3],
+                        TexResult *texres,
+                        float *r_age,
+                        float r_vec[3])
 {
 	int retval = TEX_INT;
-	PointDensity *pd = tex->pd;
 	PointDensityRangeData pdr;
 	float density = 0.0f, age = 0.0f, time = 0.0f;
 	float vec[3] = {0.0f, 0.0f, 0.0f}, co[3];
-	float col[4];
 	float turb, noise_fac;
 	int num = 0;
 
@@ -524,7 +530,26 @@ int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres)
 		mul_v3_fl(vec, 1.0f / num);
 	}
 
+	if (r_age != NULL) {
+		*r_age = age;
+	}
+	if (r_vec != NULL) {
+		copy_v3_v3(r_vec, vec);
+	}
+
 	texres->tin = density;
+
+	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);
+	float col[4];
+
 	BRICONT;
 
 	if (pd->color_source == TEX_PD_COLOR_CONSTANT)
@@ -578,3 +603,106 @@ int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres)
 	}
 #endif
 }
+
+static void sample_dummy_point_density(int resolution, float *values)
+{
+	memset(values, 0, sizeof(float) * 4 * resolution * resolution * resolution);
+}
+
+static void particle_system_minmax(Object *object,
+                                   ParticleSystem *psys,
+                                   float radius,
+                                   float min[3], float max[3])
+{
+	ParticleSettings *part = psys->part;
+	float imat[4][4];
+	float size[3] = {radius, radius, radius};
+	PARTICLE_P;
+	INIT_MINMAX(min, max);
+	if (part->type == PART_HAIR) {
+		/* TOOD(sergey): Not supported currently. */
+		return;
+	}
+	invert_m4_m4(imat, object->obmat);
+	LOOP_PARTICLES {
+		float co_object[3], co_min[3], co_max[3];
+		mul_v3_m4v3(co_object, imat, pa->state.co);
+		sub_v3_v3v3(co_min, co_object, size);
+		add_v3_v3v3(co_max, co_object, size);
+		minmax_v3v3_v3(min, max, co_min);
+		minmax_v3v3_v3(min, max, co_max);
+	}
+}
+
+void RE_sample_point_density(Scene *scene, PointDensity *pd,
+                             int resolution, float *values)
+{
+	const size_t resolution2 = resolution * resolution;
+	Object *object = pd->object;
+	size_t x, y, z;
+	float min[3], max[3], dim[3], mat[4][4];
+
+	if (object == NULL) {
+		sample_dummy_point_density(resolution, values);
+		return;
+	}
+
+	if (pd->source == TEX_PD_PSYS) {
+		ParticleSystem *psys;
+		if (pd->psys == 0) {
+			sample_dummy_point_density(resolution, values);
+			return;
+		}
+		psys = BLI_findlink(&object->particlesystem, pd->psys - 1);
+		if (psys == NULL) {
+			sample_dummy_point_density(resolution, values);
+			return;
+		}
+		particle_system_minmax(object, psys, pd->radius, min, 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);
+		/* Adjust texture space to include density points on the boundaries. */
+		sub_v3_v3(min, radius);
+		add_v3_v3(max, radius);
+	}
+
+	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);
+		return;
+	}
+
+	/* Same matricies/resolution as dupli_render_particle_set(). */
+	unit_m4(mat);
+
+	BLI_mutex_lock(&sample_mutex);
+	cache_pointdensity_ex(scene, pd, mat, mat, 1, 1);
+	BLI_mutex_unlock(&sample_mutex);
+
+	for (z = 0; z < resolution; ++z) {
+		for (y = 0; y < resolution; ++y) {
+			for (x = 0; x < resolution; ++x) {
+				size_t index = z * resolution2 + y * resolution + x;
+				float texvec[3];
+				float age, vec[3];
+				TexResult texres;
+
+				copy_v3_v3(texvec, min);
+				texvec[0] += dim[0] * (float)x / (float)resolution;
+				texvec[1] += dim[1] * (float)y / (float)resolution;
+				texvec[2] += dim[2] * (float)z / (float)resolution;
+
+				pointdensity(pd, texvec, &texres, &age, vec);
+
+				copy_v3_v3(&values[index*4 + 0], &texres.tr);
+				values[index*4 + 3] = texres.tin;
+			}
+		}
+	}
+	free_pointdensity(pd);
+}
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index 0e66494..a94d920 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -628,6 +628,7 @@ void RE_engine_update_memory_stats(struct RenderEngine *engine, float mem_used,
 struct RenderEngine *RE_engine_create(struct RenderEngineType *type) RET_NULL
 void RE_engine_frame_set(struct RenderEngine *engine, int frame, float subframe) RET_NONE
 void RE_FreePersistentData(void) RET_NONE
+void RE_sample_point_density(struct Scene *scene, struct PointDensity *pd, int resolution, float *values) RET_NONE;
 void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3]) RET_NONE
 
 /* python */




More information about the Bf-blender-cvs mailing list