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:
-rw-r--r--source/blender/blenkernel/BKE_constraint.h4
-rw-r--r--source/blender/blenkernel/intern/armature.c10
-rw-r--r--source/blender/blenkernel/intern/constraint.c40
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h4
-rw-r--r--source/blender/src/buttons_object.c98
-rw-r--r--source/blender/src/editconstraint.c31
-rw-r--r--source/blender/src/poseobject.c3
7 files changed, 150 insertions, 40 deletions
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index aa8e9cf18f8..5d145dc6dee 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -117,6 +117,9 @@ void copy_constraints(struct ListBase *dst, struct ListBase *src);
void relink_constraints(struct ListBase *list);
void free_constraint_data(struct bConstraint *con);
+/* Constraints + Proxies function prototypes */
+void extract_proxylocal_constraints(struct ListBase *dst, struct ListBase *src);
+short proxylocked_constraints_owner(struct Object *ob, struct bPoseChannel *pchan);
/* Constraint Channel function prototypes */
struct bConstraintChannel *get_constraint_channel(struct ListBase *list, const char *name);
@@ -126,6 +129,7 @@ void copy_constraint_channels(struct ListBase *dst, struct ListBase *src);
void clone_constraint_channels(struct ListBase *dst, struct ListBase *src);
void free_constraint_channels(struct ListBase *chanbase);
+
/* Constraint Evaluation function prototypes */
struct bConstraintOb *constraints_make_evalob(struct Object *ob, void *subdata, short datatype);
void constraints_clear_evalob(struct bConstraintOb *cob);
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 6bdb663545c..f4da821e3ea 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -1317,6 +1317,7 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
pchan= pose->chanbase.first;
for(; pchan; pchan= pchan->next) {
if(pchan->bone->layer & layer_protected) {
+ ListBase proxylocal_constraints = {NULL, NULL};
pchanp= get_pose_channel(frompose, pchan->name);
/* copy posechannel to temp, but restore important pointers */
@@ -1327,9 +1328,16 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
pchanw.child= pchan->child;
pchanw.path= NULL;
- /* constraints, set target ob pointer to own object */
+ /* constraints - proxy constraints are flushed... local ones are added after
+ * 1. extract constraints not from proxy (CONSTRAINT_PROXY_LOCAL) from pchan's constraints
+ * 2. copy proxy-pchan's constraints on-to new
+ * 3. add extracted local constraints back on top
+ */
+ extract_proxylocal_constraints(&proxylocal_constraints, &pchan->constraints);
copy_constraints(&pchanw.constraints, &pchanp->constraints);
+ addlisttolist(&pchanw.constraints, &proxylocal_constraints);
+ /* constraints - set target ob pointer to own object */
for (con= pchanw.constraints.first; con; con= con->next) {
bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index c87c75b0190..295c52f1415 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -3246,6 +3246,46 @@ void copy_constraints (ListBase *dst, ListBase *src)
}
}
+/* -------- Constraints and Proxies ------- */
+
+/* Rescue all constraints tagged as being CONSTRAINT_PROXY_LOCAL (i.e. added to bone that's proxy-synced in this file) */
+void extract_proxylocal_constraints (ListBase *dst, ListBase *src)
+{
+ bConstraint *con, *next;
+
+ /* for each tagged constraint, remove from src and move to dst */
+ for (con= src->first; con; con= next) {
+ next= con->next;
+
+ /* check if tagged */
+ if (con->flag & CONSTRAINT_PROXY_LOCAL) {
+ BLI_remlink(src, con);
+ BLI_addtail(dst, con);
+ }
+ }
+}
+
+/* Returns if the owner of the constraint is proxy-protected */
+short proxylocked_constraints_owner (Object *ob, bPoseChannel *pchan)
+{
+ /* Currently, constraints can only be on object or bone level */
+ if (ob && ob->proxy) {
+ if (ob->pose && pchan) {
+ bArmature *arm= ob->data;
+
+ /* On bone-level, check if bone is on proxy-protected layer */
+ if ((pchan->bone) && (pchan->bone->layer & arm->layer_protected))
+ return 1;
+ }
+ else {
+ /* FIXME: constraints on object-level are not handled well yet */
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
/* -------- Target-Matrix Stuff ------- */
/* This function is a relic from the prior implementations of the constraints system, when all
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index 7f9fa49e7a9..4ae8d6b39e6 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -352,7 +352,9 @@ typedef enum B_CONSTRAINT_FLAG {
/* to indicate that the owner's space should only be changed into ownspace, but not out of it */
CONSTRAINT_SPACEONCE = (1<<6),
/* influence ipo is on constraint itself, not in action channel */
- CONSTRAINT_OWN_IPO = (1<<7)
+ CONSTRAINT_OWN_IPO = (1<<7),
+ /* indicates that constraint was added locally (i.e. didn't come from the proxy-lib) */
+ CONSTRAINT_PROXY_LOCAL = (1<<8)
} B_CONSTRAINT_FLAG;
/* bConstraint->ownspace/tarspace */
diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c
index 243681bc800..66cd59d1751 100644
--- a/source/blender/src/buttons_object.c
+++ b/source/blender/src/buttons_object.c
@@ -190,15 +190,18 @@ static void constraint_active_func(void *ob_v, void *con_v)
static void add_constraint_to_active(Object *ob, bConstraint *con)
{
- ListBase *list;
+ ListBase *list= get_active_constraints(ob);
+ bPoseChannel *pchan= get_active_posechannel(ob);
- list = get_active_constraints(ob);
if (list) {
unique_constraint_name(con, list);
BLI_addtail(list, con);
+ if (proxylocked_constraints_owner(ob, pchan))
+ con->flag |= CONSTRAINT_PROXY_LOCAL;
+
con->flag |= CONSTRAINT_ACTIVE;
- for(con= con->prev; con; con= con->prev)
+ for (con= con->prev; con; con= con->prev)
con->flag &= ~CONSTRAINT_ACTIVE;
}
}
@@ -209,8 +212,7 @@ static void get_constraint_ipo_context(void *ob_v, char *actname)
{
Object *ob= ob_v;
- /* todo; check object if it has ob-level action ipo */
-
+ /* todo: check object if it has ob-level action ipo */
if (ob->flag & OB_POSEMODE) {
bPoseChannel *pchan;
@@ -503,12 +505,15 @@ static void draw_constraint_spaceselect (uiBlock *block, bConstraint *con, short
static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, short *xco, short *yco)
{
Object *ob= OBACT;
+ bPoseChannel *pchan= get_active_posechannel(ob);
bConstraintTypeInfo *cti;
uiBut *but;
char typestr[32];
short height, width = 265;
+ short proxy_protected;
int rb_col;
+ /* get constraint typeinfo */
cti= constraint_get_typeinfo(con);
if (cti == NULL) {
/* exception for 'Null' constraint - it doesn't have constraint typeinfo! */
@@ -520,6 +525,13 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
else
strcpy(typestr, cti->name);
+ /* determine whether constraint is proxy protected or not */
+ if (proxylocked_constraints_owner(ob, pchan)) {
+ proxy_protected= (con->flag & CONSTRAINT_PROXY_LOCAL) ? 0 : 1;
+ }
+ else
+ proxy_protected= 0;
+
/* unless button has own callback, it adds this callback to button */
uiBlockSetFunc(block, constraint_active_func, ob, con);
@@ -534,17 +546,8 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
/* open/close */
uiDefIconButBitS(block, ICONTOG, CONSTRAINT_EXPAND, B_CONSTRAINT_TEST, ICON_DISCLOSURE_TRI_RIGHT, *xco-10, *yco, 20, 20, &con->flag, 0.0, 0.0, 0.0, 0.0, "Collapse/Expand Constraint");
- /* up/down */
- uiBlockBeginAlign(block);
- uiBlockSetEmboss(block, UI_EMBOSS);
- but = uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_UP, *xco+width-50, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move constraint up in constraint stack");
- uiButSetFunc(but, constraint_moveUp, ob, con);
-
- but = uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_DOWN, *xco+width-50+18, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move constraint down in constraint stack");
- uiButSetFunc(but, constraint_moveDown, ob, con);
- uiBlockEndAlign(block);
-
- if (con->flag & CONSTRAINT_EXPAND) {
+ /* name */
+ if ((con->flag & CONSTRAINT_EXPAND) && (proxy_protected==0)) {
if (con->flag & CONSTRAINT_DISABLE)
uiBlockSetCol(block, TH_REDALERT);
@@ -568,14 +571,60 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
uiBlockSetCol(block, TH_AUTO);
- uiBlockSetEmboss(block, UI_EMBOSSN);
+ /* proxy-protected constraints cannot be edited, so hide up/down + close buttons */
+ if (proxy_protected) {
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+
+ /* draw a ghost icon (for proxy) and also a lock beside it, to show that constraint is "proxy locked" */
+ uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_GHOST, *xco+244, *yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Proxy Protected");
+ uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_LOCKED, *xco+262, *yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Proxy Protected");
+
+ uiBlockSetEmboss(block, UI_EMBOSS);
+ }
+ else {
+ short prev_proxylock;
+
+ /* Up/Down buttons:
+ * Proxy-constraints are not allowed to occur after local (non-proxy) constraints
+ * as that poses problems when restoring them, so disable the "up" button where
+ * it may cause this situation.
+ */
+ if (proxylocked_constraints_owner(ob, pchan)) {
+ if (con->prev) {
+ prev_proxylock= (con->prev->flag & CONSTRAINT_PROXY_LOCAL) ? 0 : 1;
+ }
+ else
+ prev_proxylock= 0;
+ }
+ else
+ prev_proxylock= 0;
+
+ uiBlockBeginAlign(block);
+ uiBlockSetEmboss(block, UI_EMBOSS);
+
+ if (prev_proxylock == 0) {
+ but = uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_UP, *xco+width-50, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move constraint up in constraint stack");
+ uiButSetFunc(but, constraint_moveUp, ob, con);
+ }
+
+ but = uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_DOWN, *xco+width-50+18, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move constraint down in constraint stack");
+ uiButSetFunc(but, constraint_moveDown, ob, con);
+ uiBlockEndAlign(block);
+
+
+ /* Close 'button' - emboss calls here disable drawing of 'button' behind X */
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+
+ but = uiDefIconBut(block, BUT, B_CONSTRAINT_CHANGETARGET, ICON_X, *xco+262, *yco, 19, 19, list, 0.0, 0.0, 0.0, 0.0, "Delete constraint");
+ uiButSetFunc(but, del_constraint_func, ob, con);
+
+ uiBlockSetEmboss(block, UI_EMBOSS);
+ }
+
+ /* Set but-locks for protected settings (magic numbers are used here!) */
+ if (proxy_protected)
+ uiSetButLock(1, "Cannot edit Proxy-Protected Constraint");
- but = uiDefIconBut(block, BUT, B_CONSTRAINT_CHANGETARGET, ICON_X, *xco+262, *yco, 19, 19, list, 0.0, 0.0, 0.0, 0.0, "Delete constraint");
- uiButSetFunc(but, del_constraint_func, ob, con);
-
- uiBlockSetEmboss(block, UI_EMBOSS);
-
-
/* Draw constraint data */
if ((con->flag & CONSTRAINT_EXPAND) == 0) {
(*yco) -= 21;
@@ -1649,6 +1698,9 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
else {
(*yco)-=3;
}
+
+ /* clear any locks set up for proxies/lib-linking */
+ uiClearButLock();
}
static uiBlock *add_constraintmenu(void *arg_unused)
diff --git a/source/blender/src/editconstraint.c b/source/blender/src/editconstraint.c
index e0588b4c2a0..940634290bd 100644
--- a/source/blender/src/editconstraint.c
+++ b/source/blender/src/editconstraint.c
@@ -247,6 +247,9 @@ void add_constraint_to_object(bConstraint *con, Object *ob)
unique_constraint_name(con, list);
BLI_addtail(list, con);
+ if (proxylocked_constraints_owner(ob, NULL))
+ con->flag |= CONSTRAINT_PROXY_LOCAL;
+
con->flag |= CONSTRAINT_ACTIVE;
for (con= con->prev; con; con= con->prev)
con->flag &= ~CONSTRAINT_ACTIVE;
@@ -258,7 +261,6 @@ void add_constraint_to_object(bConstraint *con, Object *ob)
*/
static void test_constraints (Object *owner, const char substring[])
{
-
bConstraint *curcon;
ListBase *conlist= NULL;
int type;
@@ -266,8 +268,6 @@ static void test_constraints (Object *owner, const char substring[])
if (owner==NULL) return;
/* Check parents */
- /* Get the constraint list for this object */
-
if (strlen (substring)) {
switch (owner->type) {
case OB_ARMATURE:
@@ -281,7 +281,7 @@ static void test_constraints (Object *owner, const char substring[])
else
type = CONSTRAINT_OBTYPE_OBJECT;
-
+ /* Get the constraint list for this object */
switch (type) {
case CONSTRAINT_OBTYPE_OBJECT:
conlist = &owner->constraints;
@@ -656,12 +656,6 @@ void add_constraint(int only_IK)
/* find active channel */
pchanact= get_active_posechannel(ob);
if(pchanact==NULL) return;
-
- /* check protection */
- if(ob->proxy && (pchanact->bone->layer & arm->layer_protected)) {
- error("Bone is Proxy protected");
- return;
- }
/* find selected bone */
for(pchansel= ob->pose->chanbase.first; pchansel; pchansel= pchansel->next) {
@@ -745,8 +739,11 @@ void add_constraint(int only_IK)
con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC);
BLI_addtail(&pchanact->constraints, con);
unique_constraint_name(con, &pchanact->constraints);
- pchanact->constflag |= PCHAN_HAS_IK; // for draw, but also for detecting while pose solving
- if(nr==11) pchanact->constflag |= PCHAN_HAS_TARGET;
+ pchanact->constflag |= PCHAN_HAS_IK; /* for draw, but also for detecting while pose solving */
+ if (nr==11)
+ pchanact->constflag |= PCHAN_HAS_TARGET;
+ if (proxylocked_constraints_owner(ob, pchanact))
+ con->flag |= CONSTRAINT_PROXY_LOCAL;
}
else {
@@ -812,10 +809,14 @@ void add_constraint(int only_IK)
BLI_addtail(&pchanact->constraints, con);
unique_constraint_name(con, &pchanact->constraints);
pchanact->constflag |= PCHAN_HAS_CONST; /* for draw */
+ if (proxylocked_constraints_owner(ob, pchanact))
+ con->flag |= CONSTRAINT_PROXY_LOCAL;
}
else {
BLI_addtail(&ob->constraints, con);
unique_constraint_name(con, &ob->constraints);
+ if (proxylocked_constraints_owner(ob, NULL))
+ con->flag |= CONSTRAINT_PROXY_LOCAL;
}
}
@@ -867,9 +868,9 @@ void add_constraint(int only_IK)
else
DAG_object_flush_update(G.scene, ob, OB_RECALC_OB); // and all its relations
- allqueue (REDRAWVIEW3D, 0);
- allqueue (REDRAWBUTSOBJECT, 0);
- allqueue (REDRAWOOPS, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ allqueue(REDRAWOOPS, 0);
if (only_IK)
BIF_undo_push("Add IK Constraint");
diff --git a/source/blender/src/poseobject.c b/source/blender/src/poseobject.c
index 585ff320b71..e1854c0043e 100644
--- a/source/blender/src/poseobject.c
+++ b/source/blender/src/poseobject.c
@@ -165,6 +165,9 @@ bPoseChannel *get_active_posechannel (Object *ob)
bArmature *arm= ob->data;
bPoseChannel *pchan;
+ if ELEM(NULL, ob, ob->pose)
+ return NULL;
+
/* find active */
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
if(pchan->bone && (pchan->bone->flag & BONE_ACTIVE) && (pchan->bone->layer & arm->layer))