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:
authorCampbell Barton <ideasman42@gmail.com>2019-02-14 09:21:55 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-02-14 09:21:55 +0300
commit6074f62d1a099fc378aa25506a93321dba2d956b (patch)
treebecbb4abdb6c9c9a047c1a6f5d5c94c53e56ff50 /source/blender/blenkernel
parentcaa8e7ff2894ed22ea436bc61b06fb292d844108 (diff)
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.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_curve.h4
-rw-r--r--source/blender/blenkernel/BKE_displist.h10
-rw-r--r--source/blender/blenkernel/intern/curve.c17
-rw-r--r--source/blender/blenkernel/intern/displist.c36
-rw-r--r--source/blender/blenkernel/intern/effect.c2
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.c4
-rw-r--r--source/blender/blenkernel/intern/object_update.c2
7 files changed, 54 insertions, 21 deletions
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/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index 4975bc3bafb..59068dc4cd5 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -202,7 +202,7 @@ void BKE_object_handle_data_update(
case OB_CURVE:
case OB_SURF:
case OB_FONT:
- BKE_displist_make_curveTypes(depsgraph, scene, ob, false, false);
+ BKE_displist_make_curveTypes(depsgraph, scene, ob, false, false, NULL);
break;
case OB_LATTICE: