diff options
-rw-r--r-- | source/blender/blenkernel/intern/displist.c | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index a18579f9402..d35dc32738b 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -848,7 +848,8 @@ static ModifierData *curve_get_tessellate_point(Scene *scene, return pretessellatePoint; } -static void curve_calc_modifiers_pre( +/* Return true if any modifier was applied. */ +static bool curve_calc_modifiers_pre( Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *nurb, const bool for_render) { VirtualModifierData virtualModifierData; @@ -861,6 +862,7 @@ static void curve_calc_modifiers_pre( float(*deformedVerts)[3] = NULL; float *keyVerts = NULL; int required_mode; + bool modified = false; modifiers_clearErrors(ob); @@ -913,6 +915,7 @@ static void curve_calc_modifiers_pre( } mti->deformVerts(md, &mectx, NULL, deformedVerts, numVerts); + modified = true; if (md == pretessellatePoint) { break; @@ -931,6 +934,7 @@ static void curve_calc_modifiers_pre( if (keyVerts) { MEM_freeN(keyVerts); } + return modified; } static float (*displist_vert_coords_alloc(ListBase *dispbase, int *r_vert_len))[3] @@ -974,7 +978,8 @@ static void curve_calc_modifiers_post(Depsgraph *depsgraph, ListBase *nurb, ListBase *dispbase, Mesh **r_final, - const bool for_render) + const bool for_render, + const bool force_mesh_conversion) { VirtualModifierData virtualModifierData; ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData); @@ -1128,6 +1133,22 @@ static void curve_calc_modifiers_post(Depsgraph *depsgraph, } if (r_final) { + if (force_mesh_conversion && !modified) { + /* XXX 2.8 : This is a workaround for by some deeper technical depts: + * - DRW Batch cache is stored inside the ob->data. + * - Curve data is not COWed for instances that use different modifiers. + * This can causes the modifiers to be applied on all user of the same datablock (see T71055) + * + * The easy workaround is to force to generate a Mesh that will be used for display data + * since a Mesh output is already used for generative modifiers. + * However it does not fix problems with actual edit data still being shared. + * + * The right solution would be to COW the Curve data block at the input of the modifer stack + * just like what the mesh modifier does. + * */ + modified = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase); + } + if (modified) { /* XXX2.8(Sybren): make sure the face normals are recalculated as well */ @@ -1202,6 +1223,7 @@ void BKE_displist_make_surf(Depsgraph *depsgraph, DispList *dl; float *data; int len; + bool force_mesh_conversion = false; if (!for_render && cu->editnurb) { BKE_nurbList_duplicate(&nubase, BKE_curve_editNurbs_get(cu)); @@ -1211,7 +1233,7 @@ void BKE_displist_make_surf(Depsgraph *depsgraph, } if (!for_orco) { - curve_calc_modifiers_pre(depsgraph, scene, ob, &nubase, for_render); + force_mesh_conversion = curve_calc_modifiers_pre(depsgraph, scene, ob, &nubase, for_render); } for (nu = nubase.first; nu; nu = nu->next) { @@ -1289,7 +1311,8 @@ void BKE_displist_make_surf(Depsgraph *depsgraph, if (!for_orco) { BKE_nurbList_duplicate(&ob->runtime.curve_cache->deformed_nurbs, &nubase); - curve_calc_modifiers_post(depsgraph, scene, ob, &nubase, dispbase, r_final, for_render); + curve_calc_modifiers_post( + depsgraph, scene, ob, &nubase, dispbase, r_final, for_render, force_mesh_conversion); } BKE_nurbList_free(&nubase); @@ -1537,6 +1560,7 @@ static void do_makeDispListCurveTypes(Depsgraph *depsgraph, else if (ELEM(ob->type, OB_CURVE, OB_FONT)) { ListBase dlbev; ListBase nubase = {NULL, NULL}; + bool force_mesh_conversion = false; BKE_curve_bevelList_free(&ob->runtime.curve_cache->bev); @@ -1559,7 +1583,7 @@ static void do_makeDispListCurveTypes(Depsgraph *depsgraph, } if (!for_orco) { - curve_calc_modifiers_pre(depsgraph, scene, ob, &nubase, for_render); + force_mesh_conversion = curve_calc_modifiers_pre(depsgraph, scene, ob, &nubase, for_render); } BKE_curve_bevelList_make(ob, &nubase, for_render); @@ -1769,7 +1793,8 @@ static void do_makeDispListCurveTypes(Depsgraph *depsgraph, if (!for_orco) { BKE_nurbList_duplicate(&ob->runtime.curve_cache->deformed_nurbs, &nubase); - curve_calc_modifiers_post(depsgraph, scene, ob, &nubase, dispbase, r_final, for_render); + curve_calc_modifiers_post( + depsgraph, scene, ob, &nubase, dispbase, r_final, for_render, force_mesh_conversion); } if (cu->flag & CU_DEFORM_FILL && !ob->runtime.data_eval) { |