[Bf-blender-cvs] [7b66e7b] alembic: Implemented hair cutting for cached strands, based on a cutoff parameter for child hairs.

Lukas Tönne noreply at git.blender.org
Fri May 22 17:53:33 CEST 2015


Commit: 7b66e7bdd1b45b106557b880e29748bf3fa9fb05
Author: Lukas Tönne
Date:   Fri May 22 16:22:57 2015 +0200
Branches: alembic
https://developer.blender.org/rB7b66e7bdd1b45b106557b880e29748bf3fa9fb05

Implemented hair cutting for cached strands, based on a cutoff parameter
for child hairs.

The algorithm works by finding the first intersection of each child
hair with the target mesh. The child hairs have to be deformed with
their parents first (this usually happens *after* modifiers).

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

M	intern/cycles/blender/blender_curves.cpp
M	release/scripts/startup/bl_ui/properties_object.py
M	source/blender/blenkernel/BKE_cache_library.h
M	source/blender/blenkernel/BKE_strands.h
M	source/blender/blenkernel/intern/cache_library.c
M	source/blender/blenkernel/intern/strands.c
M	source/blender/editors/io/io_cache_shapekey.c
M	source/blender/editors/space_view3d/drawstrands.c
M	source/blender/makesdna/DNA_cache_library_types.h
M	source/blender/makesdna/DNA_strands_types.h
M	source/blender/makesrna/intern/rna_cache_library.c
M	source/blender/makesrna/intern/rna_strands.c
M	source/blender/pointcache/alembic/abc_particles.cpp

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

diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp
index e417a9f..8d23003 100644
--- a/intern/cycles/blender/blender_curves.cpp
+++ b/intern/cycles/blender/blender_curves.cpp
@@ -373,7 +373,7 @@ static bool ObtainCacheStrandsData(Mesh *mesh, BL::Scene /*b_scene*/, BL::Object
 	int ivert = 0;
 	for(; icurve < totcurves; ++icurve) {
 		CurveT b_curve = b_strands.curves[icurve];
-		int numverts = b_curve.size();
+		int numverts = b_curve.render_size();
 		int usedverts = 0;
 		CData->curve_firstkey.push_back(keyno);
 		
diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py
index f870f65..3e771e4 100644
--- a/release/scripts/startup/bl_ui/properties_object.py
+++ b/release/scripts/startup/bl_ui/properties_object.py
@@ -570,6 +570,7 @@ class OBJECT_PT_cache_library(ObjectButtonsPanel, Panel):
         row = layout.row()
         row.prop_search(md, "target", context.blend_data, "objects", icon='OBJECT_DATA')
         row.prop(md, "use_internal_target", text="Internal")
+        layout.prop(md, "cut_mode", toggle=True, expand=True)
 
         layout = layout.column()
         layout.active = md.hair_system is not None
diff --git a/source/blender/blenkernel/BKE_cache_library.h b/source/blender/blenkernel/BKE_cache_library.h
index 900d541..beb8e81 100644
--- a/source/blender/blenkernel/BKE_cache_library.h
+++ b/source/blender/blenkernel/BKE_cache_library.h
@@ -50,6 +50,7 @@ struct ID;
 struct CacheProcessData;
 struct BVHTreeFromMesh;
 struct Strands;
+struct StrandsChildren;
 struct StrandsKeyCacheModifier;
 struct Key;
 struct KeyBlock;
@@ -179,7 +180,7 @@ struct CacheModifier *BKE_cache_modifier_copy(struct CacheLibrary *cachelib, str
 void BKE_cache_modifier_foreachIDLink(struct CacheLibrary *cachelib, struct CacheModifier *md, CacheModifier_IDWalkFunc walk, void *userdata);
 
 bool BKE_cache_modifier_find_object(struct DupliCache *dupcache, struct Object *ob, struct DupliObjectData **r_data);
-bool BKE_cache_modifier_find_strands(struct DupliCache *dupcache, struct Object *ob, int hair_system, struct DupliObjectData **r_data, struct Strands **r_strands, const char **r_name);
+bool BKE_cache_modifier_find_strands(struct DupliCache *dupcache, struct Object *ob, int hair_system, struct DupliObjectData **r_data, struct Strands **r_strands, struct StrandsChildren **r_children, const char **r_name);
 
 struct KeyBlock *BKE_cache_modifier_strands_key_insert_key(struct StrandsKeyCacheModifier *md, struct Strands *strands, const char *name, const bool from_mix);
 bool BKE_cache_modifier_strands_key_get(struct Object *ob, struct StrandsKeyCacheModifier **r_skmd, struct DerivedMesh **r_dm, struct Strands **r_strands,
diff --git a/source/blender/blenkernel/BKE_strands.h b/source/blender/blenkernel/BKE_strands.h
index 674a76a..61f55e3 100644
--- a/source/blender/blenkernel/BKE_strands.h
+++ b/source/blender/blenkernel/BKE_strands.h
@@ -23,6 +23,8 @@
 
 #include "DNA_strands_types.h"
 
+struct StrandChildIterator;
+
 struct Strands *BKE_strands_new(int strands, int verts);
 struct Strands *BKE_strands_copy(struct Strands *strands);
 void BKE_strands_free(struct Strands *strands);
@@ -44,6 +46,9 @@ void BKE_strands_children_free(struct StrandsChildren *strands);
 void BKE_strands_children_add_uvs(struct StrandsChildren *strands, int num_layers);
 void BKE_strands_children_add_vcols(struct StrandsChildren *strands, int num_layers);
 
+int BKE_strands_children_max_length(struct StrandsChildren *strands);
+int *BKE_strands_calc_vertex_start(struct Strands *strands);
+void BKE_strands_children_strand_deform(struct StrandChildIterator *it_strand, struct Strands *parents, int *vertstart, bool use_motion, float (*out)[3]);
 void BKE_strands_children_deform(struct StrandsChildren *strands, struct Strands *parents, bool use_motion);
 
 void BKE_strands_children_ensure_normals(struct StrandsChildren *strands);
diff --git a/source/blender/blenkernel/intern/cache_library.c b/source/blender/blenkernel/intern/cache_library.c
index 07b24a5..4009a48 100644
--- a/source/blender/blenkernel/intern/cache_library.c
+++ b/source/blender/blenkernel/intern/cache_library.c
@@ -1030,12 +1030,13 @@ bool BKE_cache_modifier_find_object(DupliCache *dupcache, Object *ob, DupliObjec
 	return true;
 }
 
-bool BKE_cache_modifier_find_strands(DupliCache *dupcache, Object *ob, int hair_system, DupliObjectData **r_data, Strands **r_strands, const char **r_name)
+bool BKE_cache_modifier_find_strands(DupliCache *dupcache, Object *ob, int hair_system, DupliObjectData **r_data, Strands **r_strands, StrandsChildren **r_children, const char **r_name)
 {
 	DupliObjectData *dobdata;
 	ParticleSystem *psys;
 	DupliObjectDataStrands *link;
 	Strands *strands;
+	StrandsChildren *children;
 	
 	if (!ob)
 		return false;
@@ -1048,17 +1049,20 @@ bool BKE_cache_modifier_find_strands(DupliCache *dupcache, Object *ob, int hair_
 		return false;
 	
 	strands = NULL;
+	children = NULL;
 	for (link = dobdata->strands.first; link; link = link->next) {
 		if (link->strands && STREQ(link->name, psys->name)) {
 			strands = link->strands;
+			children = link->strands_children;
 			break;
 		}
 	}
-	if (!strands)
+	if ((r_strands && !strands) || (r_children && !children))
 		return false;
 	
 	if (r_data) *r_data = dobdata;
 	if (r_strands) *r_strands = strands;
+	if (r_children) *r_children = children;
 	if (r_name) *r_name = psys->name;
 	return true;
 }
@@ -1150,7 +1154,7 @@ static void hairsim_process(HairSimCacheModifier *hsmd, CacheProcessContext *ctx
 //	if (eval_mode != CACHE_LIBRARY_EVAL_REALTIME)
 //		return;
 	
-	if (!BKE_cache_modifier_find_strands(data->dupcache, ob, hsmd->hair_system, NULL, &strands, NULL))
+	if (!BKE_cache_modifier_find_strands(data->dupcache, ob, hsmd->hair_system, NULL, &strands, NULL, NULL))
 		return;
 	
 	/* Note: motion state data should always be created regardless of actual sim.
@@ -1447,7 +1451,7 @@ static void shrinkwrap_process(ShrinkWrapCacheModifier *smd, CacheProcessContext
 	
 	ShrinkWrapCacheData shrinkwrap;
 	
-	if (!BKE_cache_modifier_find_strands(data->dupcache, ob, smd->hair_system, NULL, &strands, NULL))
+	if (!BKE_cache_modifier_find_strands(data->dupcache, ob, smd->hair_system, NULL, &strands, NULL, NULL))
 		return;
 	if (!BKE_cache_modifier_find_object(data->dupcache, smd->target, &target_data))
 		return;
@@ -1526,7 +1530,7 @@ static void strandskey_process(StrandsKeyCacheModifier *skmd, CacheProcessContex
 	KeyBlock *actkb;
 	float *shape;
 	
-	if (!BKE_cache_modifier_find_strands(data->dupcache, ob, skmd->hair_system, NULL, &strands, NULL))
+	if (!BKE_cache_modifier_find_strands(data->dupcache, ob, skmd->hair_system, NULL, &strands, NULL, NULL))
 		return;
 	if (use_motion && !strands->state)
 		return;
@@ -1622,7 +1626,7 @@ bool BKE_cache_modifier_strands_key_get(Object *ob, StrandsKeyCacheModifier **r_
 			StrandsKeyCacheModifier *skmd = (StrandsKeyCacheModifier *)md;
 			DupliObjectData *dobdata;
 			
-			if (BKE_cache_modifier_find_strands(ob->dup_cache, skmd->object, skmd->hair_system, &dobdata, r_strands, r_name)) {
+			if (BKE_cache_modifier_find_strands(ob->dup_cache, skmd->object, skmd->hair_system, &dobdata, r_strands, NULL, r_name)) {
 				if (r_skmd) *r_skmd = skmd;
 				if (r_dm) *r_dm = dobdata->dm;
 				if (r_dobdata) *r_dobdata = dobdata;
@@ -1709,16 +1713,25 @@ static void haircut_data_get_bvhtree(HaircutCacheData *data, DerivedMesh *dm, bo
 
 static void haircut_data_get_instances(HaircutCacheData *data, Object *ob, float obmat[4][4], ListBase *duplilist)
 {
-	DupliObject *dob;
-	
-	for (dob = duplilist->first; dob; dob = dob->next) {
-		HaircutCacheInstance *inst;
+	if (duplilist) {
+		DupliObject *dob;
 		
-		if (dob->ob != ob)
-			continue;
-		
-		inst = MEM_callocN(sizeof(HaircutCacheInstance), "shrink wrap instance");
-		mul_m4_m4m4(inst->mat, obmat, dob->mat);
+		for (dob = duplilist->first; dob; dob = dob->next) {
+			HaircutCacheInstance *inst;
+			
+			if (dob->ob != ob)
+				continue;
+			
+			inst = MEM_callocN(sizeof(HaircutCacheInstance), "haircut instance");
+			mul_m4_m4m4(inst->mat, obmat, dob->mat);
+			invert_m4_m4(inst->imat, inst->mat);
+			
+			BLI_addtail(&data->instances, inst);
+		}
+	}
+	else {
+		HaircutCacheInstance *inst = MEM_callocN(sizeof(HaircutCacheInstance), "haircut instance");
+		mul_m4_m4m4(inst->mat, obmat, ob->obmat);
 		invert_m4_m4(inst->imat, inst->mat);
 		
 		BLI_addtail(&data->instances, inst);
@@ -1736,76 +1749,208 @@ static void haircut_data_free(HaircutCacheData *data)
 	}
 }
 
-static void haircut_apply_vertex(HaircutCacheModifier *UNUSED(hmd), HaircutCacheData *data, HaircutCacheInstance *inst, StrandsVertex *vertex, StrandsMotionState *UNUSED(state))
+/* XXX intersection counting does not work reliably */
+#if 0
+typedef struct PointInsideBVH {
+	BVHTreeFromMesh bvhdata;
+	int num_hits;
+} PointInsideBVH;
+
+static void point_inside_bvh_cb(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
 {
-//	const float *point = state->co;
-//	float *npoint = state->co;
-	const float *point = vertex->co;
-	float *npoint = vertex->co;
+	PointInsideBVH *data = userdata;
 	
-	BVHTreeNearest nearest = {0, };
-	float co[3];
+	data->bvhdata.raycast_callback(&data->bvhdata, index, ray, hit);
+	
+	if (hit->index != -1)
+		++data->num_hits;
+}
+
+/* true if the point is inside the target mesh */
+static bool haircut_test_point(HaircutCacheModifier *hmd, HaircutCacheData *data, HaircutCacheInstance *inst, const float *v)
+{
+	const float dir[3] = {1.0f, 0.0f, 0.0f};
+	float start[3];
+	PointInsideBVH userdata;
+	
+	if (!(hmd->cut_mode & eHaircutCacheModifier_CutMode_Enter))
+		return false;
+	
+	userdata.bvhdata = data->treedata;
+	userdata.num_hits = 0;
+	
+	/* lookup in target space */
+	mul_v3_m4v3(start, inst->imat, v);
+	
+	BLI_bvhtree_ray_cast_all(data->treedata.tree, start, dir, 0.0f, point_inside_bvh_cb, &userdata);
+	
+	/* for any point inside a watertight mesh the number of hits is uneven */
+	return (userdata.num_hits % 2) == 1;
+}
+#else
+/* true if the point is inside the target mesh */
+static bool haircut_test_point(HaircutCacheModifier *hmd, HaircutCacheData *data, HaircutCach

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list