From 6d64da1e67e319e826450cefc1f6541b0fbb57e9 Mon Sep 17 00:00:00 2001 From: Sebastian Parborg Date: Fri, 23 Aug 2019 15:50:53 +0200 Subject: Fix potential issues when loading files with missing libraries This is a continuation of rB39f005eae8eed8b939579aff8c9a05a4f50e5e38 Now all the fields where we check for object type in RNA (like rna_Curve_object_poll) will have a safe guard for when this isn't the case. For example when loading files that has missing object libraries and all missing objects are replaced with empties (placeholders). Reviewed By: Brecht Differential Revision: http://developer.blender.org/D5425 --- source/blender/editors/object/object_constraint.c | 12 +++++-- .../gpencil_modifiers/intern/MOD_gpencilarmature.c | 7 +++- .../gpencil_modifiers/intern/MOD_gpencillattice.c | 7 +++- source/blender/modifiers/intern/MOD_armature.c | 2 +- source/blender/modifiers/intern/MOD_array.c | 42 ++++++++++++++++------ source/blender/modifiers/intern/MOD_boolean.c | 7 +++- source/blender/modifiers/intern/MOD_curve.c | 7 +++- source/blender/modifiers/intern/MOD_datatransfer.c | 9 +++-- source/blender/modifiers/intern/MOD_lattice.c | 7 +++- source/blender/modifiers/intern/MOD_mask.c | 16 ++++++++- source/blender/modifiers/intern/MOD_meshdeform.c | 7 +++- .../modifiers/intern/MOD_particleinstance.c | 7 +++- source/blender/modifiers/intern/MOD_shrinkwrap.c | 14 +++++++- .../blender/modifiers/intern/MOD_surfacedeform.c | 8 ++++- 14 files changed, 127 insertions(+), 25 deletions(-) (limited to 'source') diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index c780ae4cf8c..14813f9a936 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -493,8 +493,12 @@ static void test_constraint( CONSTRAINT_TYPE_CLAMPTO, CONSTRAINT_TYPE_SPLINEIK)) { if (ct->tar) { + /* The object type check is only needed here in case we have a placeholder + * object assigned (because the library containing the curve is missing). + * + * In other cases it should be impossible to have a type missmatch. + */ if (ct->tar->type != OB_CURVE) { - ct->tar = NULL; con->flag |= CONSTRAINT_DISABLE; } else { @@ -507,8 +511,12 @@ static void test_constraint( } else if (con->type == CONSTRAINT_TYPE_ARMATURE) { if (ct->tar) { + /* The object type check is only needed here in case we have a placeholder + * object assigned (because the library containing the armature is missing). + * + * In other cases it should be impossible to have a type missmatch. + */ if (ct->tar->type != OB_ARMATURE) { - ct->tar = NULL; con->flag |= CONSTRAINT_DISABLE; } else if (!BKE_armature_find_bone_name(BKE_armature_from_object(ct->tar), diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c index 4297cbb545c..acf9b5c3642 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c @@ -155,7 +155,12 @@ static bool isDisabled(GpencilModifierData *md, int UNUSED(userRenderParams)) { ArmatureGpencilModifierData *mmd = (ArmatureGpencilModifierData *)md; - return !mmd->object; + /* The object type check is only needed here in case we have a placeholder + * object assigned (because the library containing the armature is missing). + * + * In other cases it should be impossible to have a type missmatch. + */ + return !mmd->object || mmd->object->type != OB_ARMATURE; } static void updateDepsgraph(GpencilModifierData *md, const ModifierUpdateDepsgraphContext *ctx) diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c index d5295fc7306..765967d8346 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c @@ -169,7 +169,12 @@ static bool isDisabled(GpencilModifierData *md, int UNUSED(userRenderParams)) { LatticeGpencilModifierData *mmd = (LatticeGpencilModifierData *)md; - return !mmd->object; + /* The object type check is only needed here in case we have a placeholder + * object assigned (because the library containing the lattice is missing). + * + * In other cases it should be impossible to have a type missmatch. + */ + return !mmd->object || mmd->object->type != OB_LATTICE; } static void updateDepsgraph(GpencilModifierData *md, const ModifierUpdateDepsgraphContext *ctx) diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c index 7ae5fda7111..522b387411b 100644 --- a/source/blender/modifiers/intern/MOD_armature.c +++ b/source/blender/modifiers/intern/MOD_armature.c @@ -82,7 +82,7 @@ static bool isDisabled(const struct Scene *UNUSED(scene), /* The object type check is only needed here in case we have a placeholder * object assigned (because the library containing the armature is missing). * - * In other cases it should be impossible. + * In other cases it should be impossible to have a type missmatch. */ return !amd->object || amd->object->type != OB_ARMATURE; } diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index fd6f58a21d4..48718a47419 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -395,7 +395,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, count = amd->count; Object *start_cap_ob = amd->start_cap; - if (start_cap_ob && start_cap_ob != ctx->object && start_cap_ob->type == OB_MESH) { + if (start_cap_ob && start_cap_ob != ctx->object) { vgroup_start_cap_remap = BKE_object_defgroup_index_map_create( start_cap_ob, ctx->object, &vgroup_start_cap_remap_len); @@ -408,7 +408,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, } } Object *end_cap_ob = amd->end_cap; - if (end_cap_ob && end_cap_ob != ctx->object && end_cap_ob->type == OB_MESH) { + if (end_cap_ob && end_cap_ob != ctx->object) { vgroup_end_cap_remap = BKE_object_defgroup_index_map_create( end_cap_ob, ctx->object, &vgroup_end_cap_remap_len); @@ -465,13 +465,10 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, if (amd->fit_type == MOD_ARR_FITCURVE && amd->curve_ob != NULL) { Object *curve_ob = amd->curve_ob; - Curve *cu = curve_ob->data; - if (cu) { - CurveCache *curve_cache = curve_ob->runtime.curve_cache; - if (curve_cache != NULL && curve_cache->path != NULL) { - float scale_fac = mat4_to_scale(curve_ob->obmat); - length = scale_fac * curve_cache->path->totdist; - } + CurveCache *curve_cache = curve_ob->runtime.curve_cache; + if (curve_cache != NULL && curve_cache->path != NULL) { + float scale_fac = mat4_to_scale(curve_ob->obmat); + length = scale_fac * curve_cache->path->totdist; } } @@ -769,6 +766,31 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes return arrayModifier_doArray(amd, ctx, mesh); } +static bool isDisabled(const struct Scene *UNUSED(scene), + ModifierData *md, + bool UNUSED(useRenderParams)) +{ + ArrayModifierData *amd = (ArrayModifierData *)md; + + /* The object type check is only needed here in case we have a placeholder + * object assigned (because the library containing the curve/mesh is missing). + * + * In other cases it should be impossible to have a type missmatch. + */ + + if (amd->curve_ob && amd->curve_ob->type != OB_CURVE) { + return true; + } + else if (amd->start_cap && amd->start_cap->type != OB_MESH) { + return true; + } + else if (amd->end_cap && amd->end_cap->type != OB_MESH) { + return true; + } + + return false; +} + ModifierTypeInfo modifierType_Array = { /* name */ "Array", /* structName */ "ArrayModifierData", @@ -789,7 +811,7 @@ ModifierTypeInfo modifierType_Array = { /* initData */ initData, /* requiredDataMask */ NULL, /* freeData */ NULL, - /* isDisabled */ NULL, + /* isDisabled */ isDisabled, /* updateDepsgraph */ updateDepsgraph, /* dependsOnTime */ NULL, /* dependsOnNormals */ NULL, diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c index dc4898c83ff..ea42ddb03f4 100644 --- a/source/blender/modifiers/intern/MOD_boolean.c +++ b/source/blender/modifiers/intern/MOD_boolean.c @@ -71,7 +71,12 @@ static bool isDisabled(const struct Scene *UNUSED(scene), { BooleanModifierData *bmd = (BooleanModifierData *)md; - return !bmd->object; + /* The object type check is only needed here in case we have a placeholder + * object assigned (because the library containing the mesh is missing). + * + * In other cases it should be impossible to have a type missmatch. + */ + return !bmd->object || bmd->object->type != OB_MESH; } static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData) diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c index 7a07d9b28eb..bedd6e519eb 100644 --- a/source/blender/modifiers/intern/MOD_curve.c +++ b/source/blender/modifiers/intern/MOD_curve.c @@ -66,7 +66,12 @@ static bool isDisabled(const Scene *UNUSED(scene), ModifierData *md, bool UNUSED { CurveModifierData *cmd = (CurveModifierData *)md; - return !cmd->object; + /* The object type check is only needed here in case we have a placeholder + * object assigned (because the library containing the curve is missing). + * + * In other cases it should be impossible to have a type missmatch. + */ + return !cmd->object || cmd->object->type != OB_CURVE; } static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData) diff --git a/source/blender/modifiers/intern/MOD_datatransfer.c b/source/blender/modifiers/intern/MOD_datatransfer.c index c994a680fb0..fa60bd2a502 100644 --- a/source/blender/modifiers/intern/MOD_datatransfer.c +++ b/source/blender/modifiers/intern/MOD_datatransfer.c @@ -141,9 +141,14 @@ static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams)) { - DataTransferModifierData *dtmd = (DataTransferModifierData *)md; /* If no source object, bypass. */ - return (dtmd->ob_source == NULL); + DataTransferModifierData *dtmd = (DataTransferModifierData *)md; + /* The object type check is only needed here in case we have a placeholder + * object assigned (because the library containing the mesh is missing). + * + * In other cases it should be impossible to have a type missmatch. + */ + return !dtmd->ob_source || dtmd->ob_source->type != OB_MESH; } #define HIGH_POLY_WARNING 10000 diff --git a/source/blender/modifiers/intern/MOD_lattice.c b/source/blender/modifiers/intern/MOD_lattice.c index b639e874a88..aca5b43a7d5 100644 --- a/source/blender/modifiers/intern/MOD_lattice.c +++ b/source/blender/modifiers/intern/MOD_lattice.c @@ -64,7 +64,12 @@ static bool isDisabled(const struct Scene *UNUSED(scene), { LatticeModifierData *lmd = (LatticeModifierData *)md; - return !lmd->object; + /* The object type check is only needed here in case we have a placeholder + * object assigned (because the library containing the lattice is missing). + * + * In other cases it should be impossible to have a type missmatch. + */ + return !lmd->object || lmd->object->type != OB_LATTICE; } static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData) diff --git a/source/blender/modifiers/intern/MOD_mask.c b/source/blender/modifiers/intern/MOD_mask.c index f2f2b13b0df..bc218114432 100644 --- a/source/blender/modifiers/intern/MOD_mask.c +++ b/source/blender/modifiers/intern/MOD_mask.c @@ -344,6 +344,20 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes return result; } +static bool isDisabled(const struct Scene *UNUSED(scene), + ModifierData *md, + bool UNUSED(useRenderParams)) +{ + MaskModifierData *mmd = (MaskModifierData *)md; + + /* The object type check is only needed here in case we have a placeholder + * object assigned (because the library containing the armature is missing). + * + * In other cases it should be impossible to have a type missmatch. + */ + return mmd->ob_arm && mmd->ob_arm->type != OB_ARMATURE; +} + ModifierTypeInfo modifierType_Mask = { /* name */ "Mask", /* structName */ "MaskModifierData", @@ -363,7 +377,7 @@ ModifierTypeInfo modifierType_Mask = { /* initData */ NULL, /* requiredDataMask */ requiredDataMask, /* freeData */ NULL, - /* isDisabled */ NULL, + /* isDisabled */ isDisabled, /* updateDepsgraph */ updateDepsgraph, /* dependsOnTime */ NULL, /* dependsOnNormals */ NULL, diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index a582e179983..7ddce983c2a 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -139,7 +139,12 @@ static bool isDisabled(const struct Scene *UNUSED(scene), { MeshDeformModifierData *mmd = (MeshDeformModifierData *)md; - return !mmd->object; + /* The object type check is only needed here in case we have a placeholder + * object assigned (because the library containing the mesh is missing). + * + * In other cases it should be impossible to have a type missmatch. + */ + return !mmd->object || mmd->object->type != OB_MESH; } static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData) diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index 71913378277..01f1aeffdb2 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -80,7 +80,12 @@ static bool isDisabled(const struct Scene *scene, ModifierData *md, bool useRend ParticleSystem *psys; ModifierData *ob_md; - if (!pimd->ob) { + /* The object type check is only needed here in case we have a placeholder + * object assigned (because the library containing the mesh is missing). + * + * In other cases it should be impossible to have a type missmatch. + */ + if (!pimd->ob || pimd->ob->type != OB_MESH) { return true; } diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c index 07182d82fdc..408ec06a49c 100644 --- a/source/blender/modifiers/intern/MOD_shrinkwrap.c +++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c @@ -75,7 +75,19 @@ static bool isDisabled(const struct Scene *UNUSED(scene), bool UNUSED(useRenderParams)) { ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md; - return !smd->target; + + /* The object type check is only needed here in case we have a placeholder + * object assigned (because the library containing the mesh is missing). + * + * In other cases it should be impossible to have a type missmatch. + */ + if (!smd->target || smd->target->type != OB_MESH) { + return true; + } + else if (smd->auxTarget && smd->auxTarget->type != OB_MESH) { + return true; + } + return false; } static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData) diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c index c428325e42b..93196ea21fb 100644 --- a/source/blender/modifiers/intern/MOD_surfacedeform.c +++ b/source/blender/modifiers/intern/MOD_surfacedeform.c @@ -1279,7 +1279,13 @@ static bool isDisabled(const Scene *UNUSED(scene), ModifierData *md, bool UNUSED { SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md; - return smd->target == NULL && !(smd->verts != NULL && !(smd->flags & MOD_SDEF_BIND)); + /* The object type check is only needed here in case we have a placeholder + * object assigned (because the library containing the mesh is missing). + * + * In other cases it should be impossible to have a type missmatch. + */ + return (smd->target == NULL || smd->target->type != OB_MESH) && + !(smd->verts != NULL && !(smd->flags & MOD_SDEF_BIND)); } ModifierTypeInfo modifierType_SurfaceDeform = { -- cgit v1.2.3