From 04f063de84efde869fe712d4533361d687a66980 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 15 Oct 2012 03:16:38 +0000 Subject: Parenting an object to a deformer (armature/curve/lattice) will now attempt to check if the object is already parented to said deformer before trying to add a new modifier This should help reduce the number of cases where users inadvertantly end up creating multiple deform modifiers pointing to the same object, which has been known to be a cause of "double-transform" artifacts. Note that this is only able to detect these cases by checking if the parent object is selected, so this will only really work for the Ctrl-P shortcut where you have to select both objects first. However, it shouldn't be a problem either in the Outliner (drag and drop), as the object probably won't be a child of its parent already if you're doing this. --- source/blender/blenkernel/BKE_modifier.h | 1 + source/blender/blenkernel/intern/modifier.c | 32 +++++++++++++++++++----- source/blender/editors/object/object_relations.c | 23 +++++++++++------ 3 files changed, 43 insertions(+), 13 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index 3b675f3b620..7ee1c85d0de 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -352,6 +352,7 @@ int modifiers_isParticleEnabled(struct Object *ob); struct Object *modifiers_isDeformedByArmature(struct Object *ob); struct Object *modifiers_isDeformedByLattice(struct Object *ob); +struct Object *modifiers_isDeformedByCurve(struct Object *ob); int modifiers_usesArmature(struct Object *ob, struct bArmature *arm); int modifiers_isCorrectableDeformed(struct Object *ob); void modifier_freeTemporaryData(struct ModifierData *md); diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index f072ed4009e..0afd048e7f2 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -494,8 +494,8 @@ ModifierData *modifiers_getVirtualModifierList(Object *ob) return md; } -/* Takes an object and returns its first selected armature, else just its - * armature + +/* Takes an object and returns its first selected armature, else just its armature * This should work for multiple armatures per object */ Object *modifiers_isDeformedByArmature(Object *ob) @@ -518,9 +518,8 @@ Object *modifiers_isDeformedByArmature(Object *ob) return NULL; } -/* Takes an object and returns its first selected lattice, else just its - * lattice - * This should work for multiple lattics per object +/* Takes an object and returns its first selected lattice, else just its lattice + * This should work for multiple lattices per object */ Object *modifiers_isDeformedByLattice(Object *ob) { @@ -542,7 +541,28 @@ Object *modifiers_isDeformedByLattice(Object *ob) return NULL; } - +/* Takes an object and returns its first selected curve, else just its curve + * This should work for multiple curves per object + */ +Object *modifiers_isDeformedByCurve(Object *ob) +{ + ModifierData *md = modifiers_getVirtualModifierList(ob); + CurveModifierData *cmd = NULL; + + /* return the first selected curve, this lets us use multiple curves */ + for (; md; md = md->next) { + if (md->type == eModifierType_Curve) { + cmd = (CurveModifierData *) md; + if (cmd->object && (cmd->object->flag & SELECT)) + return cmd->object; + } + } + + if (cmd) /* if were still here then return the last curve */ + return cmd->object; + + return NULL; +} int modifiers_usesArmature(Object *ob, bArmature *arm) { diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 9e6cce7fee9..b7efe9189d8 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -669,23 +669,32 @@ int ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object ob->partype = PAROBJECT; /* note, dna define, not operator property */ //ob->partype= PARSKEL; /* note, dna define, not operator property */ - /* BUT, to keep the deforms, we need a modifier, and then we need to set the object that it uses */ + /* BUT, to keep the deforms, we need a modifier, and then we need to set the object that it uses + * - We need to ensure that the modifier we're adding doesn't already exist, so we check this by + * assuming that the parent is selected too... + */ // XXX currently this should only happen for meshes, curves, surfaces, and lattices - this stuff isn't available for metas yet if (ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) { ModifierData *md; switch (partype) { case PAR_CURVE: /* curve deform */ - md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Curve); - ((CurveModifierData *)md)->object = par; + if (modifiers_isDeformedByCurve(ob) != par) { + md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Curve); + ((CurveModifierData *)md)->object = par; + } break; case PAR_LATTICE: /* lattice deform */ - md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Lattice); - ((LatticeModifierData *)md)->object = par; + if (modifiers_isDeformedByLattice(ob) != par) { + md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Lattice); + ((LatticeModifierData *)md)->object = par; + } break; default: /* armature deform */ - md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Armature); - ((ArmatureModifierData *)md)->object = par; + if (modifiers_isDeformedByArmature(ob) != par) { + md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Armature); + ((ArmatureModifierData *)md)->object = par; + } break; } } -- cgit v1.2.3