Merging r46725 through r46963 from trunk into soc-2011-tomato
[blender.git] / source / blender / editors / transform / transform_conversions.c
index d9e4619..74afdfe 100644 (file)
@@ -53,6 +53,7 @@
 #include "DNA_meshdata_types.h"
 #include "DNA_gpencil_types.h"
 #include "DNA_movieclip_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_gpencil_types.h"
 #include "DNA_movieclip_types.h"
+#include "DNA_mask_types.h"
 
 #include "MEM_guardedalloc.h"
 
 
 #include "MEM_guardedalloc.h"
 
@@ -87,6 +88,7 @@
 #include "BKE_sequencer.h"
 #include "BKE_tessmesh.h"
 #include "BKE_tracking.h"
 #include "BKE_sequencer.h"
 #include "BKE_tessmesh.h"
 #include "BKE_tracking.h"
+#include "BKE_mask.h"
 
 
 #include "ED_anim_api.h"
 
 
 #include "ED_anim_api.h"
 #include "ED_types.h"
 #include "ED_uvedit.h"
 #include "ED_clip.h"
 #include "ED_types.h"
 #include "ED_uvedit.h"
 #include "ED_clip.h"
+#include "ED_mask.h"
 #include "ED_util.h"  /* for crazyspace correction */
 
 #include "WM_api.h"            /* for WM_event_add_notifier to deal with stabilization nodes */
 #include "ED_util.h"  /* for crazyspace correction */
 
 #include "WM_api.h"            /* for WM_event_add_notifier to deal with stabilization nodes */
@@ -4897,6 +4900,17 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
                                WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL);
                        }
                }
                                WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL);
                        }
                }
+               else if (t->options & CTX_MASK) {
+                       SpaceClip *sc = t->sa->spacedata.first;
+                       Mask *mask = ED_space_clip_mask(sc);
+
+                       if (t->scene->nodetree) {
+                               /* tracks can be used for stabilization nodes,
+                                * flush update for such nodes */
+                               nodeUpdateID(t->scene->nodetree, &mask->id);
+                               WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL);
+                       }
+               }
        }
        else if (t->spacetype == SPACE_ACTION) {
                SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first;
        }
        else if (t->spacetype == SPACE_ACTION) {
                SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first;
@@ -5392,23 +5406,24 @@ typedef struct TransDataTracking {
        short coord;
 } TransDataTracking;
 
        short coord;
 } TransDataTracking;
 
-static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTracking *tdt, MovieTrackingTrack *track,
-                                  int area, float *loc, float *rel, float *off)
+static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTracking *tdt,
+                                  MovieTrackingTrack *track, MovieTrackingMarker *marker,
+                                  int area, float *loc, float *rel, float *off, float aspx, float aspy)
 {
        int anchor = area == TRACK_AREA_POINT && off;
 
        tdt->mode = transDataTracking_ModeTracks;
 
        if (anchor) {
 {
        int anchor = area == TRACK_AREA_POINT && off;
 
        tdt->mode = transDataTracking_ModeTracks;
 
        if (anchor) {
-               td2d->loc[0] = rel[0]; /* hold original location */
-               td2d->loc[1] = rel[1];
+               td2d->loc[0] = rel[0] * aspx; /* hold original location */
+               td2d->loc[1] = rel[1] * aspy;
 
                tdt->loc= loc;
                td2d->loc2d = loc; /* current location */
        }
        else {
 
                tdt->loc= loc;
                td2d->loc2d = loc; /* current location */
        }
        else {
-               td2d->loc[0] = loc[0]; /* hold original location */
-               td2d->loc[1] = loc[1];
+               td2d->loc[0] = loc[0] * aspx; /* hold original location */
+               td2d->loc[1] = loc[1] * aspy;
 
                td2d->loc2d = loc; /* current location */
        }
 
                td2d->loc2d = loc; /* current location */
        }
@@ -5422,8 +5437,8 @@ static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTra
 
        if (rel) {
                if (!anchor) {
 
        if (rel) {
                if (!anchor) {
-                       td2d->loc[0] += rel[0];
-                       td2d->loc[1] += rel[1];
+                       td2d->loc[0] += rel[0] * aspx;
+                       td2d->loc[1] += rel[1] * aspy;
                }
 
                copy_v2_v2(tdt->srelative, rel);
                }
 
                copy_v2_v2(tdt->srelative, rel);
@@ -5434,9 +5449,12 @@ static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTra
 
        td->flag = 0;
        td->loc = td2d->loc;
 
        td->flag = 0;
        td->loc = td2d->loc;
-       copy_v3_v3(td->center, td->loc);
        copy_v3_v3(td->iloc, td->loc);
 
        copy_v3_v3(td->iloc, td->loc);
 
+       //copy_v3_v3(td->center, td->loc);
+       td->center[0] = marker->pos[0] * aspx;
+       td->center[1] = marker->pos[1] * aspy;
+
        memset(td->axismtx, 0, sizeof(td->axismtx));
        td->axismtx[2][2] = 1.0f;
 
        memset(td->axismtx, 0, sizeof(td->axismtx));
        td->axismtx[2][2] = 1.0f;
 
@@ -5451,26 +5469,36 @@ static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTra
 }
 
 static void trackToTransData(SpaceClip *sc, TransData *td, TransData2D *td2d,
 }
 
 static void trackToTransData(SpaceClip *sc, TransData *td, TransData2D *td2d,
-                             TransDataTracking *tdt, MovieTrackingTrack *track)
+                             TransDataTracking *tdt, MovieTrackingTrack *track, float aspx, float aspy)
 {
        MovieTrackingMarker *marker = BKE_tracking_ensure_marker(track, sc->user.framenr);
 
        tdt->flag = marker->flag;
 {
        MovieTrackingMarker *marker = BKE_tracking_ensure_marker(track, sc->user.framenr);
 
        tdt->flag = marker->flag;
-       marker->flag &= ~(MARKER_DISABLED|MARKER_TRACKED);
+       marker->flag &= ~(MARKER_DISABLED | MARKER_TRACKED);
 
 
-       markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_POINT, track->offset, marker->pos, track->offset);
+       markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_POINT,
+                             track->offset, marker->pos, track->offset, aspx, aspy);
 
 
-       if (track->flag & SELECT)
-               markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_POINT, marker->pos, NULL, NULL);
+       if (track->flag & SELECT) {
+               markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_POINT,
+                                     marker->pos, NULL, NULL, aspx, aspy);
+       }
 
        if (track->pat_flag & SELECT) {
 
        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);
+               int a;
+
+               for (a = 0; a < 4; a++) {
+                       markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_PAT,
+                                             marker->pattern_corners[a], marker->pos, NULL, aspx, aspy);
+               }
        }
 
        if (track->search_flag & SELECT) {
        }
 
        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);
+               markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_SEARCH,
+                                     marker->search_min, marker->pos, NULL, aspx, aspy);
+
+               markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_SEARCH,
+                                     marker->search_max, marker->pos, NULL, aspx, aspy);
        }
 }
 
        }
 }
 
@@ -5497,6 +5525,7 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t)
        MovieTrackingMarker *marker;
        TransDataTracking *tdt;
        int framenr = sc->user.framenr;
        MovieTrackingMarker *marker;
        TransDataTracking *tdt;
        int framenr = sc->user.framenr;
+       float aspx, aspy;
 
        /* count */
        t->total = 0;
 
        /* count */
        t->total = 0;
@@ -5512,7 +5541,7 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t)
                                t->total++;
 
                        if (track->pat_flag & SELECT)
                                t->total++;
 
                        if (track->pat_flag & SELECT)
-                               t->total+= 2;
+                               t->total+= 4;
 
                        if (track->search_flag & SELECT)
                                t->total+= 2;
 
                        if (track->search_flag & SELECT)
                                t->total+= 2;
@@ -5524,6 +5553,8 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t)
        if (t->total == 0)
                return;
 
        if (t->total == 0)
                return;
 
+       ED_space_clip_aspect_dimension_aware(sc, &aspx, &aspy);
+
        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");
        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");
@@ -5536,25 +5567,23 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t)
                if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) {
                        marker = BKE_tracking_get_marker(track, framenr);
 
                if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) {
                        marker = BKE_tracking_get_marker(track, framenr);
 
-                       trackToTransData(sc, td, td2d, tdt, track);
+                       trackToTransData(sc, td, td2d, tdt, track, aspx, aspy);
 
                        /* offset */
                        td++;
                        td2d++;
                        tdt++;
 
 
                        /* offset */
                        td++;
                        td2d++;
                        tdt++;
 
-                       if ((marker->flag & MARKER_DISABLED) == 0) {
-                               if (track->flag & SELECT) {
-                                       td++;
-                                       td2d++;
-                                       tdt++;
-                               }
+                       if (track->flag & SELECT) {
+                               td++;
+                               td2d++;
+                               tdt++;
+                       }
 
 
-                               if (track->pat_flag & SELECT) {
-                                       td += 2;
-                                       td2d += 2;
-                                       tdt +=2;
-                               }
+                       if (track->pat_flag & SELECT) {
+                               td += 4;
+                               td2d += 4;
+                               tdt += 4;
                        }
 
                        if (track->search_flag & SELECT) {
                        }
 
                        if (track->search_flag & SELECT) {
@@ -5706,9 +5735,6 @@ static void createTransTrackingData(bContext *C, TransInfo *t)
        if (!clip || width == 0 || height == 0)
                return;
 
        if (!clip || width == 0 || height == 0)
                return;
 
-       if (!ELEM(t->mode, TFM_RESIZE, TFM_TRANSLATION))
-               return;
-
        if (ar->regiontype == RGN_TYPE_PREVIEW) {
                /* transformation was called from graph editor */
                createTransTrackingCurvesData(C, t);
        if (ar->regiontype == RGN_TYPE_PREVIEW) {
                /* transformation was called from graph editor */
                createTransTrackingCurvesData(C, t);
@@ -5776,10 +5802,14 @@ static void cancelTransTracking(TransInfo *t)
 
 void flushTransTracking(TransInfo *t)
 {
 
 void flushTransTracking(TransInfo *t)
 {
+       SpaceClip *sc = t->sa->spacedata.first;
        TransData *td;
        TransData2D *td2d;
        TransDataTracking *tdt;
        int a;
        TransData *td;
        TransData2D *td2d;
        TransDataTracking *tdt;
        int a;
+       float aspx, aspy;
+
+       ED_space_clip_aspect_dimension_aware(sc, &aspx, &aspy);
 
        if (t->state == TRANS_CANCEL)
                cancelTransTracking(t);
 
        if (t->state == TRANS_CANCEL)
                cancelTransTracking(t);
@@ -5787,31 +5817,46 @@ void flushTransTracking(TransInfo *t)
        /* 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 (tdt->mode == transDataTracking_ModeTracks) {
        /* 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 (tdt->mode == transDataTracking_ModeTracks) {
-                       if (t->flag & T_ALT_TRANSFORM) {
-                               if (tdt->area == TRACK_AREA_POINT && tdt->relative) {
-                                       float d[2], d2[2];
+                       float loc2d[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);
-                                       }
+                       if (t->mode == TFM_ROTATION && tdt->area == TRACK_AREA_SEARCH) {
+                               continue;
+                       }
 
 
-                                       sub_v2_v2v2(d, td2d->loc, tdt->soffset);
-                                       sub_v2_v2(d, tdt->srelative);
+                       loc2d[0] = td2d->loc[0] / aspx;
+                       loc2d[1] = td2d->loc[1] / aspy;
 
 
-                                       sub_v2_v2v2(d2, td2d->loc, tdt->srelative);
+                       if (t->flag & T_ALT_TRANSFORM) {
+                               if (t->mode == TFM_RESIZE) {
+                                       if (tdt->area != TRACK_AREA_PAT)
+                                               continue;
+                               }
+                               else if (t->mode == TFM_TRANSLATION) {
+                                       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, loc2d, tdt->soffset);
+                                               sub_v2_v2(d, tdt->srelative);
 
 
-                                       for (a= 0; a<tdt->markersnr; a++)
-                                               add_v2_v2v2(tdt->markers[a].pos, tdt->smarkers[a], d2);
+                                               sub_v2_v2v2(d2, loc2d, tdt->srelative);
 
 
-                                       negate_v2_v2(td2d->loc2d, d);
+                                               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) {
                                }
                        }
 
                        if (tdt->area!=TRACK_AREA_POINT || tdt->relative==0) {
-                               td2d->loc2d[0] = td2d->loc[0];
-                               td2d->loc2d[1] = td2d->loc[1];
+                               td2d->loc2d[0] = loc2d[0];
+                               td2d->loc2d[1] = loc2d[1];
 
                                if (tdt->relative)
                                        sub_v2_v2(td2d->loc2d, tdt->relative);
 
                                if (tdt->relative)
                                        sub_v2_v2(td2d->loc2d, tdt->relative);
@@ -5823,6 +5868,188 @@ void flushTransTracking(TransInfo *t)
        }
 }
 
        }
 }
 
+/* * masking * */
+
+typedef struct TransDataMasking{
+       int   is_handle;
+
+       float handle[2], orig_handle[2];
+       float vec[3][3];
+       MaskSplinePoint *point;
+} TransDataMasking;
+
+static void MaskPointToTransData(SpaceClip *sc, MaskSplinePoint *point, TransData *td, TransData2D *td2d, TransDataMasking *tdm)
+{
+       BezTriple *bezt = &point->bezt;
+       float aspx, aspy;
+
+       tdm->point = point;
+       copy_m3_m3(tdm->vec, bezt->vec);
+
+       ED_space_clip_mask_aspect(sc, &aspx, &aspy);
+
+       if (MASKPOINT_CV_ISSEL(point)) {
+               int i;
+               for (i = 0; i < 3; i++) {
+                       /* CV coords are scaled by aspects. this is needed for rotations and
+                        * proportional editing to be consistent with the stretched CV coords
+                        * that are displayed. this also means that for display and numinput,
+                        * and when the the CV coords are flushed, these are converted each time */
+                       td2d->loc[0] = bezt->vec[i][0]*aspx;
+                       td2d->loc[1] = bezt->vec[i][1]*aspy;
+                       td2d->loc[2] = 0.0f;
+                       td2d->loc2d = bezt->vec[i];
+
+                       td->flag = 0;
+                       td->loc = td2d->loc;
+                       copy_v3_v3(td->center, td->loc);
+                       copy_v3_v3(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);
+
+                       td++;
+                       td2d++;
+               }
+       }
+       else {
+               tdm->is_handle = TRUE;
+
+               BKE_mask_point_handle(point, tdm->handle);
+
+               copy_v2_v2(tdm->orig_handle, tdm->handle);
+
+               td2d->loc[0] = tdm->handle[0]*aspx;
+               td2d->loc[1] = tdm->handle[1]*aspy;
+               td2d->loc[2] = 0.0f;
+               td2d->loc2d = tdm->handle;
+
+               td->flag = 0;
+               td->loc = td2d->loc;
+               copy_v3_v3(td->center, td->loc);
+               copy_v3_v3(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);
+
+               td++;
+               td2d++;
+       }
+}
+
+static void createTransMaskingData(bContext *C, TransInfo *t)
+{
+       SpaceClip *sc = CTX_wm_space_clip(C);
+       Mask *mask = CTX_data_edit_mask(C);
+       MaskObject *maskobj;
+       TransData *td = NULL;
+       TransData2D *td2d = NULL;
+       TransDataMasking *tdm = NULL;
+
+       /* count */
+       for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) {
+               MaskSpline *spline = maskobj->splines.first;
+
+               while (spline) {
+                       int i;
+
+                       for (i = 0; i < spline->tot_point; i++) {
+                               MaskSplinePoint *point = &spline->points[i];
+
+                               if (MASKPOINT_ISSEL(point)) {
+                                       if (MASKPOINT_CV_ISSEL(point))
+                                               t->total += 3;
+                                       else
+                                               t->total += 1;
+                               }
+                       }
+
+                       spline = spline->next;
+               }
+       }
+
+       if (t->total == 0)
+               return;
+
+       td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransObData(Mask Editing)");
+       /* for each 2d uv coord a 3d vector is allocated, so that they can be
+        * treated just as if they were 3d verts */
+       td2d = t->data2d = MEM_callocN(t->total*sizeof(TransData2D), "TransObData2D(Mask Editing)");
+       tdm = t->customData = MEM_callocN(t->total*sizeof(TransDataMasking), "TransDataMasking(Mask Editing)");
+
+       t->flag |= T_FREE_CUSTOMDATA;
+
+       /* create data */
+       for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) {
+               MaskSpline *spline = maskobj->splines.first;
+
+               while (spline) {
+                       int i;
+
+                       for (i = 0; i < spline->tot_point; i++) {
+                               MaskSplinePoint *point = &spline->points[i];
+
+                               if (MASKPOINT_ISSEL(point)) {
+                                       MaskPointToTransData(sc, point, td, td2d, tdm);
+
+                                       if (MASKPOINT_CV_ISSEL(point)) {
+                                               td += 3;
+                                               td2d += 3;
+                                               tdm += 3;
+                                       }
+                                       else {
+                                               td++;
+                                               td2d++;
+                                               tdm++;
+                                       }
+                               }
+                       }
+
+                       spline = spline->next;
+               }
+       }
+}
+
+void flushTransMasking(TransInfo *t)
+{
+       SpaceClip *sc = t->sa->spacedata.first;
+       TransData2D *td;
+       TransDataMasking *tdm;
+       int a;
+       float aspx, aspy, invx, invy;
+
+       ED_space_clip_mask_aspect(sc, &aspx, &aspy);
+       invx = 1.0f/aspx;
+       invy = 1.0f/aspy;
+
+       /* flush to 2d vector from internally used 3d vector */
+       for(a=0, td = t->data2d, tdm = t->customData; a<t->total; a++, td++, tdm++) {
+               td->loc2d[0]= td->loc[0]*invx;
+               td->loc2d[1]= td->loc[1]*invy;
+
+               if (tdm->is_handle)
+                       BKE_mask_point_set_handle(tdm->point, td->loc2d, t->flag & T_ALT_TRANSFORM, aspx, aspy, tdm->orig_handle, tdm->vec);
+       }
+}
+
 void createTransData(bContext *C, TransInfo *t)
 {
        Scene *scene = t->scene;
 void createTransData(bContext *C, TransInfo *t)
 {
        Scene *scene = t->scene;
@@ -5892,6 +6119,8 @@ void createTransData(bContext *C, TransInfo *t)
                t->flag |= T_POINTS|T_2D_EDIT;
                if (t->options & CTX_MOVIECLIP)
                        createTransTrackingData(C, t);
                t->flag |= T_POINTS|T_2D_EDIT;
                if (t->options & CTX_MOVIECLIP)
                        createTransTrackingData(C, t);
+               else if (t->options & CTX_MASK)
+                       createTransMaskingData(C, t);
        }
        else if (t->obedit) {
                t->ext = NULL;
        }
        else if (t->obedit) {
                t->ext = NULL;