Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2020-04-30 16:46:45 +0300
committerClément Foucault <foucault.clem@gmail.com>2020-05-01 01:03:28 +0300
commit4d790516fbf85e1d8909d09ebd7769a7d8bf34b3 (patch)
treecffc0d30b9d4dbf0dd3cdc601fbb6feccf605c5a
parent03f4d20bcf7f1819f31aa78315a7e8358928ca68 (diff)
Curve: Force pretesselate modifier to output a Mesh output
This is to improve the case of T71055 where curves share the same batch cache when they shouldn't. This however, does not help to fix edit mode display. The real fix would be to have a similar handling to what the mesh modifiers do and duplicate the whole Curve data. But this is too much work/change for the 2.83 release. Reviewed By: sergey Differential Revision: https://developer.blender.org/D7569
-rw-r--r--source/blender/blenkernel/intern/displist.c37
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) {