[Bf-blender-cvs] [bb0fae907f0] hair_guides_grooming: Use eval mesh for the scalp consistently, never directly access scalp_object->data.

Lukas Tönne noreply at git.blender.org
Thu Jun 7 21:03:32 CEST 2018


Commit: bb0fae907f0617f667fbe1604be973a92b32e904
Author: Lukas Tönne
Date:   Thu Jun 7 20:02:54 2018 +0100
Branches: hair_guides_grooming
https://developer.blender.org/rBbb0fae907f0617f667fbe1604be973a92b32e904

Use eval mesh for the scalp consistently, never directly access scalp_object->data.

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

M	source/blender/blenkernel/BKE_groom.h
M	source/blender/blenkernel/BKE_hair.h
M	source/blender/blenkernel/intern/groom.c
M	source/blender/blenkernel/intern/hair.c
M	source/blender/draw/engines/eevee/eevee_materials.c
M	source/blender/draw/modes/object_mode.c
M	source/blender/editors/groom/editgroom.c
M	source/blender/editors/groom/editgroom_region.c
M	source/blender/editors/groom/groom_hair.c
M	source/blender/editors/include/ED_groom.h
M	source/blender/makesrna/intern/rna_groom.c

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

diff --git a/source/blender/blenkernel/BKE_groom.h b/source/blender/blenkernel/BKE_groom.h
index ef9be249897..415c9feedab 100644
--- a/source/blender/blenkernel/BKE_groom.h
+++ b/source/blender/blenkernel/BKE_groom.h
@@ -60,32 +60,42 @@ struct BoundBox *BKE_groom_boundbox_get(struct Object *ob);
 
 /* === Curve cache === */
 
-void BKE_groom_curve_cache_update(struct Groom *groom, const struct Mesh *scalp);
+void BKE_groom_curve_cache_update(const struct Depsgraph *depsgraph, struct Groom *groom);
 void BKE_groom_curve_cache_clear(struct Groom *groom);
 
 
 /* === Scalp regions === */
 
+struct Mesh* BKE_groom_get_scalp(const struct Depsgraph *depsgraph, struct Groom *groom);
+
+/* Set the region's facemap name.
+ * Returns false if no facemap of that name can be found in the scalp object.
+ */
+bool BKE_groom_set_region_scalp_facemap(struct Groom *groom, struct GroomRegion *region, const char *facemap_name);
+
 /* Try to bind bundles to their scalp regions */
-void BKE_groom_bind_scalp_regions(struct Groom *groom, bool force_rebind);
+void BKE_groom_bind_scalp_regions(const struct Depsgraph *depsgraph, struct Groom *groom, bool force_rebind);
 
-bool BKE_groom_region_bind(struct Groom *groom, struct GroomRegion *region, bool force_rebind);
+bool BKE_groom_region_bind(const struct Depsgraph *depsgraph, struct Groom *groom, struct GroomRegion *region, bool force_rebind);
 void BKE_groom_region_unbind(struct GroomRegion *region);
 
+/* Calculates the scalp orientation at the root of the region */
+bool BKE_groom_calc_region_transform_on_scalp(const struct GroomRegion *region, const struct Mesh *scalp, float r_loc[3], float r_rot[3][3]);
+
 
 /* === Constraints === */
 
 /* Apply constraints on groom geometry */
-void BKE_groom_apply_constraints(struct Groom *groom, struct Mesh *scalp);
+void BKE_groom_apply_constraints(const struct Depsgraph *depsgraph, struct Groom *groom);
 
 
 /* === Hair System === */
 
 /* Create follicles on the scalp surface for hair fiber rendering */
-void BKE_groom_hair_distribute(struct Groom *groom, unsigned int seed, int hair_count);
+void BKE_groom_hair_distribute(const struct Depsgraph *depsgraph, struct Groom *groom, unsigned int seed, int hair_count);
 
 /* Calculate guide curve shapes based on groom bundle deformation */
-void BKE_groom_hair_update_guide_curves(struct Groom *groom);
+void BKE_groom_hair_update_guide_curves(const struct Depsgraph *depsgraph, struct Groom *groom);
 
 
 /* === Depsgraph evaluation === */
@@ -128,7 +138,4 @@ typedef struct GroomIterator
 		     iter.isectionvertex < (bundle)->numloopverts; \
 		     ++iter.isectionvertex, ++iter.vertex)
 
-/* === Utility functions === */
-struct Mesh* BKE_groom_get_scalp(struct Groom *groom);
-
 #endif /*  __BKE_GROOM_H__ */
diff --git a/source/blender/blenkernel/BKE_hair.h b/source/blender/blenkernel/BKE_hair.h
index 1f74caa79e0..be27b02c8c8 100644
--- a/source/blender/blenkernel/BKE_hair.h
+++ b/source/blender/blenkernel/BKE_hair.h
@@ -117,7 +117,7 @@ void BKE_hair_generate_follicles_ex(
         int count,
         const float *loop_weights);
 
-void BKE_hair_bind_follicles(struct HairSystem *hsys, struct Mesh *scalp);
+void BKE_hair_bind_follicles(struct HairSystem *hsys, const struct Mesh *scalp);
 
 /* === Draw Settings === */
 
diff --git a/source/blender/blenkernel/intern/groom.c b/source/blender/blenkernel/intern/groom.c
index 61060de42b9..0aec6fc0da0 100644
--- a/source/blender/blenkernel/intern/groom.c
+++ b/source/blender/blenkernel/intern/groom.c
@@ -295,26 +295,57 @@ void BKE_groom_boundbox_calc(Groom *groom)
 
 /* === Scalp regions === */
 
-void BKE_groom_bind_scalp_regions(Groom *groom, bool force_rebind)
+Mesh* BKE_groom_get_scalp(const Depsgraph *depsgraph, Groom *groom)
+{
+	if (groom->scalp_object)
+	{
+		BLI_assert(groom->scalp_object->type == OB_MESH);
+		return (Mesh *)DEG_get_evaluated_id(depsgraph, groom->scalp_object->data);
+	}
+	return NULL;
+}
+
+/* Set the region's facemap name.
+ * Returns false if no facemap of that name can be found in the scalp object.
+ */
+bool BKE_groom_set_region_scalp_facemap(Groom *groom, GroomRegion *region, const char *facemap_name)
+{
+	if (groom->scalp_object && facemap_name)
+	{
+		bFaceMap *fm = BKE_object_facemap_find_name(groom->scalp_object, facemap_name);
+		if (fm) {
+			/* no need for BLI_strncpy_utf8, since this matches an existing facemap */
+			BLI_strncpy(region->scalp_facemap_name, facemap_name, sizeof(region->scalp_facemap_name));
+			return true;
+		}
+	}
+	
+	region->scalp_facemap_name[0] = '\0';
+	/* Unbind the region */
+	BKE_groom_region_unbind(region);
+	return false;
+}
+
+void BKE_groom_bind_scalp_regions(const Depsgraph *depsgraph, Groom *groom, bool force_rebind)
 {
 	if (groom->editgroom)
 	{
 		for (GroomRegion *region = groom->editgroom->regions.first; region; region = region->next)
 		{
-			BKE_groom_region_bind(groom, region, force_rebind);
+			BKE_groom_region_bind(depsgraph, groom, region, force_rebind);
 		}
 	}
 	else
 	{
 		for (GroomRegion *region = groom->regions.first; region; region = region->next)
 		{
-			BKE_groom_region_bind(groom, region, force_rebind);
+			BKE_groom_region_bind(depsgraph, groom, region, force_rebind);
 		}
 	}
 }
 
-/* Returns the transform at the root of the bundle */
-static bool groom_get_region_transform_on_scalp(const GroomRegion *region, const Mesh *scalp, float r_loc[3], float r_rot[3][3])
+/* Calculates the scalp orientation at the root of the region */
+bool BKE_groom_calc_region_transform_on_scalp(const GroomRegion *region, const Mesh *scalp, float r_loc[3], float r_rot[3][3])
 {
 	const int numverts = region->numverts;
 	if (numverts == 0 || region->scalp_samples == NULL)
@@ -338,21 +369,18 @@ static bool groom_get_region_transform_on_scalp(const GroomRegion *region, const
 	}
 }
 
-static bool groom_shape_rebuild(GroomRegion *region, Object *scalp_ob)
+static bool groom_shape_rebuild(GroomRegion *region, const Mesh *scalp)
 {
 	GroomBundle *bundle = &region->bundle;
 	BLI_assert(region->scalp_samples != NULL);
-	BLI_assert(scalp_ob->type == OB_MESH);
 	const int numshapeverts = region->numverts;
 	
 	bool result = true;
 	float (*shape)[2] = MEM_mallocN(sizeof(*shape) * numshapeverts, "groom section shape");
 	
-	Mesh *me = scalp_ob->data;
-	
 	float center_loc[3];
 	float center_mat[3][3];
-	if (!groom_get_region_transform_on_scalp(region, me, center_loc, center_mat))
+	if (!BKE_groom_calc_region_transform_on_scalp(region, scalp, center_loc, center_mat))
 	{
 		result = false;
 		goto cleanup;
@@ -364,7 +392,7 @@ static bool groom_shape_rebuild(GroomRegion *region, Object *scalp_ob)
 	{
 		/* 3D position of the shape vertex origin on the mesh */
 		float co[3], nor[3], tang[3];
-		if (!BKE_mesh_sample_eval(me, sample, co, nor, tang))
+		if (!BKE_mesh_sample_eval(scalp, sample, co, nor, tang))
 		{
 			result = false;
 			goto cleanup;
@@ -412,21 +440,24 @@ static BMesh *groom_create_scalp_bmesh(Mesh *me)
 	return bm;
 }
 
-static bool groom_region_from_mesh_fmap(GroomRegion *region, Object *scalp_ob)
+static bool groom_region_from_mesh_fmap(const Depsgraph *depsgraph, Groom *groom, GroomRegion *region)
 {
-	BLI_assert(scalp_ob->type == OB_MESH);
+	Mesh *scalp = BKE_groom_get_scalp(depsgraph, groom);
+	if (!scalp)
+	{
+		return false;
+	}
 	
 	BKE_groom_bundle_curve_cache_clear(&region->bundle);
 	
-	Mesh *me = scalp_ob->data;
-	const int scalp_fmap_nr = BKE_object_facemap_name_index(scalp_ob, region->scalp_facemap_name);
-	const int cd_fmap_offset = CustomData_get_offset(&me->pdata, CD_FACEMAP);
+	const int scalp_fmap_nr = BKE_object_facemap_name_index(groom->scalp_object, region->scalp_facemap_name);
+	const int cd_fmap_offset = CustomData_get_offset(&scalp->pdata, CD_FACEMAP);
 	if (scalp_fmap_nr < 0 || cd_fmap_offset < 0)
 	{
 		return false;
 	}
 	
-	BMesh *bm = groom_create_scalp_bmesh(me);
+	BMesh *bm = groom_create_scalp_bmesh(scalp);
 	bool result = true;
 	
 	/* Tag faces in the face map for the BMO walker */
@@ -481,7 +512,7 @@ static bool groom_region_from_mesh_fmap(GroomRegion *region, Object *scalp_ob)
 	{
 		/* BVH tree for binding the region center location */
 		BVHTreeFromMesh bvhtree;
-		BKE_bvhtree_from_mesh_get(&bvhtree, me, BVHTREE_FROM_LOOPTRI, 2);
+		BKE_bvhtree_from_mesh_get(&bvhtree, scalp, BVHTREE_FROM_LOOPTRI, 2);
 		if (bvhtree.tree != NULL) {
 			BVHTreeNearest nearest;
 			nearest.index = -1;
@@ -492,7 +523,7 @@ static bool groom_region_from_mesh_fmap(GroomRegion *region, Object *scalp_ob)
 			{
 				/* last sample is the center position */
 				MeshSample *center_sample = &region->scalp_samples[numverts];
-				BKE_mesh_sample_weights_from_loc(center_sample, me, nearest.index, nearest.co);
+				BKE_mesh_sample_weights_from_loc(center_sample, scalp, nearest.index, nearest.co);
 				BLI_assert(BKE_mesh_sample_is_valid(center_sample));
 			}
 		}
@@ -507,7 +538,7 @@ static bool groom_region_from_mesh_fmap(GroomRegion *region, Object *scalp_ob)
 finalize:
 	if (result == true)
 	{
-		groom_shape_rebuild(region, scalp_ob);
+		groom_shape_rebuild(region, scalp);
 	}
 	else
 	{
@@ -524,27 +555,24 @@ finalize:
 	return result;
 }
 
-bool BKE_groom_region_bind(Groom *groom, GroomRegion *region, bool force_rebind)
+bool BKE_groom_region_bind(const Depsgraph *depsgraph, Groom *groom, GroomRegion *region, bool force_rebind)
 {
-	if (region->scalp_samples && !force_rebind)
+	bool has_facemap = (groom->scalp_object &&
+	                    BKE_object_facemap_find_name(groom->scalp_object, region->scalp_facemap_name));
+	
+	if (has_facemap && region->scalp_samples && !force_rebind)
 	{
 		return true;
 	}
 	
 	BKE_groom_region_unbind(region);
-	if (!groom->scalp_object)
-	{
-		return false;
-	}
-	if (!BKE_object_facemap_find_name(groom->scalp_object, region->scalp_facemap_name))
+	
+	if (!has_facemap)
 	{
 		return false;
 	}
 	
-	if (groom->scalp_object->type == OB_MESH)
-	{
-		groom_region_from_mesh_fmap(region, groom->scalp_object);
-	}
+	groom_region_from_mesh_fmap(depsgraph, groom, region);
 	
 	return (region->scalp_samples != NULL);
 }
@@ -562,8 +590,10 @@ void BKE_groom_region_unbind(GroomRegion *region)
 /* === Constraints === */
 
 /* Apply constraints on groom geometry */
-void BKE_groom_ap

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list