Merging r40265 through r40492 from trunk into soc-2011-tomato
[blender.git] / source / blender / editors / transform / transform_conversions.c
index d76e5c8a88a955b836fbe2960f38edda240f5bd5..d02be58ba7eda620817506ccf7dba895dc8e24fc 100644 (file)
@@ -53,6 +53,7 @@
 #include "DNA_scene_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_gpencil_types.h"
+#include "DNA_movieclip_types.h"
 
 #include "MEM_guardedalloc.h"
 
@@ -76,6 +77,9 @@
 #include "BKE_bmesh.h"
 #include "BKE_scene.h"
 #include "BKE_report.h"
+#include "BKE_tracking.h"
+#include "BKE_movieclip.h"
+#include "BKE_node.h"
 
 
 #include "ED_anim_api.h"
 #include "ED_node.h"
 #include "ED_types.h"
 #include "ED_uvedit.h"
+#include "ED_clip.h"
 #include "ED_util.h"  /* for crazyspace correction */
 
+#include "WM_api.h"            /* for WM_event_add_notifier to deal with stabilization nodes */
+#include "WM_types.h"
+
 #include "UI_view2d.h"
 
 #include "BLI_math.h"
@@ -1807,7 +1815,7 @@ void flushTransParticles(TransInfo *t)
 /* ********************* mesh ****************** */
 
 /* proportional distance based on connectivity  */
-#define THRESHOLD      0.0001f
+#define THRESHOLDFACTOR (1.0f-0.0001f)
 
 static int connectivity_edge(float mtx[][3], EditVert *v1, EditVert *v2)
 {
@@ -1828,10 +1836,10 @@ static int connectivity_edge(float mtx[][3], EditVert *v1, EditVert *v2)
 
        if (v1->f2) {
                if (v2->f2) {
-                       if (v2->tmp.fp + edge_len + THRESHOLD < v1->tmp.fp) {
+                       if (v2->tmp.fp + edge_len < THRESHOLDFACTOR * v1->tmp.fp) {
                                v1->tmp.fp = v2->tmp.fp + edge_len;
                                done = 1;
-                       } else if (v1->tmp.fp + edge_len + THRESHOLD < v2->tmp.fp) {
+                       } else if (v1->tmp.fp + edge_len < THRESHOLDFACTOR * v2->tmp.fp) {
                                v2->tmp.fp = v1->tmp.fp + edge_len;
                                done = 1;
                        }
@@ -1983,7 +1991,7 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
        float *mappedcos = NULL, *quats= NULL;
        float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL;
        int count=0, countsel=0, a, totleft;
-       int propmode = t->flag & T_PROP_EDIT;
+       int propmode = (t->flag & T_PROP_EDIT) ? (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) : 0;
        int mirror = 0;
        short selectmode = ts->selectmode;
 
@@ -2053,7 +2061,9 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
        copy_m3_m4(mtx, t->obedit->obmat);
        invert_m3_m3(smtx, mtx);
 
-       if(propmode) editmesh_set_connectivity_distance(em, mtx);
+       if(propmode & T_PROP_CONNECTED) {
+               editmesh_set_connectivity_distance(em, mtx);
+       }
 
        /* detect CrazySpace [tm] */
        if(modifiers_getCageIndex(t->scene, t->obedit, NULL, 1)>=0) {
@@ -3406,7 +3416,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
                                const char sel3= use_handle ? bezt->f3 & SELECT : 0;
 
                                TransDataCurveHandleFlags *hdata = NULL;
-                               short h1=1, h2=1;
+                               /* short h1=1, h2=1; */ /* UNUSED */
                                
                                /* only include handles if selected, irrespective of the interpolation modes.
                                 * also, only treat handles specially if the center point isn't selected. 
@@ -3416,16 +3426,18 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
                                                hdata = initTransDataCurveHandles(td, bezt);
                                                bezt_to_transdata(td++, td2d++, adt, bezt, 0, 1, 1, intvals, mtx, smtx);
                                        } 
-                                       else
-                                               h1= 0;
+                                       else {
+                                               /* h1= 0; */ /* UNUSED */
+                                       }
                                        
                                        if (sel3) {
                                                if (hdata==NULL)
                                                        hdata = initTransDataCurveHandles(td, bezt);
                                                bezt_to_transdata(td++, td2d++, adt, bezt, 2, 1, 1, intvals, mtx, smtx);
                                        } 
-                                       else
-                                               h2= 0;
+                                       else {
+                                               /* h2= 0; */ /* UNUSED */
+                                       }
                                }
                                
                                /* only include main vert if selected */
@@ -4779,6 +4791,17 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
                /* clear link line */
                ED_node_link_intersect_test(t->sa, 0);
        }
+       else if (t->spacetype == SPACE_CLIP) {
+               SpaceClip *sc= t->sa->spacedata.first;
+               MovieClip *clip= ED_space_clip(sc);
+
+               if(t->scene->nodetree) {
+                       /* tracks can be used for stabilization nodes,
+                          flush update for such nodes */
+                       NodeTagIDChanged(t->scene->nodetree, &clip->id);
+                       WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL);
+               }
+       }
        else if (t->spacetype == SPACE_ACTION) {
                SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first;
                bAnimContext ac;
@@ -5241,6 +5264,229 @@ static void createTransNodeData(bContext *C, TransInfo *t)
        CTX_DATA_END
 }
 
+/* *** CLIP EDITOR *** */
+
+typedef struct TransDataTracking {
+       int area;
+       float *relative, *loc;
+       float soffset[2], srelative[2];
+       float offset[2];
+
+       float (*smarkers)[2];
+       int markersnr;
+       MovieTrackingMarker *markers;
+} TransDataTracking;
+
+static void markerToTransDataInit(TransData *td, TransData2D *td2d,
+                       TransDataTracking *tdt, MovieTrackingTrack *track, int area, float *loc, float *rel, float *off)
+{
+       int anchor = area==TRACK_AREA_POINT && off;
+
+       if(anchor) {
+               td2d->loc[0] = rel[0]; /* hold original location */
+               td2d->loc[1] = rel[1];
+
+               tdt->loc= loc;
+               td2d->loc2d = loc; /* current location */
+       } else {
+               td2d->loc[0] = loc[0]; /* hold original location */
+               td2d->loc[1] = loc[1];
+
+               td2d->loc2d = loc; /* current location */
+       }
+       td2d->loc[2] = 0.0f;
+
+       tdt->relative= rel;
+       tdt->area= area;
+
+       tdt->markersnr= track->markersnr;
+       tdt->markers= track->markers;
+
+       if(rel) {
+               if(!anchor) {
+                       td2d->loc[0]+= rel[0];
+                       td2d->loc[1]+= rel[1];
+               }
+
+               copy_v2_v2(tdt->srelative, rel);
+       }
+
+       if(off)
+               copy_v2_v2(tdt->soffset, off);
+
+       td->flag = 0;
+       td->loc = td2d->loc;
+       VECCOPY(td->center, td->loc);
+       VECCOPY(td->iloc, td->loc);
+
+       memset(td->axismtx, 0, sizeof(td->axismtx));
+       td->axismtx[2][2] = 1.0f;
+
+       td->ext= NULL; td->val= NULL;
+
+       td->flag |= TD_SELECTED;
+       td->dist= 0.0;
+
+       unit_m3(td->mtx);
+       unit_m3(td->smtx);
+}
+
+static void trackToTransData(SpaceClip *sc, TransData *td, TransData2D *td2d,
+                       TransDataTracking *tdt, MovieTrackingTrack *track)
+{
+       MovieTrackingMarker *marker= BKE_tracking_ensure_marker(track, sc->user.framenr);
+
+       track->transflag= marker->flag;
+
+       marker->flag&= ~(MARKER_DISABLED|MARKER_TRACKED);
+
+       markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_POINT, track->offset, marker->pos, track->offset);
+
+       if(track->flag&SELECT)
+               markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_POINT, marker->pos, NULL, NULL);
+
+       if(track->pat_flag&SELECT) {
+               markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_PAT, track->pat_min, marker->pos, NULL);
+               markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_PAT, track->pat_max, marker->pos, NULL);
+       }
+
+       if(track->search_flag&SELECT) {
+               markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_SEARCH, track->search_min, marker->pos, NULL);
+               markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_SEARCH, track->search_max, marker->pos, NULL);
+       }
+}
+
+static void transDataTrackingFree(TransInfo *t)
+{
+       TransDataTracking *tdt= t->customData;
+
+       if(tdt) {
+               if(tdt->smarkers) MEM_freeN(tdt->smarkers);
+               MEM_freeN(tdt);
+       }
+}
+
+static void createTransTrackingData(bContext *C, TransInfo *t)
+{
+       TransData *td;
+       TransData2D *td2d;
+       SpaceClip *sc = CTX_wm_space_clip(C);
+       MovieClip *clip = ED_space_clip(sc);
+       MovieTrackingTrack *track;
+       MovieTrackingMarker *marker;
+       TransDataTracking *tdt;
+       int framenr = sc->user.framenr;
+
+       if(clip && !BKE_movieclip_has_frame(clip, &sc->user)) {
+               t->total = 0;
+               return;
+       }
+
+       /* count */
+       t->total = 0;
+
+       track = clip->tracking.tracks.first;
+       while(track) {
+               if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_LOCKED)==0) {
+                       marker= BKE_tracking_get_marker(track, framenr);
+
+                       if(marker) {
+                               t->total++;     /* offset */
+
+                               if(track->flag&SELECT) t->total++;
+                               if(track->pat_flag&SELECT) t->total+= 2;
+                               if(track->search_flag&SELECT) t->total+= 2;
+                       }
+               }
+
+               track = track->next;
+       }
+
+       if(t->total==0)
+               return;
+
+       td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransTracking TransData");
+       td2d = t->data2d = MEM_callocN(t->total*sizeof(TransData2D), "TransTracking TransData2D");
+       tdt = t->customData = MEM_callocN(t->total*sizeof(TransDataTracking), "TransTracking TransDataTracking");
+
+       t->customFree= transDataTrackingFree;
+
+       /* create actual data */
+       track = clip->tracking.tracks.first;
+       while(track) {
+               if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_LOCKED)==0) {
+                       marker= BKE_tracking_get_marker(track, framenr);
+
+                       trackToTransData(sc, td, td2d, tdt, track);
+
+                       /* offset */
+                       td++;
+                       td2d++;
+                       tdt++;
+
+                       if((marker->flag&MARKER_DISABLED)==0) {
+                               if(track->flag&SELECT) {td++; td2d++; tdt++;}
+                               if(track->pat_flag&SELECT) {td+= 2; td2d+= 2;tdt+=2;}
+                       }
+
+                       if(track->search_flag&SELECT) {
+                               td+= 2;
+                               td2d+= 2;
+                               tdt+= 2;
+
+                               if(marker->flag&MARKER_DISABLED) {
+                                       td+= 3;
+                                       td2d+= 3;
+                                       tdt+= 3;
+                               };
+                       }
+               }
+
+               track = track->next;
+       }
+}
+
+void flushTransTracking(TransInfo *t)
+{
+       TransData *td;
+       TransData2D *td2d;
+       TransDataTracking *tdt;
+       int a;
+
+       /* flush to 2d vector from internally used 3d vector */
+       for(a=0, td= t->data, td2d= t->data2d, tdt= t->customData; a<t->total; a++, td2d++, td++, tdt++) {
+               if(t->flag&T_ALT_TRANSFORM) {
+                       if(tdt->area==TRACK_AREA_POINT && tdt->relative) {
+                               float d[2], d2[2];
+
+                               if(!tdt->smarkers) {
+                                       tdt->smarkers= MEM_callocN(sizeof(*tdt->smarkers)*tdt->markersnr, "flushTransTracking markers");
+                                       for(a= 0; a<tdt->markersnr; a++)
+                                               copy_v2_v2(tdt->smarkers[a], tdt->markers[a].pos);
+                               }
+
+                               sub_v2_v2v2(d, td2d->loc, tdt->soffset);
+                               sub_v2_v2(d, tdt->srelative);
+
+                               sub_v2_v2v2(d2, td2d->loc, tdt->srelative);
+
+                               for(a= 0; a<tdt->markersnr; a++)
+                                       add_v2_v2v2(tdt->markers[a].pos, tdt->smarkers[a], d2);
+
+                               negate_v2_v2(td2d->loc2d, d);
+                       }
+               }
+
+               if(tdt->area!=TRACK_AREA_POINT || tdt->relative==0) {
+                       td2d->loc2d[0] = td2d->loc[0];
+                       td2d->loc2d[1] = td2d->loc[1];
+
+                       if(tdt->relative)
+                               sub_v2_v2(td2d->loc2d, tdt->relative);
+               }
+       }
+}
+
 void createTransData(bContext *C, TransInfo *t)
 {
        Scene *scene = t->scene;
@@ -5306,6 +5552,10 @@ void createTransData(bContext *C, TransInfo *t)
                        sort_trans_data_dist(t);
                }
        }
+       else if (t->spacetype == SPACE_CLIP) {
+               t->flag |= T_POINTS|T_2D_EDIT;
+               createTransTrackingData(C, t);
+       }
        else if (t->obedit) {
                t->ext = NULL;
                if (t->obedit->type == OB_MESH) {