[Bf-blender-cvs] [6074f62d1a0] master: Fix T61353: Crash converting a curve to a mesh

Campbell Barton noreply at git.blender.org
Thu Feb 14 07:32:43 CET 2019


Commit: 6074f62d1a099fc378aa25506a93321dba2d956b
Author: Campbell Barton
Date:   Thu Feb 14 17:21:55 2019 +1100
Branches: master
https://developer.blender.org/rB6074f62d1a099fc378aa25506a93321dba2d956b

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.

===================================================================

M	source/blender/blenkernel/BKE_curve.h
M	source/blender/blenkernel/BKE_displist.h
M	source/blender/blenkernel/intern/curve.c
M	source/blender/blenkernel/intern/displist.c
M	source/blender/blenkernel/intern/effect.c
M	source/blender/blenkernel/intern/mesh_convert.c
M	source/blender/blenkernel/intern/object_update.c
M	source/blender/editors/curve/editcurve.c
M	source/blender/editors/object/object_add.c
M	source/blender/editors/object/object_modifier.c
M	source/blender/editors/object/object_relations.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index 236c5e8da06..fe8f9ace134 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -27,6 +27,7 @@ struct Curve;
 struct Depsgraph;
 struct EditNurb;
 struct GHash;
+struct LinkNode;
 struct ListBase;
 struct Main;
 struct Nurb;
@@ -119,7 +120,8 @@ void BKE_curve_bevelList_free(struct ListBase *bev);
 void BKE_curve_bevelList_make(struct Object *ob, struct ListBase *nurbs, bool for_render);
 void BKE_curve_bevel_make(
         struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob,  struct ListBase *disp,
-        const bool for_render, const bool use_render_resolution);
+        const bool for_render, const bool use_render_resolution,
+        struct LinkNode *ob_cyclic_list);
 
 void BKE_curve_forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride);
 void BKE_curve_forward_diff_tangent_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride);
diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h
index 3f9589ae341..c232234dd62 100644
--- a/source/blender/blenkernel/BKE_displist.h
+++ b/source/blender/blenkernel/BKE_displist.h
@@ -49,6 +49,7 @@ enum {
 /* prototypes */
 
 struct Depsgraph;
+struct LinkNode;
 struct ListBase;
 struct Main;
 struct Mesh;
@@ -83,12 +84,15 @@ void BKE_displist_make_surf(
         struct Mesh **r_final, const bool for_render, const bool for_orco, const bool use_render_resolution);
 void BKE_displist_make_curveTypes(
         struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob,
-        const bool for_render, const bool for_orco);
+        const bool for_render, const bool for_orco,
+        struct LinkNode *ob_cyclic_list);
 void BKE_displist_make_curveTypes_forRender(
         struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct ListBase *dispbase,
-        struct Mesh **r_final, const bool for_orco, const bool use_render_resolution);
+        struct Mesh **r_final, const bool for_orco, const bool use_render_resolution,
+        struct LinkNode *ob_cyclic_list);
 void BKE_displist_make_curveTypes_forOrco(
-        struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct ListBase *dispbase);
+        struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct ListBase *dispbase,
+        struct LinkNode *ob_cyclic_list);
 void BKE_displist_make_mball(
         struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob);
 void BKE_displist_make_mball_forRender(
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 8bb47a6a69b..3be101134ec 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -31,6 +31,7 @@
 #include "BLI_math.h"
 #include "BLI_utildefines.h"
 #include "BLI_ghash.h"
+#include "BLI_linklist.h"
 
 #include "DNA_anim_types.h"
 #include "DNA_curve_types.h"
@@ -1735,7 +1736,7 @@ float *BKE_curve_make_orco(Depsgraph *depsgraph, Scene *scene, Object *ob, int *
 	float *fp, *coord_array;
 	ListBase disp = {NULL, NULL};
 
-	BKE_displist_make_curveTypes_forOrco(depsgraph, scene, ob, &disp);
+	BKE_displist_make_curveTypes_forOrco(depsgraph, scene, ob, &disp, NULL);
 
 	numVerts = 0;
 	for (dl = disp.first; dl; dl = dl->next) {
@@ -1828,7 +1829,8 @@ float *BKE_curve_make_orco(Depsgraph *depsgraph, Scene *scene, Object *ob, int *
 
 void BKE_curve_bevel_make(
         Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *disp,
-        const bool for_render, const bool use_render_resolution)
+        const bool for_render, const bool use_render_resolution,
+        LinkNode *ob_cyclic_list)
 {
 	DispList *dl, *dlnew;
 	Curve *bevcu, *cu;
@@ -1852,8 +1854,15 @@ void BKE_curve_bevel_make(
 			facy = cu->bevobj->size[1];
 
 			if (for_render) {
-				BKE_displist_make_curveTypes_forRender(depsgraph, scene, cu->bevobj, &bevdisp, NULL, false, use_render_resolution);
-				dl = bevdisp.first;
+				if (BLI_linklist_index(ob_cyclic_list, cu->bevobj) == -1) {
+					BKE_displist_make_curveTypes_forRender(
+					        depsgraph, scene, cu->bevobj, &bevdisp, NULL, false, use_render_resolution,
+					        &(LinkNode){ .link = ob, .next = ob_cyclic_list, });
+					dl = bevdisp.first;
+				}
+				else {
+					dl = NULL;
+				}
 			}
 			else if (cu->bevobj->runtime.curve_cache) {
 				dl = cu->bevobj->runtime.curve_cache->disp.first;
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])
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index d10aafdc513..c3e9afcca1e 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -158,7 +158,7 @@ static void precalculate_effector(struct Depsgraph *depsgraph, EffectorCache *ef
 		Curve *cu = eff->ob->data;
 		if (cu->flag & CU_PATH) {
 			if (eff->ob->runtime.curve_cache == NULL || eff->ob->runtime.curve_cache->path == NULL || eff->ob->runtime.curve_cache->path->data == NULL)
-				BKE_displist_make_curveTypes(depsgraph, eff->scene, eff->ob, false, false);
+				BKE_displist_make_curveTypes(depsgraph, eff->scene, eff->ob, false, false, NULL);
 
 			if (eff->ob->runtime.curve_cache->path && eff->ob->runtime.curve_cache->path->data) {
 				where_on_path(eff->ob, 0.0, eff->guide_loc, eff->guide_dir, NULL, &eff->guide_radius, NULL);
diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c
index 3e7d51716a1..ded0982c2da 100644
--- a/source/blender/blenkernel/intern/mesh_convert.c
+++ b/source/blender/blenkernel/intern/mesh_convert.c
@@ -896,7 +896,9 @@ Mesh *BKE_mesh_new_from_object(
 			copycu->editnurb = tmpcu->editnurb;
 
 			/* get updated display list, and convert to a mesh */
-			BKE_displist_make_curveTypes_forRender(depsgraph, sce, tmpobj, &dispbase, &me_eval_final, false, render);
+			BKE_displist_make_curveTypes_forRender(
+			        depsgraph, sce, tmpobj, &dispbase, &me_eval_final, false, render,
+			        NULL);
 
 			copycu->editfont = NULL;
 			copycu->editnurb = NULL;
diff --git a/source

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list