[Bf-blender-cvs] [37876f6] temp_hair_flow: New grid struct for hair volumetrics.

Lukas Tönne noreply at git.blender.org
Wed Jan 7 19:37:42 CET 2015


Commit: 37876f644a087d4ef5708b4c7b6ede52f091b385
Author: Lukas Tönne
Date:   Wed Jan 7 10:22:32 2015 +0100
Branches: temp_hair_flow
https://developer.blender.org/rB37876f644a087d4ef5708b4c7b6ede52f091b385

New grid struct for hair volumetrics.

This is supposed to unify volumetric calculations for hair edit mode
and dynamics eventually.

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

M	source/blender/editors/hair/hair_flow.c
M	source/blender/physics/BPH_strands.h
A	source/blender/physics/intern/grid.cpp
A	source/blender/physics/intern/grid.h
M	source/blender/physics/intern/hair_flow.cpp

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

diff --git a/source/blender/editors/hair/hair_flow.c b/source/blender/editors/hair/hair_flow.c
index 2185e3d..40d4ea5 100644
--- a/source/blender/editors/hair/hair_flow.c
+++ b/source/blender/editors/hair/hair_flow.c
@@ -67,8 +67,9 @@ static int hair_solve_flow_exec(bContext *C, wmOperator *op)
 	int max_strands = RNA_int_get(op->ptr, "max_strands");
 	float max_length = RNA_float_get(op->ptr, "max_length");
 	int segments = RNA_int_get(op->ptr, "segments");
+	int res = RNA_int_get(op->ptr, "resolution");
 	
-	struct HairFlowData *data = BPH_strands_solve_hair_flow(scene, ob);
+	struct HairFlowData *data = BPH_strands_solve_hair_flow(scene, ob, max_length, res);
 	if (data) {
 		/* remove existing hair strands */
 		BM_mesh_clear(edit->bm);
@@ -100,4 +101,5 @@ void HAIR_OT_solve_flow(wmOperatorType *ot)
 	RNA_def_int(ot->srna, "max_strands", 1, 1, INT_MAX, "Strands", "Maximum number of strands to generate", 1, 100000);
 	RNA_def_float(ot->srna, "max_length", 1.0f, 0.0f, FLT_MAX, "Length", "Maximum length of strands", 0.0001f, 10000.0f);
 	RNA_def_int(ot->srna, "segments", 5, 1, INT_MAX, "Segments", "Number of segments per strand", 1, 100);
+	RNA_def_int(ot->srna, "resolution", 10, 1, INT_MAX, "Resolution", "Resolution of the hair flow grid", 1, 100);
 }
diff --git a/source/blender/physics/BPH_strands.h b/source/blender/physics/BPH_strands.h
index 8c7c182..f2b1b16 100644
--- a/source/blender/physics/BPH_strands.h
+++ b/source/blender/physics/BPH_strands.h
@@ -42,7 +42,7 @@ void BPH_strands_solve_constraints(struct Object *ob, struct BMEditStrands *es,
 
 struct HairFlowData;
 
-struct HairFlowData *BPH_strands_solve_hair_flow(struct Scene *scene, struct Object *ob);
+struct HairFlowData *BPH_strands_solve_hair_flow(struct Scene *scene, struct Object *ob, float max_length, int max_res);
 void BPH_strands_free_hair_flow(struct HairFlowData *data);
 
 void BPH_strands_sample_hair_flow(struct Object *ob, struct BMEditStrands *edit, struct HairFlowData *data,
diff --git a/source/blender/physics/BPH_strands.h b/source/blender/physics/intern/grid.cpp
similarity index 58%
copy from source/blender/physics/BPH_strands.h
copy to source/blender/physics/intern/grid.cpp
index 8c7c182..18223ab 100644
--- a/source/blender/physics/BPH_strands.h
+++ b/source/blender/physics/intern/grid.cpp
@@ -25,31 +25,56 @@
  * ***** END GPL LICENSE BLOCK *****
  */
 
-#ifndef __BPH_STRANDS_H__
-#define __BPH_STRANDS_H__
+/** \file grid.cpp
+ *  \ingroup bph
+ */
+
+#include "MEM_guardedalloc.h"
 
-#ifdef __cplusplus
 extern "C" {
-#endif
+#include "BLI_math.h"
+}
 
-struct Object;
-struct Scene;
-struct BMEditStrands;
+#include "grid.h"
 
-void BPH_strands_solve_constraints(struct Object *ob, struct BMEditStrands *es, float (*orig)[3]);
+namespace BPH {
 
-/* Hair Flow Solver */
+Grid::Grid() :
+    cellsize(0.0f),
+    inv_cellsize(0.0f),
+    num_cells(0)
+{
+	zero_v3(offset);
+	zero_v3_int(res);
+}
 
-struct HairFlowData;
+Grid::~Grid()
+{
+}
 
-struct HairFlowData *BPH_strands_solve_hair_flow(struct Scene *scene, struct Object *ob);
-void BPH_strands_free_hair_flow(struct HairFlowData *data);
+void Grid::resize(float _cellsize, const float _offset[3], const int _res[3])
+{
+	cellsize = _cellsize;
+	inv_cellsize = 1.0f / _cellsize;
+	copy_v3_v3(offset, _offset);
+	copy_v3_v3_int(res, _res);
+	num_cells = _res[0] * _res[1] * _res[2];
+	
+	divergence = lVector(num_cells);
+	pressure = lVector(num_cells);
+}
 
-void BPH_strands_sample_hair_flow(struct Object *ob, struct BMEditStrands *edit, struct HairFlowData *data,
-                                  unsigned int seed, int max_strands, float max_length, int segments);
+void Grid::init()
+{
+	divergence.setZero();
+}
 
-#ifdef __cplusplus
+void Grid::clear()
+{
+	pressure.setZero();
 }
-#endif
 
-#endif
+} /* namespace BPH */
+
+#include "implicit.h"
+
diff --git a/source/blender/physics/BPH_strands.h b/source/blender/physics/intern/grid.h
similarity index 59%
copy from source/blender/physics/BPH_strands.h
copy to source/blender/physics/intern/grid.h
index 8c7c182..829d944 100644
--- a/source/blender/physics/BPH_strands.h
+++ b/source/blender/physics/intern/grid.h
@@ -25,31 +25,42 @@
  * ***** END GPL LICENSE BLOCK *****
  */
 
-#ifndef __BPH_STRANDS_H__
-#define __BPH_STRANDS_H__
+#ifndef __BPH_GRID_H__
+#define __BPH_GRID_H__
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct Object;
-struct Scene;
-struct BMEditStrands;
-
-void BPH_strands_solve_constraints(struct Object *ob, struct BMEditStrands *es, float (*orig)[3]);
+/** \file grid.h
+ *  \ingroup bph
+ */
 
-/* Hair Flow Solver */
+#include "BLI_utildefines.h"
 
-struct HairFlowData;
+#include "eigen_utils.h"
 
-struct HairFlowData *BPH_strands_solve_hair_flow(struct Scene *scene, struct Object *ob);
-void BPH_strands_free_hair_flow(struct HairFlowData *data);
+namespace BPH {
 
-void BPH_strands_sample_hair_flow(struct Object *ob, struct BMEditStrands *edit, struct HairFlowData *data,
-                                  unsigned int seed, int max_strands, float max_length, int segments);
+typedef struct Grid {
+	Grid();
+	~Grid();
+	
+	void resize(float cellsize, const float offset[3], const int res[3]);
+	
+	void init();
+	void clear();
+	
+	float cellsize, inv_cellsize;
+	float offset[3];
+	int res[3];
+	int num_cells;
+	
+	lVector divergence;
+	lVector pressure;
+	
+	struct SimDebugData *debug_data;
+	float debug1, debug2;
+	int debug3, debug4;
+	
+} Grid;
 
-#ifdef __cplusplus
-}
-#endif
+} /* namespace BPH */
 
 #endif
diff --git a/source/blender/physics/intern/hair_flow.cpp b/source/blender/physics/intern/hair_flow.cpp
index a0f76a3..d41dc0f 100644
--- a/source/blender/physics/intern/hair_flow.cpp
+++ b/source/blender/physics/intern/hair_flow.cpp
@@ -42,32 +42,98 @@ extern "C" {
 #include "BKE_editstrands.h"
 #include "BKE_effect.h"
 #include "BKE_mesh_sample.h"
+#include "BKE_object.h"
 
 #include "bmesh.h"
 }
 
 #include "BPH_strands.h"
 
-#include "implicit.h"
 #include "eigen_utils.h"
+#include "implicit.h"
+#include "grid.h"
+
+using namespace BPH;
+
+BLI_INLINE int floor_int(float value)
+{
+	return value > 0.0f ? (int)value : ((int)value) - 1;
+}
+
+BLI_INLINE float floor_mod(float value)
+{
+	return value - floorf(value);
+}
 
 struct HairFlowData {
-	float cellsize;
+	HairFlowData()
+	{
+	}
+	
+	~HairFlowData()
+	{
+	}
+	
+	Grid grid;
+	
+	MEM_CXX_CLASS_ALLOC_FUNCS("HairFlowData")
 };
 
-HairFlowData *BPH_strands_solve_hair_flow(Scene *scene, Object *ob)
+HairFlowData *BPH_strands_solve_hair_flow(Scene *scene, Object *ob, float max_length, int max_res)
 {
-	/* XXX just a dummy for now ... */
-	HairFlowData *data = (HairFlowData *)MEM_callocN(sizeof(HairFlowData), "hair flow data");
+	HairFlowData *data = new HairFlowData();
+	int i, k;
+	
+	BoundBox *bb = BKE_object_boundbox_get(ob);
+	if (!bb)
+		return NULL;
+	
+	BoundBox bbworld;
+	float bbmin[3], bbmax[3], extent[3];
+	INIT_MINMAX(bbmin, bbmax);
+	for (i = 0; i < 8; ++i) {
+		mul_v3_m4v3(bbworld.vec[i], ob->obmat, bb->vec[i]);
+		for (k = 0; k < 3; ++k) {
+			if (bbmin[k] > bbworld.vec[i][k])
+				bbmin[k] = bbworld.vec[i][k];
+			if (bbmax[k] < bbworld.vec[i][k])
+				bbmax[k] = bbworld.vec[i][k];
+		}
+	}
+	float max_extent = -1.0f;
+	int max_extent_index = -1;
+	for (k = 0; k < 3; ++k) {
+		/* hair can extend at most max_length in either direction from the mesh,
+		 * which defines the maximum extent of the bounding volume we need
+		 */
+		extent[k] = bbmax[k] - bbmin[k] + 2.0f * max_length;
+		if (max_extent < extent[k]) {
+			max_extent = extent[k];
+			max_extent_index = k;
+		}
+	}
+	
+	/* 1-cell margin of the grid means the actual extent uses 2 cells less */
+	float cellsize = max_extent / (max_res - 2);
+	float offset[3] = {(float)(bbmin[0] - max_length - 0.5*cellsize),
+	                   (float)(bbmin[1] - max_length - 0.5*cellsize),
+	                   (float)(bbmin[2] - max_length - 0.5*cellsize)};
+	
+	int res[3];
+	res[max_extent_index] = max_res;
+	k = (max_extent_index + 1) % 3;
+	res[k] = floor_int(extent[k] / cellsize) + 2;
+	k = (max_extent_index + 2) % 3;
+	res[k] = floor_int(extent[k] / cellsize) + 2;
 	
-	data->cellsize = 100.0f;
+	data->grid.resize(cellsize, offset, res);
 	
 	return data;
 }
 
 void BPH_strands_free_hair_flow(HairFlowData *data)
 {
-	MEM_freeN(data);
+	delete data;
 }
 
 BLI_INLINE void construct_m4_loc_nor_tan(float mat[4][4], const float loc[3], const float nor[3], const float tang[3])
@@ -161,7 +227,7 @@ void BPH_strands_sample_hair_flow(Object *ob, BMEditStrands *edit, HairFlowData
 		return;
 	
 	/* integration step size */
-	dt = min_ff(0.5f * data->cellsize, max_length / (float)segments);
+	dt = min_ff(0.5f * data->grid.cellsize, max_length / (float)segments);
 	
 	samples = (MSurfaceSample *)MEM_mallocN(sizeof(MSurfaceSample) * max_strands, "hair flow sampling origins");
 	BKE_mesh_sample_storage_array(&storage, samples, max_strands);




More information about the Bf-blender-cvs mailing list