diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-03-18 00:44:58 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-03-18 00:44:58 +0300 |
commit | d52400bfbd2a7e4d09b5a71bc461a554d232af15 (patch) | |
tree | 08815f065fc90aac0ae62ae5f3a89d20e19399e6 /source/blender/editors | |
parent | 1ac0d54fea831c485e8e27e8bfa887e15beb58de (diff) | |
parent | 28f6d223d079b1e5cb67e3fc22fb7f818deb8dcb (diff) |
2.50: svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r18677:19317
Notes:
* Sequence transform strip uses G.scene global, this is commented
out now, should be fixed.
* Etch-a-ton code was most difficult to merge. The files already in
2.5 got merged, but no new files were added. Calls to these files
are commented out with "XXX etch-a-ton". editarmature.c and
transform_snap.c were complex to merge. Martin, please check?
* Game engine compiles and links again here for scons/make/cmake
(player still fails to link).
Diffstat (limited to 'source/blender/editors')
25 files changed, 1198 insertions, 668 deletions
diff --git a/source/blender/editors/CMakeLists.txt b/source/blender/editors/CMakeLists.txt index b014454d252..06b0fb4ab41 100644 --- a/source/blender/editors/CMakeLists.txt +++ b/source/blender/editors/CMakeLists.txt @@ -52,6 +52,10 @@ IF(WITH_OPENEXR) ADD_DEFINITIONS(-DWITH_OPENEXR) ENDIF(WITH_OPENEXR) +IF(WITH_OPENJPEG) + ADD_DEFINITIONS(-DWITH_OPENJPEG) +ENDIF(WITH_OPENJPEG) + IF(WITH_QUICKTIME) SET(INC ${INC} ${QUICKTIME_INC}) ADD_DEFINITIONS(-DWITH_QUICKTIME) diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h index 9f50bb3f044..06b6efab94b 100644 --- a/source/blender/editors/armature/armature_intern.h +++ b/source/blender/editors/armature/armature_intern.h @@ -31,7 +31,7 @@ /* internal exports only */ struct wmOperatorType; -/* editarmature.c */ +/* editarmature.c operators */ void ARMATURE_OT_bone_primitive_add(struct wmOperatorType *ot); void ARMATURE_OT_align_bones(struct wmOperatorType *ot); void ARMATURE_OT_calculate_roll(struct wmOperatorType *ot); @@ -61,5 +61,24 @@ void POSE_OT_select_parent(struct wmOperatorType *ot); void POSE_OT_select_hierarchy(struct wmOperatorType *ot); void POSE_OT_select_connected(struct wmOperatorType *ot); +/* editarmature.c */ +struct bArmature; +struct EditBone; + +struct EditBone *addEditBone(struct bArmature *arm, char *name); + +/* duplicate method */ +void preEditBoneDuplicate(struct ListBase *editbones); +struct EditBone *duplicateEditBone(struct EditBone *curBone, char *name, struct ListBase *editbones, struct Object *ob); +void updateDuplicateSubtarget(struct EditBone *dupBone, struct ListBase *editbones, struct Object *ob); + +/* duplicate method (cross objects */ + +/* editbones is the target list */ +struct EditBone *duplicateEditBoneObjects(struct EditBone *curBone, char *name, struct ListBase *editbones, struct Object *src_ob, struct Object *dst_ob); + +/* editbones is the source list */ +void updateDuplicateSubtargetObjects(struct EditBone *dupBone, struct ListBase *editbones, struct Object *src_ob, struct Object *dst_ob); + #endif /* ED_ARMATURE_INTERN_H */ diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 021f87ea663..2aed96b61c5 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -75,6 +75,7 @@ #include "BIF_gl.h" #include "BIF_transform.h" +// XXX etch-a-ton #include "BIF_generate.h" #include "RNA_access.h" #include "RNA_define.h" @@ -463,13 +464,16 @@ static EditBone *editbone_name_exists (ListBase *edbo, char *name) } /* note: there's a unique_bone_name() too! */ -void unique_editbone_name (ListBase *edbo, char *name) +void unique_editbone_name (ListBase *edbo, char *name, EditBone *bone) { + EditBone *dupli; char tempname[64]; int number; char *dot; + + dupli = editbone_name_exists(edbo, name); - if (editbone_name_exists(edbo, name)) { + if (dupli && bone != dupli) { /* Strip off the suffix, if it's a number */ number= strlen(name); if (number && isdigit(name[number-1])) { @@ -717,7 +721,7 @@ int join_armature(Scene *scene, View3D *v3d) curbone= editbone_name_exists(curarm->edbo, pchan->name); /* Get new name */ - unique_editbone_name(arm->edbo, curbone->name); + unique_editbone_name(arm->edbo, curbone->name, NULL); /* Transform the bone */ { @@ -1851,6 +1855,8 @@ void ED_armature_to_edit(Object *ob) ED_armature_edit_free(ob); arm->edbo= MEM_callocN(sizeof(ListBase), "edbo armature"); make_boneList(arm->edbo, &arm->bonebase,NULL); + + // XXX etch-a-ton BIF_freeTemplates(); /* force template update when entering editmode */ } @@ -2085,14 +2091,12 @@ void undo_push_armature(bContext *C, char *name) /* *************** Adding stuff in editmode *************** */ /* default bone add, returns it selected, but without tail set */ -static EditBone *add_editbone(Object *obedit, char *name) +EditBone *addEditBone(bArmature *arm, char *name) { - bArmature *arm= obedit->data; - EditBone *bone= MEM_callocN(sizeof(EditBone), "eBone"); BLI_strncpy(bone->name, name, 32); - unique_editbone_name(arm->edbo, bone->name); + unique_editbone_name(arm->edbo, bone->name, NULL); BLI_addtail(arm->edbo, bone); @@ -2111,6 +2115,14 @@ static EditBone *add_editbone(Object *obedit, char *name) return bone; } +/* default bone add, returns it selected, but without tail set */ +static EditBone *add_editbone(Object *obedit, char *name) +{ + bArmature *arm= obedit->data; + + return addEditBone(arm, name); +} + /* v3d and rv3d are allowed to be NULL */ void add_primitive_bone(Scene *scene, View3D *v3d, RegionView3D *rv3d) { @@ -2341,19 +2353,35 @@ static EditBone *get_named_editbone(ListBase *edbo, char *name) return NULL; } -static void update_dup_subtarget(Object *obedit, EditBone *dupBone) +/* Call this before doing any duplications + * */ +void preEditBoneDuplicate(ListBase *editbones) +{ + EditBone *eBone; + + /* clear temp */ + for (eBone = editbones->first; eBone; eBone = eBone->next) + { + eBone->temp = NULL; + } +} + +/* + * 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 * they point to has also been duplicated */ - bArmature *arm = obedit->data; EditBone *oldtarget, *newtarget; bPoseChannel *chan; bConstraint *curcon; ListBase *conlist; - if ( (chan = verify_pose_channel(obedit->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 @@ -2367,14 +2395,15 @@ static void update_dup_subtarget(Object *obedit, EditBone *dupBone) cti->get_constraint_targets(curcon, &targets); for (ct= targets.first; ct; ct= ct->next) { - if ((ct->tar == obedit) && (ct->subtarget[0])) { - oldtarget = get_named_editbone(arm->edbo, ct->subtarget); + if ((ct->tar == src_ob) && (ct->subtarget[0])) { + ct->tar = dst_ob; /* update target */ + oldtarget = get_named_editbone(editbones, ct->subtarget); if (oldtarget) { /* was the subtarget bone duplicated too? If * so, update the constraint to point at the * duplicate of the old subtarget. */ - if (oldtarget->flag & BONE_SELECTED){ + if (oldtarget->temp) { newtarget = (EditBone *) oldtarget->temp; strcpy(ct->subtarget, newtarget->name); } @@ -2390,6 +2419,79 @@ static void update_dup_subtarget(Object *obedit, EditBone *dupBone) } } +void updateDuplicateSubtarget(EditBone *dupBone, ListBase *editbones, Object *ob) +{ + updateDuplicateSubtargetObjects(dupBone, editbones, ob, ob); +} + + +EditBone *duplicateEditBoneObjects(EditBone *curBone, char *name, ListBase *editbones, Object *src_ob, Object *dst_ob) +{ + EditBone *eBone = MEM_callocN(sizeof(EditBone), "addup_editbone"); + + /* Copy data from old bone to new bone */ + memcpy(eBone, curBone, sizeof(EditBone)); + + curBone->temp = eBone; + eBone->temp = curBone; + + if (name != NULL) + { + BLI_strncpy(eBone->name, name, 32); + } + + unique_editbone_name(editbones, eBone->name, NULL); + BLI_addtail(editbones, eBone); + + /* Lets duplicate the list of constraints that the + * current bone has. + */ + if (src_ob->pose) { + bPoseChannel *chanold, *channew; + ListBase *listold, *listnew; + + chanold = verify_pose_channel(src_ob->pose, curBone->name); + if (chanold) { + listold = &chanold->constraints; + if (listold) { + /* WARNING: this creates a new posechannel, but there will not be an attached bone + * yet as the new bones created here are still 'EditBones' not 'Bones'. + */ + channew = + verify_pose_channel(dst_ob->pose, eBone->name); + if (channew) { + /* copy transform locks */ + channew->protectflag = chanold->protectflag; + + /* copy bone group */ + channew->agrp_index= chanold->agrp_index; + + /* ik (dof) settings */ + channew->ikflag = chanold->ikflag; + VECCOPY(channew->limitmin, chanold->limitmin); + VECCOPY(channew->limitmax, chanold->limitmax); + VECCOPY(channew->stiffness, chanold->stiffness); + channew->ikstretch= chanold->ikstretch; + + /* constraints */ + listnew = &channew->constraints; + copy_constraints(listnew, listold); + + /* custom shape */ + channew->custom= chanold->custom; + } + } + } + } + + return eBone; +} + +EditBone *duplicateEditBone(EditBone *curBone, char *name, ListBase *editbones, Object *ob) +{ + return duplicateEditBoneObjects(curBone, name, editbones, ob, ob); +} + /* previously adduplicate_armature */ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op) { @@ -2407,6 +2509,8 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op) armature_sync_selection(arm->edbo); // XXX why is this needed? + preEditBoneDuplicate(arm->edbo); + /* Select mirrored bones */ if (arm->flag & ARM_MIRROR_EDIT) { for (curBone=arm->edbo->first; curBone; curBone=curBone->next) { @@ -2419,6 +2523,7 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op) } } } + /* Find the selected bones and duplicate them as needed */ for (curBone=arm->edbo->first; curBone && curBone!=firstDup; curBone=curBone->next) { @@ -2433,7 +2538,7 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op) curBone->temp = eBone; eBone->temp = curBone; - unique_editbone_name(arm->edbo, eBone->name); + unique_editbone_name(arm->edbo, eBone->name, NULL); BLI_addtail(arm->edbo, eBone); if (!firstDup) firstDup=eBone; @@ -2494,9 +2599,9 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op) */ eBone->parent = NULL; } - else if (curBone->parent->flag & BONE_SELECTED) { - /* If this bone has a parent that IS selected, - * Set the duplicate->parent to the curBone->parent->duplicate + else if (curBone->parent->temp) { + /* If this bone has a parent that was duplicated, + * Set the duplicate->parent to the curBone->parent->temp */ eBone->parent= (EditBone *)curBone->parent->temp; } @@ -2511,7 +2616,7 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op) /* Lets try to fix any constraint subtargets that might * have been duplicated */ - update_dup_subtarget(obedit, eBone); + updateDuplicateSubtarget(eBone, arm->edbo, obedit); } } } @@ -3122,7 +3227,7 @@ static int armature_extrude_exec(bContext *C, wmOperator *op) else strcat(newbone->name, "_R"); } } - unique_editbone_name(arm->edbo, newbone->name); + unique_editbone_name(arm->edbo, newbone->name, NULL); /* Add the new bone to the list */ BLI_addtail(arm->edbo, newbone); @@ -3299,7 +3404,7 @@ static int armature_subdivide_exec(bContext *C, wmOperator *op) newbone->flag |= BONE_CONNECTED; - unique_editbone_name(arm->edbo, newbone->name); + unique_editbone_name(arm->edbo, newbone->name, NULL); /* correct parent bones */ for (tbone = arm->edbo->first; tbone; tbone=tbone->next) { @@ -5009,7 +5114,7 @@ void armature_bone_rename(Object *ob, char *oldnamep, char *newnamep) eBone= editbone_name_exists(arm->edbo, oldname); if (eBone) { - unique_editbone_name(arm->edbo, newname); + unique_editbone_name(arm->edbo, newname, NULL); BLI_strncpy(eBone->name, newname, MAXBONENAME); } else return; @@ -5236,9 +5341,9 @@ EditBone * subdivideByAngle(Scene *scene, Object *obedit, ReebArc *arc, ReebNode if (scene->toolsettings->skgen_options & SKGEN_CUT_ANGLE) { - ReebArcIterator iter; - EmbedBucket *current = NULL; - EmbedBucket *previous = NULL; + ReebArcIterator arc_iter; + BArcIterator *iter = (BArcIterator*)&arc_iter; + float *previous = NULL, *current = NULL; EditBone *child = NULL; EditBone *parent = NULL; EditBone *root = NULL; @@ -5250,22 +5355,28 @@ EditBone * subdivideByAngle(Scene *scene, Object *obedit, ReebArc *arc, ReebNode root = parent; - for (initArcIterator(&iter, arc, head), previous = nextBucket(&iter), current = nextBucket(&iter); - current; - previous = current, current = nextBucket(&iter)) + initArcIterator(iter, arc, head); + IT_next(iter); + previous = iter->p; + + for (IT_next(iter); + IT_stopped(iter) == 0; + previous = iter->p, IT_next(iter)) { float vec1[3], vec2[3]; float len1, len2; + + current = iter->p; - VecSubf(vec1, previous->p, parent->head); - VecSubf(vec2, current->p, previous->p); + VecSubf(vec1, previous, parent->head); + VecSubf(vec2, current, previous); len1 = Normalize(vec1); len2 = Normalize(vec2); if (len1 > 0.0f && len2 > 0.0f && Inpf(vec1, vec2) < angleLimit) { - VECCOPY(parent->tail, previous->p); + VECCOPY(parent->tail, previous); child = add_editbone(obedit, "Bone"); VECCOPY(child->head, parent->tail); @@ -5292,182 +5403,29 @@ EditBone * subdivideByAngle(Scene *scene, Object *obedit, ReebArc *arc, ReebNode return lastBone; } -float calcVariance(ReebArc *arc, int start, int end, float v0[3], float n[3]) -{ - int len = 2 + abs(end - start); - - if (len > 2) - { - ReebArcIterator iter; - EmbedBucket *bucket = NULL; - float avg_t = 0.0f; - float s_t = 0.0f; - float s_xyz = 0.0f; - - /* First pass, calculate average */ - for (initArcIterator2(&iter, arc, start, end), bucket = nextBucket(&iter); - bucket; - bucket = nextBucket(&iter)) - { - float v[3]; - - VecSubf(v, bucket->p, v0); - avg_t += Inpf(v, n); - } - - avg_t /= Inpf(n, n); - avg_t += 1.0f; /* adding start (0) and end (1) values */ - avg_t /= len; - - /* Second pass, calculate s_xyz and s_t */ - for (initArcIterator2(&iter, arc, start, end), bucket = nextBucket(&iter); - bucket; - bucket = nextBucket(&iter)) - { - float v[3], d[3]; - float dt; - - VecSubf(v, bucket->p, v0); - Projf(d, v, n); - VecSubf(v, v, d); - - dt = VecLength(d) - avg_t; - - s_t += dt * dt; - s_xyz += Inpf(v, v); - } - - /* adding start(0) and end(1) values to s_t */ - s_t += (avg_t * avg_t) + (1 - avg_t) * (1 - avg_t); - - return s_xyz / s_t; - } - else - { - return 0; - } -} - -float calcDistance(ReebArc *arc, int start, int end, float head[3], float tail[3]) -{ - ReebArcIterator iter; - EmbedBucket *bucket = NULL; - float max_dist = 0; - - /* calculate maximum distance */ - for (initArcIterator2(&iter, arc, start, end), bucket = nextBucket(&iter); - bucket; - bucket = nextBucket(&iter)) - { - float v1[3], v2[3], c[3]; - float dist; - - VecSubf(v1, head, tail); - VecSubf(v2, bucket->p, tail); - - Crossf(c, v1, v2); - - dist = Inpf(c, c) / Inpf(v1, v1); - - max_dist = dist > max_dist ? dist : max_dist; - } - - - return max_dist; -} - -EditBone * subdivideByCorrelation(Scene *scene, Object *obedit, ReebArc *arc, ReebNode *head, ReebNode *tail) +EditBone * test_subdivideByCorrelation(Scene *scene, Object *obedit, ReebArc *arc, ReebNode *head, ReebNode *tail) { - ReebArcIterator iter; - float n[3]; - float ADAPTIVE_THRESHOLD = scene->toolsettings->skgen_correlation_limit; EditBone *lastBone = NULL; - - /* init iterator to get start and end from head */ - initArcIterator(&iter, arc, head); - - /* Calculate overall */ - VecSubf(n, arc->buckets[iter.end].p, head->p); - + if (scene->toolsettings->skgen_options & SKGEN_CUT_CORRELATION) { - EmbedBucket *bucket = NULL; - EmbedBucket *previous = NULL; - EditBone *child = NULL; - EditBone *parent = NULL; - float normal[3] = {0, 0, 0}; - float avg_normal[3]; - int total = 0; - int boneStart = iter.start; - - parent = add_editbone(obedit, "Bone"); - parent->flag = BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL; - VECCOPY(parent->head, head->p); + float invmat[4][4] = { {1, 0, 0, 0}, + {0, 1, 0, 0}, + {0, 0, 1, 0}, + {0, 0, 0, 1}}; + float tmat[3][3] = { {1, 0, 0}, + {0, 1, 0}, + {0, 0, 1}}; + ReebArcIterator arc_iter; + BArcIterator *iter = (BArcIterator*)&arc_iter; + bArmature *arm= obedit->data; - for (previous = nextBucket(&iter), bucket = nextBucket(&iter); - bucket; - previous = bucket, bucket = nextBucket(&iter)) - { - float btail[3]; - float value = 0; - - if (scene->toolsettings->skgen_options & SKGEN_STICK_TO_EMBEDDING) - { - VECCOPY(btail, bucket->p); - } - else - { - float length; - - /* Calculate normal */ - VecSubf(n, bucket->p, parent->head); - length = Normalize(n); - - total += 1; - VecAddf(normal, normal, n); - VECCOPY(avg_normal, normal); - VecMulf(avg_normal, 1.0f / total); - - VECCOPY(btail, avg_normal); - VecMulf(btail, length); - VecAddf(btail, btail, parent->head); - } - - if (scene->toolsettings->skgen_options & SKGEN_ADAPTIVE_DISTANCE) - { - value = calcDistance(arc, boneStart, iter.index, parent->head, btail); - } - else - { - float n[3]; - - VecSubf(n, btail, parent->head); - value = calcVariance(arc, boneStart, iter.index, parent->head, n); - } - - if (value > ADAPTIVE_THRESHOLD) - { - VECCOPY(parent->tail, btail); - - child = add_editbone(obedit, "Bone"); - VECCOPY(child->head, parent->tail); - child->parent = parent; - child->flag |= BONE_CONNECTED|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL; - - parent = child; // new child is next parent - boneStart = iter.index; // start from end - - normal[0] = normal[1] = normal[2] = 0; - total = 0; - } - } - - VECCOPY(parent->tail, tail->p); + initArcIterator(iter, arc, head); - lastBone = parent; /* set last bone in the chain */ + lastBone = subdivideArcBy(arm, arm->edbo, iter, invmat, tmat, nextAdaptativeSubdivision); } - return lastBone; + return lastBone; } float arcLengthRatio(ReebArc *arc) @@ -5497,108 +5455,26 @@ float arcLengthRatio(ReebArc *arc) return embedLength / arcLength; } -EditBone * subdivideByLength(Scene *scene, Object *obedit, ReebArc *arc, ReebNode *head, ReebNode *tail) +EditBone * test_subdivideByLength(Scene *scene, Object *obedit, ReebArc *arc, ReebNode *head, ReebNode *tail) { EditBone *lastBone = NULL; - if ((scene->toolsettings->skgen_options & SKGEN_CUT_LENGTH) && - arcLengthRatio(arc) >= scene->toolsettings->skgen_length_ratio) + arcLengthRatio(arc) >= G.scene->toolsettings->skgen_length_ratio) { - ReebArcIterator iter; - EmbedBucket *bucket = NULL; - EmbedBucket *previous = NULL; - EditBone *child = NULL; - EditBone *parent = NULL; - float lengthLimit = scene->toolsettings->skgen_length_limit; - int same = 0; - - parent = add_editbone(obedit, "Bone"); - parent->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL; - VECCOPY(parent->head, head->p); - - initArcIterator(&iter, arc, head); - - bucket = nextBucket(&iter); + float invmat[4][4] = { {1, 0, 0, 0}, + {0, 1, 0, 0}, + {0, 0, 1, 0}, + {0, 0, 0, 1}}; + float tmat[3][3] = { {1, 0, 0}, + {0, 1, 0}, + {0, 0, 1}}; + ReebArcIterator arc_iter; + BArcIterator *iter = (BArcIterator*)&arc_iter; + bArmature *arm= obedit->data; - while (bucket != NULL) - { - float *vec0 = NULL; - float *vec1 = bucket->p; - - /* first bucket. Previous is head */ - if (previous == NULL) - { - vec0 = head->p; - } - /* Previous is a valid bucket */ - else - { - vec0 = previous->p; - } - - /* If lengthLimit hits the current segment */ - if (VecLenf(vec1, parent->head) > lengthLimit) - { - if (same == 0) - { - float dv[3], off[3]; - float a, b, c, f; - - /* Solve quadratic distance equation */ - VecSubf(dv, vec1, vec0); - a = Inpf(dv, dv); - - VecSubf(off, vec0, parent->head); - b = 2 * Inpf(dv, off); - - c = Inpf(off, off) - (lengthLimit * lengthLimit); - - f = (-b + (float)sqrt(b * b - 4 * a * c)) / (2 * a); - - //printf("a %f, b %f, c %f, f %f\n", a, b, c, f); - - if (isnan(f) == 0 && f < 1.0f) - { - VECCOPY(parent->tail, dv); - VecMulf(parent->tail, f); - VecAddf(parent->tail, parent->tail, vec0); - } - else - { - VECCOPY(parent->tail, vec1); - } - } - else - { - float dv[3]; - - VecSubf(dv, vec1, vec0); - Normalize(dv); - - VECCOPY(parent->tail, dv); - VecMulf(parent->tail, lengthLimit); - VecAddf(parent->tail, parent->tail, parent->head); - } - - child = add_editbone(obedit, "Bone"); - VECCOPY(child->head, parent->tail); - child->parent = parent; - child->flag |= BONE_CONNECTED|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL; - - parent = child; // new child is next parent - - same = 1; // mark as same - } - else - { - previous = bucket; - bucket = nextBucket(&iter); - same = 0; // Reset same - } - } - VECCOPY(parent->tail, tail->p); + initArcIterator(iter, arc, head); - lastBone = parent; /* set last bone in the chain */ + lastBone = subdivideArcBy(arm, arm->edbo, iter, invmat, tmat, nextLengthSubdivision); } return lastBone; @@ -5693,13 +5569,13 @@ void generateSkeletonFromReebGraph(Scene *scene, ReebGraph *rg) switch(scene->toolsettings->skgen_subdivisions[i]) { case SKGEN_SUB_LENGTH: - lastBone = subdivideByLength(scene, obedit, arc, head, tail); + lastBone = test_subdivideByLength(scene, obedit, arc, head, tail); break; case SKGEN_SUB_ANGLE: lastBone = subdivideByAngle(scene, obedit, arc, head, tail); break; case SKGEN_SUB_CORRELATION: - lastBone = subdivideByCorrelation(scene, obedit, arc, head, tail); + lastBone = test_subdivideByCorrelation(scene, obedit, arc, head, tail); break; } } diff --git a/source/blender/editors/armature/reeb.h b/source/blender/editors/armature/reeb.h index c4c062196fc..6aeb0a37f78 100644 --- a/source/blender/editors/armature/reeb.h +++ b/source/blender/editors/armature/reeb.h @@ -25,7 +25,7 @@ #ifndef REEB_H_ #define REEB_H_ -//#define WITH_BF_REEB +#define WITH_BF_REEB #include "DNA_listBase.h" @@ -60,6 +60,7 @@ typedef struct EmbedBucket { float val; int nv; float p[3]; + float no[3]; /* if non-null, normal of the bucket */ } EmbedBucket; typedef struct ReebNode { @@ -76,6 +77,8 @@ typedef struct ReebNode { int symmetry_flag; float symmetry_axis[3]; /*********************************/ + + float no[3]; int index; float weight; @@ -114,12 +117,23 @@ typedef struct ReebArc { } ReebArc; typedef struct ReebArcIterator { - struct ReebArc *arc; + HeadFct head; + TailFct tail; + PeekFct peek; + NextFct next; + NextNFct nextN; + PreviousFct previous; + StoppedFct stopped; + + float *p, *no; + + int length; int index; + /*********************************/ + struct ReebArc *arc; int start; int end; - int stride; - int length; + int stride; } ReebArcIterator; struct EditMesh; @@ -136,15 +150,9 @@ void renormalizeWeight(struct EditMesh *em, float newmax); ReebGraph * generateReebGraph(struct EditMesh *me, int subdivisions); ReebGraph * newReebGraph(); -void initArcIterator(struct ReebArcIterator *iter, struct ReebArc *arc, struct ReebNode *head); -void initArcIterator2(struct ReebArcIterator *iter, struct ReebArc *arc, int start, int end); -void initArcIteratorStart(struct ReebArcIterator *iter, struct ReebArc *arc, struct ReebNode *head, int start); -struct EmbedBucket * nextBucket(struct ReebArcIterator *iter); -struct EmbedBucket * nextNBucket(ReebArcIterator *iter, int n); -struct EmbedBucket * peekBucket(ReebArcIterator *iter, int n); -struct EmbedBucket * currentBucket(struct ReebArcIterator *iter); -struct EmbedBucket * previousBucket(struct ReebArcIterator *iter); -int iteratorStopped(struct ReebArcIterator *iter); +void initArcIterator(BArcIterator *iter, struct ReebArc *arc, struct ReebNode *head); +void initArcIterator2(BArcIterator *iter, struct ReebArc *arc, int start, int end); +void initArcIteratorStart(BArcIterator *iter, struct ReebArc *arc, struct ReebNode *head, int start); /* Filtering */ void filterNullReebGraph(ReebGraph *rg); @@ -182,6 +190,7 @@ ReebNode *BIF_lowestLevelNode(ReebNode *node); ReebGraph *BIF_graphForMultiNode(ReebGraph *rg, ReebNode *node); void REEB_freeGraph(ReebGraph *rg); +void REEB_freeArc(BArc *barc); void REEB_exportGraph(ReebGraph *rg, int count); void REEB_draw(); diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 830d36dcfd8..cc1d7fb1f81 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -3490,8 +3490,7 @@ static int toggle_cyclic_exec(bContext *C, wmOperator *op) Nurb *nu; BezTriple *bezt; BPoint *bp; - float *fp; - int a, b, direction= RNA_enum_get(op->ptr, "direction"); + int a, direction= RNA_enum_get(op->ptr, "direction"); for(nu= editnurb->first; nu; nu= nu->next) { if( nu->pntsu>1 || nu->pntsv>1) { @@ -3500,8 +3499,7 @@ static int toggle_cyclic_exec(bContext *C, wmOperator *op) bp= nu->bp; while(a--) { if( bp->f1 & SELECT ) { - if(nu->flagu & CU_CYCLIC) nu->flagu &= ~CU_CYCLIC; - else nu->flagu |= CU_CYCLIC; + nu->flagu ^= CU_CYCLIC; break; } bp++; @@ -3512,8 +3510,7 @@ static int toggle_cyclic_exec(bContext *C, wmOperator *op) bezt= nu->bezt; while(a--) { if( BEZSELECTED_HIDDENHANDLES(bezt) ) { - if(nu->flagu & CU_CYCLIC) nu->flagu &= ~CU_CYCLIC; - else nu->flagu |= CU_CYCLIC; + nu->flagu ^= CU_CYCLIC; break; } bezt++; @@ -3526,19 +3523,8 @@ static int toggle_cyclic_exec(bContext *C, wmOperator *op) bp= nu->bp; while(a--) { if( bp->f1 & SELECT ) { - if(nu->flagu & CU_CYCLIC) nu->flagu &= ~CU_CYCLIC; - else { - nu->flagu |= CU_CYCLIC; - nu->flagu &= ~2; /* endpoint flag, fixme */ - fp= MEM_mallocN(sizeof(float)*KNOTSU(nu), "makecyclicN"); - b= (nu->orderu+nu->pntsu); - memcpy(fp, nu->knotsu, sizeof(float)*b); - MEM_freeN(nu->knotsu); - nu->knotsu= fp; - - makeknots(nu, 1, 0); /* 1==u 0==uniform */ - - } + nu->flagu ^= CU_CYCLIC; + makeknots(nu, 1, nu->flagu>>1); /* 1==u type is ignored for cyclic curves */ break; } bp++; @@ -3552,38 +3538,12 @@ static int toggle_cyclic_exec(bContext *C, wmOperator *op) if( bp->f1 & SELECT) { if(direction==0 && nu->pntsu>1) { - if(nu->flagu & CU_CYCLIC) nu->flagu &= ~CU_CYCLIC; - else { - nu->flagu |= CU_CYCLIC; - if (check_valid_nurb_u(nu)) { - fp= MEM_mallocN(sizeof(float)*KNOTSU(nu), "makecyclicN"); - b= (nu->orderu+nu->pntsu); - if (nu->knotsu) { /* null if check_valid_nurb_u failed before but is valid now */ - memcpy(fp, nu->knotsu, sizeof(float)*b); - MEM_freeN(nu->knotsu); - } - nu->knotsu= fp; - - makeknots(nu, 1, 0); /* 1==u 0==uniform */ - } - } + nu->flagu ^= CU_CYCLIC; + makeknots(nu, 1, nu->flagu>>1); /* 1==u type is ignored for cyclic curves */ } if(direction==1 && nu->pntsv>1) { - if(nu->flagv & 1) nu->flagv--; - else { - nu->flagv++; - if (check_valid_nurb_v(nu)) { - fp= MEM_mallocN(sizeof(float)*KNOTSV(nu), "makecyclicN"); - b= (nu->orderv+nu->pntsv); - if (nu->knotsv) { /* null if check_valid_nurb_v failed before but is valid now */ - memcpy(fp, nu->knotsv, sizeof(float)*b); - MEM_freeN(nu->knotsv); - } - nu->knotsv= fp; - - makeknots(nu, 2, 0); /* 2==v 0==uniform */ - } - } + nu->flagv ^= CU_CYCLIC; + makeknots(nu, 2, nu->flagv>>1); /* 2==v type is ignored for cyclic curves */ } break; } diff --git a/source/blender/editors/gpencil/gpencil.c b/source/blender/editors/gpencil/gpencil.c index dfe76ac6a07..7a251f2c252 100644 --- a/source/blender/editors/gpencil/gpencil.c +++ b/source/blender/editors/gpencil/gpencil.c @@ -944,7 +944,7 @@ static void gp_stroke_to_bonechain (bGPDlayer *gpl, bGPDstroke *gps, bArmature * /* add new bone - note: sync with editarmature.c::add_editbone() */ { BLI_strncpy(ebo->name, "Stroke", 32); - unique_editbone_name(bones, ebo->name); + unique_editbone_name(bones, ebo->name, NULL); BLI_addtail(bones, ebo); diff --git a/source/blender/editors/include/BIF_transform.h b/source/blender/editors/include/BIF_transform.h index 2cb07b35632..f8fb78d8559 100644 --- a/source/blender/editors/include/BIF_transform.h +++ b/source/blender/editors/include/BIF_transform.h @@ -95,6 +95,7 @@ struct TransInfo; struct ScrArea; struct Base; struct Scene; +struct Object; void BIF_setSingleAxisConstraint(float vec[3], char *text); void BIF_setDualAxisConstraint(float vec1[3], float vec2[3], char *text); @@ -130,5 +131,33 @@ void ManipulatorTransform(); //int BIF_do_manipulator(struct ScrArea *sa); //void BIF_draw_manipulator(struct ScrArea *sa); +/* Snapping */ + + +typedef struct DepthPeel +{ + struct DepthPeel *next, *prev; + + float depth; + float p[3]; + float no[3]; + struct Object *ob; + int flag; +} DepthPeel; + +struct ListBase; + +typedef enum SnapMode +{ + SNAP_ALL = 0, + SNAP_NOT_SELECTED = 1, + SNAP_NOT_OBEDIT = 2 +} SnapMode; + +#define SNAP_MIN_DISTANCE 30 + +int snapObjects(struct TransInfo *t, int *dist, float *loc, float *no, SnapMode mode); +int peelObjects(struct TransInfo *t, struct ListBase *depth_peels, short mval[2]); + #endif diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 290c7bfbcad..a6eb7be8615 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -111,7 +111,7 @@ void create_vgroups_from_armature(struct Scene *scene, struct Object *ob, struct void docenter_armature (struct Scene *scene, struct View3D *v3d, struct Object *ob, int centermode); void auto_align_armature(struct Scene *scene, struct View3D *v3d, short mode); -void unique_editbone_name (ListBase *edbo, char *name); +void unique_editbone_name(struct ListBase *ebones, char *name, EditBone *bone); /* if bone is already in list, pass it as param to ignore it */ void armature_bone_rename(Object *ob, char *oldnamep, char *newnamep); void undo_push_armature(struct bContext *C, char *name); diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 128af0fd36a..fbe6362db7c 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -91,6 +91,7 @@ void viewline(struct ARegion *ar, struct View3D *v3d, short mval[2], float ray_s void viewray(struct ARegion *ar, struct View3D *v3d, short mval[2], float ray_start[3], float ray_normal[3]); int get_view3d_viewplane(struct View3D *v3d, struct RegionView3D *rv3d, int winxi, int winyi, rctf *viewplane, float *clipsta, float *clipend, float *pixsize); +int get_view3d_ortho(struct View3D *v3d, struct RegionView3D *rv3d); void view3d_get_object_project_mat(struct RegionView3D *v3d, struct Object *ob, float pmat[4][4], float vmat[4][4]); void view3d_project_float(struct ARegion *a, float *vec, float *adr, float mat[4][4]); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 79c0cf5eae0..194ccd285bf 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -2424,12 +2424,13 @@ void autocomplete_do_name(AutoComplete *autocpl, const char *name) } void autocomplete_end(AutoComplete *autocpl, char *autoname) -{ +{ if(autocpl->truncate[0]) BLI_strncpy(autoname, autocpl->truncate, autocpl->maxlen); - else - BLI_strncpy(autoname, autocpl->startname, autocpl->maxlen); - + else { + if (autoname != autocpl->startname) /* dont copy a string over its self */ + BLI_strncpy(autoname, autocpl->startname, autocpl->maxlen); + } MEM_freeN(autocpl->truncate); MEM_freeN(autocpl); } diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index fd6719d63bb..bff2e0dd81b 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -5101,7 +5101,11 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op) if(G.f & G_TEXTUREPAINT) { G.f &= ~G_TEXTUREPAINT; + + if(U.glreslimit != 0) + GPU_free_images(); GPU_paint_set_mipmap(1); + toggle_paint_cursor(C, 0); } else { @@ -5112,7 +5116,11 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op) NULL, me->totface); brush_check_exists(&scene->toolsettings->imapaint.brush); + + if(U.glreslimit != 0) + GPU_free_images(); GPU_paint_set_mipmap(0); + toggle_paint_cursor(C, 1); } diff --git a/source/blender/editors/space_buttons/SConscript b/source/blender/editors/space_buttons/SConscript index d36dd89b681..541da52f7f9 100644 --- a/source/blender/editors/space_buttons/SConscript +++ b/source/blender/editors/space_buttons/SConscript @@ -7,4 +7,12 @@ incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf' incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' incs += ' ../../makesrna ../../render/extern/include' -env.BlenderLib ( 'bf_editors_space_buttons', sources, Split(incs), [], libtype=['core'], priority=[120] ) +defs = [] + +if env['WITH_BF_GAMEENGINE']: + defs.append('GAMEBLENDER=1') + + if env['WITH_BF_SOLID']: + defs.append('USE_SUMO_SOLID') + +env.BlenderLib ( 'bf_editors_space_buttons', sources, Split(incs), defs, libtype=['core'], priority=[120] ) diff --git a/source/blender/editors/space_file/Makefile b/source/blender/editors/space_file/Makefile index 7a41f66fb1d..480a4ee3889 100644 --- a/source/blender/editors/space_file/Makefile +++ b/source/blender/editors/space_file/Makefile @@ -54,3 +54,8 @@ CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include # own include CPPFLAGS += -I../include + +ifeq ($(WITH_OPENJPEG),true) + CPPFLAGS += -DWITH_OPENJPEG +endif + diff --git a/source/blender/editors/space_image/image_panels.c b/source/blender/editors/space_image/image_panels.c index c0fe8afd036..9f6a379ff2b 100644 --- a/source/blender/editors/space_image/image_panels.c +++ b/source/blender/editors/space_image/image_panels.c @@ -459,6 +459,7 @@ static void image_panel_view_properties(const bContext *C, ARegion *ar) uiDefButBitI(block, TOG, ME_DRAWEDGES, B_REDR, "Edges", 70, 30,60,19, &me->drawflag, 0, 0, 0, 0, "Displays selected edges using hilights in the 3d view and UV editor"); uiDefButBitI(block, TOG, SI_DRAWSHADOW, B_REDR, "Final Shadow", 130, 30,110,19, &sima->flag, 0, 0, 0, 0, "Draw the final result from the objects modifiers"); + uiDefButBitI(block, TOG, SI_DRAW_OTHER, B_REDR, "Other Objs", 230, 30, 80, 19, &sima->flag, 0, 0, 0, 0, "Also draw all 3d view selected mesh objects that use this image"); uiDefButBitI(block, TOG, SI_DRAW_STRETCH, B_REDR, "UV Stretch", 10,0,100,19, &sima->flag, 0, 0, 0, 0, "Difference between UV's and the 3D coords (blue for low distortion, red is high)"); if (sima->flag & SI_DRAW_STRETCH) { diff --git a/source/blender/editors/space_info/SConscript b/source/blender/editors/space_info/SConscript index faedcbfa587..9723a7fcfe2 100644 --- a/source/blender/editors/space_info/SConscript +++ b/source/blender/editors/space_info/SConscript @@ -6,4 +6,12 @@ sources = env.Glob('*.c') incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf ../../blenfont' incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' -env.BlenderLib ( 'bf_editors_space_info', sources, Split(incs), [], libtype=['core'], priority=[70] ) +defs = [] + +if env['WITH_BF_GAMEENGINE']: + defs.append('GAMEBLENDER=1') + + if env['WITH_BF_SOLID']: + defs.append('USE_SUMO_SOLID') + +env.BlenderLib ( 'bf_editors_space_info', sources, Split(incs), defs, libtype=['core'], priority=[70] ) diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index a9a3591c54f..0aad0cdd775 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -169,7 +169,7 @@ Sequence *get_forground_frame_seq(Scene *scene, int frame) if(!ed) return NULL; for (seq=ed->seqbasep->first; seq; seq= seq->next) { - if(seq->startdisp > frame || seq->enddisp <= frame) + if(seq->flag & SEQ_MUTE || seq->startdisp > frame || seq->enddisp <= frame) continue; /* only use elements you can see - not */ if (ELEM6(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE, SEQ_MOVIE_AND_HD_SOUND, SEQ_COLOR)) { diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index 5eb7caf50f1..1807de9efbb 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -353,9 +353,10 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O solidtex= 1; Gtexdraw.islit= -1; } - else + else { /* draw with lights in the scene otherwise */ - Gtexdraw.islit= GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat); + Gtexdraw.islit= GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat, get_view3d_ortho(v3d, rv3d)); + } obcol[0]= CLAMPIS(ob->col[0]*255, 0, 255); obcol[1]= CLAMPIS(ob->col[1]*255, 0, 255); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index f9a5195860d..2bb532288ef 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -1097,14 +1097,15 @@ void lattice_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, BPo float *co = dl?dl->verts:NULL; float pmat[4][4], vmat[4][4]; int i, N = lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw; - short s[2]; + short s[2] = {IS_CLIPPED, 0}; view3d_get_object_project_mat(vc->rv3d, vc->obedit, pmat, vmat); for (i=0; i<N; i++, bp++, co+=3) { if (bp->hide==0) { view3d_project_short_clip(vc->ar, dl?co:bp->vec, s, pmat, vmat); - func(userData, bp, s[0], s[1]); + if (s[0] != IS_CLIPPED) + func(userData, bp, s[0], s[1]); } } } @@ -1198,16 +1199,18 @@ static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co { struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; ViewContext vc; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData; EditVert *eve = EM_get_vert_for_index(index); - short s[2]; if (eve->h==0) { + short s[2]= {IS_CLIPPED, 0}; + if (data->clipVerts) { view3d_project_short_clip(data->vc.ar, co, s, data->pmat, data->vmat); } else { view3d_project_short_noclip(data->vc.ar, co, s, data->pmat); } - data->func(data->userData, eve, s[0], s[1], index); + if (s[0]!=IS_CLIPPED) + data->func(data->userData, eve, s[0], s[1], index); } } @@ -1309,7 +1312,7 @@ void nurbs_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, Nurb { Curve *cu= vc->obedit->data; float pmat[4][4], vmat[4][4]; - short s[2]; + short s[2] = {IS_CLIPPED, 0}; Nurb *nu; int i; @@ -1345,7 +1348,8 @@ void nurbs_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, Nurb if(bp->hide==0) { view3d_project_short_clip(vc->ar, bp->vec, s, pmat, vmat); - func(userData, nu, bp, NULL, -1, s[0], s[1]); + if (s[0] != IS_CLIPPED) + func(userData, nu, bp, NULL, -1, s[0], s[1]); } } } diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index d3af8a05faf..26b6dcc22ff 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -1557,6 +1557,144 @@ static void view3d_panel_gpencil(const bContext *C, ARegion *ar, short cntrl) // uiEndBlock(C, block); } +/* XXX etch-a-ton */ +#if 0 +static void delete_sketch_armature(void *arg1, void *arg2) +{ + BIF_deleteSketch(); +} + +static void convert_sketch_armature(void *arg1, void *arg2) +{ + BIF_convertSketch(); +} + +static void assign_template_sketch_armature(void *arg1, void *arg2) +{ + int index = *(int*)arg1; + BIF_setTemplate(index); +} +static void view3d_panel_bonesketch_spaces(short cntrl) +{ + static int template_index; + static char joint_label[128]; + uiBlock *block; + uiBut *but; + char *bone_name; + int yco = 130, height = 140; + int nb_joints; + + /* replace with check call to sketching lib */ + if (G.obedit && G.obedit->type == OB_ARMATURE) + { + static char subdiv_tooltip[4][64] = { + "Subdivide arcs based on a fixed number of bones", + "Subdivide arcs in bones of equal length", + "Subdivide arcs based on correlation", + "Retarget template to stroke" + }; + + + block= uiNewBlock(&curarea->uiblocks, "view3d_panel_bonesketch_spaces", UI_EMBOSS, UI_HELV, curarea->win); + uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); + uiSetPanelHandler(VIEW3D_HANDLER_BONESKETCH); // for close and esc + + if(uiNewPanel(curarea, block, "Bone Sketching", "View3d", 10, 230, 250, height)==0) return; + + uiNewPanelHeight(block, height); + + uiBlockBeginAlign(block); + + /* use real flag instead of 1 */ + uiDefButBitC(block, TOG, BONE_SKETCHING, B_REDR, "Use Bone Sketching", 10, yco, 160, 20, &G.scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Use sketching to create and edit bones"); + uiDefButBitC(block, TOG, BONE_SKETCHING_ADJUST, B_REDR, "A", 170, yco, 20, 20, &G.scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Adjust strokes by drawing near them"); + uiDefButBitC(block, TOG, BONE_SKETCHING_QUICK, B_REDR, "Q", 190, yco, 20, 20, &G.scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Automatically convert and delete on stroke end"); + yco -= 20; + + but = uiDefBut(block, BUT, B_REDR, "Convert", 10,yco,100,20, 0, 0, 0, 0, 0, "Convert sketch to armature"); + uiButSetFunc(but, convert_sketch_armature, NULL, NULL); + + but = uiDefBut(block, BUT, B_REDR, "Delete", 110,yco,100,20, 0, 0, 0, 0, 0, "Delete sketch"); + uiButSetFunc(but, delete_sketch_armature, NULL, NULL); + yco -= 20; + + uiBlockEndAlign(block); + + uiBlockBeginAlign(block); + + uiDefButC(block, MENU, B_REDR, "Subdivision Method%t|Length%x1|Adaptative%x2|Fixed%x0|Template%x3", 10,yco,60,19, &G.scene->toolsettings->bone_sketching_convert, 0, 0, 0, 0, subdiv_tooltip[(unsigned char)G.scene->toolsettings->bone_sketching_convert]); + + switch(G.scene->toolsettings->bone_sketching_convert) + { + case SK_CONVERT_CUT_LENGTH: + uiDefButF(block, NUM, B_REDR, "Lim:", 70, yco, 140, 19, &G.scene->toolsettings->skgen_length_limit,0.1,50.0, 10, 0, "Maximum length of the subdivided bones"); + yco -= 20; + break; + case SK_CONVERT_CUT_ADAPTATIVE: + uiDefButF(block, NUM, B_REDR, "Thres:", 70, yco, 140, 19, &G.scene->toolsettings->skgen_correlation_limit,0.0, 1.0, 0.01, 0, "Correlation threshold for subdivision"); + yco -= 20; + break; + default: + case SK_CONVERT_CUT_FIXED: + uiDefButC(block, NUM, B_REDR, "Num:", 70, yco, 140, 19, &G.scene->toolsettings->skgen_subdivision_number,1, 100, 1, 5, "Number of subdivided bones"); + yco -= 20; + break; + case SK_CONVERT_RETARGET: + uiDefButC(block, ROW, B_DIFF, "No", 70, yco, 40,19, &G.scene->toolsettings->skgen_retarget_roll, 0, 0, 0, 0, "No special roll treatment"); + uiDefButC(block, ROW, B_DIFF, "View", 110, yco, 50,19, &G.scene->toolsettings->skgen_retarget_roll, 0, SK_RETARGET_ROLL_VIEW, 0, 0, "Roll bones perpendicular to view"); + uiDefButC(block, ROW, B_DIFF, "Joint", 160, yco, 50,19, &G.scene->toolsettings->skgen_retarget_roll, 0, SK_RETARGET_ROLL_JOINT, 0, 0, "Roll bones relative to joint bend"); + yco -= 30; + + uiBlockEndAlign(block); + + uiBlockBeginAlign(block); + /* button here to select what to do (copy or not), template, ...*/ + + BIF_makeListTemplates(); + template_index = BIF_currentTemplate(); + + but = uiDefButI(block, MENU, B_REDR, BIF_listTemplates(), 10,yco,200,19, &template_index, 0, 0, 0, 0, "Template"); + uiButSetFunc(but, assign_template_sketch_armature, &template_index, NULL); + + yco -= 20; + + uiDefButF(block, NUM, B_DIFF, "A:", 10, yco, 66,19, &G.scene->toolsettings->skgen_retarget_angle_weight, 0, 10, 1, 0, "Angle Weight"); + uiDefButF(block, NUM, B_DIFF, "L:", 76, yco, 67,19, &G.scene->toolsettings->skgen_retarget_length_weight, 0, 10, 1, 0, "Length Weight"); + uiDefButF(block, NUM, B_DIFF, "D:", 143,yco, 67,19, &G.scene->toolsettings->skgen_retarget_distance_weight, 0, 10, 1, 0, "Distance Weight"); + yco -= 20; + + uiDefBut(block, TEX,B_DIFF,"S:", 10, yco, 90, 20, G.scene->toolsettings->skgen_side_string, 0.0, 8.0, 0, 0, "Text to replace &S with"); + uiDefBut(block, TEX,B_DIFF,"N:", 100, yco, 90, 20, G.scene->toolsettings->skgen_num_string, 0.0, 8.0, 0, 0, "Text to replace &N with"); + uiDefIconButBitC(block, TOG, SK_RETARGET_AUTONAME, B_DIFF, ICON_AUTO,190,yco,20,20, &G.scene->toolsettings->skgen_retarget_options, 0, 0, 0, 0, "Use Auto Naming"); + yco -= 20; + + /* auto renaming magic */ + uiBlockEndAlign(block); + + nb_joints = BIF_nbJointsTemplate(); + + if (nb_joints == -1) + { + nb_joints = G.totvertsel; + } + + bone_name = BIF_nameBoneTemplate(); + + BLI_snprintf(joint_label, 32, "%i joints: %s", nb_joints, bone_name); + + uiDefBut(block, LABEL, 1, joint_label, 10, yco, 200, 20, NULL, 0.0, 0.0, 0, 0, ""); + yco -= 20; + break; + } + + uiBlockEndAlign(block); + + uiDefButBitS(block, TOG, SCE_SNAP_PEEL_OBJECT, B_DIFF, "Peel Objects", 10, yco, 200, 20, &G.scene->snap_flag, 0, 0, 0, 0, "Peel whole objects as one"); + + if(yco < 0) uiNewPanelHeight(block, height-yco); + } +} +#endif void view3d_buttons_area_defbuts(const bContext *C, ARegion *ar) { @@ -1570,6 +1708,7 @@ void view3d_buttons_area_defbuts(const bContext *C, ARegion *ar) view3d_panel_transform_spaces(C, ar, 0); if(0) view3d_panel_gpencil(C, ar, 0); + // XXX etch-a-ton view3d_panel_bonesketch_spaces(C, ar, 0); uiDrawPanels(C, 1); /* 1 = align */ uiMatchPanelsView2d(ar); /* sets v2d->totrct */ diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 80728a77244..7531193dc92 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -2053,6 +2053,8 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) // if (v3d->flag2 & V3D_DISPGP) // draw_gpencil_3dview(ar, 1); + // XXX etch-a-ton BDR_drawSketch(); + ED_region_pixelspace(ar); /* Draw Sculpt Mode brush XXX (removed) */ diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index a7dd419f672..d1ac6976515 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -133,6 +133,7 @@ static int retopo_mesh_paint_check() {return 0;} #define VIEW3D_HANDLER_MULTIRES 5 #define VIEW3D_HANDLER_TRANSFORM 6 #define VIEW3D_HANDLER_GREASEPENCIL 7 +#define VIEW3D_HANDLER_BONESKETCH 8 /* end XXX ************* */ @@ -3718,6 +3719,9 @@ static void do_view3d_edit_armaturemenu(bContext *C, void *arg, int event) case 22: /* separate */ separate_armature(); break; + case 23: /* bone sketching panel */ + add_blockhandler(curarea, VIEW3D_HANDLER_BONESKETCH, UI_PNL_UNSTOW); + break; } #endif @@ -3796,6 +3800,7 @@ static uiBlock *view3d_edit_armaturemenu(bContext *C, ARegion *ar, void *arg_unu uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Transform Properties|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Bone Sketching|P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 23, ""); uiDefIconTextBlockBut(block, view3d_transformmenu, NULL, ICON_RIGHTARROW_THIN, "Transform", 0, yco-=20, 120, 19, ""); uiDefIconTextBlockBut(block, view3d_edit_mirrormenu, NULL, ICON_RIGHTARROW_THIN, "Mirror", 0, yco-=20, menuwidth, 19, ""); uiDefIconTextBlockBut(block, view3d_edit_snapmenu, NULL, ICON_RIGHTARROW_THIN, "Snap", 0, yco-=20, 120, 19, ""); @@ -4847,6 +4852,7 @@ static char *snapmode_pup(void) str += sprintf(str, "%s", "|Vertex%x0"); str += sprintf(str, "%s", "|Edge%x1"); str += sprintf(str, "%s", "|Face%x2"); + str += sprintf(str, "%s", "|Volume%x3"); return string; } diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index b1bd39a66da..072aab55ed4 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -71,6 +71,9 @@ #include "ED_screen.h" #include "ED_view3d.h" +// XXX etch-a-ton #include "BIF_sketch.h" +// XXX etch-a-ton #include "BDR_sketch.h" + #include "UI_interface.h" #include "UI_resources.h" #include "UI_view2d.h" @@ -802,7 +805,28 @@ void project_float_noclip(ARegion *ar, float *vec, float *adr) } } - +int get_view3d_ortho(View3D *v3d, RegionView3D *rv3d) +{ + Camera *cam; + + if(rv3d->persp==V3D_CAMOB) { + if(v3d->camera && v3d->camera->type==OB_CAMERA) { + cam= v3d->camera->data; + + if(cam && cam->type==CAM_ORTHO) + return 1; + else + return 0; + } + else + return 0; + } + + if(rv3d->persp==V3D_ORTHO) + return 1; + + return 0; +} /* also exposed in previewrender.c */ int get_view3d_viewplane(View3D *v3d, RegionView3D *rv3d, int winxi, int winyi, rctf *viewplane, float *clipsta, float *clipend, float *pixsize) @@ -1120,8 +1144,13 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b if(vc->obedit && vc->obedit->type==OB_MBALL) { draw_object(scene, ar, v3d, BASACT, DRAW_PICKING|DRAW_CONSTCOLOR); } - else if ((vc->obedit && vc->obedit->type==OB_ARMATURE)) { - draw_object(scene, ar, v3d, BASACT, DRAW_PICKING|DRAW_CONSTCOLOR); + else if((vc->obedit && vc->obedit->type==OB_ARMATURE)) { + /* XXX etch-a-ton if(BIF_fullSketchMode()) { + BDR_drawSketchNames(); + } + else*/ { + draw_object(scene, ar, v3d, BASACT, DRAW_PICKING|DRAW_CONSTCOLOR); + } } else { Base *base; @@ -1236,7 +1265,7 @@ static void initlocalview(Scene *scene, ScrArea *sa) locallay= free_localbit(); if(locallay==0) { - printf("Sorry, no more than 8 localviews\n"); // XXX error + printf("Sorry, no more than 8 localviews\n"); // XXX error ok= 0; } else { diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 6676459e59f..6a94dc68d3e 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -671,7 +671,7 @@ static void bone_children_clear_transflag(TransInfo *t, ListBase *lb) { bone->flag |= BONE_HINGE_CHILD_TRANSFORM; } - else if (bone->flag & BONE_TRANSFORM && (t->mode == TFM_ROTATION || t->mode == TFM_TRACKBALL)) + else if (bone->flag & BONE_TRANSFORM && (t->mode == TFM_ROTATION || t->mode == TFM_TRACKBALL) && t->around == V3D_LOCAL) { bone->flag |= BONE_TRANSFORM_CHILD; } @@ -4049,7 +4049,7 @@ static void set_trans_object_base_flags(bContext *C, TransInfo *t) if(parsel) { - if (t->mode == TFM_ROTATION || t->mode == TFM_TRACKBALL) + if ((t->mode == TFM_ROTATION || t->mode == TFM_TRACKBALL) && t->around == V3D_LOCAL) { base->flag |= BA_TRANSFORM_CHILD; } diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 447c4b810ab..73b858aa8ca 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -34,6 +34,8 @@ #include "PIL_time.h" +#include "DNA_action_types.h" +#include "DNA_armature_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_meshdata_types.h" // Temporary, for snapping to other unselected meshes @@ -44,6 +46,7 @@ #include "BLI_arithb.h" #include "BLI_editVert.h" +#include "BLI_blenlib.h" //#include "BDR_drawobject.h" // @@ -57,6 +60,8 @@ //#include "BIF_drawimage.h" //#include "BIF_editmesh.h" +#include "BIF_transform.h" + #include "BKE_global.h" #include "BKE_utildefines.h" #include "BKE_DerivedMesh.h" @@ -64,6 +69,7 @@ #include "BKE_anim.h" /* for duplis */ #include "BKE_context.h" +#include "ED_armature.h" #include "ED_image.h" #include "ED_mesh.h" #include "ED_uvedit.h" @@ -100,12 +106,6 @@ float RotationBetween(TransInfo *t, float p1[3], float p2[3]); float TranslationBetween(TransInfo *t, float p1[3], float p2[3]); float ResizeBetween(TransInfo *t, float p1[3], float p2[3]); -/* Modes */ -#define SNAP_ALL 0 -#define SNAP_NOT_SELECTED 1 -#define SNAP_NOT_OBEDIT 2 -int snapObjects(TransInfo *t, int *dist, float *loc, float *no, int mode); - /****************** IMPLEMENTATIONS *********************/ @@ -113,7 +113,7 @@ int BIF_snappingSupported(Object *obedit) { int status = 0; - if (obedit == NULL || obedit->type==OB_MESH) /* only support object or mesh */ + if (obedit == NULL || ELEM(obedit->type, OB_MESH, OB_ARMATURE)) /* only support object mesh or armature */ { status = 1; } @@ -289,7 +289,7 @@ void initSnapping(TransInfo *t) /* Edit mode */ if (t->tsnap.applySnap != NULL && // A snapping function actually exist (scene->snap_flag & SCE_SNAP) && // Only if the snap flag is on - (obedit != NULL && obedit->type==OB_MESH) ) // Temporary limited to edit mode meshes + (obedit != NULL && ELEM(obedit->type, OB_MESH, OB_ARMATURE)) ) // Temporary limited to edit mode meshes or armature { t->tsnap.status |= SNAP_ON; t->tsnap.modePoint = SNAP_GEO; @@ -503,85 +503,162 @@ void CalcSnapGrid(TransInfo *t, float *vec) void CalcSnapGeometry(TransInfo *t, float *vec) { - /* Object mode */ - if (t->obedit == NULL) + if (t->spacetype == SPACE_VIEW3D) { - if (t->spacetype == SPACE_VIEW3D) + float loc[3]; + float no[3]; + int found = 0; + int dist = SNAP_MIN_DISTANCE; // Use a user defined value here + SnapMode mode; + + if (t->scene->snap_mode == SCE_SNAP_MODE_VOLUME) { - float vec[3]; - float no[3]; - int found = 0; - int dist = 40; // Use a user defined value here + ListBase depth_peels; + DepthPeel *p1, *p2; + float *last_p = NULL; + float dist = FLT_MAX; + float p[3]; + + depth_peels.first = depth_peels.last = NULL; + + peelObjects(t, &depth_peels, t->mval); + +// if (stk->nb_points > 0 && stk->points[stk->nb_points - 1].type == PT_CONTINUOUS) +// { +// last_p = stk->points[stk->nb_points - 1].p; +// } +// else if (LAST_SNAP_POINT_VALID) +// { +// last_p = LAST_SNAP_POINT; +// } - found = snapObjects(t, &dist, vec, no, t->tsnap.mode); - if (found == 1) + + for (p1 = depth_peels.first; p1; p1 = p1->next) { - float tangent[3]; - - VecSubf(tangent, vec, t->tsnap.snapPoint); - tangent[2] = 0; - - if (Inpf(tangent, tangent) > 0) + if (p1->flag == 0) { - VECCOPY(t->tsnap.snapTangent, tangent); + float vec[3]; + float new_dist; + + p2 = NULL; + p1->flag = 1; + + /* if peeling objects, take the first and last from each object */ + if (t->scene->snap_flag & SCE_SNAP_PEEL_OBJECT) + { + DepthPeel *peel; + for (peel = p1->next; peel; peel = peel->next) + { + if (peel->ob == p1->ob) + { + peel->flag = 1; + p2 = peel; + } + } + } + /* otherwise, pair first with second and so on */ + else + { + for (p2 = p1->next; p2 && p2->ob != p1->ob; p2 = p2->next) + { + /* nothing to do here */ + } + } + + if (p2) + { + p2->flag = 1; + + VecAddf(vec, p1->p, p2->p); + VecMulf(vec, 0.5f); + } + else + { + VECCOPY(vec, p1->p); + } + + if (last_p == NULL) + { + VECCOPY(p, vec); + dist = 0; + break; + } + + new_dist = VecLenf(last_p, vec); + + if (new_dist < dist) + { + VECCOPY(p, vec); + dist = new_dist; + } } - - VECCOPY(t->tsnap.snapPoint, vec); - VECCOPY(t->tsnap.snapNormal, no); - - t->tsnap.status |= POINT_INIT; } - else + + if (dist != FLT_MAX) { - t->tsnap.status &= ~POINT_INIT; + VECCOPY(loc, p); + found = 1; } + + BLI_freelistN(&depth_peels); } - } - /* Mesh edit mode */ - else if (t->obedit->type==OB_MESH) - { - if (t->spacetype == SPACE_VIEW3D) + else { - float vec[3]; - float no[3]; - int found = 0; - int dist = 40; // Use a user defined value here - - found = snapObjects(t, &dist, vec, no, t->tsnap.mode); - if (found == 1) + if (t->obedit == NULL) { - VECCOPY(t->tsnap.snapPoint, vec); - VECCOPY(t->tsnap.snapNormal, no); - - t->tsnap.status |= POINT_INIT; + mode = SNAP_NOT_SELECTED; } else { - t->tsnap.status &= ~POINT_INIT; + mode = SNAP_NOT_OBEDIT; } + + found = snapObjects(t, &dist, loc, no, mode); } - else if (t->spacetype == SPACE_IMAGE) + + if (found == 1) { - /* same as above but for UV's */ - Image *ima= ED_space_image(t->sa->spacedata.first); - float aspx, aspy, co[2]; + float tangent[3]; - UI_view2d_region_to_view(&t->ar->v2d, t->mval[0], t->mval[1], co, co+1); - - if(ED_uvedit_nearest_uv(t->scene, t->obedit, ima, co, t->tsnap.snapPoint)) - { - ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy); - t->tsnap.snapPoint[0] *= aspx; - t->tsnap.snapPoint[1] *= aspy; - - Mat4MulVecfl(t->obedit->obmat, t->tsnap.snapPoint); - - t->tsnap.status |= POINT_INIT; - } - else + VecSubf(tangent, loc, t->tsnap.snapPoint); + tangent[2] = 0; + + if (Inpf(tangent, tangent) > 0) { - t->tsnap.status &= ~POINT_INIT; + VECCOPY(t->tsnap.snapTangent, tangent); } + + VECCOPY(t->tsnap.snapPoint, loc); + VECCOPY(t->tsnap.snapNormal, no); + + t->tsnap.status |= POINT_INIT; + } + else + { + t->tsnap.status &= ~POINT_INIT; + } + } + else if (t->spacetype == SPACE_IMAGE && t->obedit != NULL && t->obedit->type==OB_MESH) + { /* same as above but for UV's */ + /* same as above but for UV's */ + Image *ima= ED_space_image(t->sa->spacedata.first); + float aspx, aspy, co[2]; + + UI_view2d_region_to_view(&t->ar->v2d, t->mval[0], t->mval[1], co, co+1); + + if(ED_uvedit_nearest_uv(t->scene, t->obedit, ima, co, t->tsnap.snapPoint)) + { + ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy); + t->tsnap.snapPoint[0] *= aspx; + t->tsnap.snapPoint[1] *= aspy; + + Mat4MulVecfl(t->obedit->obmat, t->tsnap.snapPoint); + + t->tsnap.status |= POINT_INIT; + } + else + { + t->tsnap.status &= ~POINT_INIT; } } } @@ -757,6 +834,251 @@ void TargetSnapClosest(TransInfo *t) } /*================================================================*/ +int snapFace(TransInfo *t, float v1co[3], float v2co[3], float v3co[3], float *v4co, short mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth) +{ + float lambda; + int result; + int retval = 0; + + result = RayIntersectsTriangleThreshold(ray_start_local, ray_normal_local, v1co, v2co, v3co, &lambda, NULL, 0.001); + + if (result) { + float location[3], normal[3]; + float intersect[3]; + float new_depth; + int screen_loc[2]; + int new_dist; + + VECCOPY(intersect, ray_normal_local); + VecMulf(intersect, lambda); + VecAddf(intersect, intersect, ray_start_local); + + VECCOPY(location, intersect); + + if (v4co) + CalcNormFloat4(v1co, v2co, v3co, v4co, normal); + else + CalcNormFloat(v1co, v2co, v3co, normal); + + Mat4MulVecfl(obmat, location); + + new_depth = VecLenf(location, ray_start); + + project_int(t->ar, location, screen_loc); + new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); + + if (new_dist <= *dist && new_depth < *depth) + { + *depth = new_depth; + retval = 1; + + VECCOPY(loc, location); + VECCOPY(no, normal); + + Mat3MulVecfl(timat, no); + Normalize(no); + + *dist = new_dist; + } + } + + return retval; +} + +int snapEdge(TransInfo *t, float v1co[3], short v1no[3], float v2co[3], short v2no[3], short mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth) +{ + float intersect[3] = {0, 0, 0}, ray_end[3], dvec[3]; + int result; + int retval = 0; + + VECCOPY(ray_end, ray_normal_local); + VecMulf(ray_end, 2000); + VecAddf(ray_end, ray_start_local, ray_end); + + result = LineIntersectLine(v1co, v2co, ray_start_local, ray_end, intersect, dvec); /* dvec used but we don't care about result */ + + if (result) + { + float edge_loc[3], vec[3]; + float mul; + + /* check for behind ray_start */ + VecSubf(dvec, intersect, ray_start_local); + + VecSubf(edge_loc, v1co, v2co); + VecSubf(vec, intersect, v2co); + + mul = Inpf(vec, edge_loc) / Inpf(edge_loc, edge_loc); + + if (mul > 1) { + mul = 1; + VECCOPY(intersect, v1co); + } + else if (mul < 0) { + mul = 0; + VECCOPY(intersect, v2co); + } + + if (Inpf(ray_normal_local, dvec) > 0) + { + float location[3]; + float new_depth; + int screen_loc[2]; + int new_dist; + + VECCOPY(location, intersect); + + Mat4MulVecfl(obmat, location); + + new_depth = VecLenf(location, ray_start); + + project_int(t->ar, location, screen_loc); + new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); + + /* 10% threshold if edge is closer but a bit further + * this takes care of series of connected edges a bit slanted w.r.t the viewport + * otherwise, it would stick to the verts of the closest edge and not slide along merrily + * */ + if (new_dist <= *dist && new_depth < *depth * 1.001) + { + float n1[3], n2[3]; + + *depth = new_depth; + retval = 1; + + VecSubf(edge_loc, v1co, v2co); + VecSubf(vec, intersect, v2co); + + mul = Inpf(vec, edge_loc) / Inpf(edge_loc, edge_loc); + + if (no) + { + NormalShortToFloat(n1, v1no); + NormalShortToFloat(n2, v2no); + VecLerpf(no, n2, n1, mul); + Mat3MulVecfl(timat, no); + Normalize(no); + } + + VECCOPY(loc, location); + + *dist = new_dist; + } + } + } + + return retval; +} + +int snapVertex(TransInfo *t, float vco[3], short vno[3], short mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth) +{ + int retval = 0; + float dvec[3]; + + VecSubf(dvec, vco, ray_start_local); + + if (Inpf(ray_normal_local, dvec) > 0) + { + float location[3]; + float new_depth; + int screen_loc[2]; + int new_dist; + + VECCOPY(location, vco); + + Mat4MulVecfl(obmat, location); + + new_depth = VecLenf(location, ray_start); + + project_int(t->ar, location, screen_loc); + new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); + + if (new_dist <= *dist && new_depth < *depth) + { + *depth = new_depth; + retval = 1; + + VECCOPY(loc, location); + + if (no) + { + NormalShortToFloat(no, vno); + Mat3MulVecfl(timat, no); + Normalize(no); + } + + *dist = new_dist; + } + } + + return retval; +} + +int snapArmature(TransInfo *t, Object *ob, bArmature *arm, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth) +{ + float imat[4][4]; + float ray_start_local[3], ray_normal_local[3]; + int retval = 0; + + Mat4Invert(imat, obmat); + + VECCOPY(ray_start_local, ray_start); + VECCOPY(ray_normal_local, ray_normal); + + Mat4MulVecfl(imat, ray_start_local); + Mat4Mul3Vecfl(imat, ray_normal_local); + + if(arm->edbo) + { + EditBone *eBone; + + for (eBone=arm->edbo->first; eBone; eBone=eBone->next) { + if (eBone->layer & arm->layer) { + /* skip hidden or moving (selected) bones */ + if ((eBone->flag & (BONE_HIDDEN_A|BONE_ROOTSEL|BONE_TIPSEL))==0) { + switch (t->scene->snap_mode) + { + case SCE_SNAP_MODE_VERTEX: + retval |= snapVertex(t, eBone->head, NULL, mval, ray_start, ray_start_local, ray_normal_local, obmat, NULL, loc, NULL, dist, depth); + retval |= snapVertex(t, eBone->tail, NULL, mval, ray_start, ray_start_local, ray_normal_local, obmat, NULL, loc, NULL, dist, depth); + break; + case SCE_SNAP_MODE_EDGE: + retval |= snapEdge(t, eBone->head, NULL, eBone->tail, NULL, mval, ray_start, ray_start_local, ray_normal_local, obmat, NULL, loc, NULL, dist, depth); + break; + } + } + } + } + } + else if (ob->pose && ob->pose->chanbase.first) + { + bPoseChannel *pchan; + Bone *bone; + + for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + bone= pchan->bone; + /* skip hidden bones */ + if (bone && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))) { + float *head_vec = pchan->pose_head; + float *tail_vec = pchan->pose_tail; + + switch (t->scene->snap_mode) + { + case SCE_SNAP_MODE_VERTEX: + retval |= snapVertex(t, head_vec, NULL, mval, ray_start, ray_start_local, ray_normal_local, obmat, NULL, loc, NULL, dist, depth); + retval |= snapVertex(t, tail_vec, NULL, mval, ray_start, ray_start_local, ray_normal_local, obmat, NULL, loc, NULL, dist, depth); + break; + case SCE_SNAP_MODE_EDGE: + retval |= snapEdge(t, head_vec, NULL, tail_vec, NULL, mval, ray_start, ray_start_local, ray_normal_local, obmat, NULL, loc, NULL, dist, depth); + break; + } + } + } + } + + return retval; +} + int snapDerivedMesh(TransInfo *t, Object *ob, DerivedMesh *dm, EditMesh *em, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth) { int retval = 0; @@ -810,8 +1132,6 @@ int snapDerivedMesh(TransInfo *t, Object *ob, DerivedMesh *dm, EditMesh *em, flo for( i = 0; i < totface; i++) { EditFace *efa = NULL; MFace *f = faces + i; - float lambda; - int result; test = 1; /* reset for every face */ @@ -844,91 +1164,20 @@ int snapDerivedMesh(TransInfo *t, Object *ob, DerivedMesh *dm, EditMesh *em, flo if (test) { - result = RayIntersectsTriangle(ray_start_local, ray_normal_local, verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, &lambda, NULL); + int result; + float *v4co = NULL; - if (result) { - float location[3], normal[3]; - float intersect[3]; - float new_depth; - int screen_loc[2]; - int new_dist; - - VECCOPY(intersect, ray_normal_local); - VecMulf(intersect, lambda); - VecAddf(intersect, intersect, ray_start_local); - - VECCOPY(location, intersect); - - if (f->v4) - CalcNormFloat4(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, verts[f->v4].co, normal); - else - CalcNormFloat(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, normal); - - Mat4MulVecfl(obmat, location); - - new_depth = VecLenf(location, ray_start); - - project_int(t->ar, location, screen_loc); - new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); - - if (new_dist <= *dist && new_depth < *depth) - { - *depth = new_depth; - retval = 1; - - VECCOPY(loc, location); - VECCOPY(no, normal); - - Mat3MulVecfl(timat, no); - Normalize(no); - - *dist = new_dist; - } + if (f->v4) + { + v4co = verts[f->v4].co; } - + + result = snapFace(t, verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, v4co, mval, ray_start, ray_start_local, ray_normal_local, obmat, timat, loc, no, dist, depth); + retval |= result; + if (f->v4 && result == 0) { - result = RayIntersectsTriangle(ray_start_local, ray_normal_local, verts[f->v3].co, verts[f->v4].co, verts[f->v1].co, &lambda, NULL); - - if (result) { - float location[3], normal[3]; - float intersect[3]; - float new_depth; - int screen_loc[2]; - int new_dist; - - VECCOPY(intersect, ray_normal_local); - VecMulf(intersect, lambda); - VecAddf(intersect, intersect, ray_start_local); - - VECCOPY(location, intersect); - - if (f->v4) - CalcNormFloat4(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, verts[f->v4].co, normal); - else - CalcNormFloat(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, normal); - - Mat4MulVecfl(obmat, location); - - new_depth = VecLenf(location, ray_start); - - project_int(t->ar, location, screen_loc); - new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); - - if (new_dist <= *dist && new_depth < *depth) - { - *depth = new_depth; - retval = 1; - - VECCOPY(loc, location); - VECCOPY(no, normal); - - Mat3MulVecfl(timat, no); - Normalize(no); - - *dist = new_dist; - } - } + retval |= snapFace(t, verts[f->v3].co, verts[f->v4].co, verts[f->v1].co, verts[f->v2].co, mval, ray_start, ray_start_local, ray_normal_local, obmat, timat, loc, no, dist, depth); } } } @@ -987,40 +1236,7 @@ int snapDerivedMesh(TransInfo *t, Object *ob, DerivedMesh *dm, EditMesh *em, flo if (test) { - float dvec[3]; - - VecSubf(dvec, v->co, ray_start_local); - - if (Inpf(ray_normal_local, dvec) > 0) - { - float location[3]; - float new_depth; - int screen_loc[2]; - int new_dist; - - VECCOPY(location, v->co); - - Mat4MulVecfl(obmat, location); - - new_depth = VecLenf(location, ray_start); - - project_int(t->ar, location, screen_loc); - new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); - - if (new_dist <= *dist && new_depth < *depth) - { - *depth = new_depth; - retval = 1; - - VECCOPY(loc, location); - - NormalShortToFloat(no, v->no); - Mat3MulVecfl(timat, no); - Normalize(no); - - *dist = new_dist; - } - } + retval |= snapVertex(t, v->co, v->no, mval, ray_start, ray_start_local, ray_normal_local, obmat, timat, loc, no, dist, depth); } } @@ -1080,79 +1296,7 @@ int snapDerivedMesh(TransInfo *t, Object *ob, DerivedMesh *dm, EditMesh *em, flo if (test) { - float intersect[3] = {0, 0, 0}, ray_end[3], dvec[3]; - int result; - - VECCOPY(ray_end, ray_normal_local); - VecMulf(ray_end, 2000); - VecAddf(ray_end, ray_start_local, ray_end); - - result = LineIntersectLine(verts[e->v1].co, verts[e->v2].co, ray_start_local, ray_end, intersect, dvec); /* dvec used but we don't care about result */ - - if (result) - { - float edge_loc[3], vec[3]; - float mul; - - /* check for behind ray_start */ - VecSubf(dvec, intersect, ray_start_local); - - VecSubf(edge_loc, verts[e->v1].co, verts[e->v2].co); - VecSubf(vec, intersect, verts[e->v2].co); - - mul = Inpf(vec, edge_loc) / Inpf(edge_loc, edge_loc); - - if (mul > 1) { - mul = 1; - VECCOPY(intersect, verts[e->v1].co); - } - else if (mul < 0) { - mul = 0; - VECCOPY(intersect, verts[e->v2].co); - } - - if (Inpf(ray_normal_local, dvec) > 0) - { - float location[3]; - float new_depth; - int screen_loc[2]; - int new_dist; - - VECCOPY(location, intersect); - - Mat4MulVecfl(obmat, location); - - new_depth = VecLenf(location, ray_start); - - project_int(t->ar, location, screen_loc); - new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); - - if (new_dist <= *dist && new_depth < *depth) - { - float n1[3], n2[3]; - - *depth = new_depth; - retval = 1; - - VecSubf(edge_loc, verts[e->v1].co, verts[e->v2].co); - VecSubf(vec, intersect, verts[e->v2].co); - - mul = Inpf(vec, edge_loc) / Inpf(edge_loc, edge_loc); - - NormalShortToFloat(n1, verts[e->v1].no); - NormalShortToFloat(n2, verts[e->v2].no); - VecLerpf(no, n2, n1, mul); - Normalize(no); - - VECCOPY(loc, location); - - Mat3MulVecfl(timat, no); - Normalize(no); - - *dist = new_dist; - } - } - } + retval |= snapEdge(t, verts[e->v1].co, verts[e->v1].no, verts[e->v2].co, verts[e->v2].no, mval, ray_start, ray_start_local, ray_normal_local, obmat, timat, loc, no, dist, depth); } } @@ -1169,7 +1313,44 @@ int snapDerivedMesh(TransInfo *t, Object *ob, DerivedMesh *dm, EditMesh *em, flo return retval; } -int snapObjects(TransInfo *t, int *dist, float *loc, float *no, int mode) { +int snapObject(TransInfo *t, Object *ob, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth) +{ + int editobject = 0; + int retval = 0; + + if (ob == t->obedit) + { + editobject = 1; + } + + if (ob->type == OB_MESH) { + EditMesh *em; + DerivedMesh *dm; + + if (editobject) + { + em = ((Mesh *)ob->data)->edit_mesh; + dm = editmesh_get_derived_cage(t->scene, t->obedit, em, CD_MASK_BAREMESH); + } + else + { + em = NULL; + dm = mesh_get_derived_final(t->scene, ob, CD_MASK_BAREMESH); + } + + retval = snapDerivedMesh(t, ob, dm, em, obmat, ray_start, ray_normal, mval, loc, no, dist, depth); + + dm->release(dm); + } + else if (ob->type == OB_ARMATURE) + { + retval = snapArmature(t, ob, ob->data, obmat, ray_start, ray_normal, mval, loc, no, dist, depth); + } + + return retval; +} + +int snapObjects(TransInfo *t, int *dist, float *loc, float *no, SnapMode mode) { Scene *scene = t->scene; View3D *v3d = t->view; Base *base; @@ -1181,23 +1362,215 @@ int snapObjects(TransInfo *t, int *dist, float *loc, float *no, int mode) { if (mode == SNAP_ALL && t->obedit) { - DerivedMesh *dm; Object *ob = t->obedit; - EditMesh *em = ((Mesh *)t->obedit->data)->edit_mesh; - dm = editmesh_get_derived_cage(t->scene, t->obedit, em, CD_MASK_BAREMESH); + retval |= snapObject(t, ob, ob->obmat, ray_start, ray_normal, t->mval, loc, no, dist, &depth); + } + + base= FIRSTBASE; + for ( base = FIRSTBASE; base != NULL; base = base->next ) { + if ( BASE_SELECTABLE(v3d, base) && (base->flag & (BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA)) == 0 && ((mode == SNAP_NOT_SELECTED && (base->flag & (SELECT|BA_WAS_SEL)) == 0) || (mode == SNAP_NOT_OBEDIT && base != BASACT)) ) { + Object *ob = base->object; + + if (ob->transflag & OB_DUPLI) + { + DupliObject *dupli_ob; + ListBase *lb = object_duplilist(t->scene, ob); + + for(dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) + { + Object *ob = dupli_ob->ob; + + retval |= snapObject(t, ob, dupli_ob->mat, ray_start, ray_normal, t->mval, loc, no, dist, &depth); + } + + free_object_duplilist(lb); + } + + retval |= snapObject(t, ob, ob->obmat, ray_start, ray_normal, t->mval, loc, no, dist, &depth); + } + } + + return retval; +} + +/******************** PEELING *********************************/ + + +int cmpPeel(void *arg1, void *arg2) +{ + DepthPeel *p1 = arg1; + DepthPeel *p2 = arg2; + int val = 0; + + if (p1->depth < p2->depth) + { + val = -1; + } + else if (p1->depth > p2->depth) + { + val = 1; + } + + return val; +} + +void removeDoublesPeel(ListBase *depth_peels) +{ + DepthPeel *peel; + + for (peel = depth_peels->first; peel; peel = peel->next) + { + DepthPeel *next_peel = peel->next; - retval = snapDerivedMesh(t, ob, dm, em, ob->obmat, ray_start, ray_normal, t->mval, loc, no, dist, &depth); + if (peel && next_peel && ABS(peel->depth - next_peel->depth) < 0.0015) + { + peel->next = next_peel->next; + + if (next_peel->next) + { + next_peel->next->prev = peel; + } + + MEM_freeN(next_peel); + } + } +} + +void addDepthPeel(ListBase *depth_peels, float depth, float p[3], float no[3], Object *ob) +{ + DepthPeel *peel = MEM_callocN(sizeof(DepthPeel), "DepthPeel"); + + peel->depth = depth; + peel->ob = ob; + VECCOPY(peel->p, p); + VECCOPY(peel->no, no); + + BLI_addtail(depth_peels, peel); + + peel->flag = 0; +} + +int peelDerivedMesh(TransInfo *t, Object *ob, DerivedMesh *dm, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], ListBase *depth_peels) +{ + int retval = 0; + int totvert = dm->getNumVerts(dm); + int totface = dm->getNumFaces(dm); + + if (totvert > 0) { + float imat[4][4]; + float timat[3][3]; /* transpose inverse matrix for normals */ + float ray_start_local[3], ray_normal_local[3]; + int test = 1; + + Mat4Invert(imat, obmat); + + Mat3CpyMat4(timat, imat); + Mat3Transp(timat); - dm->release(dm); + VECCOPY(ray_start_local, ray_start); + VECCOPY(ray_normal_local, ray_normal); + + Mat4MulVecfl(imat, ray_start_local); + Mat4Mul3Vecfl(imat, ray_normal_local); + + + /* If number of vert is more than an arbitrary limit, + * test against boundbox first + * */ + if (totface > 16) { + struct BoundBox *bb = object_get_boundbox(ob); + test = ray_hit_boundbox(bb, ray_start_local, ray_normal_local); + } + + if (test == 1) { + MVert *verts = dm->getVertArray(dm); + MFace *faces = dm->getFaceArray(dm); + int i; + + for( i = 0; i < totface; i++) { + MFace *f = faces + i; + float lambda; + int result; + + + result = RayIntersectsTriangleThreshold(ray_start_local, ray_normal_local, verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, &lambda, NULL, 0.001); + + if (result) { + float location[3], normal[3]; + float intersect[3]; + float new_depth; + + VECCOPY(intersect, ray_normal_local); + VecMulf(intersect, lambda); + VecAddf(intersect, intersect, ray_start_local); + + VECCOPY(location, intersect); + + if (f->v4) + CalcNormFloat4(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, verts[f->v4].co, normal); + else + CalcNormFloat(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, normal); + + Mat4MulVecfl(obmat, location); + + new_depth = VecLenf(location, ray_start); + + Mat3MulVecfl(timat, normal); + Normalize(normal); + + addDepthPeel(depth_peels, new_depth, location, normal, ob); + } + + if (f->v4 && result == 0) + { + result = RayIntersectsTriangleThreshold(ray_start_local, ray_normal_local, verts[f->v3].co, verts[f->v4].co, verts[f->v1].co, &lambda, NULL, 0.001); + + if (result) { + float location[3], normal[3]; + float intersect[3]; + float new_depth; + + VECCOPY(intersect, ray_normal_local); + VecMulf(intersect, lambda); + VecAddf(intersect, intersect, ray_start_local); + + VECCOPY(location, intersect); + + if (f->v4) + CalcNormFloat4(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, verts[f->v4].co, normal); + else + CalcNormFloat(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, normal); + + Mat4MulVecfl(obmat, location); + + new_depth = VecLenf(location, ray_start); + + Mat3MulVecfl(timat, normal); + Normalize(normal); + + addDepthPeel(depth_peels, new_depth, location, normal, ob); + } + } + } + } } + + return retval; +} + +int peelObjects(TransInfo *t, ListBase *depth_peels, short mval[2]) +{ + Scene *scene= t->scene; + View3D *v3d= t->view; + Base *base; + int retval = 0; + float ray_start[3], ray_normal[3]; + viewray(t->ar, v3d, t->mval, ray_start, ray_normal); + for ( base = scene->base.first; base != NULL; base = base->next ) { - if ( BASE_SELECTABLE(v3d, base) && /* SELECTABLE */ - (base->flag & (BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA)) == 0 && /* IS NOT AFFECTED BY TRANSFORM */ - ( (mode == SNAP_NOT_SELECTED && (base->flag & (SELECT|BA_WAS_SEL)) == 0) || /* NOT_SELECTED */ - ((mode == SNAP_NOT_OBEDIT || mode == SNAP_ALL) && base->object != t->obedit)) /* OR NOT OBEDIT */ - ) { + if ( BASE_SELECTABLE(v3d, base) ) { Object *ob = base->object; if (ob->transflag & OB_DUPLI) @@ -1211,21 +1584,9 @@ int snapObjects(TransInfo *t, int *dist, float *loc, float *no, int mode) { if (ob->type == OB_MESH) { DerivedMesh *dm; - EditMesh *em; int val; - - if(ob == t->obedit) - { - em = ((Mesh *)ob->data)->edit_mesh; - dm = editmesh_get_derived_cage(t->scene, t->obedit, em, CD_MASK_BAREMESH); - } - else - { - em = NULL; - dm = mesh_get_derived_final(t->scene, ob, CD_MASK_BAREMESH); - } - - val = snapDerivedMesh(t, ob, dm, em, dupli_ob->mat, ray_start, ray_normal, t->mval, loc, no, dist, &depth); + + val = peelDerivedMesh(t, ob, dm, dupli_ob->mat, ray_start, ray_normal, mval, depth_peels); retval = retval || val; @@ -1237,11 +1598,24 @@ int snapObjects(TransInfo *t, int *dist, float *loc, float *no, int mode) { } if (ob->type == OB_MESH) { - DerivedMesh *dm = mesh_get_derived_final(t->scene, ob, CD_MASK_BAREMESH); + EditMesh *em; + DerivedMesh *dm = NULL; int val; - - val = snapDerivedMesh(t, ob, dm, NULL, ob->obmat, ray_start, ray_normal, t->mval, loc, no, dist, &depth); - + + if (ob != t->obedit) + { + dm = mesh_get_derived_final(t->scene, ob, CD_MASK_BAREMESH); + + val = peelDerivedMesh(t, ob, dm, ob->obmat, ray_start, ray_normal, mval, depth_peels); + } + else + { + em = ((Mesh *)ob->data)->edit_mesh; + dm = editmesh_get_derived_cage(t->scene, t->obedit, em, CD_MASK_BAREMESH); + + val = peelDerivedMesh(t, ob, dm, ob->obmat, ray_start, ray_normal, mval, depth_peels); + } + retval = retval || val; dm->release(dm); @@ -1249,6 +1623,9 @@ int snapObjects(TransInfo *t, int *dist, float *loc, float *no, int mode) { } } + BLI_sortlist(depth_peels, cmpPeel); + removeDoublesPeel(depth_peels); + return retval; } diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index 9686d4d6094..34c9dd23b18 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -373,6 +373,45 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFac } } +static void draw_uvs_other(SpaceImage *sima, Scene *scene, Object *obedit, MTFace *activetf) +{ + Base *base; + Image *curimage; + + curimage= (activetf)? activetf->tpage: NULL; + + glColor3ub(96, 96, 96); + + for(base=scene->base.first; base; base=base->next) { + Object *ob= base->object; + + if(!(base->flag & SELECT)) continue; + if(!(base->lay & scene->lay)) continue; + if(ob->restrictflag & OB_RESTRICT_VIEW) continue; + + if((ob->type==OB_MESH) && (ob!=obedit)) { + Mesh *me= ob->data; + + if(me->mtface) { + MFace *mface= me->mface; + MTFace *tface= me->mtface; + int a; + + for(a=me->totface; a>0; a--, tface++, mface++) { + if(tface->tpage == curimage) { + glBegin(GL_LINE_LOOP); + glVertex2fv(tface->uv[0]); + glVertex2fv(tface->uv[1]); + glVertex2fv(tface->uv[2]); + if(mface->v4) glVertex2fv(tface->uv[3]); + glEnd(); + } + } + } + } + } +} + /* draws uv's in the image space */ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) { @@ -397,6 +436,10 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) interpedges= (scene->selectmode & SCE_SELECT_VERTEX); else interpedges= (settings->uv_selectmode == UV_SELECT_VERTEX); + + /* draw other uvs */ + if(sima->flag & SI_DRAW_OTHER) + draw_uvs_other(sima, scene, obedit, activetf); /* 1. draw shadow mesh */ @@ -576,7 +619,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) } glLineWidth(1); - col2[0] = col2[1] = col2[2] = 128; col2[3] = 255; + col2[0] = col2[1] = col2[2] = 192; col2[3] = 255; glColor4ubv((unsigned char *)col2); if(me->drawflag & ME_DRAWEDGES) { |