== Preview Range ==

Preview Range is a useful tool for animating (espcially on longer timelines). It allows you to only run through a limited set of frames to quickly preview the timing of a section of movement without going through the whole timeline. It means you don't have to set/reset start/end frame for rendering everytime you wish to only preview a region of frames.

Hi Ton,

Attached is a patch (I know you've already got lots of them in the tracker ;-) ) for a feature that I've sometimes wanted. It seems that this sort of thing is supported in other packages, but I can't be sure.

Note: I may have left in a few bits and pieces I didn't mean to in the patch (this is off a source tree which had quite a few revisions in it, all of which was experimental)



== Preview Range ==
Preview range is useful for animating (espcially on longer timelines). It allows you to only run through a limited set of frames to quickly preview the timing of a section of movement without going through the whole timeline. It means you don't have to set/reset start/end frame for rendering everytime you wish to only preview a region of frames.

* 'Ctrl P' in Action/NLA/Timeline sets preview range. Click+drag to form selection-box defining region of frames to preview
* 'Alt P' in Action/NLA/Timeline to clear preview range
* 'Pre' button beside Start/End fields in timeline toggles whether start/end fields refer to scene or preview
* 'Ctrl Rightarrow' and 'Ctrl Leftarrow' jump to start/end of preview region when it is set
* 'S' and 'E' set the start/end frames of preview region when it is set (just like normally) in Timeline only
* In Action/NLA editors, frames out of preview region are now drawn darkened when preview-region is set


See the following page for more info later:
http://wiki.blender.org/index.php/User:Aligorith/Preview_Range
This commit is contained in:
2007-03-19 07:32:36 +00:00
parent 819fc06a80
commit 8b4b8d4dd2
14 changed files with 269 additions and 36 deletions

View File

@@ -56,6 +56,12 @@ void make_marker_cfra_list(struct ListBase *lb, short only_sel);
void draw_markers_timespace(void);
/* ******** Animation - Preview Range ************* */
void anim_previewrange_set(void);
void anim_previewrange_clear(void);
void draw_anim_preview_timespace(void);
/* *********** TimeLine Specific ***************/
void timeline_frame_to_center(void);
void nextprev_timeline_key(short dir);

View File

@@ -109,6 +109,8 @@
#define F_CFRA ((float)(G.scene->r.cfra))
#define SFRA (G.scene->r.sfra)
#define EFRA (G.scene->r.efra)
#define PSFRA ((G.scene->r.psfra != 0)? (G.scene->r.psfra): (G.scene->r.sfra))
#define PEFRA ((G.scene->r.psfra != 0)? (G.scene->r.pefra): (G.scene->r.efra))
#define ISPOIN(a, b, c) ( (a->b) && (a->c) )
#define ISPOIN3(a, b, c, d) ( (a->b) && (a->c) && (a->d) )
@@ -392,6 +394,7 @@
#define B_TL_PREVKEY 754
#define B_TL_NEXTKEY 755
#define B_TL_STOP 756
#define B_TL_PREVIEWON 757
/* NLA: 801-850 */
#define B_NLAHOME 801

View File

@@ -162,7 +162,8 @@ typedef struct RenderData {
struct QuicktimeCodecData *qtcodecdata;
struct FFMpegCodecData ffcodecdata;
int cfra, sfra, efra; /* fames as in 'images' */
int cfra, sfra, efra; /* frames as in 'images' */
int psfra, pefra; /* start+end frames of preview range */
int images, framapto;
short flag, threads;

View File

@@ -692,7 +692,7 @@ void drawactionspace(ScrArea *sa, void *spacedata)
draw_mesh_strips(G.saction, key);
}
/* Draw current frame */
/* reset matrices for stuff to be drawn on top of keys*/
glViewport(ofsx+G.v2d->mask.xmin,
ofsy+G.v2d->mask.ymin,
( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1,
@@ -702,11 +702,16 @@ void drawactionspace(ScrArea *sa, void *spacedata)
( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1,
( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1);
myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
/* Draw current frame */
draw_cfra_action();
/* Draw markers */
draw_markers_timespace();
/* Draw 'curtains' for preview */
draw_anim_preview_timespace();
/* Draw scroll */
mywinset(curarea->win); // reset scissor too
if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) {

View File

@@ -711,15 +711,20 @@ void drawnlaspace(ScrArea *sa, void *spacedata)
/* the right hand side, with strips and keys */
draw_nla_strips_keys(G.snla);
/* Draw current frame */
glViewport(ofsx+G.v2d->mask.xmin, ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1);
glScissor(ofsx+G.v2d->mask.xmin, ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1);
myortho2 (G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
/* Draw current frame */
draw_cfra_action();
/* draw markers */
draw_markers_timespace();
/* Draw preview 'curtains' */
draw_anim_preview_timespace();
/* Draw scroll */
mywinset(curarea->win); // reset scissor too
if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) {

View File

@@ -210,22 +210,42 @@ void draw_markers_timespace()
}
void draw_anim_preview_timespace()
{
/* only draw this if preview range is set */
if (G.scene->r.psfra) {
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glEnable(GL_BLEND);
glColor4f(0, 0, 0, 0.4);
if (PSFRA < PEFRA) {
glRectf(G.v2d->cur.xmin, G.v2d->cur.ymin, PSFRA, G.v2d->cur.ymax);
glRectf(PEFRA, G.v2d->cur.ymin, G.v2d->cur.xmax, G.v2d->cur.ymax);
}
else {
glRectf(G.v2d->cur.xmin, G.v2d->cur.ymin, G.v2d->cur.xmax, G.v2d->cur.ymax);
}
glDisable(GL_BLEND);
}
}
static void draw_sfra_efra()
{
BIF_ThemeColorShade(TH_BACK, -25);
if (G.scene->r.sfra < G.scene->r.efra) {
glRectf(G.v2d->cur.xmin, G.v2d->cur.ymin, G.scene->r.sfra, G.v2d->cur.ymax);
glRectf(G.scene->r.efra, G.v2d->cur.ymin, G.v2d->cur.xmax, G.v2d->cur.ymax);
} else {
if (PSFRA < PEFRA) {
glRectf(G.v2d->cur.xmin, G.v2d->cur.ymin, PSFRA, G.v2d->cur.ymax);
glRectf(PEFRA, G.v2d->cur.ymin, G.v2d->cur.xmax, G.v2d->cur.ymax);
}
else {
glRectf(G.v2d->cur.xmin, G.v2d->cur.ymin, G.v2d->cur.xmax, G.v2d->cur.ymax);
}
BIF_ThemeColorShade(TH_BACK, -60);
/* thin lines where the actual frames are */
fdrawline(G.scene->r.sfra, G.v2d->cur.ymin, G.scene->r.sfra, G.v2d->cur.ymax);
fdrawline(G.scene->r.efra, G.v2d->cur.ymin, G.scene->r.efra, G.v2d->cur.ymax);
fdrawline(PSFRA, G.v2d->cur.ymin, PSFRA, G.v2d->cur.ymax);
fdrawline(PEFRA, G.v2d->cur.ymin, PEFRA, G.v2d->cur.ymax);
glDisable(GL_BLEND);
}
@@ -325,7 +345,9 @@ void drawtimespace(ScrArea *sa, void *spacedata)
myortho2(stime->v2d.cur.xmin, stime->v2d.cur.xmax, stime->v2d.cur.ymin, stime->v2d.cur.ymax);
/* draw darkened area outside of active timeline */
/* draw darkened area outside of active timeline
* frame range used is preview range or scene range
*/
draw_sfra_efra();
/* boundbox_seq(); */

View File

@@ -3116,9 +3116,9 @@ void inner_play_anim_loop(int init, int mode)
tottime -= swaptime;
while (update_time()) PIL_sleep_ms(1);
if(CFRA>=EFRA) {
if(CFRA>=PEFRA) {
if (tottime > 0.0) tottime = 0.0;
CFRA= SFRA;
CFRA= PSFRA;
audiostream_stop();
audiostream_start( CFRA );
}
@@ -3144,7 +3144,7 @@ int play_anim(int mode)
if(SFRA==0) SFRA= 1;
if(EFRA==0) EFRA= 250;
if(SFRA>EFRA) return 0;
if(PSFRA>PEFRA) return 0;
update_time();
@@ -3196,7 +3196,7 @@ int play_anim(int mode)
inner_play_anim_loop(0, 0);
screen_swapbuffers();
if((mode & 2) && CFRA==EFRA) break; /* no replay */
if((mode & 2) && CFRA==PEFRA) break; /* no replay */
}
if(event==SPACEKEY);

View File

@@ -139,7 +139,9 @@ void circle_selectCB(select_CBfunc func);
/* local protos ---------------*/
void snap_curs_to_firstsel(void);
/* flag==2 only border, flag==3 cross+border */
/* flag==2 only border, flag==3 cross+border
flag==5 cross + border + start&end frame
*/
int get_border(rcti *rect, short flag)
{
float dvec[4], fac1, fac2;
@@ -294,6 +296,49 @@ int get_border(rcti *rect, short flag)
glColor3f(0.9, 0.9, 0.9);
BMF_DrawString(G.fonts, str);
}
else if ((ELEM3(curarea->spacetype, SPACE_ACTION, SPACE_NLA, SPACE_TIME)) && flag==5) {
/* only while setting preview range */
View2D *v2d;
switch (curarea->spacetype)
{
case SPACE_ACTION:
{
SpaceAction *saaction= curarea->spacedata.first;
v2d= &saaction->v2d;
}
break;
case SPACE_NLA:
{
SpaceNla *snla= curarea->spacedata.first;
v2d= &snla->v2d;
}
break;
default:
v2d= G.v2d;
break;
}
mvalo[2]= x1;
mvalo[3]= y1;
areamouseco_to_ipoco(v2d, mval, dvec, dvec+1);
areamouseco_to_ipoco(v2d, mvalo+2, dvec+2, dvec+3);
if (dvec[0] < dvec[2])
sprintf(str, "Preview Range: %d to %d", (int)dvec[0], (int)dvec[2]);
else
sprintf(str, "Preview Range: %d to %d", (int)dvec[2], (int)dvec[0]);
BIF_ThemeColor(TH_BACK);
glRecti(14, 24, 165, 38);
glColor3f(0.0, 0.0, 0.0);
glRasterPos2i(15, 27);
BMF_DrawString(G.fonts, str);
glColor3f(0.8, 0.8, 0.8);
glRasterPos2i(16, 28);
BMF_DrawString(G.fonts, str);
}
bglFlush();
@@ -343,6 +388,9 @@ int get_border(rcti *rect, short flag)
if ELEM(curarea->spacetype, SPACE_VIEW3D, SPACE_IPO) {
scrarea_queue_winredraw(curarea);
}
else if ELEM3(curarea->spacetype, SPACE_ACTION, SPACE_NLA, SPACE_TIME) {
scrarea_queue_winredraw(curarea); // only really needed for
}
}
bglFlush();

View File

@@ -3049,6 +3049,17 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
clean_actionchannels(act);
break;
case PKEY:
if (G.qual & LR_CTRLKEY) /* set preview range */
anim_previewrange_set();
else if (G.qual & LR_ALTKEY) /* clear preview range */
anim_previewrange_clear();
allqueue(REDRAWTIME, 0);
allqueue(REDRAWBUTSALL, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWNLA, 0);
break;
case SKEY:
if (mval[0]>=ACTWIDTH) {
if(G.qual & LR_SHIFTKEY) {

View File

@@ -1914,6 +1914,17 @@ void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
relink_active_strip();
break;
case PKEY:
if (G.qual & LR_CTRLKEY) /* set preview range */
anim_previewrange_set();
else if (G.qual & LR_ALTKEY) /* clear preview range */
anim_previewrange_clear();
allqueue(REDRAWTIME, 0);
allqueue(REDRAWBUTSALL, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWNLA, 0);
break;
case SKEY:
if(G.qual==LR_ALTKEY) {
val= pupmenu("Action Strip Scale%t|Clear Strip Scale%x1|Remap Start/End%x2");

View File

@@ -1054,8 +1054,8 @@ int has_screenhandler(bScreen *sc, short eventcode)
static void animated_screen(bScreen *sc, short val)
{
if (U.mixbufsize && (val & TIME_WITH_SEQ_AUDIO)) {
if(CFRA>=EFRA) {
CFRA= SFRA;
if(CFRA>=PEFRA) {
CFRA= PSFRA;
audiostream_stop();
audiostream_start( CFRA );
}
@@ -1067,7 +1067,7 @@ static void animated_screen(bScreen *sc, short val)
}
else {
CFRA++;
if(CFRA > EFRA) CFRA= SFRA;
if(CFRA > PEFRA) CFRA= PSFRA;
}
update_for_newframe_nodraw(1);

View File

@@ -577,6 +577,61 @@ static void select_timeline_marker_frame(int frame, unsigned char shift)
/* *********** end Markers - TimeLine *************** */
/* set the animation preview range of scene */
void anim_previewrange_set()
{
extern float get_action_frame(Object *ob, float cframe);
rcti rect;
rctf rectf;
short val, mval[2];
/* set range by drawing border-select rectangle */
if ( (val = get_border(&rect, 5)) ) {
/* get frame numbers */
mval[0]= rect.xmin;
mval[1]= rect.ymin+2;
areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
mval[0]= rect.xmax;
mval[1]= rect.ymax-2;
areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
/* check if this is called from the action editor (with scaling) */
if (curarea->spacetype == SPACE_ACTION) {
/* if action is mapped in NLA, it returns a correction */
if(G.saction->pin==0 && OBACT) {
rectf.xmin= get_action_frame(OBACT, rectf.xmin);
rectf.xmax= get_action_frame(OBACT, rectf.xmax);
}
}
/* set preview-range */
G.scene->r.psfra= rectf.xmin;
G.scene->r.pefra= rectf.xmax;
BIF_undo_push("Set anim-preview range");
allqueue(REDRAWTIME, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWNLA, 0);
allqueue(REDRAWBUTSALL, 0);
}
}
/* clear the animation preview range for scene */
void anim_previewrange_clear()
{
G.scene->r.psfra = 0;
G.scene->r.pefra = 0;
BIF_undo_push("Clear anim-preview range");
allqueue(REDRAWTIME, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWNLA, 0);
allqueue(REDRAWBUTSALL, 0);
}
/* ************ end Animation Preview Range ********** */
static int float_to_frame(float frame)
{
int to= (int) floor(0.5 + frame/G.scene->r.framelen );
@@ -875,6 +930,12 @@ void winqreadtimespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
transform_markers('g', 0);
break;
case EKEY: /* set end frame */
if (G.scene->r.psfra) {
if (CFRA > G.scene->r.psfra)
G.scene->r.psfra= CFRA;
G.scene->r.pefra= CFRA;
}
else
G.scene->r.efra = CFRA;
allqueue(REDRAWBUTSALL, 0);
allqueue(REDRAWTIME, 1);
@@ -890,7 +951,18 @@ void winqreadtimespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
allqueue(REDRAWNLA, 0);
allqueue(REDRAWSOUND, 0);
break;
case PKEY: /* preview-range stuff */
if (G.qual & LR_CTRLKEY) /* set preview range */
anim_previewrange_set();
else if (G.qual & LR_ALTKEY) /* clear preview range */
anim_previewrange_clear();
break;
case SKEY: /* set start frame */
if (G.scene->r.psfra) {
G.scene->r.psfra= CFRA;
G.scene->r.pefra= (EFRA > CFRA)? (EFRA):(CFRA);
}
else
G.scene->r.sfra = CFRA;
allqueue(REDRAWBUTSALL, 0);
allqueue(REDRAWTIME, 1);

View File

@@ -76,7 +76,7 @@ void do_time_buttons(ScrArea *sa, unsigned short event)
switch(event) {
case B_TL_REW:
CFRA= SFRA;
CFRA= PSFRA;
update_for_newframe();
break;
case B_TL_PLAY:
@@ -94,7 +94,7 @@ void do_time_buttons(ScrArea *sa, unsigned short event)
break;
case B_TL_FF:
/* end frame */
CFRA= EFRA;
CFRA= PEFRA;
update_for_newframe();
break;
case B_TL_PREVKEY:
@@ -105,6 +105,21 @@ void do_time_buttons(ScrArea *sa, unsigned short event)
/* next keyframe */
nextprev_timeline_key(1);
break;
case B_TL_PREVIEWON:
if (G.scene->r.psfra) {
/* turn on preview range */
G.scene->r.psfra= G.scene->r.sfra;
G.scene->r.pefra= G.scene->r.efra;
}
else {
/* turn off preview range */
G.scene->r.psfra= 0;
G.scene->r.pefra= 0;
}
BIF_undo_push("Set anim-preview range");
allqueue(REDRAWALL, 0);
break;
}
}
@@ -286,10 +301,21 @@ static void do_time_framemenu(void *arg, int event)
{
switch(event) {
case 1: /*Set as Start */
if (G.scene->r.psfra) {
G.scene->r.psfra= CFRA;
G.scene->r.pefra= (EFRA > CFRA)? (EFRA):(CFRA);
}
else
G.scene->r.sfra = CFRA;
allqueue(REDRAWALL, 1);
break;
case 2: /* Set as End */
if (G.scene->r.psfra) {
if (CFRA > G.scene->r.psfra)
G.scene->r.psfra= CFRA;
G.scene->r.pefra= CFRA;
}
else
G.scene->r.efra = CFRA;
allqueue(REDRAWALL, 1);
break;
@@ -424,6 +450,28 @@ void time_buttons(ScrArea *sa)
uiBlockSetEmboss(block, UI_EMBOSS);
uiBlockBeginAlign(block);
uiDefButI(block, TOG, B_TL_PREVIEWON,"Preview",
xco,0, XIC, YIC,
&G.scene->r.psfra,0, 1, 0, 0,
"Show settings for frame range of animation preview");
xco += XIC;
if (G.scene->r.psfra) {
uiDefButI(block, NUM, REDRAWALL,"Start:",
xco,0, 4.5*XIC, YIC,
&G.scene->r.psfra,MINFRAMEF, MAXFRAMEF, 0, 0,
"The start frame of the animation preview");
xco += 4.5*XIC;
uiDefButI(block, NUM, REDRAWALL,"End:",
xco,0,4.5*XIC,YIC,
&G.scene->r.pefra,PSFRA,MAXFRAMEF, 0, 0,
"The end frame of the animation preview");
}
else {
uiDefButI(block, NUM, REDRAWALL,"Start:",
xco,0, 4.5*XIC, YIC,
&G.scene->r.sfra,MINFRAMEF, MAXFRAMEF, 0, 0,
@@ -435,6 +483,7 @@ void time_buttons(ScrArea *sa)
xco,0,4.5*XIC,YIC,
&G.scene->r.efra,SFRA,MAXFRAMEF, 0, 0,
"The end frame of the animation");
}
uiBlockEndAlign(block);
xco += 4.5*XIC+16;

View File

@@ -603,7 +603,7 @@ int blenderqread(unsigned short event, short val)
CFRA--;
if(G.qual==LR_SHIFTKEY)
CFRA= SFRA;
CFRA= PSFRA;
if(CFRA<1) CFRA=1;
update_for_newframe();
@@ -631,7 +631,7 @@ int blenderqread(unsigned short event, short val)
CFRA++;
if(G.qual==LR_SHIFTKEY)
CFRA= EFRA;
CFRA= PEFRA;
update_for_newframe();
}