diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index 74876691dac..989070c1147 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -1174,6 +1174,7 @@ int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Strok SK_Stroke *snap_stk; float vec[3]; float no[3]; + float mval[2]; int found = 0; int dist = SNAP_MIN_DISTANCE; // Use a user defined value here @@ -1197,9 +1198,12 @@ int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Strok point_added = 1; } } + + mval[0] = dd->mval[0]; + mval[1] = dd->mval[1]; /* try to snap to closer object */ - found = snapObjectsContext(C, dd->mval, &dist, vec, no, SNAP_NOT_SELECTED); + found = snapObjectsContext(C, mval, &dist, vec, no, SNAP_NOT_SELECTED); if (found == 1) { pt->type = dd->type; diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index a7ffefba8df..e07cbff429a 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -166,10 +166,10 @@ typedef enum SnapMode #define SNAP_MIN_DISTANCE 30 -int peelObjectsTransForm(struct TransInfo *t, struct ListBase *depth_peels, short mval[2]); -int peelObjectsContext(struct bContext *C, struct ListBase *depth_peels, short mval[2]); -int snapObjectsTransform(struct TransInfo *t, short mval[2], int *dist, float *loc, float *no, SnapMode mode); -int snapObjectsContext(struct bContext *C, short mval[2], int *dist, float *loc, float *no, SnapMode mode); +int peelObjectsTransForm(struct TransInfo *t, struct ListBase *depth_peels, float mval[2]); +int peelObjectsContext(struct bContext *C, struct ListBase *depth_peels, float mval[2]); +int snapObjectsTransform(struct TransInfo *t, float mval[2], int *dist, float *loc, float *no, SnapMode mode); +int snapObjectsContext(struct bContext *C, float mval[2], int *dist, float *loc, float *no, SnapMode mode); #endif diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 7b1022d1a3f..2752402fb66 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -88,8 +88,8 @@ void project_int_noclip(struct ARegion *ar, float *vec, int *adr); void project_float(struct ARegion *ar, float *vec, float *adr); void project_float_noclip(struct ARegion *ar, float *vec, float *adr); -void viewline(struct ARegion *ar, struct View3D *v3d, short mval[2], float ray_start[3], float ray_end[3]); -void viewray(struct ARegion *ar, struct View3D *v3d, short mval[2], float ray_start[3], float ray_normal[3]); +void viewline(struct ARegion *ar, struct View3D *v3d, float mval[2], float ray_start[3], float ray_end[3]); +void viewray(struct ARegion *ar, struct View3D *v3d, float 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); diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index a44e3743bb4..8dcc8791d88 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -2144,6 +2144,10 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) uiDefIconButBitS(block, TOG, SCE_SNAP_PEEL_OBJECT, B_REDR, ICON_SNAP_PEEL_OBJECT,xco,yco,XIC,YIC, &ts->snap_flag, 0, 0, 0, 0, "Consider objects as whole when finding volume center"); xco+= XIC; } + if (ts->snap_mode == SCE_SNAP_MODE_FACE) { + uiDefIconButBitS(block, TOG, SCE_SNAP_PROJECT, B_REDR, ICON_ROTATECOLLECTION,xco,yco,XIC,YIC, &ts->snap_flag, 0, 0, 0, 0, "Project elements instead of snapping them"); + xco+= XIC; + } uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_SNAP_VERTEX, snapmode_pup(), xco,yco,XIC+10,YIC, &(ts->snap_mode), 0.0, 0.0, 0, 0, "Snapping mode"); xco+= XIC + 10; uiDefButS(block, MENU, B_NOP, "Snap Mode%t|Closest%x0|Center%x1|Median%x2|Active%x3",xco,yco,70,YIC, &ts->snap_target, 0, 0, 0, 0, "Snap Target Mode"); diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index fd850e90ff5..8b378f05eb2 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -482,7 +482,7 @@ void VIEW3D_OT_setobjectascamera(wmOperatorType *ot) /* ********************************** */ /* create intersection coordinates in view Z direction at mouse coordinates */ -void viewline(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float ray_end[3]) +void viewline(ARegion *ar, View3D *v3d, float mval[2], float ray_start[3], float ray_end[3]) { RegionView3D *rv3d= ar->regiondata; float vec[4]; @@ -517,7 +517,7 @@ void viewline(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float } /* create intersection ray in view Z direction at mouse coordinates */ -void viewray(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float ray_normal[3]) +void viewray(ARegion *ar, View3D *v3d, float mval[2], float ray_start[3], float ray_normal[3]) { float ray_end[3]; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 0b7a672a0b6..4c24d366162 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -2605,7 +2605,6 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short center = td->center; } else { - /* !TODO! Make this if not rely on G */ if(around==V3D_LOCAL && (t->settings->selectmode & SCE_SELECT_FACE)) { center = td->center; } diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 60786127e3a..5cee1f51b0a 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -87,6 +87,7 @@ typedef struct TransSnap { short modeTarget; short mode; short align; + short project; short status; float snapPoint[3]; /* snapping from this point */ float snapTarget[3]; /* to this point */ @@ -578,6 +579,7 @@ void snapGrid(TransInfo *t, float *val); void snapGridAction(TransInfo *t, float *val, GearsType action); void initSnapping(struct TransInfo *t, struct wmOperator *op); +void applyProject(TransInfo *t); void applySnapping(TransInfo *t, float *vec); void resetSnapping(TransInfo *t); int handleSnapping(TransInfo *t, struct wmEvent *event); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 51ce87803fd..826fcb0c2dd 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -125,7 +125,6 @@ #include "ED_object.h" #include "ED_markers.h" #include "ED_mesh.h" -#include "ED_retopo.h" #include "ED_types.h" #include "ED_uvedit.h" #include "ED_view3d.h" @@ -4478,12 +4477,6 @@ void special_aftertrans_update(TransInfo *t) if (t->obedit) { if (cancelled==0) { EM_automerge(t->scene, t->obedit, 1); -#if 0 // TRANSFORM_FIX_ME - /* when snapping, delay retopo until after automerge */ - if (G.qual & LR_CTRLKEY) { - retopo_do_all(); - } -#endif } } } diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index c3ceea1a0c8..20d136e4790 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -91,7 +91,6 @@ #include "ED_keyframing.h" #include "ED_markers.h" #include "ED_mesh.h" -#include "ED_retopo.h" #include "ED_particle.h" #include "ED_screen_types.h" #include "ED_space_api.h" @@ -617,201 +616,201 @@ void recalcData(TransInfo *t) } } } - else if (t->obedit) { - if ELEM(t->obedit->type, OB_CURVE, OB_SURF) { - Curve *cu= t->obedit->data; - Nurb *nu= cu->editnurb->first; - - DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */ - - if (t->state == TRANS_CANCEL) { - while(nu) { - calchandlesNurb(nu); /* Cant do testhandlesNurb here, it messes up the h1 and h2 flags */ - nu= nu->next; - } - } else { - /* Normal updating */ - while(nu) { - test2DNurb(nu); - calchandlesNurb(nu); - nu= nu->next; - } - /* TRANSFORM_FIX_ME */ - // retopo_do_all(); - } + else if (t->spacetype == SPACE_VIEW3D) { + + /* project */ + if(t->state != TRANS_CANCEL) { + applyProject(t); } - else if(t->obedit->type==OB_LATTICE) { - Lattice *la= t->obedit->data; - DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */ - - if(la->editlatt->flag & LT_OUTSIDE) outside_lattice(la->editlatt); - } - else if (t->obedit->type == OB_MESH) { - if(t->spacetype==SPACE_IMAGE) { - SpaceImage *sima= t->sa->spacedata.first; + + if (t->obedit) { + if ELEM(t->obedit->type, OB_CURVE, OB_SURF) { + Curve *cu= t->obedit->data; + Nurb *nu= cu->editnurb->first; - flushTransUVs(t); - if(sima->flag & SI_LIVE_UNWRAP) - ED_uvedit_live_unwrap_re_solve(); - - DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); - } else { - EditMesh *em = ((Mesh*)t->obedit->data)->edit_mesh; - /* mirror modifier clipping? */ - if(t->state != TRANS_CANCEL) { - /* TRANSFORM_FIX_ME */ -// if ((G.qual & LR_CTRLKEY)==0) { -// /* Only retopo if not snapping, Note, this is the only case of G.qual being used, but we have no T_SHIFT_MOD - Campbell */ -// retopo_do_all(); -// } - clipMirrorModifier(t, t->obedit); - } - if((t->options & CTX_NO_MIRROR) == 0 && (t->flag & T_MIRROR)) - editmesh_apply_to_mirror(t); - DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */ - recalc_editnormals(em); - } - } - else if(t->obedit->type==OB_ARMATURE) { /* no recalc flag, does pose */ - bArmature *arm= t->obedit->data; - ListBase *edbo = arm->edbo; - EditBone *ebo; - TransData *td = t->data; - int i; - - /* Ensure all bones are correctly adjusted */ - for (ebo = edbo->first; ebo; ebo = ebo->next){ - - if ((ebo->flag & BONE_CONNECTED) && ebo->parent){ - /* If this bone has a parent tip that has been moved */ - if (ebo->parent->flag & BONE_TIPSEL){ - VECCOPY (ebo->head, ebo->parent->tail); - if(t->mode==TFM_BONE_ENVELOPE) ebo->rad_head= ebo->parent->rad_tail; + if (t->state == TRANS_CANCEL) { + while(nu) { + calchandlesNurb(nu); /* Cant do testhandlesNurb here, it messes up the h1 and h2 flags */ + nu= nu->next; } - /* If this bone has a parent tip that has NOT been moved */ - else{ - VECCOPY (ebo->parent->tail, ebo->head); - if(t->mode==TFM_BONE_ENVELOPE) ebo->parent->rad_tail= ebo->rad_head; - } - } - - /* on extrude bones, oldlength==0.0f, so we scale radius of points */ - ebo->length= VecLenf(ebo->head, ebo->tail); - if(ebo->oldlength==0.0f) { - ebo->rad_head= 0.25f*ebo->length; - ebo->rad_tail= 0.10f*ebo->length; - ebo->dist= 0.25f*ebo->length; - if(ebo->parent) { - if(ebo->rad_head > ebo->parent->rad_tail) - ebo->rad_head= ebo->parent->rad_tail; - } - } - else if(t->mode!=TFM_BONE_ENVELOPE) { - /* if bones change length, lets do that for the deform distance as well */ - ebo->dist*= ebo->length/ebo->oldlength; - ebo->rad_head*= ebo->length/ebo->oldlength; - ebo->rad_tail*= ebo->length/ebo->oldlength; - ebo->oldlength= ebo->length; - } - } - - - if (t->mode != TFM_BONE_ROLL) - { - /* fix roll */ - for(i = 0; i < t->total; i++, td++) - { - if (td->extra) - { - float vec[3], up_axis[3]; - float qrot[4]; - - ebo = td->extra; - VECCOPY(up_axis, td->axismtx[2]); - - if (t->mode != TFM_ROTATION) - { - VecSubf(vec, ebo->tail, ebo->head); - Normalize(vec); - RotationBetweenVectorsToQuat(qrot, td->axismtx[1], vec); - QuatMulVecf(qrot, up_axis); - } - else - { - Mat3MulVecfl(t->mat, up_axis); - } - - ebo->roll = ED_rollBoneToVector(ebo, up_axis); + } else { + /* Normal updating */ + while(nu) { + test2DNurb(nu); + calchandlesNurb(nu); + nu= nu->next; } } } - - if(arm->flag & ARM_MIRROR_EDIT) - transform_armature_mirror_update(t->obedit); - - } - else - DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */ - } - else if( (t->flag & T_POSE) && t->poseobj) { - Object *ob= t->poseobj; - bArmature *arm= ob->data; - - /* if animtimer is running, and the object already has animation data, - * check if the auto-record feature means that we should record 'samples' - * (i.e. uneditable animation values) - */ - // TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes? - if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) { - int targetless_ik= (t->flag & T_AUTOIK); // XXX this currently doesn't work, since flags aren't set yet! - - animrecord_check_state(t->scene, &ob->id, t->animtimer); - autokeyframe_pose_cb_func(t->scene, (View3D *)t->view, ob, t->mode, targetless_ik); - } - - /* old optimize trick... this enforces to bypass the depgraph */ - if (!(arm->flag & ARM_DELAYDEFORM)) { - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */ - } - else - where_is_pose(scene, ob); - } - else { - for(base= FIRSTBASE; base; base= base->next) { - Object *ob= base->object; - - /* this flag is from depgraph, was stored in initialize phase, handled in drawview.c */ - if(base->flag & BA_HAS_RECALC_OB) - ob->recalc |= OB_RECALC_OB; - if(base->flag & BA_HAS_RECALC_DATA) - ob->recalc |= OB_RECALC_DATA; - - /* if object/base is selected */ - if ((base->flag & SELECT) || (ob->flag & SELECT)) { - /* if animtimer is running, and the object already has animation data, - * check if the auto-record feature means that we should record 'samples' - * (i.e. uneditable animation values) - */ - // TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes? - if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) { - animrecord_check_state(t->scene, &ob->id, t->animtimer); - autokeyframe_ob_cb_func(t->scene, (View3D *)t->view, ob, t->mode); - } - } - - /* proxy exception */ - if(ob->proxy) - ob->proxy->recalc |= ob->recalc; - if(ob->proxy_group) - group_tag_recalc(ob->proxy_group->dup_group); - } - } + else if(t->obedit->type==OB_LATTICE) { + Lattice *la= t->obedit->data; + DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */ - /* update shaded drawmode while transform */ - if(t->spacetype==SPACE_VIEW3D && ((View3D*)t->view)->drawtype == OB_SHADED) - reshadeall_displist(t->scene); + if(la->editlatt->flag & LT_OUTSIDE) outside_lattice(la->editlatt); + } + else if (t->obedit->type == OB_MESH) { + if(t->spacetype==SPACE_IMAGE) { + SpaceImage *sima= t->sa->spacedata.first; + + flushTransUVs(t); + if(sima->flag & SI_LIVE_UNWRAP) + ED_uvedit_live_unwrap_re_solve(); + + DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); + } else { + EditMesh *em = ((Mesh*)t->obedit->data)->edit_mesh; + /* mirror modifier clipping? */ + if(t->state != TRANS_CANCEL) { + clipMirrorModifier(t, t->obedit); + } + if((t->options & CTX_NO_MIRROR) == 0 && (t->flag & T_MIRROR)) + editmesh_apply_to_mirror(t); + + DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */ + + recalc_editnormals(em); + } + } + else if(t->obedit->type==OB_ARMATURE) { /* no recalc flag, does pose */ + bArmature *arm= t->obedit->data; + ListBase *edbo = arm->edbo; + EditBone *ebo; + TransData *td = t->data; + int i; + + /* Ensure all bones are correctly adjusted */ + for (ebo = edbo->first; ebo; ebo = ebo->next){ + + if ((ebo->flag & BONE_CONNECTED) && ebo->parent){ + /* If this bone has a parent tip that has been moved */ + if (ebo->parent->flag & BONE_TIPSEL){ + VECCOPY (ebo->head, ebo->parent->tail); + if(t->mode==TFM_BONE_ENVELOPE) ebo->rad_head= ebo->parent->rad_tail; + } + /* If this bone has a parent tip that has NOT been moved */ + else{ + VECCOPY (ebo->parent->tail, ebo->head); + if(t->mode==TFM_BONE_ENVELOPE) ebo->parent->rad_tail= ebo->rad_head; + } + } + + /* on extrude bones, oldlength==0.0f, so we scale radius of points */ + ebo->length= VecLenf(ebo->head, ebo->tail); + if(ebo->oldlength==0.0f) { + ebo->rad_head= 0.25f*ebo->length; + ebo->rad_tail= 0.10f*ebo->length; + ebo->dist= 0.25f*ebo->length; + if(ebo->parent) { + if(ebo->rad_head > ebo->parent->rad_tail) + ebo->rad_head= ebo->parent->rad_tail; + } + } + else if(t->mode!=TFM_BONE_ENVELOPE) { + /* if bones change length, lets do that for the deform distance as well */ + ebo->dist*= ebo->length/ebo->oldlength; + ebo->rad_head*= ebo->length/ebo->oldlength; + ebo->rad_tail*= ebo->length/ebo->oldlength; + ebo->oldlength= ebo->length; + } + } + + + if (t->mode != TFM_BONE_ROLL) + { + /* fix roll */ + for(i = 0; i < t->total; i++, td++) + { + if (td->extra) + { + float vec[3], up_axis[3]; + float qrot[4]; + + ebo = td->extra; + VECCOPY(up_axis, td->axismtx[2]); + + if (t->mode != TFM_ROTATION) + { + VecSubf(vec, ebo->tail, ebo->head); + Normalize(vec); + RotationBetweenVectorsToQuat(qrot, td->axismtx[1], vec); + QuatMulVecf(qrot, up_axis); + } + else + { + Mat3MulVecfl(t->mat, up_axis); + } + + ebo->roll = ED_rollBoneToVector(ebo, up_axis); + } + } + } + + if(arm->flag & ARM_MIRROR_EDIT) + transform_armature_mirror_update(t->obedit); + + } + else + DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */ + } + else if( (t->flag & T_POSE) && t->poseobj) { + Object *ob= t->poseobj; + bArmature *arm= ob->data; + + /* if animtimer is running, and the object already has animation data, + * check if the auto-record feature means that we should record 'samples' + * (i.e. uneditable animation values) + */ + // TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes? + if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) { + int targetless_ik= (t->flag & T_AUTOIK); // XXX this currently doesn't work, since flags aren't set yet! + + animrecord_check_state(t->scene, &ob->id, t->animtimer); + autokeyframe_pose_cb_func(t->scene, (View3D *)t->view, ob, t->mode, targetless_ik); + } + + /* old optimize trick... this enforces to bypass the depgraph */ + if (!(arm->flag & ARM_DELAYDEFORM)) { + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */ + } + else + where_is_pose(scene, ob); + } + else { + for(base= FIRSTBASE; base; base= base->next) { + Object *ob= base->object; + + /* this flag is from depgraph, was stored in initialize phase, handled in drawview.c */ + if(base->flag & BA_HAS_RECALC_OB) + ob->recalc |= OB_RECALC_OB; + if(base->flag & BA_HAS_RECALC_DATA) + ob->recalc |= OB_RECALC_DATA; + + /* if object/base is selected */ + if ((base->flag & SELECT) || (ob->flag & SELECT)) { + /* if animtimer is running, and the object already has animation data, + * check if the auto-record feature means that we should record 'samples' + * (i.e. uneditable animation values) + */ + // TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes? + if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) { + animrecord_check_state(t->scene, &ob->id, t->animtimer); + autokeyframe_ob_cb_func(t->scene, (View3D *)t->view, ob, t->mode); + } + } + + /* proxy exception */ + if(ob->proxy) + ob->proxy->recalc |= ob->recalc; + if(ob->proxy_group) + group_tag_recalc(ob->proxy_group->dup_group); + } + } + + if(t->spacetype==SPACE_VIEW3D && ((View3D*)t->view)->drawtype == OB_SHADED) + reshadeall_displist(t->scene); + } } void drawLine(TransInfo *t, float *center, float *dir, char axis, short options) diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index b0e79b3b062..3408f6cf3f7 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -63,32 +63,6 @@ EnumPropertyItem proportional_mode_types[] = { {0, NULL, 0, NULL, NULL} }; -EnumPropertyItem snap_mode_types[] = { - {SCE_SNAP_TARGET_CLOSEST, "CLOSEST", 0, "Closest", ""}, - {SCE_SNAP_TARGET_CENTER, "CENTER", 0, "Center", ""}, - {SCE_SNAP_TARGET_MEDIAN, "MEDIAN", 0, "Median", ""}, - {SCE_SNAP_TARGET_ACTIVE, "ACTIVE", 0, "Active", ""}, - {0, NULL, 0, NULL, NULL} -}; - -EnumPropertyItem proportional_falloff_types[] = { - {PROP_SMOOTH, "SMOOTH", 0, "Smooth", ""}, - {PROP_SPHERE, "SPHERE", 0, "Sphere", ""}, - {PROP_ROOT, "ROOT", 0, "Root", ""}, - {PROP_SHARP, "SHARP", 0, "Sharp", ""}, - {PROP_LIN, "LINEAR", 0, "Linear", ""}, - {PROP_CONST, "CONSTANT", 0, "Constant", ""}, - {PROP_RANDOM, "RANDOM", 0, "Random", ""}, - {0, NULL, 0, NULL, NULL} -}; - -EnumPropertyItem orientation_items[]= { - {V3D_MANIP_GLOBAL, "GLOBAL", 0, "Global", ""}, - {V3D_MANIP_NORMAL, "NORMAL", 0, "Normal", ""}, - {V3D_MANIP_LOCAL, "LOCAL", 0, "Local", ""}, - {V3D_MANIP_VIEW, "VIEW", 0, "View", ""}, - {0, NULL, 0, NULL, NULL}}; - char OP_TRANSLATION[] = "TFM_OT_translate"; char OP_ROTATION[] = "TFM_OT_rotate"; char OP_TOSPHERE[] = "TFM_OT_tosphere"; @@ -157,7 +131,8 @@ void TFM_OT_select_orientation(struct wmOperatorType *ot) ot->exec = select_orientation_exec; ot->poll = ED_operator_areaactive; - prop= RNA_def_enum(ot->srna, "orientation", orientation_items, V3D_MANIP_GLOBAL, "Orientation", "DOC_BROKEN"); + prop= RNA_def_property(ot->srna, "orientation", PROP_ENUM, PROP_NONE); + RNA_def_property_ui_text(prop, "Orientation", "Transformation orientation."); RNA_def_enum_funcs(prop, rna_TransformOrientation_itemf); } @@ -374,7 +349,7 @@ void Properties_Proportional(struct wmOperatorType *ot) void Properties_Snapping(struct wmOperatorType *ot, short align) { RNA_def_boolean(ot->srna, "snap", 0, "Snap to Point", ""); - RNA_def_enum(ot->srna, "snap_mode", snap_mode_types, 0, "Mode", ""); + RNA_def_enum(ot->srna, "snap_mode", snap_mode_items, 0, "Mode", ""); RNA_def_float_vector(ot->srna, "snap_point", 3, NULL, -FLT_MAX, FLT_MAX, "Point", "", -FLT_MAX, FLT_MAX); if (align) @@ -389,7 +364,8 @@ void Properties_Constraints(struct wmOperatorType *ot) PropertyRNA *prop; RNA_def_boolean_vector(ot->srna, "constraint_axis", 3, NULL, "Constraint Axis", ""); - prop= RNA_def_enum(ot->srna, "constraint_orientation", orientation_items, V3D_MANIP_GLOBAL, "Orientation", "DOC_BROKEN"); + prop= RNA_def_property(ot->srna, "constraint_orientation", PROP_ENUM, PROP_NONE); + RNA_def_property_ui_text(prop, "Orientation", "Transformation orientation."); RNA_def_enum_funcs(prop, rna_TransformOrientation_itemf); } diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 84dc9e69e7a..0e3f999d47b 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -217,8 +217,69 @@ int handleSnapping(TransInfo *t, wmEvent *event) return status; } +void applyProject(TransInfo *t) +{ + /* XXX FLICKER IN OBJECT MODE */ + if ((t->tsnap.project) && (t->tsnap.status & SNAP_ON) && (t->modifiers & MOD_SNAP_GEARS)) + { + TransData *td = t->data; + float tvec[3]; + float imat[4][4]; + int i; + + if(t->flag & (T_EDIT|T_POSE)) { + Object *ob = t->obedit?t->obedit:t->poseobj; + Mat4Invert(imat, ob->obmat); + } + + for(i = 0 ; i < t->total; i++, td++) { + float iloc[3], loc[3], no[3]; + float mval[2]; + int dist = 1000; + + if (td->flag & TD_NOACTION) + break; + + if (td->flag & TD_SKIP) + continue; + + VECCOPY(iloc, td->loc); + if (t->flag & (T_EDIT|T_POSE)) + { + Object *ob = t->obedit?t->obedit:t->poseobj; + Mat4MulVecfl(ob->obmat, iloc); + } + else if (t->flag & T_OBJECT) + { + VECCOPY(iloc, td->ob->obmat[3]); + } + + project_float(t->ar, iloc, mval); + + if (snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.mode)) + { +// if(t->flag & (T_EDIT|T_POSE)) { +// Mat4MulVecfl(imat, loc); +// } +// + VecSubf(tvec, loc, iloc); + + Mat3MulVecfl(td->smtx, tvec); + + VecAddf(td->loc, td->loc, tvec); + } + + //XXX constraintTransLim(t, td); + } + } +} + void applySnapping(TransInfo *t, float *vec) { + /* project is not applied this way */ + if (t->tsnap.project) + return; + if (t->tsnap.status & SNAP_FORCED) { t->tsnap.targetSnap(t); @@ -305,12 +366,24 @@ void initSnapping(TransInfo *t, wmOperator *op) RNA_float_get_array(op->ptr, "snap_normal", t->tsnap.snapNormal); Normalize(t->tsnap.snapNormal); } + + if (RNA_struct_find_property(op->ptr, "snap_project")) + { + t->tsnap.project = RNA_boolean_get(op->ptr, "snap_project"); + } } } else { snapping = ((ts->snap_flag & SCE_SNAP) == SCE_SNAP); t->tsnap.align = ((t->settings->snap_flag & SCE_SNAP_ROTATE) == SCE_SNAP_ROTATE); + t->tsnap.project = ((t->settings->snap_flag & SCE_SNAP_PROJECT) == SCE_SNAP_PROJECT); + } + + /* force project off when not supported */ + if (ts->snap_mode != SCE_SNAP_MODE_FACE) + { + t->tsnap.project = 0; } if ((t->spacetype == SPACE_VIEW3D || t->spacetype == SPACE_IMAGE) && // Only 3D view or UV @@ -537,9 +610,13 @@ void CalcSnapGeometry(TransInfo *t, float *vec) { float loc[3]; float no[3]; + float mval[2]; int found = 0; int dist = SNAP_MIN_DISTANCE; // Use a user defined value here + mval[0] = t->mval[0]; + mval[1] = t->mval[1]; + if (t->settings->snap_mode == SCE_SNAP_MODE_VOLUME) { ListBase depth_peels; @@ -550,7 +627,7 @@ void CalcSnapGeometry(TransInfo *t, float *vec) depth_peels.first = depth_peels.last = NULL; - peelObjectsTransForm(t, &depth_peels, t->mval); + peelObjectsTransForm(t, &depth_peels, mval); // if (LAST_SNAP_POINT_VALID) // { @@ -633,7 +710,7 @@ void CalcSnapGeometry(TransInfo *t, float *vec) } else { - found = snapObjectsTransform(t, t->mval, &dist, loc, no, t->tsnap.mode); + found = snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.mode); } if (found == 1) @@ -854,7 +931,7 @@ void TargetSnapClosest(TransInfo *t) } /*================================================================*/ -int snapFace(ARegion *ar, 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) +int snapFace(ARegion *ar, float v1co[3], float v2co[3], float v3co[3], float *v4co, float 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; @@ -885,7 +962,7 @@ int snapFace(ARegion *ar, float v1co[3], float v2co[3], float v3co[3], float *v4 new_depth = VecLenf(location, ray_start); project_int(ar, location, screen_loc); - new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); + new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); if (new_dist <= *dist && new_depth < *depth) { @@ -905,7 +982,7 @@ int snapFace(ARegion *ar, float v1co[3], float v2co[3], float v3co[3], float *v4 return retval; } -int snapEdge(ARegion *ar, 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) +int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2no[3], float 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; @@ -953,7 +1030,7 @@ int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2n new_depth = VecLenf(location, ray_start); project_int(ar, location, screen_loc); - new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); + new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)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 @@ -990,7 +1067,7 @@ int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2n return retval; } -int snapVertex(ARegion *ar, 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 snapVertex(ARegion *ar, float vco[3], short vno[3], float 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]; @@ -1011,7 +1088,7 @@ int snapVertex(ARegion *ar, float vco[3], short vno[3], short mval[2], float ray new_depth = VecLenf(location, ray_start); project_int(ar, location, screen_loc); - new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); + new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); if (new_dist <= *dist && new_depth < *depth) { @@ -1034,7 +1111,7 @@ int snapVertex(ARegion *ar, float vco[3], short vno[3], short mval[2], float ray return retval; } -int snapArmature(short snap_mode, ARegion *ar, 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) +int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float obmat[][4], float ray_start[3], float ray_normal[3], float mval[2], float *loc, float *no, int *dist, float *depth) { float imat[4][4]; float ray_start_local[3], ray_normal_local[3]; @@ -1099,7 +1176,7 @@ int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float return retval; } -int snapDerivedMesh(short snap_mode, ARegion *ar, 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 snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, EditMesh *em, float obmat[][4], float ray_start[3], float ray_normal[3], float mval[2], float *loc, float *no, int *dist, float *depth) { int retval = 0; int totvert = dm->getNumVerts(dm); @@ -1333,7 +1410,7 @@ int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, E return retval; } -int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth) +int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obmat[][4], float ray_start[3], float ray_normal[3], float mval[2], float *loc, float *no, int *dist, float *depth) { ToolSettings *ts= scene->toolsettings; int retval = 0; @@ -1365,7 +1442,7 @@ int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obma return retval; } -int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, short mval[2], int *dist, float *loc, float *no, SnapMode mode) { +int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, float mval[2], int *dist, float *loc, float *no, SnapMode mode) { Base *base; float depth = FLT_MAX; int retval = 0; @@ -1382,7 +1459,7 @@ int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, short mv 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)) ) { + 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) || (ELEM(mode, SNAP_ALL, SNAP_NOT_OBEDIT) && base != BASACT)) ) { Object *ob = base->object; if (ob->transflag & OB_DUPLI) @@ -1407,12 +1484,12 @@ int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, short mv return retval; } -int snapObjectsTransform(TransInfo *t, short mval[2], int *dist, float *loc, float *no, SnapMode mode) +int snapObjectsTransform(TransInfo *t, float mval[2], int *dist, float *loc, float *no, SnapMode mode) { return snapObjects(t->scene, t->view, t->ar, t->obedit, mval, dist, loc, no, mode); } -int snapObjectsContext(bContext *C, short mval[2], int *dist, float *loc, float *no, SnapMode mode) +int snapObjectsContext(bContext *C, float mval[2], int *dist, float *loc, float *no, SnapMode mode) { ScrArea *sa = CTX_wm_area(C); View3D *v3d = sa->spacedata.first; @@ -1477,7 +1554,7 @@ void addDepthPeel(ListBase *depth_peels, float depth, float p[3], float no[3], O peel->flag = 0; } -int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], ListBase *depth_peels) +int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_start[3], float ray_normal[3], float mval[2], ListBase *depth_peels) { int retval = 0; int totvert = dm->getNumVerts(dm); @@ -1585,7 +1662,7 @@ int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta return retval; } -int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, ListBase *depth_peels, short mval[2]) +int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, ListBase *depth_peels, float mval[2]) { Base *base; int retval = 0; @@ -1666,12 +1743,12 @@ int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, ListBase return retval; } -int peelObjectsTransForm(TransInfo *t, ListBase *depth_peels, short mval[2]) +int peelObjectsTransForm(TransInfo *t, ListBase *depth_peels, float mval[2]) { return peelObjects(t->scene, t->view, t->ar, t->obedit, depth_peels, mval); } -int peelObjectsContext(bContext *C, ListBase *depth_peels, short mval[2]) +int peelObjectsContext(bContext *C, ListBase *depth_peels, float mval[2]) { ScrArea *sa = CTX_wm_area(C); View3D *v3d = sa->spacedata.first; diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 437b45cfda1..e069136d46a 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -982,6 +982,7 @@ typedef struct Scene { #define SCE_SNAP 1 #define SCE_SNAP_ROTATE 2 #define SCE_SNAP_PEEL_OBJECT 4 +#define SCE_SNAP_PROJECT 8 /* toolsettings->snap_target */ #define SCE_SNAP_TARGET_CLOSEST 0 #define SCE_SNAP_TARGET_CENTER 1 diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index ff4eee8d074..4db76c7f312 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -32,6 +32,7 @@ extern EnumPropertyItem object_mode_items[]; extern EnumPropertyItem prop_mode_items[]; +extern EnumPropertyItem snap_mode_items[]; extern EnumPropertyItem space_type_items[]; extern EnumPropertyItem region_type_items[]; extern EnumPropertyItem modifier_type_items[]; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 4a42a63bf6b..29fb9e4deb2 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -43,7 +43,14 @@ #include "WM_types.h" -/* prop_mode needs to be accessible from transform operator */ + +EnumPropertyItem snap_mode_items[] = { + {SCE_SNAP_TARGET_CLOSEST, "CLOSEST", 0, "Closest", "Snap closest point onto target."}, + {SCE_SNAP_TARGET_CENTER, "CENTER", 0, "Center", "Snap center onto target."}, + {SCE_SNAP_TARGET_MEDIAN, "MEDIAN", 0, "Median", "Snap median onto target."}, + {SCE_SNAP_TARGET_ACTIVE, "ACTIVE", 0, "Active", "Snap active onto target."}, + {0, NULL, 0, NULL, NULL}}; + EnumPropertyItem prop_mode_items[] ={ {PROP_SMOOTH, "SMOOTH", 0, "Smooth", ""}, {PROP_SPHERE, "SPHERE", 0, "Sphere", ""}, @@ -54,6 +61,7 @@ EnumPropertyItem prop_mode_items[] ={ {PROP_RANDOM, "RANDOM", 0, "Random", ""}, {0, NULL, 0, NULL, NULL}}; + #ifdef RNA_RUNTIME #include "DNA_anim_types.h" @@ -489,13 +497,6 @@ static void rna_def_tool_settings(BlenderRNA *brna) {SCE_SNAP_MODE_VOLUME, "VOLUME", ICON_SNAP_VOLUME, "Volume", "Snap to volume."}, {0, NULL, 0, NULL, NULL}}; - static EnumPropertyItem snap_mode_items[] = { - {SCE_SNAP_TARGET_CLOSEST, "CLOSEST", 0, "Closest", "Snap closest point onto target."}, - {SCE_SNAP_TARGET_CENTER, "CENTER", 0, "Center", "Snap center onto target."}, - {SCE_SNAP_TARGET_MEDIAN, "MEDIAN", 0, "Median", "Snap median onto target."}, - {SCE_SNAP_TARGET_ACTIVE, "ACTIVE", 0, "Active", "Snap active onto target."}, - {0, NULL, 0, NULL, NULL}}; - static EnumPropertyItem auto_key_items[] = { {AUTOKEY_MODE_NORMAL, "ADD_REPLACE_KEYS", 0, "Add & Replace", ""}, {AUTOKEY_MODE_EDITKEYS, "REPLACE_KEYS", 0, "Replace", ""}, @@ -570,6 +571,11 @@ static void rna_def_tool_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Snap Peel Object", "Consider objects as whole when finding volume center."); RNA_def_property_ui_icon(prop, ICON_SNAP_PEEL_OBJECT, 0); + prop= RNA_def_property(srna, "snap_project", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "snap_flag", SCE_SNAP_PROJECT); + RNA_def_property_ui_text(prop, "Project Individual Elements", "DOC_BROKEN"); + RNA_def_property_ui_icon(prop, ICON_ROTATECOLLECTION, 0); + /* Auto Keying */ prop= RNA_def_property(srna, "enable_auto_key", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "autokey_mode", AUTOKEY_ON);