Blender V2.61 - r43446

clip_editor.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2011 Blender Foundation.
00019  * All rights reserved.
00020  *
00021  *
00022  * Contributor(s): Blender Foundation,
00023  *                 Sergey Sharybin
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00032 #include <stddef.h>
00033 
00034 #include "BKE_main.h"
00035 #include "BKE_movieclip.h"
00036 #include "BKE_context.h"
00037 #include "BKE_tracking.h"
00038 #include "DNA_object_types.h"   /* SELECT */
00039 
00040 #include "BLI_utildefines.h"
00041 #include "BLI_math.h"
00042 
00043 #include "IMB_imbuf_types.h"
00044 #include "IMB_imbuf.h"
00045 
00046 #include "ED_screen.h"
00047 #include "ED_clip.h"
00048 
00049 #include "BIF_gl.h"
00050 
00051 #include "WM_api.h"
00052 #include "WM_types.h"
00053 
00054 #include "UI_view2d.h"
00055 
00056 #include "clip_intern.h"    // own include
00057 
00058 int ED_space_clip_poll(bContext *C)
00059 {
00060     SpaceClip *sc= CTX_wm_space_clip(C);
00061 
00062     if(sc && sc->clip)
00063         return 1;
00064 
00065     return 0;
00066 }
00067 
00068 void ED_space_clip_set(bContext *C, SpaceClip *sc, MovieClip *clip)
00069 {
00070     sc->clip= clip;
00071 
00072     if(sc->clip && sc->clip->id.us==0)
00073         sc->clip->id.us= 1;
00074 
00075     if(C)
00076         WM_event_add_notifier(C, NC_MOVIECLIP|NA_SELECTED, sc->clip);
00077 }
00078 
00079 MovieClip *ED_space_clip(SpaceClip *sc)
00080 {
00081     return sc->clip;
00082 }
00083 
00084 ImBuf *ED_space_clip_get_buffer(SpaceClip *sc)
00085 {
00086     if(sc->clip) {
00087         ImBuf *ibuf;
00088 
00089         ibuf= BKE_movieclip_get_postprocessed_ibuf(sc->clip, &sc->user, sc->postproc_flag);
00090 
00091         if(ibuf && (ibuf->rect || ibuf->rect_float))
00092             return ibuf;
00093 
00094         if(ibuf)
00095             IMB_freeImBuf(ibuf);
00096     }
00097 
00098     return NULL;
00099 }
00100 
00101 ImBuf *ED_space_clip_get_stable_buffer(SpaceClip *sc, float loc[2], float *scale, float *angle)
00102 {
00103     if(sc->clip) {
00104         ImBuf *ibuf;
00105 
00106         ibuf= BKE_movieclip_get_stable_ibuf(sc->clip, &sc->user, loc, scale, angle, sc->postproc_flag);
00107 
00108         if(ibuf && (ibuf->rect || ibuf->rect_float))
00109             return ibuf;
00110 
00111         if(ibuf)
00112             IMB_freeImBuf(ibuf);
00113     }
00114 
00115     return NULL;
00116 }
00117 
00118 void ED_space_clip_size(SpaceClip *sc, int *width, int *height)
00119 {
00120     if(!sc->clip) {
00121         *width= 0;
00122         *height= 0;
00123     } else
00124         BKE_movieclip_get_size(sc->clip, &sc->user, width, height);
00125 }
00126 
00127 void ED_space_clip_zoom(SpaceClip *sc, ARegion *ar, float *zoomx, float *zoomy)
00128 {
00129     int width, height;
00130 
00131     ED_space_clip_size(sc, &width, &height);
00132 
00133     *zoomx= (float)(ar->winrct.xmax - ar->winrct.xmin + 1)/(float)((ar->v2d.cur.xmax - ar->v2d.cur.xmin)*width);
00134     *zoomy= (float)(ar->winrct.ymax - ar->winrct.ymin + 1)/(float)((ar->v2d.cur.ymax - ar->v2d.cur.ymin)*height);
00135 }
00136 
00137 void ED_space_clip_aspect(SpaceClip *sc, float *aspx, float *aspy)
00138 {
00139     MovieClip *clip= ED_space_clip(sc);
00140 
00141     if(clip)
00142         BKE_movieclip_aspect(clip, aspx, aspy);
00143     else
00144         *aspx= *aspy= 1.0f;
00145 }
00146 
00147 void ED_clip_update_frame(const Main *mainp, int cfra)
00148 {
00149     wmWindowManager *wm;
00150     wmWindow *win;
00151 
00152     /* image window, compo node users */
00153     for(wm=mainp->wm.first; wm; wm= wm->id.next) { /* only 1 wm */
00154         for(win= wm->windows.first; win; win= win->next) {
00155             ScrArea *sa;
00156             for(sa= win->screen->areabase.first; sa; sa= sa->next) {
00157                 if(sa->spacetype==SPACE_CLIP) {
00158                     SpaceClip *sc= sa->spacedata.first;
00159 
00160                     sc->scopes.ok= 0;
00161 
00162                     BKE_movieclip_user_set_frame(&sc->user, cfra);
00163                 }
00164             }
00165         }
00166     }
00167 }
00168 
00169 static int selected_boundbox(SpaceClip *sc, float min[2], float max[2])
00170 {
00171     MovieClip *clip= ED_space_clip(sc);
00172     MovieTrackingTrack *track;
00173     int width, height, ok= 0;
00174     ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking);
00175 
00176     INIT_MINMAX2(min, max);
00177 
00178     ED_space_clip_size(sc, &width, &height);
00179 
00180     track= tracksbase->first;
00181     while(track) {
00182         if(TRACK_VIEW_SELECTED(sc, track)) {
00183             MovieTrackingMarker *marker= BKE_tracking_get_marker(track, sc->user.framenr);
00184 
00185             if(marker) {
00186                 float pos[3];
00187 
00188                 pos[0]= marker->pos[0]+track->offset[0];
00189                 pos[1]= marker->pos[1]+track->offset[1];
00190                 pos[2]= 0.0f;
00191 
00192                 /* undistortion happens for normalized coords */
00193                 if(sc->user.render_flag&MCLIP_PROXY_RENDER_UNDISTORT)
00194                     /* undistortion happens for normalized coords */
00195                     ED_clip_point_undistorted_pos(sc, pos, pos);
00196 
00197                 pos[0]*= width;
00198                 pos[1]*= height;
00199 
00200                 mul_v3_m4v3(pos, sc->stabmat, pos);
00201 
00202                 DO_MINMAX2(pos, min, max);
00203 
00204                 ok= 1;
00205             }
00206         }
00207 
00208         track= track->next;
00209     }
00210 
00211     return ok;
00212 }
00213 
00214 int ED_clip_view_selection(SpaceClip *sc, ARegion *ar, int fit)
00215 {
00216     int w, h, frame_width, frame_height;
00217     float min[2], max[2];
00218 
00219     ED_space_clip_size(sc, &frame_width, &frame_height);
00220 
00221     if(frame_width==0 || frame_height==0) return 0;
00222 
00223     if(!selected_boundbox(sc, min, max))
00224         return 0;
00225 
00226     /* center view */
00227     clip_view_center_to_point(sc, (max[0]+min[0])/(2*frame_width), (max[1]+min[1])/(2*frame_height));
00228 
00229     w= max[0]-min[0];
00230     h= max[1]-min[1];
00231 
00232     /* set zoom to see all selection */
00233     if(w>0 && h>0) {
00234         int width, height;
00235         float zoomx, zoomy, newzoom, aspx, aspy;
00236 
00237         ED_space_clip_aspect(sc, &aspx, &aspy);
00238 
00239         width= ar->winrct.xmax - ar->winrct.xmin + 1;
00240         height= ar->winrct.ymax - ar->winrct.ymin + 1;
00241 
00242         zoomx= (float)width/w/aspx;
00243         zoomy= (float)height/h/aspy;
00244 
00245         newzoom= 1.0f/power_of_2(1/MIN2(zoomx, zoomy));
00246 
00247         if(fit || sc->zoom>newzoom)
00248             sc->zoom= newzoom;
00249     }
00250 
00251     return 1;
00252 }
00253 
00254 void ED_clip_point_undistorted_pos(SpaceClip *sc, float co[2], float nco[2])
00255 {
00256     copy_v2_v2(nco, co);
00257 
00258     if(sc->user.render_flag&MCLIP_PROXY_RENDER_UNDISTORT) {
00259         MovieClip *clip= ED_space_clip(sc);
00260         float aspy= 1.0f/clip->tracking.camera.pixel_aspect;
00261         int width, height;
00262 
00263         ED_space_clip_size(sc, &width, &height);
00264 
00265         nco[0]*= width;
00266         nco[1]*= height*aspy;
00267 
00268         BKE_tracking_invert_intrinsics(&clip->tracking, nco, nco);
00269         nco[0]/= width;
00270         nco[1]/= height*aspy;
00271     }
00272 }
00273 
00274 void ED_clip_point_stable_pos(bContext *C, float x, float y, float *xr, float *yr)
00275 {
00276     ARegion *ar= CTX_wm_region(C);
00277     SpaceClip *sc= CTX_wm_space_clip(C);
00278     int sx, sy, width, height;
00279     float zoomx, zoomy, pos[3]={0.0f, 0.0f, 0.0f}, imat[4][4];
00280 
00281     ED_space_clip_zoom(sc, ar, &zoomx, &zoomy);
00282     ED_space_clip_size(sc, &width, &height);
00283 
00284     UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &sx, &sy);
00285 
00286     pos[0]= (x-sx)/zoomx;
00287     pos[1]= (y-sy)/zoomy;
00288 
00289     invert_m4_m4(imat, sc->stabmat);
00290     mul_v3_m4v3(pos, imat, pos);
00291 
00292     *xr= pos[0]/width;
00293     *yr= pos[1]/height;
00294 
00295     if(sc->user.render_flag&MCLIP_PROXY_RENDER_UNDISTORT) {
00296         MovieClip *clip= ED_space_clip(sc);
00297         MovieTracking *tracking= &clip->tracking;
00298         float aspy= 1.0f/tracking->camera.pixel_aspect;
00299         float tmp[2]= {*xr*width, *yr*height*aspy};
00300 
00301         BKE_tracking_apply_intrinsics(tracking, tmp, tmp);
00302 
00303         *xr= tmp[0]/width;
00304         *yr= tmp[1]/(height*aspy);
00305     }
00306 }
00307 
00308 void ED_clip_mouse_pos(bContext *C, wmEvent *event, float co[2])
00309 {
00310     ED_clip_point_stable_pos(C, event->mval[0], event->mval[1], &co[0], &co[1]);
00311 }