From 6074f62d1a099fc378aa25506a93321dba2d956b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 Feb 2019 17:21:55 +1100 Subject: Fix T61353: Crash converting a curve to a mesh This was caused by curves pointing to each other creating a cyclic dependency. While the dependency graph detects this, generating a mesh for render recursively generates data which cashes in this case. Add in a check to detect cyclic links. Note, this bug exists in 2.7x too - but only crashes on render since 2.7x didn't use 'for_render' when converting data. --- source/blender/blenkernel/intern/displist.c | 36 +++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 10 deletions(-) (limited to 'source/blender/blenkernel/intern/displist.c') diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 869d5e6f362..0f3a3192d75 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -38,6 +38,7 @@ #include "BLI_math.h" #include "BLI_scanfill.h" #include "BLI_utildefines.h" +#include "BLI_linklist.h" #include "BKE_displist.h" #include "BKE_cdderivedmesh.h" @@ -683,7 +684,7 @@ static float displist_calc_taper(Depsgraph *depsgraph, Scene *scene, Object *tap dl = taperobj->runtime.curve_cache ? taperobj->runtime.curve_cache->disp.first : NULL; if (dl == NULL) { - BKE_displist_make_curveTypes(depsgraph, scene, taperobj, false, false); + BKE_displist_make_curveTypes(depsgraph, scene, taperobj, false, false, NULL); dl = taperobj->runtime.curve_cache->disp.first; } if (dl) { @@ -1554,8 +1555,9 @@ static void calc_bevfac_mapping(Curve *cu, BevList *bl, Nurb *nu, static void do_makeDispListCurveTypes( Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *dispbase, - Mesh **r_final, - const bool for_render, const bool for_orco, const bool use_render_resolution) + const bool for_render, const bool for_orco, const bool use_render_resolution, + LinkNode *ob_cyclic_list, + Mesh **r_final) { Curve *cu = ob->data; @@ -1593,7 +1595,9 @@ static void do_makeDispListCurveTypes( BKE_curve_bevelList_make(ob, &nubase, use_render_resolution); /* If curve has no bevel will return nothing */ - BKE_curve_bevel_make(depsgraph, scene, ob, &dlbev, for_render, use_render_resolution); + BKE_curve_bevel_make( + depsgraph, scene, ob, &dlbev, for_render, use_render_resolution, + ob_cyclic_list); /* no bevel or extrude, and no width correction? */ if (!dlbev.first && cu->width == 1.0f) { @@ -1801,7 +1805,8 @@ static void do_makeDispListCurveTypes( } void BKE_displist_make_curveTypes( - Depsgraph *depsgraph, Scene *scene, Object *ob, const bool for_render, const bool for_orco) + Depsgraph *depsgraph, Scene *scene, Object *ob, const bool for_render, const bool for_orco, + LinkNode *ob_cyclic_list) { ListBase *dispbase; @@ -1819,7 +1824,10 @@ void BKE_displist_make_curveTypes( dispbase = &(ob->runtime.curve_cache->disp); - do_makeDispListCurveTypes(depsgraph, scene, ob, dispbase, &ob->runtime.mesh_eval, for_render, for_orco, false); + do_makeDispListCurveTypes( + depsgraph, scene, ob, dispbase, for_render, for_orco, false, + ob_cyclic_list, + &ob->runtime.mesh_eval); boundbox_displist_object(ob); } @@ -1827,23 +1835,31 @@ void BKE_displist_make_curveTypes( void BKE_displist_make_curveTypes_forRender( Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *dispbase, Mesh **r_final, const bool for_orco, - const bool use_render_resolution) + const bool use_render_resolution, + LinkNode *ob_cyclic_list) { if (ob->runtime.curve_cache == NULL) { ob->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for Curve"); } - do_makeDispListCurveTypes(depsgraph, scene, ob, dispbase, r_final, true, for_orco, use_render_resolution); + do_makeDispListCurveTypes( + depsgraph, scene, ob, dispbase, true, for_orco, use_render_resolution, + ob_cyclic_list, + r_final); } void BKE_displist_make_curveTypes_forOrco( - Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *dispbase) + Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *dispbase, + LinkNode *ob_cyclic_list) { if (ob->runtime.curve_cache == NULL) { ob->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for Curve"); } - do_makeDispListCurveTypes(depsgraph, scene, ob, dispbase, NULL, 1, 1, 1); + do_makeDispListCurveTypes( + depsgraph, scene, ob, dispbase, 1, 1, 1, + ob_cyclic_list, + NULL); } void BKE_displist_minmax(ListBase *dispbase, float min[3], float max[3]) -- cgit v1.2.3