From a405ed75fe830bd3ce110a94452af093a890bd04 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Wed, 5 Nov 2008 20:15:32 +0000 Subject: [PATCH] Sketch retargetting. Templating from other armature objects. Moving stuff home, saving doesn't work ok yet, will finish this later today, demo video when done. Also a couple of bug fixes for crashing and some text reformulation and the like. --- source/blender/blenlib/intern/graph.c | 5 ++ source/blender/blenloader/intern/readfile.c | 2 + source/blender/include/BIF_editarmature.h | 10 +++- source/blender/makesdna/DNA_scene_types.h | 1 + source/blender/src/drawview.c | 8 ++++ source/blender/src/editarmature.c | 49 ++++++++++++------- source/blender/src/editarmature_retarget.c | 52 ++++++++++++--------- source/blender/src/editarmature_sketch.c | 18 +++++-- 8 files changed, 101 insertions(+), 44 deletions(-) diff --git a/source/blender/blenlib/intern/graph.c b/source/blender/blenlib/intern/graph.c index 8f35b38379e..e2ed8f11ee2 100644 --- a/source/blender/blenlib/intern/graph.c +++ b/source/blender/blenlib/intern/graph.c @@ -1033,6 +1033,11 @@ void BLI_markdownSymmetry(BGraph *graph, BNode *root_node, float limit) BNode *node; BArc *arc; + if (root_node == NULL) + { + return; + } + if (BLI_isGraphCyclic(graph)) { return; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index acedf51e619..154f6d7264a 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3549,6 +3549,8 @@ static void direct_link_scene(FileData *fd, Scene *sce) sce->radio= newdataadr(fd, sce->radio); sce->toolsettings= newdataadr(fd, sce->toolsettings); + + sce->toolsettings->skgen_template = newdataadr(fd, sce->toolsettings->skgen_template); sce->sculptdata.session= NULL; /* SculptData textures */ diff --git a/source/blender/include/BIF_editarmature.h b/source/blender/include/BIF_editarmature.h index a89aecf854e..88e6630078f 100644 --- a/source/blender/include/BIF_editarmature.h +++ b/source/blender/include/BIF_editarmature.h @@ -73,7 +73,15 @@ EditBone *addEditBone(char *name, struct ListBase *ebones, struct bArmature *arm /* duplicate method */ void preEditBoneDuplicate(struct ListBase *editbones); EditBone *duplicateEditBone(EditBone *curBone, struct ListBase *editbones, struct Object *ob); -void updateDuplicateSubtarget(EditBone *dupBone, struct Object *ob); +void updateDuplicateSubtarget(EditBone *dupBone, struct ListBase *editbones, struct Object *ob); + +/* duplicate method (cross objects */ + +/* editbones is the target list */ +EditBone *duplicateEditBoneObjects(EditBone *curBone, struct ListBase *editbones, struct Object *src_ob, struct Object *dst_ob); + +/* editbones is the source list */ +void updateDuplicateSubtargetObjects(EditBone *dupBone, struct ListBase *editbones, struct Object *src_ob, struct Object *dst_ob); /* -- */ diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 3899600af30..b92799cdf2a 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -443,6 +443,7 @@ typedef struct ToolSettings { char skgen_multi_level; /* Skeleton Sketching */ + struct Object *skgen_template; char bone_sketching; char bone_sketching_convert; char skgen_subdivision_number; diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index d799d31c742..59a96bed319 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -2338,12 +2338,20 @@ static void view3d_panel_bonesketch_spaces(short cntrl) yco -= 20; uiBlockEndAlign(block); + + yco -= 10; + uiBlockBeginAlign(block); + + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_DIFF, "OB:", 10, yco, 150, 19, &G.scene->toolsettings->skgen_template, "Template Object"); + yco -= 20; uiDefButF(block, NUM, B_DIFF, "Ang:", 10, yco, 50,19, &G.scene->toolsettings->skgen_retarget_angle_weight, 0, 10, 1, 0, "Angle Weight"); uiDefButF(block, NUM, B_DIFF, "Len:", 60, yco, 50,19, &G.scene->toolsettings->skgen_retarget_length_weight, 0, 10, 1, 0, "Length Weight"); uiDefButF(block, NUM, B_DIFF, "Dist:", 110,yco, 50,19, &G.scene->toolsettings->skgen_retarget_distance_weight, 0, 10, 1, 0, "Distance Weight"); yco -= 20; + uiBlockEndAlign(block); + if(yco < 0) uiNewPanelHeight(block, height-yco); } } diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c index 63d5b9ce1f5..38d8262ea4d 100644 --- a/source/blender/src/editarmature.c +++ b/source/blender/src/editarmature.c @@ -2197,13 +2197,12 @@ static EditBone *add_points_bone (float head[], float tail[]) return ebo; } - -static EditBone *get_named_editbone(char *name) +static EditBone *get_named_editbone_from_list(char *name, ListBase *editbones) { EditBone *eBone; if (name) { - for (eBone=G.edbo.first; eBone; eBone=eBone->next) { + for (eBone=editbones->first; eBone; eBone=eBone->next) { if (!strcmp(name, eBone->name)) return eBone; } @@ -2212,6 +2211,11 @@ static EditBone *get_named_editbone(char *name) return NULL; } +static EditBone *get_named_editbone(char *name) +{ + return get_named_editbone_from_list(name, &G.edbo); +} + /* Call this before doing any duplications * */ void preEditBoneDuplicate(ListBase *editbones) @@ -2225,7 +2229,11 @@ void preEditBoneDuplicate(ListBase *editbones) } } -void updateDuplicateSubtarget(EditBone *dupBone, Object *ob) +/* + * Note: When duplicating cross objects, editbones here is the list of bones + * from the SOURCE object but ob is the DESTINATION object + * */ +void updateDuplicateSubtargetObjects(EditBone *dupBone, ListBase *editbones, Object *src_ob, Object *dst_ob) { /* If an edit bone has been duplicated, lets * update it's constraints if the subtarget @@ -2236,7 +2244,7 @@ void updateDuplicateSubtarget(EditBone *dupBone, Object *ob) bConstraint *curcon; ListBase *conlist; - if ( (chan = verify_pose_channel(ob->pose, dupBone->name)) ) { + if ( (chan = verify_pose_channel(dst_ob->pose, dupBone->name)) ) { if ( (conlist = &chan->constraints) ) { for (curcon = conlist->first; curcon; curcon=curcon->next) { /* does this constraint have a subtarget in @@ -2250,8 +2258,9 @@ void updateDuplicateSubtarget(EditBone *dupBone, Object *ob) cti->get_constraint_targets(curcon, &targets); for (ct= targets.first; ct; ct= ct->next) { - if ((ct->tar == G.obedit) && (ct->subtarget[0])) { - oldtarget = get_named_editbone(ct->subtarget); + if ((ct->tar == src_ob) && (ct->subtarget[0])) { + ct->tar = dst_ob; /* update target */ + oldtarget = get_named_editbone_from_list(ct->subtarget, editbones); if (oldtarget) { /* was the subtarget bone duplicated too? If * so, update the constraint to point at the @@ -2273,7 +2282,13 @@ void updateDuplicateSubtarget(EditBone *dupBone, Object *ob) } } -EditBone *duplicateEditBone(EditBone *curBone, ListBase *editbones, Object *ob) +void updateDuplicateSubtarget(EditBone *dupBone, ListBase *editbones, Object *ob) +{ + updateDuplicateSubtargetObjects(dupBone, editbones, ob, ob); +} + + +EditBone *duplicateEditBoneObjects(EditBone *curBone, ListBase *editbones, Object *src_ob, Object *dst_ob) { EditBone *eBone = MEM_callocN(sizeof(EditBone), "addup_editbone"); @@ -2289,11 +2304,11 @@ EditBone *duplicateEditBone(EditBone *curBone, ListBase *editbones, Object *ob) /* Lets duplicate the list of constraints that the * current bone has. */ - if (ob->pose) { + if (src_ob->pose) { bPoseChannel *chanold, *channew; ListBase *listold, *listnew; - chanold = verify_pose_channel(ob->pose, curBone->name); + chanold = verify_pose_channel(src_ob->pose, curBone->name); if (chanold) { listold = &chanold->constraints; if (listold) { @@ -2301,7 +2316,7 @@ EditBone *duplicateEditBone(EditBone *curBone, ListBase *editbones, Object *ob) * yet as the new bones created here are still 'EditBones' not 'Bones'. */ channew = - verify_pose_channel(ob->pose, eBone->name); + verify_pose_channel(dst_ob->pose, eBone->name); if (channew) { /* copy transform locks */ channew->protectflag = chanold->protectflag; @@ -2327,14 +2342,14 @@ EditBone *duplicateEditBone(EditBone *curBone, ListBase *editbones, Object *ob) } } - /* --------------------WARNING-------------------- - * - * need to call static void updateDuplicateSubtarget(EditBone *dupBone) at some point - * */ - return eBone; } +EditBone *duplicateEditBone(EditBone *curBone, ListBase *editbones, Object *ob) +{ + return duplicateEditBoneObjects(curBone, editbones, ob, ob); +} + void adduplicate_armature(void) { bArmature *arm= G.obedit->data; @@ -2448,7 +2463,7 @@ void adduplicate_armature(void) /* Lets try to fix any constraint subtargets that might have been duplicated */ - updateDuplicateSubtarget(eBone, OBACT); + updateDuplicateSubtarget(eBone, &G.edbo, OBACT); } } } diff --git a/source/blender/src/editarmature_retarget.c b/source/blender/src/editarmature_retarget.c index a51c9ec0c43..fb9ba740ec3 100644 --- a/source/blender/src/editarmature_retarget.c +++ b/source/blender/src/editarmature_retarget.c @@ -398,7 +398,7 @@ static void RIG_addEdgeToArc(RigArc *arc, float tail[3], EditBone *bone) } /************************************** CLONING TEMPLATES **********************************************/ -static RigControl *cloneControl(RigGraph *rg, RigControl *src_ctrl, GHash *ptr_hash) +static RigControl *cloneControl(RigGraph *rg, RigGraph *src_rg, RigControl *src_ctrl, GHash *ptr_hash) { RigControl *ctrl; @@ -411,7 +411,7 @@ static RigControl *cloneControl(RigGraph *rg, RigControl *src_ctrl, GHash *ptr_h ctrl->flag = src_ctrl->flag; - ctrl->bone = duplicateEditBone(src_ctrl->bone, rg->editbones, rg->ob); + ctrl->bone = duplicateEditBoneObjects(src_ctrl->bone, rg->editbones, src_rg->ob, rg->ob); ctrl->bone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL|BONE_ACTIVE); BLI_ghash_insert(ptr_hash, src_ctrl->bone, ctrl->bone); @@ -420,7 +420,7 @@ static RigControl *cloneControl(RigGraph *rg, RigControl *src_ctrl, GHash *ptr_h return ctrl; } -static RigArc *cloneArc(RigGraph *rg, RigArc *src_arc, GHash *ptr_hash) +static RigArc *cloneArc(RigGraph *rg, RigGraph *src_rg, RigArc *src_arc, GHash *ptr_hash) { RigEdge *src_edge; RigArc *arc; @@ -452,7 +452,7 @@ static RigArc *cloneArc(RigGraph *rg, RigArc *src_arc, GHash *ptr_hash) if (src_edge->bone != NULL) { - edge->bone = duplicateEditBone(src_edge->bone, rg->editbones, rg->ob); + edge->bone = duplicateEditBoneObjects(src_edge->bone, rg->editbones, src_rg->ob, rg->ob); edge->bone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL|BONE_ACTIVE); BLI_ghash_insert(ptr_hash, src_edge->bone, edge->bone); } @@ -463,7 +463,7 @@ static RigArc *cloneArc(RigGraph *rg, RigArc *src_arc, GHash *ptr_hash) return arc; } -static RigGraph *cloneRigGraph(RigGraph *src) +static RigGraph *cloneRigGraph(RigGraph *src, ListBase *editbones, Object *ob) { GHash *ptr_hash; RigNode *node; @@ -475,10 +475,11 @@ static RigGraph *cloneRigGraph(RigGraph *src) rg = newRigGraph(); - rg->ob = src->ob; - rg->editbones = src->editbones; + rg->ob = ob; + rg->editbones = editbones; preEditBoneDuplicate(rg->editbones); /* prime bones for duplication */ + preEditBoneDuplicate(src->editbones); /* prime bones for duplication */ /* Clone nodes */ for (node = src->nodes.first; node; node = node->next) @@ -492,13 +493,13 @@ static RigGraph *cloneRigGraph(RigGraph *src) /* Clone arcs */ for (arc = src->arcs.first; arc; arc = arc->next) { - cloneArc(rg, arc, ptr_hash); + cloneArc(rg, src, arc, ptr_hash); } /* Clone controls */ for (ctrl = src->controls.first; ctrl; ctrl = ctrl->next) { - cloneControl(rg, ctrl, ptr_hash); + cloneControl(rg, src, ctrl, ptr_hash); } /* Relink bones properly */ @@ -512,7 +513,7 @@ static RigGraph *cloneRigGraph(RigGraph *src) { EditBone *bone; - updateDuplicateSubtarget(edge->bone, rg->ob); + updateDuplicateSubtargetObjects(edge->bone, src->editbones, src->ob, rg->ob); bone = BLI_ghash_lookup(ptr_hash, edge->bone->parent); @@ -528,7 +529,7 @@ static RigGraph *cloneRigGraph(RigGraph *src) { EditBone *bone; - updateDuplicateSubtarget(ctrl->bone, rg->ob); + updateDuplicateSubtargetObjects(ctrl->bone, src->editbones, src->ob, rg->ob); bone = BLI_ghash_lookup(ptr_hash, ctrl->bone->parent); @@ -2804,23 +2805,32 @@ void BIF_retargetArmature() void BIF_retargetArc(ReebArc *earc) { Object *ob; - RigGraph *template; + RigGraph *template_rigg; RigGraph *rigg; RigArc *iarc; bArmature *arm; - - ob = G.obedit; - arm = ob->data; - template = armatureSelectedToGraph(ob, arm); - - if (template->arcs.first == NULL) + if (G.scene->toolsettings->skgen_template && + G.scene->toolsettings->skgen_template->type == OB_ARMATURE) { - error("No deforming bones selected"); + ob = G.scene->toolsettings->skgen_template; + arm = ob->data; + template_rigg = armatureToGraph(ob, arm); + } + else + { + ob = G.obedit; + arm = ob->data; + template_rigg = armatureSelectedToGraph(ob, arm); + } + + if (template_rigg->arcs.first == NULL) + { + error("No Template and no deforming bones selected"); return; } - rigg = cloneRigGraph(template); + rigg = cloneRigGraph(template_rigg, &G.edbo, G.obedit); iarc = rigg->arcs.first; @@ -2832,7 +2842,7 @@ void BIF_retargetArc(ReebArc *earc) finishRetarget(rigg); - RIG_freeRigGraph((BGraph*)template); + RIG_freeRigGraph((BGraph*)template_rigg); RIG_freeRigGraph((BGraph*)rigg); BIF_undo_push("Retarget Arc"); diff --git a/source/blender/src/editarmature_sketch.c b/source/blender/src/editarmature_sketch.c index 2b4bc9b89b0..5da96cd61d5 100644 --- a/source/blender/src/editarmature_sketch.c +++ b/source/blender/src/editarmature_sketch.c @@ -355,12 +355,13 @@ int peelObjects(ListBase *depth_peels, short mval[2]) } /*********************** CONVERSION ***************************/ -ReebNode *sk_pointToNode(SK_Point *pt) +ReebNode *sk_pointToNode(SK_Point *pt, float imat[][4]) { ReebNode *node; node = MEM_callocN(sizeof(ReebNode), "reeb node"); VECCOPY(node->p, pt->p); + Mat4MulVecfl(imat, node->p); if (G.scene->toolsettings->skgen_retarget_options & SK_RETARGET_ROLL) { @@ -370,14 +371,14 @@ ReebNode *sk_pointToNode(SK_Point *pt) return node; } -ReebArc *sk_strokeToArc(SK_Stroke *stk) +ReebArc *sk_strokeToArc(SK_Stroke *stk, float imat[][4]) { ReebArc *arc; int i; arc = MEM_callocN(sizeof(ReebArc), "reeb arc"); - arc->head = sk_pointToNode(stk->points); - arc->tail = sk_pointToNode(sk_lastStrokePoint(stk)); + arc->head = sk_pointToNode(stk->points, imat); + arc->tail = sk_pointToNode(sk_lastStrokePoint(stk), imat); arc->bcount = stk->nb_points - 2; /* first and last are nodes, don't count */ arc->buckets = MEM_callocN(sizeof(EmbedBucket) * arc->bcount, "Buckets"); @@ -385,6 +386,8 @@ ReebArc *sk_strokeToArc(SK_Stroke *stk) for (i = 0; i < arc->bcount; i++) { VECCOPY(arc->buckets[i].p, stk->points[i + 1].p); + Mat4MulVecfl(imat, arc->buckets[i].p); + if (G.scene->toolsettings->skgen_retarget_options & SK_RETARGET_ROLL) { arc->buckets[i].no = stk->points[i + 1].no; @@ -396,7 +399,12 @@ ReebArc *sk_strokeToArc(SK_Stroke *stk) void sk_retargetStroke(SK_Stroke *stk) { - ReebArc *arc = sk_strokeToArc(stk); + float imat[4][4]; + ReebArc *arc; + + Mat4Invert(imat, G.obedit->obmat); + + arc = sk_strokeToArc(stk, imat); BIF_retargetArc(arc);