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.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
/* -- */
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user