[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 = ®ion->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(®ion->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 = ®ion->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