=bmesh= merge from trunk at r36529
[blender.git] / source / blender / editors / transform / transform_generics.c
index 03fd48cd598fa67a1818725a12183c88aba7cc10..9a19f1f3205ab9a9387e41ab6e3d5aef7b0e5acb 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
@@ -15,7 +15,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
  * All rights reserved.
  * ***** END GPL LICENSE BLOCK *****
  */
 
+/** \file blender/editors/transform/transform_generics.c
+ *  \ingroup edtransform
+ */
+
+
 #include <string.h>
 #include <math.h>
 
 #include "BLO_sys_types.h" // for intptr_t support
 
 #include "DNA_anim_types.h"
-#include "DNA_action_types.h"
 #include "DNA_armature_types.h"
-#include "DNA_constraint_types.h"
-#include "DNA_curve_types.h"
 #include "DNA_lattice_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_nla_types.h"
-#include "DNA_node_types.h"
-#include "DNA_object_types.h"
-#include "DNA_object_force.h"
-#include "DNA_particle_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_space_types.h"
 #include "DNA_scene_types.h"
-#include "DNA_userdef_types.h"
+#include "DNA_object_types.h"
+#include "DNA_meshdata_types.h"
 #include "DNA_view3d_types.h"
-#include "DNA_windowmanager_types.h"
+#include "DNA_modifier_types.h"
 
 #include "RNA_access.h"
 
 
 #include "BKE_animsys.h"
 #include "BKE_action.h"
-#include "BKE_anim.h"
 #include "BKE_armature.h"
-#include "BKE_cloth.h"
 #include "BKE_curve.h"
 #include "BKE_depsgraph.h"
 #include "BKE_displist.h"
-#include "BKE_depsgraph.h"
 #include "BKE_fcurve.h"
-#include "BKE_global.h"
-#include "BKE_group.h"
 #include "BKE_lattice.h"
-#include "BKE_key.h"
 #include "BKE_mesh.h"
-#include "BKE_modifier.h"
 #include "BKE_nla.h"
-#include "BKE_object.h"
-#include "BKE_utildefines.h"
 #include "BKE_context.h"
 #include "BKE_tessmesh.h"
 
@@ -98,6 +85,7 @@
 #include "ED_space_api.h"
 #include "ED_uvedit.h"
 #include "ED_view3d.h"
+#include "ED_curve.h" /* for ED_curve_editnurbs */
 
 //#include "BDR_unwrapper.h"
 
 #include "BLI_blenlib.h"
 #include "BLI_editVert.h"
 #include "BLI_rand.h"
-
-#include "RNA_access.h"
+#include "BLI_utildefines.h"
 
 #include "WM_types.h"
+#include "WM_api.h"
 
 #include "UI_resources.h"
 
@@ -203,8 +191,8 @@ static void clipMirrorModifier(TransInfo *t, Object *ob)
                                                copy_v3_v3(iloc, td->iloc);
 
                                                if (mmd->mirror_ob) {
-                                                       mul_v3_m4v3(loc, mtx, loc);
-                                                       mul_v3_m4v3(iloc, mtx, iloc);
+                                                       mul_m4_v3(mtx, loc);
+                                                       mul_m4_v3(mtx, iloc);
                                                }
 
                                                clip = 0;
@@ -232,7 +220,7 @@ static void clipMirrorModifier(TransInfo *t, Object *ob)
                                                }
                                                if (clip) {
                                                        if (mmd->mirror_ob) {
-                                                               mul_v3_m4v3(loc, imtx, loc);
+                                                               mul_m4_v3(imtx, loc);
                                                        }
                                                        copy_v3_v3(td->loc, loc);
                                                }
@@ -249,7 +237,6 @@ static void editbmesh_apply_to_mirror(TransInfo *t)
 {
        TransData *td = t->data;
        BMVert *eve;
-       BMIter iter;
        int i;
 
        for(i = 0 ; i < t->total; i++, td++) {
@@ -274,23 +261,6 @@ static void editbmesh_apply_to_mirror(TransInfo *t)
        }
 }
 
-/* tags the given ID block for refreshes (if applicable) due to 
- * Animation Editor editing
- */
-static void animedit_refresh_id_tags (Scene *scene, ID *id)
-{
-       if (id) {
-               AnimData *adt= BKE_animdata_from_id(id);
-               
-               /* tag AnimData for refresh so that other views will update in realtime with these changes */
-               if (adt)
-                       adt->recalc |= ADT_RECALC_ANIM;
-                       
-               /* set recalc flags */
-               DAG_id_flush_update(id, OB_RECALC); // XXX or do we want something more restrictive?
-       }
-}
-
 /* for the realtime animation recording feature, handle overlapping data */
 static void animrecord_check_state (Scene *scene, ID *id, wmTimer *animtimer)
 {
@@ -305,7 +275,7 @@ static void animrecord_check_state (Scene *scene, ID *id, wmTimer *animtimer)
         *      - we're not only keying for available channels
         *      - the option to add new actions for each round is not enabled
         */
-       if (IS_AUTOKEY_FLAG(INSERTAVAIL)==0 && (scene->toolsettings->autokey_flag & ANIMRECORD_FLAG_WITHNLA)) {
+       if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL)==0 && (scene->toolsettings->autokey_flag & ANIMRECORD_FLAG_WITHNLA)) {
                /* if playback has just looped around, we need to add a new NLA track+strip to allow a clean pass to occur */
                if ((sad) && (sad->flag & ANIMPLAY_FLAG_JUMPED)) {
                        AnimData *adt= BKE_animdata_from_id(id);
@@ -339,11 +309,25 @@ static void animrecord_check_state (Scene *scene, ID *id, wmTimer *animtimer)
        }
 }
 
+static int fcu_test_selected(FCurve *fcu)
+{
+       BezTriple *bezt= fcu->bezt;
+       unsigned int i;
+
+       if (bezt==NULL) /* ignore baked */
+               return 0;
+
+       for (i=0; i < fcu->totvert; i++, bezt++) {
+               if (BEZSELECTED(bezt)) return 1;
+       }
+
+       return 0;
+}
+
 /* called for updating while transform acts, once per redraw */
 void recalcData(TransInfo *t)
 {
-       Scene *scene = t->scene;
-       Base *base = scene->basact;
+       Base *base = t->scene->basact;
 
        if (t->spacetype==SPACE_NODE) {
                flushTransNodes(t);
@@ -353,16 +337,15 @@ void recalcData(TransInfo *t)
        }
        else if (t->spacetype == SPACE_ACTION) {
                Scene *scene= t->scene;
+               SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first;
                
-               bAnimContext ac;
+               bAnimContext ac= {NULL};
                ListBase anim_data = {NULL, NULL};
                bAnimListElem *ale;
                int filter;
                
                /* initialise relevant anim-context 'context' data from TransInfo data */
                        /* NOTE: sync this with the code in ANIM_animdata_get_context() */
-               memset(&ac, 0, sizeof(bAnimContext));
-               
                ac.scene= t->scene;
                ac.obact= OBACT;
                ac.sa= t->sa;
@@ -372,21 +355,33 @@ void recalcData(TransInfo *t)
                
                ANIM_animdata_context_getdata(&ac);
                
-               /* get animdata blocks visible in editor, assuming that these will be the ones where things changed */
-               filter= (ANIMFILTER_VISIBLE | ANIMFILTER_ANIMDATA);
-               ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-               
-               /* just tag these animdata-blocks to recalc, assuming that some data there changed */
-               for (ale= anim_data.first; ale; ale= ale->next) {
-                       /* set refresh tags for objects using this animation */
-                       animedit_refresh_id_tags(t->scene, ale->id);
+               /* perform flush */
+               if (ac.datatype == ANIMCONT_GPENCIL) {
+                       /* flush transform values back to actual coordinates */
+                       flushTransGPactionData(t);
+               }
+               else {
+                       /* get animdata blocks visible in editor, assuming that these will be the ones where things changed */
+                       filter= (ANIMFILTER_VISIBLE | ANIMFILTER_ANIMDATA);
+                       ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+                       
+                       /* just tag these animdata-blocks to recalc, assuming that some data there changed 
+                        * BUT only do this if realtime updates are enabled
+                        */
+                       if ((saction->flag & SACTION_NOREALTIMEUPDATES) == 0) {
+                               for (ale= anim_data.first; ale; ale= ale->next) {
+                                       /* set refresh tags for objects using this animation */
+                                       ANIM_list_elem_update(t->scene, ale);
+                               }
+                       }
+                       
+                       /* now free temp channels */
+                       BLI_freelistN(&anim_data);
                }
-               
-               /* now free temp channels */
-               BLI_freelistN(&anim_data);
        }
        else if (t->spacetype == SPACE_IPO) {
                Scene *scene;
+               SpaceIpo *sipo= (SpaceIpo *)t->sa->spacedata.first;
                
                ListBase anim_data = {NULL, NULL};
                bAnimContext ac;
@@ -420,14 +415,25 @@ void recalcData(TransInfo *t)
                for (ale= anim_data.first; ale; ale= ale->next) {
                        FCurve *fcu= (FCurve *)ale->key_data;
                        
+                       /* ignore unselected fcurves */
+                       if (!fcu_test_selected(fcu))
+                               continue;
+                       
+                       // fixme: only do this for selected verts...
+                       ANIM_unit_mapping_apply_fcurve(ac.scene, ale->id, ale->key_data, ANIM_UNITCONV_ONLYSEL|ANIM_UNITCONV_SELVERTS|ANIM_UNITCONV_RESTORE);
+                       
+                       
                        /* watch it: if the time is wrong: do not correct handles yet */
                        if (test_time_fcurve(fcu))
                                dosort++;
                        else
                                calchandles_fcurve(fcu);
-                               
-                       /* set refresh tags for objects using this animation */
-                       animedit_refresh_id_tags(t->scene, ale->id);
+                       
+                       /* set refresh tags for objects using this animation,
+                        * BUT only if realtime updates are enabled  
+                        */
+                       if ((sipo->flag & SIPO_NOREALTIMEUPDATES) == 0)
+                               ANIM_list_elem_update(t->scene, ale);
                }
                
                /* do resort and other updates? */
@@ -457,8 +463,11 @@ void recalcData(TransInfo *t)
                        if (tdn->handle == 0)
                                continue;
                        
-                       /* set refresh tags for objects using this animation */
-                       animedit_refresh_id_tags(t->scene, tdn->id);
+                       /* set refresh tags for objects using this animation,
+                        * BUT only if realtime updates are enabled  
+                        */
+                       if ((snla->flag & SNLA_NOREALTIMEUPDATES) == 0)
+                               ANIM_id_update(t->scene, tdn->id);
                        
                        /* if cancelling transform, just write the values without validating, then move on */
                        if (t->state == TRANS_CANCEL) {
@@ -555,8 +564,8 @@ void recalcData(TransInfo *t)
                        // TODO: do we need to write in 2 passes to make sure that no truncation goes on?
                        RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &strip_ptr);
                        
-                       RNA_float_set(&strip_ptr, "start_frame", tdn->h1[0]);
-                       RNA_float_set(&strip_ptr, "end_frame", tdn->h2[0]);
+                       RNA_float_set(&strip_ptr, "frame_start", tdn->h1[0]);
+                       RNA_float_set(&strip_ptr, "frame_end", tdn->h2[0]);
                        
                        /* flush transforms to child strips (since this should be a meta) */
                        BKE_nlameta_flush_transforms(strip);
@@ -585,7 +594,7 @@ void recalcData(TransInfo *t)
                                                        BKE_nlatrack_add_strip(track, strip);
                                                        
                                                        tdn->nlt= track;
-                                                       tdn->trackIndex += (n + 1); /* + 1, since n==0 would mean that we didn't change track */
+                                                       tdn->trackIndex++;
                                                }
                                                else /* can't move any further */
                                                        break;
@@ -603,7 +612,7 @@ void recalcData(TransInfo *t)
                                                        BKE_nlatrack_add_strip(track, strip);
                                                        
                                                        tdn->nlt= track;
-                                                       tdn->trackIndex -= (n - 1); /* - 1, since n==0 would mean that we didn't change track */
+                                                       tdn->trackIndex--;
                                                }
                                                else /* can't move any further */
                                                        break;
@@ -620,53 +629,60 @@ void recalcData(TransInfo *t)
                        if(sima->flag & SI_LIVE_UNWRAP)
                                ED_uvedit_live_unwrap_re_solve();
                        
-                       DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA);
+                       DAG_id_tag_update(t->obedit->data, 0);
                }
        }
        else if (t->spacetype == SPACE_VIEW3D) {
                
-               /* project */
-               if(t->state != TRANS_CANCEL) {
-                       applyProject(t);
-               }
-               
                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;
+                       if ELEM(t->obedit->type, OB_CURVE, OB_SURF) {
+                               Curve *cu= t->obedit->data;
+                               ListBase *nurbs= ED_curve_editnurbs(cu);
+                               Nurb *nu= nurbs->first;
+
+                               if(t->state != TRANS_CANCEL) {
+                                       clipMirrorModifier(t, t->obedit);
+                                       applyProject(t);
                                }
-                       } else {
-                               /* Normal updating */
-                               while(nu) {
-                                       test2DNurb(nu);
-                                       calchandlesNurb(nu);
-                                       nu= nu->next;
+
+                               DAG_id_tag_update(t->obedit->data, 0);  /* 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;
+                                       }
                                }
-                       }
-               }
-               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 */
+                       } else if(t->obedit->type==OB_LATTICE) {
+                               Lattice *la= t->obedit->data;
 
-                       if(la->editlatt->flag & LT_OUTSIDE) outside_lattice(la->editlatt);
-               }
-               else if (t->obedit->type == OB_MESH) {
+                               if(t->state != TRANS_CANCEL) {
+                                       applyProject(t);
+                               }
+
+                               DAG_id_tag_update(t->obedit->data, 0);  /* sets recalc flags */
+       
+                               if(la->editlatt->latt->flag & LT_OUTSIDE) outside_lattice(la->editlatt->latt);
+                       }
+                       else if (t->obedit->type == OB_MESH) {
                                BMEditMesh *em = ((Mesh*)t->obedit->data)->edit_btmesh;
+
                                /* mirror modifier clipping? */
                                if(t->state != TRANS_CANCEL) {
                                        clipMirrorModifier(t, t->obedit);
+                                       applyProject(t);
                                }
                                if((t->options & CTX_NO_MIRROR) == 0 && (t->flag & T_MIRROR))
                                        editbmesh_apply_to_mirror(t);
 
-                               DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA);  /* sets recalc flags */
+                               DAG_id_tag_update(t->obedit->data, 0);  /* sets recalc flags */
 
                                EDBM_RecalcNormals(em);
                                BMEdit_RecalcTesselation(em);
@@ -678,6 +694,10 @@ void recalcData(TransInfo *t)
                                TransData *td = t->data;
                                int i;
                                
+                               if(t->state != TRANS_CANCEL) {
+                                       applyProject(t);
+                               }
+
                                /* Ensure all bones are correctly adjusted */
                                for (ebo = edbo->first; ebo; ebo = ebo->next){
                                        
@@ -740,7 +760,7 @@ void recalcData(TransInfo *t)
                                                                mul_m3_v3(t->mat, up_axis);
                                                        }
                                                        
-                                                       ebo->roll = ED_rollBoneToVector(ebo, up_axis);
+                                                       ebo->roll = ED_rollBoneToVector(ebo, up_axis, FALSE);
                                                }
                                        }
                                }
@@ -750,7 +770,13 @@ void recalcData(TransInfo *t)
                                
                        }
                        else
-                               DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA);  /* sets recalc flags */
+                       {
+                               if(t->state != TRANS_CANCEL) {
+                                       applyProject(t);
+                               }
+                               DAG_id_tag_update(t->obedit->data, 0);  /* sets recalc flags */
+                       }
+       
                }
                else if( (t->flag & T_POSE) && t->poseobj) {
                        Object *ob= t->poseobj;
@@ -759,38 +785,37 @@ void recalcData(TransInfo *t)
                        /* 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)
+                        *
+                        * context is needed for keying set poll() functions.
                         */
                        // TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes?
-                       if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) {
+                       if ((t->animtimer) && (t->context) && 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);
+                               autokeyframe_pose_cb_func(t->context, 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 */
+                               DAG_id_tag_update(&ob->id, OB_RECALC_DATA);  /* sets recalc flags */
                        }
                        else
-                               where_is_pose(scene, ob);
+                               where_is_pose(t->scene, ob);
                }
-               else if(base && (base->object->mode & OB_MODE_PARTICLE_EDIT) && PE_get_current(scene, base->object)) {
+               else if(base && (base->object->mode & OB_MODE_PARTICLE_EDIT) && PE_get_current(t->scene, base->object)) {
+                       if(t->state != TRANS_CANCEL) {
+                               applyProject(t);
+                       }
                        flushTransParticles(t);
                }
                else {
                        int i;
                        
-                       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(t->state != TRANS_CANCEL) {
+                               applyProject(t);
                        }
-                               
+
                        for (i = 0; i < t->total; i++) {
                                TransData *td = t->data + i;
                                Object *ob = td->ob;
@@ -801,21 +826,20 @@ void recalcData(TransInfo *t)
                                if (td->flag & TD_SKIP)
                                        continue;
                                
-                                       /* 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);
-                                       }
+                               /* 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->context, 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);
+                               /* sets recalc flags fully, instead of flushing existing ones 
+                                * otherwise proxies don't function correctly
+                                */
+                               DAG_id_tag_update(&ob->id, OB_RECALC_OB);
                        }
                }
                
@@ -827,7 +851,7 @@ void recalcData(TransInfo *t)
 void drawLine(TransInfo *t, float *center, float *dir, char axis, short options)
 {
        float v1[3], v2[3], v3[3];
-       char col[3], col2[3];
+       unsigned char col[3], col2[3];
 
        if (t->spacetype == SPACE_VIEW3D)
        {
@@ -851,7 +875,7 @@ void drawLine(TransInfo *t, float *center, float *dir, char axis, short options)
                        UI_GetThemeColor3ubv(TH_GRID, col);
                }
                UI_make_axis_color(col, col2, axis);
-               glColor3ubv((GLubyte *)col2);
+               glColor3ubv(col2);
 
                setlinestyle(0);
                glBegin(GL_LINE_STRIP);
@@ -933,7 +957,32 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
 
        unit_m3(t->mat);
 
-       t->spacetype = sa->spacetype;
+       /* if there's an event, we're modal */
+       if (event) {
+               t->flag |= T_MODAL;
+       }
+
+       /* Crease needs edge flag */
+       if (t->mode == TFM_CREASE) {
+               t->options |= CTX_EDGE;
+       }
+
+
+       /* Assign the space type, some exceptions for running in different mode */
+       if(sa == NULL) {
+               /* background mode */
+               t->spacetype= SPACE_EMPTY;
+       }
+       else if ((ar == NULL) && (sa->spacetype == SPACE_VIEW3D)) {
+               /* running in the text editor */
+               t->spacetype= SPACE_EMPTY;
+       }
+       else {
+               /* normal operation */
+               t->spacetype= sa->spacetype;
+       }
+
+
        if(t->spacetype == SPACE_VIEW3D)
        {
                View3D *v3d = sa->spacedata.first;
@@ -941,6 +990,13 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
                t->view = v3d;
                t->animtimer= CTX_wm_screen(C)->animtimer;
 
+               /* turn manipulator off during transform */
+               // FIXME: but don't do this when USING the manipulator...
+               if (t->flag & T_MODAL) {
+                       t->twtype = v3d->twtype;
+                       v3d->twtype = 0;
+               }
+
                if(v3d->flag & V3D_ALIGN) t->flag |= T_V3D_ALIGN;
                t->around = v3d->around;
 
@@ -948,7 +1004,7 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
                {
                        t->current_orientation = RNA_enum_get(op->ptr, "constraint_orientation");
 
-                       if (t->current_orientation >= V3D_MANIP_CUSTOM + BIF_countTransformOrientation(C) - 1)
+                       if (t->current_orientation >= V3D_MANIP_CUSTOM + BIF_countTransformOrientation(C))
                        {
                                t->current_orientation = V3D_MANIP_GLOBAL;
                        }
@@ -957,14 +1013,27 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
                {
                        t->current_orientation = v3d->twmode;
                }
+
+               /* exceptional case */
+               if(t->around==V3D_LOCAL && (t->settings->selectmode & SCE_SELECT_FACE)) {
+                       if(ELEM3(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL)) {
+                               t->options |= CTX_NO_PET;
+                       }
+               }
        }
-       else if(t->spacetype==SPACE_IMAGE || t->spacetype==SPACE_NODE)
+       else if(t->spacetype==SPACE_IMAGE)
        {
                SpaceImage *sima = sa->spacedata.first;
-               // XXX for now, get View2D  from the active region
+               // XXX for now, get View2D from the active region
                t->view = &ar->v2d;
                t->around = sima->around;
        }
+       else if(t->spacetype==SPACE_NODE)
+       {
+               // XXX for now, get View2D from the active region
+               t->view = &ar->v2d;
+               t->around = V3D_CENTER;
+       }
        else if(t->spacetype==SPACE_IPO) 
        {
                SpaceIpo *sipo= sa->spacedata.first;
@@ -980,6 +1049,21 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
                t->around = V3D_CENTER;
        }
 
+       if (op && RNA_property_is_set(op->ptr, "release_confirm"))
+       {
+               if (RNA_boolean_get(op->ptr, "release_confirm"))
+               {
+                       t->flag |= T_RELEASE_CONFIRM;
+               }
+       }
+       else
+       {
+               if (U.flag & USER_RELEASECONFIRM)
+               {
+                       t->flag |= T_RELEASE_CONFIRM;
+               }
+       }
+
        if (op && RNA_struct_find_property(op->ptr, "mirror") && RNA_property_is_set(op->ptr, "mirror"))
        {
                if (RNA_boolean_get(op->ptr, "mirror"))
@@ -998,60 +1082,71 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
                }
        }
 
-       /* setting PET flag only if property exist in operator. Otherwise, assume it's not supported */
        if (op && RNA_struct_find_property(op->ptr, "proportional"))
        {
                if (RNA_property_is_set(op->ptr, "proportional"))
                {
-               switch(RNA_enum_get(op->ptr, "proportional"))
-               {
-               case 2: /* XXX connected constant */
-                       t->flag |= T_PROP_CONNECTED;
-               case 1: /* XXX prop on constant */
-                       t->flag |= T_PROP_EDIT;
-                       break;
+                       switch(RNA_enum_get(op->ptr, "proportional"))
+                       {
+                       case PROP_EDIT_CONNECTED:
+                               t->flag |= T_PROP_CONNECTED;
+                       case PROP_EDIT_ON:
+                               t->flag |= T_PROP_EDIT;
+                               break;
+                       }
                }
-       }
-       else
-       {
-                       if ((t->options & CTX_NO_PET) == 0 && (ts->proportional != PROP_EDIT_OFF)) {
-                       t->flag |= T_PROP_EDIT;
+               else
+               {
+                       /* use settings from scene only if modal */
+                       if (t->flag & T_MODAL)
+                       {
+                               if ((t->options & CTX_NO_PET) == 0)
+                               {
+                                       if (t->obedit && ts->proportional != PROP_EDIT_OFF)
+                                       {
+                                               t->flag |= T_PROP_EDIT;
 
-                               if(ts->proportional == PROP_EDIT_CONNECTED)
-                                       t->flag |= T_PROP_CONNECTED;
+                                               if(ts->proportional == PROP_EDIT_CONNECTED)
+                                                       t->flag |= T_PROP_CONNECTED;
+                                       }
+                                       else if (t->obedit == NULL && ts->proportional_objects)
+                                       {
+                                               t->flag |= T_PROP_EDIT;
+                                       }
+                               }
+                       }
                }
-       }
-
-       if (op && RNA_struct_find_property(op->ptr, "proportional_size") && RNA_property_is_set(op->ptr, "proportional_size"))
-       {
-               t->prop_size = RNA_float_get(op->ptr, "proportional_size");
-       }
-       else
-       {
-               t->prop_size = ts->proportional_size;
-       }
-
+               
+               if (op && RNA_struct_find_property(op->ptr, "proportional_size") && RNA_property_is_set(op->ptr, "proportional_size"))
+               {
+                       t->prop_size = RNA_float_get(op->ptr, "proportional_size");
+               }
+               else
+               {
+                       t->prop_size = ts->proportional_size;
+               }
+               
                
                /* TRANSFORM_FIX_ME rna restrictions */
-               if (t->prop_size <= 0)
+               if (t->prop_size <= 0.00001f)
                {
+                       printf("Proportional size (%f) under 0.00001, reseting to 1!\n", t->prop_size);
                        t->prop_size = 1.0f;
                }
                
-       if (op && RNA_struct_find_property(op->ptr, "proportional_editing_falloff") && RNA_property_is_set(op->ptr, "proportional_editing_falloff"))
-       {
-               t->prop_mode = RNA_enum_get(op->ptr, "proportional_editing_falloff");
-       }
-       else
-       {
-               t->prop_mode = ts->prop_mode;
-       }
+               if (op && RNA_struct_find_property(op->ptr, "proportional_edit_falloff") && RNA_property_is_set(op->ptr, "proportional_edit_falloff"))
+               {
+                       t->prop_mode = RNA_enum_get(op->ptr, "proportional_edit_falloff");
+               }
+               else
+               {
+                       t->prop_mode = ts->prop_mode;
+               }
        }
        else /* add not pet option to context when not available */
        {
                t->options |= CTX_NO_PET;
        }
-
        
        setTransformViewMatrices(t);
        initNumInput(&t->num);
@@ -1061,15 +1156,18 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
 }
 
 /* Here I would suggest only TransInfo related issues, like free data & reset vars. Not redraws */
-void postTrans (TransInfo *t)
+void postTrans (bContext *C, TransInfo *t)
 {
        TransData *td;
 
        if (t->draw_handle_view)
                ED_region_draw_cb_exit(t->ar->type, t->draw_handle_view);
+       if (t->draw_handle_apply)
+               ED_region_draw_cb_exit(t->ar->type, t->draw_handle_apply);
        if (t->draw_handle_pixel)
                ED_region_draw_cb_exit(t->ar->type, t->draw_handle_pixel);
-       
+       if (t->draw_handle_cursor)
+               WM_paint_cursor_end(CTX_wm_manager(C), t->draw_handle_cursor);
 
        if (t->customFree) {
                /* Can take over freeing t->data and data2d etc... */
@@ -1083,7 +1181,7 @@ void postTrans (TransInfo *t)
        if (t->data) {
                int a;
 
-               /* since ipokeys are optional on objects, we mallocced them per trans-data */
+               /* free data malloced per trans-data */
                for(a=0, td= t->data; a<t->total; a++, td++) {
                        if (td->flag & TD_BEZTRIPLE) 
                                MEM_freeN(td->hdata);
@@ -1091,6 +1189,8 @@ void postTrans (TransInfo *t)
                MEM_freeN(t->data);
        }
 
+       BLI_freelistN(&t->tsnap.points);
+
        if (t->ext) MEM_freeN(t->ext);
        if (t->data2d) {
                MEM_freeN(t->data2d);
@@ -1102,6 +1202,13 @@ void postTrans (TransInfo *t)
                if(sima->flag & SI_LIVE_UNWRAP)
                        ED_uvedit_live_unwrap_end(t->state == TRANS_CANCEL);
        }
+       else if(t->spacetype==SPACE_VIEW3D) {
+               View3D *v3d = t->sa->spacedata.first;
+               /* restore manipulator */
+               if (t->flag & T_MODAL) {
+                       v3d->twtype = t->twtype;
+               }
+       }
        
        if (t->mouse.data)
        {
@@ -1140,10 +1247,18 @@ static void restoreElement(TransData *td) {
        if (td->val) {
                *td->val = td->ival;
        }
+
        if (td->ext && (td->flag&TD_NO_EXT)==0) {
                if (td->ext->rot) {
                        VECCOPY(td->ext->rot, td->ext->irot);
                }
+               if(td->ext->rotAngle) {
+                       *td->ext->rotAngle= td->ext->irotAngle;
+               }
+               if(td->ext->rotAxis) {
+                       VECCOPY(td->ext->rotAxis, td->ext->irotAxis);
+               }
+               /* XXX, drotAngle & drotAxis not used yet */
                if (td->ext->size) {
                        VECCOPY(td->ext->size, td->ext->isize);
                }
@@ -1161,11 +1276,23 @@ static void restoreElement(TransData *td) {
 void restoreTransObjects(TransInfo *t)
 {
        TransData *td;
+       TransData2D *td2d;
 
        for (td = t->data; td < t->data + t->total; td++) {
                restoreElement(td);
        }
 
+       for (td2d=t->data2d; t->data2d && td2d < t->data2d + t->total; td2d++) {
+               if (td2d->h1) {
+                       td2d->h1[0] = td2d->ih1[0];
+                       td2d->h1[1] = td2d->ih1[1];
+               }
+               if (td2d->h2) {
+                       td2d->h2[0] = td2d->ih2[0];
+                       td2d->h2[1] = td2d->ih2[1];
+               }
+       }
+
        unit_m3(t->mat);
 
        recalcData(t);
@@ -1209,21 +1336,25 @@ void calculateCenterCursor(TransInfo *t)
 
 void calculateCenterCursor2D(TransInfo *t)
 {
-       View2D *v2d= t->view;
        float aspx=1.0, aspy=1.0;
+       float *cursor= NULL;
+       
+       if(t->spacetype==SPACE_IMAGE) {
+               SpaceImage *sima= (SpaceImage *)t->sa->spacedata.first;
+               /* only space supported right now but may change */
+               ED_space_image_uv_aspect(sima, &aspx, &aspy);
+               cursor = sima->cursor;
+       }
 
-       if(t->spacetype==SPACE_IMAGE) /* only space supported right now but may change */
-               ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy);
-
-       if (v2d) {
-               t->center[0] = v2d->cursor[0] * aspx;
-               t->center[1] = v2d->cursor[1] * aspy;
+       if (cursor) {
+               t->center[0] = cursor[0] * aspx;
+               t->center[1] = cursor[1] * aspy;
        }
 
        calculateCenter2D(t);
 }
 
-void calculateCenterCursorGraph2D(TransInfo *t)
+static void calculateCenterCursorGraph2D(TransInfo *t)
 {
        SpaceIpo *sipo= (SpaceIpo *)t->sa->spacedata.first;
        Scene *scene= t->scene;
@@ -1245,7 +1376,7 @@ void calculateCenterMedian(TransInfo *t)
                if (t->data[i].flag & TD_SELECTED) {
                        if (!(t->data[i].flag & TD_NOCENTER))
                        {
-                               add_v3_v3v3(partial, partial, t->data[i].center);
+                               add_v3_v3(partial, t->data[i].center);
                                total++;
                        }
                }
@@ -1273,7 +1404,7 @@ void calculateCenterBound(TransInfo *t)
                if (i) {
                        if (t->data[i].flag & TD_SELECTED) {
                                if (!(t->data[i].flag & TD_NOCENTER))
-                                       minmax_v3_v3v3(min, max, t->data[i].center);
+                                       minmax_v3v3_v3(min, max, t->data[i].center);
                        }
                        else {
                                /*
@@ -1322,11 +1453,11 @@ void calculateCenter(TransInfo *t)
                /* EDIT MODE ACTIVE EDITMODE ELEMENT */
 
                if (t->obedit && t->obedit->type == OB_MESH) {
-                       EditSelection ese;
-                       EditMesh *em = BKE_mesh_get_editmesh(t->obedit->data);
+                       BMEditSelection ese;
+                       BMEditMesh *em = ((Mesh*)t->obedit->data)->edit_btmesh;
                        
-                       if (EM_get_actSelection(em, &ese)) {
-                       EM_editselection_center(t->center, &ese);
+                       if (EDBM_get_actSelection(em, &ese)) {
+                       EDBM_editselection_center(em, t->center, &ese);
                        calculateCenter2D(t);
                        break;
                        }
@@ -1358,7 +1489,7 @@ void calculateCenter(TransInfo *t)
        /* for panning from cameraview */
        if(t->flag & T_OBJECT)
        {
-               if(t->spacetype==SPACE_VIEW3D && t->ar->regiontype == RGN_TYPE_WINDOW)
+               if(t->spacetype==SPACE_VIEW3D && t->ar && t->ar->regiontype == RGN_TYPE_WINDOW)
                {
                        View3D *v3d = t->view;
                        Scene *scene = t->scene;
@@ -1439,7 +1570,11 @@ void calculatePropRatio(TransInfo *t)
                        else {
                                /* Use rdist for falloff calculations, it is the real distance */
                                td->flag &= ~TD_NOACTION;
-                               dist= (t->prop_size-td->rdist)/t->prop_size;
+
+                               if (connected)
+                                       dist= (t->prop_size-td->dist)/t->prop_size;
+                               else
+                                       dist= (t->prop_size-td->rdist)/t->prop_size;
 
                                /*
                                 * Clamp to positive numbers.
@@ -1510,25 +1645,3 @@ void calculatePropRatio(TransInfo *t)
                strcpy(t->proptext, "");
        }
 }
-
-float get_drawsize(ARegion *ar, float *co)
-{
-       RegionView3D *rv3d= ar->regiondata;
-       float size, vec[3], len1, len2;
-
-       /* size calculus, depending ortho/persp settings, like initgrabz() */
-       size= rv3d->persmat[0][3]*co[0]+ rv3d->persmat[1][3]*co[1]+ rv3d->persmat[2][3]*co[2]+ rv3d->persmat[3][3];
-
-       VECCOPY(vec, rv3d->persinv[0]);
-       len1= normalize_v3(vec);
-       VECCOPY(vec, rv3d->persinv[1]);
-       len2= normalize_v3(vec);
-
-       size*= 0.01f*(len1>len2?len1:len2);
-
-       /* correct for window size to make widgets appear fixed size */
-       if(ar->winx > ar->winy) size*= 1000.0f/(float)ar->winx;
-       else size*= 1000.0f/(float)ar->winy;
-
-       return size;
-}