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. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs