From 379d7827aee5a5ece24ba5c7990fbe1847b18b38 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Wed, 26 Sep 2007 13:40:38 +0000 Subject: [PATCH 01/22] * Fix for typo in AA curve commit. Thanks Stephan K for the notice! --- source/blender/src/interface_draw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/src/interface_draw.c b/source/blender/src/interface_draw.c index 5b7fb4e6248..4f1d5056111 100644 --- a/source/blender/src/interface_draw.c +++ b/source/blender/src/interface_draw.c @@ -2272,7 +2272,7 @@ static void ui_draw_but_CURVE(uiBut *but) } glEnd(); glDisable(GL_LINE_SMOOTH); - glEnable(GL_BLEND); + glDisable(GL_BLEND); /* the points, use aspect to make them visible on edges */ cmp= cuma->curve; From 54dca15a0e277da419b4dfae2cd4c123fcd67fd8 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Thu, 27 Sep 2007 06:47:59 +0000 Subject: [PATCH 02/22] == FFMPEG == First round of scons support for internal ffmpeg. --- config/linux2-config.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/config/linux2-config.py b/config/linux2-config.py index 90fe74cee6b..863885dc0bd 100644 --- a/config/linux2-config.py +++ b/config/linux2-config.py @@ -115,11 +115,13 @@ BF_ICONV_LIB = 'iconv' BF_ICONV_LIBPATH = '${BF_ICONV}/lib' # enable ffmpeg support -WITH_BF_FFMPEG = 'false' # -DWITH_FFMPEG -BF_FFMPEG = '/usr' +WITH_BF_FFMPEG = 'true' # -DWITH_FFMPEG +BF_FFMPEG = '#extern/ffmpeg' BF_FFMPEG_INC = '${BF_FFMPEG}/include' BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib' -BF_FFMPEG_LIB = 'avformat avcodec swscale avutil' +BF_FFMPEG_LIB = '' +# Uncomment the following line to use external ffmpeg +# BF_FFMPEG_LIB = 'avformat avcodec swscale avutil' # Mesa Libs should go here if your using them as well.... WITH_BF_STATICOPENGL = 'false' From fb44c5825ea7bb0dbc8bb324658877e00e5cbc80 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Thu, 27 Sep 2007 06:48:28 +0000 Subject: [PATCH 03/22] == FFMPEG == Scons support for internal ffmpeg --- extern/SConscript | 3 +++ 1 file changed, 3 insertions(+) diff --git a/extern/SConscript b/extern/SConscript index 0cdf9676862..0be34630600 100644 --- a/extern/SConscript +++ b/extern/SConscript @@ -13,3 +13,6 @@ if env['WITH_BF_INTERNATIONAL']: if env['WITH_BF_VERSE']: SConscript(['verse/dist/SConstruct']) + +if env['WITH_BF_FFMPEG']: + SConscript(['ffmpeg/SConscript']); From 41989bf1a770cbc54500f03bb2a6a80279b5153b Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Thu, 27 Sep 2007 06:53:21 +0000 Subject: [PATCH 04/22] == FFMPEG == Minor fix for using system's ffmpeg. --- config/linux2-config.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/linux2-config.py b/config/linux2-config.py index 863885dc0bd..38af4de4ac7 100644 --- a/config/linux2-config.py +++ b/config/linux2-config.py @@ -120,8 +120,9 @@ BF_FFMPEG = '#extern/ffmpeg' BF_FFMPEG_INC = '${BF_FFMPEG}/include' BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib' BF_FFMPEG_LIB = '' -# Uncomment the following line to use external ffmpeg +# Uncomment the following two lines to use system's ffmpeg # BF_FFMPEG_LIB = 'avformat avcodec swscale avutil' +# BF_FFMPEG = '/usr' # Mesa Libs should go here if your using them as well.... WITH_BF_STATICOPENGL = 'false' From 5a9273dad1d8fd728d7740def4397203e2091121 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Thu, 27 Sep 2007 07:08:22 +0000 Subject: [PATCH 05/22] == FFMPEG == External ffmpeg would have linked against both internal and external libs. --- extern/SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/SConscript b/extern/SConscript index 0be34630600..924b7f54507 100644 --- a/extern/SConscript +++ b/extern/SConscript @@ -14,5 +14,5 @@ if env['WITH_BF_INTERNATIONAL']: if env['WITH_BF_VERSE']: SConscript(['verse/dist/SConstruct']) -if env['WITH_BF_FFMPEG']: +if env['WITH_BF_FFMPEG'] and env['BF_FFMPEG_LIB'] == '': SConscript(['ffmpeg/SConscript']); From 637a22bcc37f7da13e683555a6f6468e03cd4656 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Thu, 27 Sep 2007 07:19:10 +0000 Subject: [PATCH 06/22] == FFMPEG == Another fix for external ffmpeg building. --- config/linux2-config.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/linux2-config.py b/config/linux2-config.py index 38af4de4ac7..4bf7e755c49 100644 --- a/config/linux2-config.py +++ b/config/linux2-config.py @@ -117,12 +117,12 @@ BF_ICONV_LIBPATH = '${BF_ICONV}/lib' # enable ffmpeg support WITH_BF_FFMPEG = 'true' # -DWITH_FFMPEG BF_FFMPEG = '#extern/ffmpeg' -BF_FFMPEG_INC = '${BF_FFMPEG}/include' -BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib' BF_FFMPEG_LIB = '' # Uncomment the following two lines to use system's ffmpeg -# BF_FFMPEG_LIB = 'avformat avcodec swscale avutil' # BF_FFMPEG = '/usr' +# BF_FFMPEG_LIB = 'avformat avcodec swscale avutil' +BF_FFMPEG_INC = '${BF_FFMPEG}/include' +BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib' # Mesa Libs should go here if your using them as well.... WITH_BF_STATICOPENGL = 'false' From 8c2ebc2decc22bb052242d7a305010b55fd52947 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 27 Sep 2007 16:47:08 +0000 Subject: [PATCH 07/22] glitches with UV tools fixed - P was grabbing, snap cursor to selection didnt work, and constants for black and white were reversed (not user visible error) --- source/blender/src/drawimage.c | 6 +++--- source/blender/src/editsima.c | 2 +- source/blender/src/space.c | 4 +--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/source/blender/src/drawimage.c b/source/blender/src/drawimage.c index 25e0ceed1ca..f785db8e205 100644 --- a/source/blender/src/drawimage.c +++ b/source/blender/src/drawimage.c @@ -624,7 +624,7 @@ void draw_uvs_sima(void) break; case SI_UVDT_BLACK: /* black/white */ case SI_UVDT_WHITE: - cpack((G.sima->dt_uv==SI_UVDT_WHITE) ? 0x0 : 0xFFFFFF); + cpack((G.sima->dt_uv==SI_UVDT_WHITE) ? 0xFFFFFF : 0x0); for (efa= em->faces.first; efa; efa= efa->next) { // tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); // if (SIMA_FACEDRAW_CHECK(efa, tface)) { @@ -1165,8 +1165,8 @@ static void image_panel_view_properties(short cntrl) // IMAGE_HANDLER_VIEW_PROPE uiDefBut(block, LABEL, B_NOP, "Draw Type:", 10, 20,120,19, 0, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); uiDefButC(block, ROW, B_REDR, "Dash", 10, 0,58,19, &G.sima->dt_uv, 0.0, SI_UVDT_DASH, 0, 0, "Dashed Wire UV drawtype"); - uiDefButC(block, ROW, B_REDR, "Black", 68, 0,58,19, &G.sima->dt_uv, 0.0, SI_UVDT_WHITE, 0, 0, "Black Wire UV drawtype"); - uiDefButC(block, ROW, B_REDR, "White", 126,0,58,19, &G.sima->dt_uv, 0.0, SI_UVDT_BLACK, 0, 0, "White Wire UV drawtype"); + uiDefButC(block, ROW, B_REDR, "Black", 68, 0,58,19, &G.sima->dt_uv, 0.0, SI_UVDT_BLACK, 0, 0, "Black Wire UV drawtype"); + uiDefButC(block, ROW, B_REDR, "White", 126,0,58,19, &G.sima->dt_uv, 0.0, SI_UVDT_WHITE, 0, 0, "White Wire UV drawtype"); uiDefButC(block, ROW, B_REDR, "Outline", 184,0,58,19, &G.sima->dt_uv, 0.0, SI_UVDT_OUTLINE, 0, 0, "Outline Wire UV drawtype"); uiBlockBeginAlign(block); uiDefButBitI(block, TOG, SI_SMOOTH_UV, B_REDR, "Smooth", 250,0,60,19, &G.sima->flag, 0, 0, 0, 0, "Display smooth lines in the UV view"); diff --git a/source/blender/src/editsima.c b/source/blender/src/editsima.c index 1b1c4c251d2..c1251f0dec1 100644 --- a/source/blender/src/editsima.c +++ b/source/blender/src/editsima.c @@ -1027,7 +1027,7 @@ void snap_menu_sima(void) short event; if( is_uv_tface_editing_allowed()==0 || !G.v2d) return; /* !G.v2d should never happen */ - event = pupmenu("Snap %t|Selection -> Pixels%x1|Selection -> Cursor%x2|Selection -> Adjacent Unselected%x3|Cursor-> Pixel%x3|Cursor-> Selection%x4"); + event = pupmenu("Snap %t|Selection -> Pixels%x1|Selection -> Cursor%x2|Selection -> Adjacent Unselected%x3|Cursor -> Pixel%x4|Cursor -> Selection%x5"); switch (event) { case 1: if (snap_uv_sel_to_pixels()) { diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 8563a0f634f..8bc7d8e464a 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -4817,7 +4817,6 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt) else if((G.qual==0)) borderselect_sima(UV_SELECT_ALL); break; - case CKEY: if (G.sima->flag & SI_SYNC_UVSEL) { /* operate on the editmesh */ @@ -4877,6 +4876,7 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt) pin_tface_uv(0); else pin_tface_uv(1); + break; case GKEY: if((G.qual==0) && is_uv_tface_editing_allowed()) { initTransform(TFM_TRANSLATION, CTX_NONE); @@ -4925,7 +4925,6 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt) scrarea_queue_headredraw(curarea); scrarea_queue_winredraw(curarea); break; - case PERIODKEY: if(G.qual==LR_CTRLKEY) { G.v2d->around= V3D_LOCAL; @@ -4947,7 +4946,6 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt) G.scene->prop_mode = (G.scene->prop_mode+1)%7; allqueue(REDRAWHEADERS, 0); } - break; case PADSLASHKEY: if(G.qual==0) From 0345b3b221568d9c29665397ef42496c8199a05e Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Thu, 27 Sep 2007 17:45:53 +0000 Subject: [PATCH 08/22] Improve consistency in editmesh tmp unions. EditVert had "float *fp" while the others had "float p". changed to "float p" and made all code using the float pointer use the already existing tmp.p (void*) instead. --- source/blender/blenlib/BLI_editVert.h | 2 +- source/blender/src/editmesh_mods.c | 10 ++++---- source/blender/src/transform_conversions.c | 30 +++++++++++----------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/source/blender/blenlib/BLI_editVert.h b/source/blender/blenlib/BLI_editVert.h index fd217e479ed..795f6781894 100644 --- a/source/blender/blenlib/BLI_editVert.h +++ b/source/blender/blenlib/BLI_editVert.h @@ -55,9 +55,9 @@ typedef struct EditVert struct EditVert *v; struct EditEdge *e; struct EditFace *f; - float *fp; void *p; long l; + float fp; } tmp; float no[3]; /*vertex normal */ float co[3]; /*vertex location */ diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c index 2a86c674f66..5cfeab03c0a 100644 --- a/source/blender/src/editmesh_mods.c +++ b/source/blender/src/editmesh_mods.c @@ -3894,7 +3894,7 @@ void vertexsmooth(void) eve= em->verts.first; while(eve) { if(eve->f & SELECT) { - eve->tmp.fp = adr; + eve->tmp.p = (void*)adr; eve->f1= 0; eve->f2= 0; adr+= 3; @@ -3942,11 +3942,11 @@ void vertexsmooth(void) if((eed->v1->f & SELECT) && eed->v1->f1<255) { eed->v1->f1++; - VecAddf(eed->v1->tmp.fp, eed->v1->tmp.fp, fvec); + VecAddf(eed->v1->tmp.p, eed->v1->tmp.p, fvec); } if((eed->v2->f & SELECT) && eed->v2->f1<255) { eed->v2->f1++; - VecAddf(eed->v2->tmp.fp, eed->v2->tmp.fp, fvec); + VecAddf(eed->v2->tmp.p, eed->v2->tmp.p, fvec); } } eed= eed->next; @@ -3956,7 +3956,7 @@ void vertexsmooth(void) while(eve) { if(eve->f & SELECT) { if(eve->f1) { - adr = eve->tmp.fp; + adr = eve->tmp.p; fac= 0.5/(float)eve->f1; eve->co[0]= 0.5*eve->co[0]+fac*adr[0]; @@ -3976,7 +3976,7 @@ void vertexsmooth(void) } } } - eve->tmp.fp= 0; + eve->tmp.p= NULL; } eve= eve->next; } diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index 058461806ce..d7bd3154ba1 100644 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -1580,7 +1580,7 @@ static void set_crazyspace_quats(float *origcos, float *mappedcos, float *quats) /* two abused locations in vertices */ for(eve= em->verts.first; eve; eve= eve->next, index++) { - eve->tmp.fp = NULL; + eve->tmp.p = NULL; eve->prev= (EditVert *)index; } @@ -1596,9 +1596,9 @@ static void set_crazyspace_quats(float *origcos, float *mappedcos, float *quats) co2= (origcos)? origcos + 3*(long)(efa->v2->prev): efa->v2->co; co3= (origcos)? origcos + 3*(long)(efa->v3->prev): efa->v3->co; - if(efa->v2->tmp.fp==NULL && efa->v2->f1) { + if(efa->v2->tmp.p==NULL && efa->v2->f1) { set_crazy_vertex_quat(quats, co2, co3, co1, v2, v3, v1); - efa->v2->tmp.fp= quats; + efa->v2->tmp.p= (void*)quats; quats+= 4; } @@ -1606,31 +1606,31 @@ static void set_crazyspace_quats(float *origcos, float *mappedcos, float *quats) v4= mappedcos + 3*(long)(efa->v4->prev); co4= (origcos)? origcos + 3*(long)(efa->v4->prev): efa->v4->co; - if(efa->v1->tmp.fp==NULL && efa->v1->f1) { + if(efa->v1->tmp.p==NULL && efa->v1->f1) { set_crazy_vertex_quat(quats, co1, co2, co4, v1, v2, v4); - efa->v1->tmp.fp= quats; + efa->v1->tmp.p= (void*)quats; quats+= 4; } - if(efa->v3->tmp.fp==NULL && efa->v3->f1) { + if(efa->v3->tmp.p==NULL && efa->v3->f1) { set_crazy_vertex_quat(quats, co3, co4, co2, v3, v4, v2); - efa->v3->tmp.fp= quats; + efa->v3->tmp.p= (void*)quats; quats+= 4; } - if(efa->v4->tmp.fp==NULL && efa->v4->f1) { + if(efa->v4->tmp.p==NULL && efa->v4->f1) { set_crazy_vertex_quat(quats, co4, co1, co3, v4, v1, v3); - efa->v4->tmp.fp= quats; + efa->v4->tmp.p= (void*)quats; quats+= 4; } } else { - if(efa->v1->tmp.fp==NULL && efa->v1->f1) { + if(efa->v1->tmp.p==NULL && efa->v1->f1) { set_crazy_vertex_quat(quats, co1, co2, co3, v1, v2, v3); - efa->v1->tmp.fp= quats; + efa->v1->tmp.p= (void*)quats; quats+= 4; } - if(efa->v3->tmp.fp==NULL && efa->v3->f1) { + if(efa->v3->tmp.p==NULL && efa->v3->f1) { set_crazy_vertex_quat(quats, co3, co1, co2, v3, v1, v2); - efa->v3->tmp.fp= quats; + efa->v3->tmp.p= (void*)quats; quats+= 4; } } @@ -1764,12 +1764,12 @@ static void createTransEditVerts(TransInfo *t) } /* CrazySpace */ - if(defmats || (quats && eve->tmp.fp)) { + if(defmats || (quats && eve->tmp.p)) { float mat[3][3], imat[3][3], qmat[3][3]; /* use both or either quat and defmat correction */ if(quats && eve->tmp.f) { - QuatToMat3(eve->tmp.fp, qmat); + QuatToMat3(eve->tmp.p, qmat); if(defmats) Mat3MulSerie(mat, mtx, qmat, defmats[a], From 18bd726f0b040f00ba64bf4c4106deea872201a9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 27 Sep 2007 20:41:56 +0000 Subject: [PATCH 09/22] bugfix from 11860, the derived mesh was getting free'd twice (crashed editmode + linked-dupes + texture-drawtype) Also fixed own bug with face mode setting (wasnt checking for texface) --- source/blender/src/drawobject.c | 9 +++++++-- source/blender/src/editmesh_tools.c | 7 ++++--- source/blender/src/header_view3d.c | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index 6be61478593..f637734fa34 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -2410,9 +2410,14 @@ static int draw_mesh_object(Base *base, int dt, int flag) if(dt>OB_WIRE) init_gl_materials(ob, 0); // no transp in editmode, the fancy draw over goes bad then draw_em_fancy(ob, G.editMesh, cageDM, finalDM, dt); - if (cageDM != finalDM) + /* TODO, not 100% sure this is correct, + * however I could not make it crash or leak ram with different + * linked-dup/modifier configurtions, + * should double check whats going on before release - Campbell */ + if (cageDM != finalDM) { cageDM->release(cageDM); - finalDM->release(finalDM); + finalDM->release(finalDM); + } } else if(!G.obedit && (G.f & G_SCULPTMODE) &&(G.scene->sculptdata.flags & SCULPT_DRAW_FAST) && OBACT==ob && !sculpt_modifiers_active(ob)) { diff --git a/source/blender/src/editmesh_tools.c b/source/blender/src/editmesh_tools.c index f4c6c475f1a..20aa1771331 100644 --- a/source/blender/src/editmesh_tools.c +++ b/source/blender/src/editmesh_tools.c @@ -5111,9 +5111,10 @@ void mesh_set_face_flags(short mode) short m_tex=0, m_tiles=0, m_shared=0, m_light=0, m_invis=0, m_collision=0, m_twoside=0, m_obcolor=0; short flag = 0, change = 0; - if(G.obedit==0) return; - - if(G.obedit->type != OB_MESH) return; + if (!EM_texFaceCheck()) { + error("not a mesh with uv/image layers"); + return; + } add_numbut(0, TOG|SHO, "Texture", 0, 0, &m_tex, NULL); add_numbut(1, TOG|SHO, "Tiles", 0, 0, &m_tiles, NULL); diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c index 3f27fe1a5ad..bd708e0aac2 100644 --- a/source/blender/src/header_view3d.c +++ b/source/blender/src/header_view3d.c @@ -2768,7 +2768,7 @@ static uiBlock *view3d_edit_mesh_facesmenu(void *arg_unused) uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Convert Quads to Triangles|Ctrl T", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Convert Triangles to Quads|Alt J", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Flip Triangle Edges|Ctrl F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Flip Triangle Edges|Ctrl Shift F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, ""); uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); From 41e79c054d4b328cc7f09d726f6221afcd62275c Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Thu, 27 Sep 2007 23:33:19 +0000 Subject: [PATCH 10/22] * changed a few hardcoded low frame limits in wave modifier to use MAXFRAMEF --- source/blender/src/buttons_editing.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 0ff5d26646a..e7c96586732 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -1856,11 +1856,11 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco uiBlockBeginAlign(block); if(wmd->speed >= 0) - uiDefButF(block, NUM, B_MODIFIER_RECALC, "Time sta:", lx,(cy-=19),buttonWidth,19, &wmd->timeoffs, -1000.0, 1000.0, 100, 0, "Specify starting frame of the wave"); + uiDefButF(block, NUM, B_MODIFIER_RECALC, "Time sta:", lx,(cy-=19),buttonWidth,19, &wmd->timeoffs, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify starting frame of the wave"); else - uiDefButF(block, NUM, B_MODIFIER_RECALC, "Time end:", lx,(cy-=19),buttonWidth,19, &wmd->timeoffs, -1000.0, 1000.0, 100, 0, "Specify ending frame of the wave"); - uiDefButF(block, NUM, B_MODIFIER_RECALC, "Lifetime:", lx,(cy-=19),buttonWidth,19, &wmd->lifetime, -1000.0, 1000.0, 100, 0, "Specify the lifespan of the wave"); - uiDefButF(block, NUM, B_MODIFIER_RECALC, "Damptime:", lx,(cy-=19),buttonWidth,19, &wmd->damp, -1000.0, 1000.0, 100, 0, "Specify the dampingtime of the wave"); + uiDefButF(block, NUM, B_MODIFIER_RECALC, "Time end:", lx,(cy-=19),buttonWidth,19, &wmd->timeoffs, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify ending frame of the wave"); + uiDefButF(block, NUM, B_MODIFIER_RECALC, "Lifetime:", lx,(cy-=19),buttonWidth,19, &wmd->lifetime, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify the lifespan of the wave"); + uiDefButF(block, NUM, B_MODIFIER_RECALC, "Damptime:", lx,(cy-=19),buttonWidth,19, &wmd->damp, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify the dampingtime of the wave"); cy -= 9; uiBlockBeginAlign(block); uiDefButF(block, NUM, B_MODIFIER_RECALC, "Sta x:", lx,(cy-=19),113,19, &wmd->startx, -100.0, 100.0, 100, 0, "Starting position for the X axis"); From b8deeb934a6ac3bbe0cb4c1178ffcc8e7c5e970f Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 27 Sep 2007 23:36:17 +0000 Subject: [PATCH 11/22] Bugfix #7419: Adding missing NULL checks for the Geometry Targets feature for Constraints. --- source/blender/blenkernel/intern/constraint.c | 97 ++++++++++--------- 1 file changed, 50 insertions(+), 47 deletions(-) diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 8445fe88797..9ee158be531 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -1146,56 +1146,58 @@ static void contarget_get_mesh_mat (Object *ob, char *substring, float mat[][4]) int i, j, count = 0; float co[3], nor[3]; - - /* get the average of all verts with that are in the vertex-group */ - for (i = 0; i < numVerts; i++, index++) { - for (j = 0; j < dvert[i].totweight; j++) { - /* does this vertex belong to nominated vertex group? */ - if (dvert[i].dw[j].def_nr == dgroup) { - dm->getVertCo(dm, i, co); - dm->getVertNo(dm, i, nor); - VecAddf(vec, vec, co); - VecAddf(normal, normal, nor); - count++; - break; + /* check that dvert and index are valid pointers (just in case) */ + if (dvert && index) { + /* get the average of all verts with that are in the vertex-group */ + for (i = 0; i < numVerts; i++, index++) { + for (j = 0; j < dvert[i].totweight; j++) { + /* does this vertex belong to nominated vertex group? */ + if (dvert[i].dw[j].def_nr == dgroup) { + dm->getVertCo(dm, i, co); + dm->getVertNo(dm, i, nor); + VecAddf(vec, vec, co); + VecAddf(normal, normal, nor); + count++; + break; + } + } - } + + + /* calculate averages of normal and coordinates */ + if (count > 0) { + VecMulf(vec, 1.0f / count); + VecMulf(normal, 1.0f / count); + } + + + /* derive the rotation from the average normal: + * - code taken from transform_manipulator.c, + * calc_manipulator_stats, V3D_MANIP_NORMAL case + */ + /* we need the transpose of the inverse for a normal... */ + Mat3CpyMat4(imat, ob->obmat); + + Mat3Inv(tmat, imat); + Mat3Transp(tmat); + Mat3MulVecfl(tmat, normal); + + Normalize(normal); + VECCOPY(plane, tmat[1]); + + VECCOPY(tmat[2], normal); + Crossf(tmat[0], normal, plane); + Crossf(tmat[1], tmat[2], tmat[0]); + + Mat4CpyMat3(mat, tmat); + Mat4Ortho(mat); + + + /* apply the average coordinate as the new location */ + VecMat4MulVecfl(tvec, ob->obmat, vec); + VECCOPY(mat[3], tvec); } - - - /* calculate averages of normal and coordinates */ - if (count > 0) { - VecMulf(vec, 1.0f / count); - VecMulf(normal, 1.0f / count); - } - - - /* derive the rotation from the average normal: - * - code taken from transform_manipulator.c, - * calc_manipulator_stats, V3D_MANIP_NORMAL case - */ - /* we need the transpose of the inverse for a normal... */ - Mat3CpyMat4(imat, ob->obmat); - - Mat3Inv(tmat, imat); - Mat3Transp(tmat); - Mat3MulVecfl(tmat, normal); - - Normalize(normal); - VECCOPY(plane, tmat[1]); - - VECCOPY(tmat[2], normal); - Crossf(tmat[0], normal, plane); - Crossf(tmat[1], tmat[2], tmat[0]); - - Mat4CpyMat3(mat, tmat); - Mat4Ortho(mat); - - - /* apply the average coordinate as the new location */ - VecMat4MulVecfl(tvec, ob->obmat, vec); - VECCOPY(mat[3], tvec); } /* free temporary DerivedMesh created (in EditMode case) */ @@ -1225,6 +1227,7 @@ static void contarget_get_lattice_mat (Object *ob, char *substring, float mat[][ /* get index of vertex group */ dgroup = get_named_vertexgroup_num(ob, substring); if (dgroup < 0) return; + if (dvert == NULL) return; /* 1. Loop through control-points checking if in nominated vertex-group. * 2. If it is, add it to vec to find the average point. From 6fd43fd68a3647901a5e5f77e0d8e4afa31484a0 Mon Sep 17 00:00:00 2001 From: Ken Hughes Date: Thu, 27 Sep 2007 23:42:21 +0000 Subject: [PATCH 12/22] Python API ---------- * changed a few hardcoded low frame limits in wave modifier to use MAXFRAMEF --- source/blender/python/api2_2x/Modifier.c | 6 +++--- source/blender/python/api2_2x/doc/Modifier.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/source/blender/python/api2_2x/Modifier.c b/source/blender/python/api2_2x/Modifier.c index 97231c8fff3..a1b052eb674 100644 --- a/source/blender/python/api2_2x/Modifier.c +++ b/source/blender/python/api2_2x/Modifier.c @@ -749,11 +749,11 @@ static int wave_setter( BPy_Modifier *self, int type, PyObject *value ) case EXPP_MOD_SPEED: return EXPP_setFloatClamped( value, &md->speed, -2.0, 2.0 ); case EXPP_MOD_DAMP: - return EXPP_setFloatClamped( value, &md->damp, -1000.0, 1000.0 ); + return EXPP_setFloatClamped( value, &md->damp, -MAXFRAMEF, MAXFRAMEF ); case EXPP_MOD_LIFETIME: - return EXPP_setFloatClamped( value, &md->lifetime, -1000.0, 1000.0 ); + return EXPP_setFloatClamped( value, &md->lifetime, -MAXFRAMEF, MAXFRAMEF ); case EXPP_MOD_TIMEOFFS: - return EXPP_setFloatClamped( value, &md->timeoffs, -1000.0, 1000.0 ); + return EXPP_setFloatClamped( value, &md->timeoffs, -MAXFRAMEF, MAXFRAMEF ); case EXPP_MOD_FLAG: return EXPP_setIValueRange( value, &md->flag, 0, MOD_WAVE_X | MOD_WAVE_Y | MOD_WAVE_CYCL, 'h' ); diff --git a/source/blender/python/api2_2x/doc/Modifier.py b/source/blender/python/api2_2x/doc/Modifier.py index 2770f66b318..0c53f470b63 100644 --- a/source/blender/python/api2_2x/doc/Modifier.py +++ b/source/blender/python/api2_2x/doc/Modifier.py @@ -110,9 +110,9 @@ Example:: - WIDTH - Used for Wave only (float [0.0 - 5.0]) - NARROW - Used for Wave only (float [0.0 - 10.0]) - SPEED - Used for Wave only (float [-2.0 - 2.0]) - - DAMP - Used for Wave only (float [-1000.0 - 1000.0]) - - LIFETIME - Used for Wave only (float [-1000.0 - 1000.0]) - - TIMEOFFS - Used for Wave only (float [-1000.0 - 1000.0]) + - DAMP - Used for Wave only (float [-MAXFRAME - MAXFRAME]) + - LIFETIME - Used for Wave only (float [-MAXFRAME - MAXFRAME]) + - TIMEOFFS - Used for Wave only (float [-MAXFRAME - MAXFRAME]) - OPERATION - Used for boolean only (int 0,1,2 : Intersect, Union, Difference) From 1ea472a9037d5df5000fef7785ed87ed4eb21ea6 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sat, 29 Sep 2007 03:52:25 +0000 Subject: [PATCH 13/22] Bugfix: For transform in UV/Image editor (and soon, the IPO editor), transformations on 'local' axes (i.e. GXX, or GYY) won't work. Therefore, I've disabled this for those cases. Note: A small part of the IPO editor transform-code port is in this commit too. --- source/blender/src/transform.c | 46 ++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c index dae288293ab..00d987142fd 100644 --- a/source/blender/src/transform.c +++ b/source/blender/src/transform.c @@ -267,16 +267,26 @@ void convertViewVec(TransInfo *t, float *vec, short dx, short dy) } else if(t->spacetype==SPACE_IMAGE) { float divx, divy, aspx, aspy; - + transform_aspect_ratio_tface_uv(&aspx, &aspy); - + divx= G.v2d->mask.xmax-G.v2d->mask.xmin; divy= G.v2d->mask.ymax-G.v2d->mask.ymin; - + vec[0]= aspx*(G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/divx; vec[1]= aspy*(G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/divy; vec[2]= 0.0f; } + else if(t->spacetype==SPACE_IPO) { + float divx, divy; + + divx= G.v2d->mask.xmax-G.v2d->mask.xmin; + divy= G.v2d->mask.ymax-G.v2d->mask.ymin; + + vec[0]= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx) / (divx); + vec[1]= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy) / (divy); + vec[2]= 0.0f; + } } void projectIntView(TransInfo *t, float *vec, int *adr) @@ -638,14 +648,19 @@ static void transformEvent(unsigned short event, short val) { case XKEY: if ((Trans.flag & T_NO_CONSTRAINT)==0) { if (cmode == 'X') { - if (Trans.con.mode & CON_USER) { + if (Trans.flag & T_2D_EDIT) { stopConstraint(&Trans); } else { - if (G.qual == 0) - setUserConstraint(&Trans, (CON_AXIS0), "along %s X"); - else if ((G.qual == LR_SHIFTKEY) && ((Trans.flag & T_2D_EDIT)==0)) - setUserConstraint(&Trans, (CON_AXIS1|CON_AXIS2), "locking %s X"); + if (Trans.con.mode & CON_USER) { + stopConstraint(&Trans); + } + else { + if (G.qual == 0) + setUserConstraint(&Trans, (CON_AXIS0), "along %s X"); + else if (G.qual == LR_SHIFTKEY) + setUserConstraint(&Trans, (CON_AXIS1|CON_AXIS2), "locking %s X"); + } } } else { @@ -660,14 +675,19 @@ static void transformEvent(unsigned short event, short val) { case YKEY: if ((Trans.flag & T_NO_CONSTRAINT)==0) { if (cmode == 'Y') { - if (Trans.con.mode & CON_USER) { + if (Trans.flag & T_2D_EDIT) { stopConstraint(&Trans); } else { - if (G.qual == 0) - setUserConstraint(&Trans, (CON_AXIS1), "along %s Y"); - else if ((G.qual == LR_SHIFTKEY) && ((Trans.flag & T_2D_EDIT)==0)) - setUserConstraint(&Trans, (CON_AXIS0|CON_AXIS2), "locking %s Y"); + if (Trans.con.mode & CON_USER) { + stopConstraint(&Trans); + } + else { + if (G.qual == 0) + setUserConstraint(&Trans, (CON_AXIS1), "along %s Y"); + else if (G.qual == LR_SHIFTKEY) + setUserConstraint(&Trans, (CON_AXIS0|CON_AXIS2), "locking %s Y"); + } } } else { From ae40a1d86e5917dbd23ac4bcdcbeca07a3505e0d Mon Sep 17 00:00:00 2001 From: Geoffrey Bantle Date: Sat, 29 Sep 2007 05:49:51 +0000 Subject: [PATCH 14/22] -> Active face wasn't getting set properly on editmode exit Active face was being set for the editmesh instead of the mesh on editmode exit. Fixed. --- source/blender/src/editmesh.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index 678178e6e5b..15f4e652490 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -1094,6 +1094,7 @@ void load_editMesh(void) a = 0; efa= em->faces.first; i = 0; + me->act_face = -1; while(efa) { mface= &((MFace *) me->mface)[i]; @@ -1149,8 +1150,8 @@ void load_editMesh(void) /* no index '0' at location 3 or 4 */ test_index_face(mface, &me->fdata, i, efa->v4?4:3); - if (a==me->act_face) - EM_set_actFace(efa); + if (EM_get_actFace() == efa) + me->act_face = a; #ifdef WITH_VERSE if(efa->vface) { From 51b56a4d3f17e8cea35ba02132af0c2b893e1ff2 Mon Sep 17 00:00:00 2001 From: Mal Duffin Date: Sat, 29 Sep 2007 18:51:01 +0000 Subject: [PATCH 15/22] GE Patch by Hamed Zaghaghi - Adding Motion Blur to the Game Engine. I reviewed the code, suggested an update ( initialising accumulation buffer ), and tested the resulting update successfully. It's great to see more GE developers!GE Patch by Hamed Zaghaghi to add motion blur to the GE ( using the accumulation buffer ). I reviewed code and tested, gave some feedback ( initialising accumulation buffer ) which was implemented straight away, and re-reviewed. It's great to have another GE coder on the team! --- .../BlenderRoutines/KX_BlenderRenderTools.cpp | 23 ++++++++++++++++ .../BlenderRoutines/KX_BlenderRenderTools.h | 3 +++ .../GamePlayer/common/GPC_RenderTools.cpp | 23 ++++++++++++++++ .../GamePlayer/common/GPC_RenderTools.h | 3 +++ source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 4 +++ source/gameengine/Ketsji/KX_PythonInit.cpp | 27 +++++++++++++++++++ .../gameengine/Rasterizer/RAS_IRasterizer.h | 9 ++++++- .../gameengine/Rasterizer/RAS_IRenderTools.h | 5 ++++ .../RAS_OpenGLRasterizer.cpp | 16 ++++++++++- .../RAS_OpenGLRasterizer.h | 20 +++++++++++++- 10 files changed, 130 insertions(+), 3 deletions(-) diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp index caf3d120fab..463f06869d6 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp @@ -452,4 +452,27 @@ RAS_IPolyMaterial* KX_BlenderRenderTools::CreateBlenderPolyMaterial( return NULL; } +void KX_BlenderRenderTools::MotionBlur(RAS_IRasterizer* rasterizer) +{ + int state = rasterizer->GetMotionBlurState(); + float motionblurvalue; + if(state) + { + motionblurvalue = rasterizer->GetMotionBlurValue(); + if(state==1) + { + //bugfix:load color buffer into accum buffer for the first time(state=1) + glAccum(GL_LOAD, 1.0); + rasterizer->SetMotionBlurState(2); + } + else if(motionblurvalue>=0.0 && motionblurvalue<=1.0) + { + glAccum(GL_MULT, motionblurvalue); + glAccum(GL_ACCUM, 1-motionblurvalue); + glAccum(GL_RETURN, 1.0); + glFlush(); + } + } +} + unsigned int KX_BlenderRenderTools::m_numgllights; diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h index dc638d1a43a..a79302a283e 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h @@ -100,7 +100,10 @@ public: void* tface); bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data); + + virtual void MotionBlur(RAS_IRasterizer* rasterizer); }; #endif //__KX_BLENDERRENDERTOOLS + diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp index 0f6bec30437..cc5c392d51a 100644 --- a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp +++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp @@ -570,4 +570,27 @@ void GPC_RenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmatrix,in } } +void GPC_RenderTools::MotionBlur(RAS_IRasterizer* rasterizer) +{ + int state = rasterizer->GetMotionBlurState(); + float motionblurvalue; + if(state) + { + motionblurvalue = rasterizer->GetMotionBlurValue(); + if(state==1) + { + //bugfix:load color buffer into accum buffer for the first time(state=1) + glAccum(GL_LOAD, 1.0); + rasterizer->SetMotionBlurState(2); + } + else if(motionblurvalue>=0.0 && motionblurvalue<=1.0) + { + glAccum(GL_MULT, motionblurvalue); + glAccum(GL_ACCUM, 1-motionblurvalue); + glAccum(GL_RETURN, 1.0); + glFlush(); + } + } +} + unsigned int GPC_RenderTools::m_numgllights; diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.h b/source/gameengine/GamePlayer/common/GPC_RenderTools.h index b7f73df3c34..e1f2a869c22 100644 --- a/source/gameengine/GamePlayer/common/GPC_RenderTools.h +++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.h @@ -149,6 +149,8 @@ public: int applyLights(int objectlayer); bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data); + + virtual void MotionBlur(RAS_IRasterizer* rasterizer); protected: /** * Copied from KX_BlenderGL.cpp in KX_blenderhook @@ -173,3 +175,4 @@ protected: #endif // __GPC_RENDERTOOLS_H + diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index e76e28bcb7b..f8826245aab 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -966,6 +966,9 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam) scene->CalculateVisibleMeshes(m_rasterizer,cam); scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools); + + m_rendertools->MotionBlur(m_rasterizer); + } @@ -1463,3 +1466,4 @@ void KX_KetsjiEngine::GetOverrideFrameColor(float& r, float& g, float& b) const b = m_overrideFrameColorB; } + diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 7a937d5e349..1a3a0490d21 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -618,7 +618,31 @@ static PyObject* gPyMakeScreenshot(PyObject*, Py_Return; } +static PyObject* gPyEnableMotionBlur(PyObject*, + PyObject* args, + PyObject*) +{ + float motionblurvalue; + if (PyArg_ParseTuple(args,"f",&motionblurvalue)) + { + if(gp_Rasterizer) + { + gp_Rasterizer->EnableMotionBlur(motionblurvalue); + } + } + Py_Return; +} +static PyObject* gPyDisableMotionBlur(PyObject*, + PyObject* args, + PyObject*) +{ + if(gp_Rasterizer) + { + gp_Rasterizer->DisableMotionBlur(); + } + Py_Return; +} STR_String gPyGetWindowHeight__doc__="getWindowHeight doc"; STR_String gPyGetWindowWidth__doc__="getWindowWidth doc"; @@ -645,6 +669,9 @@ static struct PyMethodDef rasterizer_methods[] = { {"setMistColor",(PyCFunction)gPySetMistColor,METH_VARARGS,"set Mist Color (rgb)"}, {"setMistStart",(PyCFunction)gPySetMistStart,METH_VARARGS,"set Mist Start(rgb)"}, {"setMistEnd",(PyCFunction)gPySetMistEnd,METH_VARARGS,"set Mist End(rgb)"}, + {"enableMotionBlur",(PyCFunction)gPyEnableMotionBlur,METH_VARARGS,"enable motion blur"}, + {"disableMotionBlur",(PyCFunction)gPyDisableMotionBlur,METH_VARARGS,"disable motion blur"}, + {"setEyeSeparation", (PyCFunction) gPySetEyeSeparation, METH_VARARGS, "set the eye separation for stereo mode"}, {"getEyeSeparation", (PyCFunction) gPyGetEyeSeparation, METH_VARARGS, "get the eye separation for stereo mode"}, diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h index 8ecc9e7ad05..560c6741260 100644 --- a/source/gameengine/Rasterizer/RAS_IRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h @@ -48,7 +48,6 @@ class RAS_IPolyMaterial; */ class RAS_IRasterizer { - public: RAS_IRasterizer(RAS_ICanvas* canv){}; @@ -398,7 +397,15 @@ public: virtual bool QueryLists(){return false;} virtual bool QueryArrays(){return false;} + + virtual void EnableMotionBlur(float motionblurvalue)=0; + virtual void DisableMotionBlur()=0; + + virtual float GetMotionBlurValue()=0; + virtual int GetMotionBlurState()=0; + virtual void SetMotionBlurState(int newstate)=0; }; #endif //__RAS_IRASTERIZER + diff --git a/source/gameengine/Rasterizer/RAS_IRenderTools.h b/source/gameengine/Rasterizer/RAS_IRenderTools.h index fa3c777553d..114783b9a47 100644 --- a/source/gameengine/Rasterizer/RAS_IRenderTools.h +++ b/source/gameengine/Rasterizer/RAS_IRenderTools.h @@ -174,6 +174,10 @@ public: struct RAS_LightObject* lightobject ); + virtual + void + MotionBlur(RAS_IRasterizer* rasterizer)=0; + virtual class RAS_IPolyMaterial* CreateBlenderPolyMaterial( @@ -195,3 +199,4 @@ public: #endif //__RAS_IRENDERTOOLS + diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index 53ec7a02e6f..85250fcd552 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -82,7 +82,9 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas) m_setfocallength(false), m_noOfScanlines(32), m_useTang(false), - m_materialCachingInfo(0) + m_materialCachingInfo(0), + m_motionblur(0), + m_motionblurvalue(-1.0) { m_viewmatrix.Identity(); @@ -1979,3 +1981,15 @@ void RAS_OpenGLRasterizer::SetPolygonOffset(float mult, float add) else glDisable(mode); } + +void RAS_OpenGLRasterizer::EnableMotionBlur(float motionblurvalue) +{ + m_motionblur = 1; + m_motionblurvalue = motionblurvalue; +} + +void RAS_OpenGLRasterizer::DisableMotionBlur() +{ + m_motionblur = 0; + m_motionblurvalue = -1.0; +} diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h index d95ced658ce..6728905aa57 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h @@ -91,6 +91,10 @@ class RAS_OpenGLRasterizer : public RAS_IRasterizer int m_noOfScanlines; bool InterlacedStereo() const; + //motion blur + int m_motionblur; + float m_motionblurvalue; + protected: int m_drawingmode; TexCoGen m_texco[RAS_MAX]; @@ -293,8 +297,22 @@ public: const RAS_TexVert& v2, const RAS_TexVert& v3, const MT_Vector3 &no); - + + virtual void EnableMotionBlur(float motionblurvalue); + virtual void DisableMotionBlur(); + virtual float GetMotionBlurValue(){return m_motionblurvalue;}; + virtual int GetMotionBlurState(){return m_motionblur;}; + virtual void SetMotionBlurState(int newstate) + { + if(newstate<0) + m_motionblur = 0; + else if(newstate>2) + m_motionblur = 2; + else + m_motionblur = newstate; + }; }; #endif //__RAS_OPENGLRASTERIZER + From b47c75953b78ec2645970effe189b8ed7cb7462c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 30 Sep 2007 08:28:15 +0000 Subject: [PATCH 16/22] - rewrote UV Stitch, (seperate from limit stitch now), does much less work for same results. - UV Stitch with the V key was not working (as stated in the menu) - Rotate UV's and Colors now have an option for CCW (was in the menu but not implimented) - Draw face dot in UV when in face mode --- source/blender/include/BIF_editsima.h | 3 +- source/blender/src/drawimage.c | 194 ++++++++++++++++++-------- source/blender/src/editmesh_tools.c | 86 ++++++++---- source/blender/src/editsima.c | 159 +++++++++++++-------- source/blender/src/header_image.c | 4 +- source/blender/src/space.c | 6 +- 6 files changed, 302 insertions(+), 150 deletions(-) diff --git a/source/blender/include/BIF_editsima.h b/source/blender/include/BIF_editsima.h index b85749f9f95..a515a01061a 100644 --- a/source/blender/include/BIF_editsima.h +++ b/source/blender/include/BIF_editsima.h @@ -93,7 +93,8 @@ void mirrormenu_tface_uv(void); void mirror_tface_uv(char mirroraxis); void hide_tface_uv(int swap); void reveal_tface_uv(void); -void stitch_uv_tface(int mode); +void stitch_limit_uv_tface(void); +void stitch_vert_uv_tface(void); void unlink_selection(void); void select_linked_tface_uv(int mode); void pin_tface_uv(int mode); diff --git a/source/blender/src/drawimage.c b/source/blender/src/drawimage.c index f785db8e205..ab675e5dce2 100644 --- a/source/blender/src/drawimage.c +++ b/source/blender/src/drawimage.c @@ -445,10 +445,31 @@ static void drawcursor_sima(float xuser_asp, float yuser_asp) setlinestyle(0); } +// checks if we are selecting only faces +static int draw_uvs_face_check(void) +{ + if (G.sima==NULL) + return 0; + if (G.sima->flag & SI_SYNC_UVSEL && G.scene->selectmode == SCE_SELECT_FACE) + return 1; + if (G.sima->flag & SI_SELACTFACE) + return 1; + return 0; +} + +void tface_center(MTFace *tf, float cent[2], void * isquad) +{ + + if (isquad) { + cent[0] = (tf->uv[0][0] + tf->uv[1][0] + tf->uv[2][0] + tf->uv[3][0]) / 4.0; + cent[1] = (tf->uv[0][1] + tf->uv[1][1] + tf->uv[2][1] + tf->uv[3][1]) / 4.0; + } else { + cent[0] = (tf->uv[0][0] + tf->uv[1][0] + tf->uv[2][0]) / 3.0; + cent[1] = (tf->uv[0][1] + tf->uv[1][1] + tf->uv[2][1]) / 3.0; + } +} + /* draws uv's in the image space */ - - - void draw_uvs_sima(void) { MTFace *tface,*activetface = NULL; @@ -457,10 +478,13 @@ void draw_uvs_sima(void) char col1[4], col2[4]; float pointsize; + int drawface; if (!G.obedit || !CustomData_has_layer(&em->fdata, CD_MTFACE)) return; + drawface = draw_uvs_face_check(); + calc_image_view(G.sima, 'f'); /* float */ myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax); glLoadIdentity(); @@ -686,74 +710,120 @@ void draw_uvs_sima(void) glDisable(GL_BLEND); } - /* unselected uv's */ - BIF_ThemeColor(TH_VERTEX); - pointsize = BIF_GetThemeValuef(TH_VERTEX_SIZE); - glPointSize(pointsize); - - bglBegin(GL_POINTS); - for (efa= em->faces.first; efa; efa= efa->next) { + if (drawface) { + // draw UV face points + float cent[2]; -// tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); -// if (SIMA_FACEDRAW_CHECK(efa, tface)) { - /*this is a shortcut to do the same as above but a faster for drawing */ - if ((tface=(MTFace *)efa->tmp.p)) { + /* unselected faces's */ + pointsize = BIF_GetThemeValuef(TH_FACEDOT_SIZE); + // TODO - drawobject.c changes this value after - Investiagate! + glPointSize(pointsize); - if(SIMA_UVSEL_CHECK(efa, tface, 0)); else bglVertex2fv(tface->uv[0]); - if(SIMA_UVSEL_CHECK(efa, tface, 1)); else bglVertex2fv(tface->uv[1]); - if(SIMA_UVSEL_CHECK(efa, tface, 2)); else bglVertex2fv(tface->uv[2]); - if(efa->v4) { - if(SIMA_UVSEL_CHECK(efa, tface, 3)); else bglVertex2fv(tface->uv[3]); - } - } - } - bglEnd(); - - /* pinned uv's */ - /* give odd pointsizes odd pin pointsizes */ - glPointSize(pointsize*2 + (((int)pointsize % 2)? (-1): 0)); - cpack(0xFF); - - bglBegin(GL_POINTS); - for (efa= em->faces.first; efa; efa= efa->next) { -// tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); -// if (SIMA_FACEDRAW_CHECK(efa, tface)) { - - /*this is a shortcut to do the same as above but a faster for drawing */ - if ((tface=(MTFace *)efa->tmp.p)) { + BIF_ThemeColor(TH_WIRE); + bglBegin(GL_POINTS); + for (efa= em->faces.first; efa; efa= efa->next) { - if(tface->unwrap & TF_PIN1) bglVertex2fv(tface->uv[0]); - if(tface->unwrap & TF_PIN2) bglVertex2fv(tface->uv[1]); - if(tface->unwrap & TF_PIN3) bglVertex2fv(tface->uv[2]); - if(efa->v4) { - if(tface->unwrap & TF_PIN4) bglVertex2fv(tface->uv[3]); +// tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); +// if (SIMA_FACEDRAW_CHECK(efa, tface)) { + + /*this is a shortcut to do the same as above but a faster for drawing */ + if ((tface=(MTFace *)efa->tmp.p)) { + if( ! SIMA_FACESEL_CHECK(efa, tface) ) { + tface_center(tface, cent, (void *)efa->v4); + bglVertex2fv(cent); + } } } - } - bglEnd(); - - /* selected uv's */ - BIF_ThemeColor(TH_VERTEX_SELECT); - glPointSize(pointsize); - - bglBegin(GL_POINTS); - for (efa= em->faces.first; efa; efa= efa->next) { -// tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); -// if (SIMA_FACEDRAW_CHECK(efa, tface)) { - - /*this is a shortcut to do the same as above but a faster for drawing */ - if ((tface=(MTFace *)efa->tmp.p)) { - - if(!SIMA_UVSEL_CHECK(efa, tface, 0)); else bglVertex2fv(tface->uv[0]); - if(!SIMA_UVSEL_CHECK(efa, tface, 1)); else bglVertex2fv(tface->uv[1]); - if(!SIMA_UVSEL_CHECK(efa, tface, 2)); else bglVertex2fv(tface->uv[2]); - if(efa->v4) { - if(!SIMA_UVSEL_CHECK(efa, tface, 3)); else bglVertex2fv(tface->uv[3]); + bglEnd(); + /* selected faces's */ + BIF_ThemeColor(TH_FACE_DOT); + bglBegin(GL_POINTS); + for (efa= em->faces.first; efa; efa= efa->next) { + +// tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); +// if (SIMA_FACEDRAW_CHECK(efa, tface)) { + + /*this is a shortcut to do the same as above but a faster for drawing */ + if ((tface=(MTFace *)efa->tmp.p)) { + if( SIMA_FACESEL_CHECK(efa, tface) ) { + tface_center(tface, cent, (void *)efa->v4); + bglVertex2fv(cent); + } } } + bglEnd(); + } else { + + /* unselected uv's */ + BIF_ThemeColor(TH_VERTEX); + pointsize = BIF_GetThemeValuef(TH_VERTEX_SIZE); + glPointSize(pointsize); + + bglBegin(GL_POINTS); + for (efa= em->faces.first; efa; efa= efa->next) { + +// tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); +// if (SIMA_FACEDRAW_CHECK(efa, tface)) { + + /*this is a shortcut to do the same as above but a faster for drawing */ + if ((tface=(MTFace *)efa->tmp.p)) { + + if(SIMA_UVSEL_CHECK(efa, tface, 0)); else bglVertex2fv(tface->uv[0]); + if(SIMA_UVSEL_CHECK(efa, tface, 1)); else bglVertex2fv(tface->uv[1]); + if(SIMA_UVSEL_CHECK(efa, tface, 2)); else bglVertex2fv(tface->uv[2]); + if(efa->v4) { + if(SIMA_UVSEL_CHECK(efa, tface, 3)); else bglVertex2fv(tface->uv[3]); + } + } + } + bglEnd(); + + /* pinned uv's */ + /* give odd pointsizes odd pin pointsizes */ + glPointSize(pointsize*2 + (((int)pointsize % 2)? (-1): 0)); + cpack(0xFF); + + bglBegin(GL_POINTS); + for (efa= em->faces.first; efa; efa= efa->next) { +// tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); +// if (SIMA_FACEDRAW_CHECK(efa, tface)) { + + /*this is a shortcut to do the same as above but a faster for drawing */ + if ((tface=(MTFace *)efa->tmp.p)) { + + if(tface->unwrap & TF_PIN1) bglVertex2fv(tface->uv[0]); + if(tface->unwrap & TF_PIN2) bglVertex2fv(tface->uv[1]); + if(tface->unwrap & TF_PIN3) bglVertex2fv(tface->uv[2]); + if(efa->v4) { + if(tface->unwrap & TF_PIN4) bglVertex2fv(tface->uv[3]); + } + } + } + bglEnd(); + + /* selected uv's */ + BIF_ThemeColor(TH_VERTEX_SELECT); + glPointSize(pointsize); + + bglBegin(GL_POINTS); + for (efa= em->faces.first; efa; efa= efa->next) { +// tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); +// if (SIMA_FACEDRAW_CHECK(efa, tface)) { + + /*this is a shortcut to do the same as above but a faster for drawing */ + if ((tface=(MTFace *)efa->tmp.p)) { + + if(!SIMA_UVSEL_CHECK(efa, tface, 0)); else bglVertex2fv(tface->uv[0]); + if(!SIMA_UVSEL_CHECK(efa, tface, 1)); else bglVertex2fv(tface->uv[1]); + if(!SIMA_UVSEL_CHECK(efa, tface, 2)); else bglVertex2fv(tface->uv[2]); + if(efa->v4) { + if(!SIMA_UVSEL_CHECK(efa, tface, 3)); else bglVertex2fv(tface->uv[3]); + } + } + } + bglEnd(); } - bglEnd(); glPointSize(1.0); } diff --git a/source/blender/src/editmesh_tools.c b/source/blender/src/editmesh_tools.c index 20aa1771331..2afac79be1d 100644 --- a/source/blender/src/editmesh_tools.c +++ b/source/blender/src/editmesh_tools.c @@ -6559,7 +6559,7 @@ void mesh_rotate_uvs(void) { EditMesh *em = G.editMesh; EditFace *efa; - short change = 0; + short change = 0, ccw; MTFace *tf; float u1, v1; @@ -6568,28 +6568,49 @@ void mesh_rotate_uvs(void) return; } + ccw = (G.qual == LR_SHIFTKEY); + for(efa=em->faces.first; efa; efa=efa->next) { if (efa->f & SELECT) { tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); u1= tf->uv[0][0]; v1= tf->uv[0][1]; - tf->uv[0][0]= tf->uv[1][0]; - tf->uv[0][1]= tf->uv[1][1]; - - tf->uv[1][0]= tf->uv[2][0]; - tf->uv[1][1]= tf->uv[2][1]; - - if(efa->v4) { - tf->uv[2][0]= tf->uv[3][0]; - tf->uv[2][1]= tf->uv[3][1]; - - tf->uv[3][0]= u1; - tf->uv[3][1]= v1; - } - else { - tf->uv[2][0]= u1; - tf->uv[2][1]= v1; + if (ccw) { + if(efa->v4) { + tf->uv[0][0]= tf->uv[3][0]; + tf->uv[0][1]= tf->uv[3][1]; + + tf->uv[3][0]= tf->uv[2][0]; + tf->uv[3][1]= tf->uv[2][1]; + } else { + tf->uv[0][0]= tf->uv[2][0]; + tf->uv[0][1]= tf->uv[2][1]; + } + + tf->uv[2][0]= tf->uv[1][0]; + tf->uv[2][1]= tf->uv[1][1]; + + tf->uv[1][0]= u1; + tf->uv[1][1]= v1; + } else { + tf->uv[0][0]= tf->uv[1][0]; + tf->uv[0][1]= tf->uv[1][1]; + + tf->uv[1][0]= tf->uv[2][0]; + tf->uv[1][1]= tf->uv[2][1]; + + if(efa->v4) { + tf->uv[2][0]= tf->uv[3][0]; + tf->uv[2][1]= tf->uv[3][1]; + + tf->uv[3][0]= u1; + tf->uv[3][1]= v1; + } + else { + tf->uv[2][0]= u1; + tf->uv[2][1]= v1; + } } change = 1; } @@ -6657,27 +6678,40 @@ void mesh_rotate_colors(void) { EditMesh *em = G.editMesh; EditFace *efa; - short change = 0; + short change = 0, ccw; MCol tmpcol, *mcol; if (!EM_vertColorCheck()) { error("mesh has no color layers"); return; } + ccw = (G.qual == LR_SHIFTKEY); + for(efa=em->faces.first; efa; efa=efa->next) { if (efa->f & SELECT) { mcol = CustomData_em_get(&em->fdata, efa->data, CD_MCOL); tmpcol= mcol[0]; - mcol[0]= mcol[1]; - mcol[1]= mcol[2]; - - if(efa->v4) { - mcol[2]= mcol[3]; - mcol[3]= tmpcol; + if (ccw) { + if(efa->v4) { + mcol[0]= mcol[3]; + mcol[3]= mcol[2]; + } else { + mcol[0]= mcol[2]; + } + mcol[2]= mcol[1]; + mcol[1]= tmpcol; + } else { + mcol[0]= mcol[1]; + mcol[1]= mcol[2]; + + if(efa->v4) { + mcol[2]= mcol[3]; + mcol[3]= tmpcol; + } + else + mcol[2]= tmpcol; } - else - mcol[2]= tmpcol; change = 1; } } diff --git a/source/blender/src/editsima.c b/source/blender/src/editsima.c index c1251f0dec1..3da7a72f249 100644 --- a/source/blender/src/editsima.c +++ b/source/blender/src/editsima.c @@ -308,16 +308,100 @@ void weld_align_tface_uv(char tool) object_uvs_changed(OBACT); } +// just for averaging UV's +typedef struct UVVertAverage { + float uv[2]; + int count; +} UVVertAverage; + +void stitch_vert_uv_tface(void) +{ + EditMesh *em = G.editMesh; + EditFace *efa; + EditVert *eve; + MTFace *tface; + int count; + UVVertAverage *uv_average, *uvav; + + if( is_uv_tface_editing_allowed()==0 ) return; + + // index and count verts + for (count=0, eve=em->verts.first; eve; count++, eve= eve->next) { + eve->tmp.l = count; + } + + uv_average = MEM_callocN(sizeof(UVVertAverage) * count, "Stitch"); + + // gather uv averages per vert + for (efa= em->faces.first; efa; efa= efa->next) { + tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + if (SIMA_FACEDRAW_CHECK(efa, tface)) { + if (SIMA_UVSEL_CHECK(efa, tface, 0)) { + uvav = uv_average + efa->v1->tmp.l; + uvav->count++; + uvav->uv[0] += tface->uv[0][0]; + uvav->uv[1] += tface->uv[0][1]; + } + if (SIMA_UVSEL_CHECK(efa, tface, 1)) { + uvav = uv_average + efa->v2->tmp.l; + uvav->count++; + uvav->uv[0] += tface->uv[1][0]; + uvav->uv[1] += tface->uv[1][1]; + } + if (SIMA_UVSEL_CHECK(efa, tface, 2)) { + uvav = uv_average + efa->v3->tmp.l; + uvav->count++; + uvav->uv[0] += tface->uv[2][0]; + uvav->uv[1] += tface->uv[2][1]; + } + if (efa->v4 && SIMA_UVSEL_CHECK(efa, tface, 3)) { + uvav = uv_average + efa->v4->tmp.l; + uvav->count++; + uvav->uv[0] += tface->uv[3][0]; + uvav->uv[1] += tface->uv[3][1]; + } + } + } + + // apply uv welding + for (efa= em->faces.first; efa; efa= efa->next) { + tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + if (SIMA_FACEDRAW_CHECK(efa, tface)) { + if (SIMA_UVSEL_CHECK(efa, tface, 0)) { + uvav = uv_average + efa->v1->tmp.l; + tface->uv[0][0] = uvav->uv[0]/uvav->count; + tface->uv[0][1] = uvav->uv[1]/uvav->count; + } + if (SIMA_UVSEL_CHECK(efa, tface, 1)) { + uvav = uv_average + efa->v2->tmp.l; + tface->uv[1][0] = uvav->uv[0]/uvav->count; + tface->uv[1][1] = uvav->uv[1]/uvav->count; + } + if (SIMA_UVSEL_CHECK(efa, tface, 2)) { + uvav = uv_average + efa->v3->tmp.l; + tface->uv[2][0] = uvav->uv[0]/uvav->count; + tface->uv[2][1] = uvav->uv[1]/uvav->count; + } + if (efa->v4 && SIMA_UVSEL_CHECK(efa, tface, 3)) { + uvav = uv_average + efa->v4->tmp.l; + tface->uv[3][0] = uvav->uv[0]/uvav->count; + tface->uv[3][1] = uvav->uv[1]/uvav->count; + } + } + } + MEM_freeN(uv_average); + object_uvs_changed(OBACT); +} + void weld_align_menu_tface_uv(void) { short mode= 0; if( is_uv_tface_editing_allowed()==0 ) return; - mode= pupmenu("Weld/Align%t|Weld%x1|Align X%x2|Align Y%x3|"); + mode= pupmenu("Weld/Align%t|Weld%x1|Align X%x2|Align Y%x3"); if(mode==-1) return; - if(mode==1) weld_align_tface_uv('w'); else if(mode==2) weld_align_tface_uv('x'); else if(mode==3) weld_align_tface_uv('y'); @@ -1201,12 +1285,12 @@ void mouseco_to_cursor_sima(void) scrarea_queue_winredraw(curarea); } -void stitch_uv_tface(int mode) +void stitch_limit_uv_tface(void) { MTFace *tf; int a, vtot; float newuv[2], limit[2]; - UvMapVert *vlist, *iterv, *v; + UvMapVert *vlist, *iterv; EditMesh *em = G.editMesh; EditVert *ev; EditFace *efa; @@ -1222,11 +1306,9 @@ void stitch_uv_tface(int mode) } limit[0]= limit[1]= 20.0; - if(mode==1) { - add_numbut(0, NUM|FLO, "Limit:", 0.1, 1000.0, &limit[0], NULL); - if (!do_clever_numbuts("Stitch UVs", 1, REDRAW)) - return; - } + add_numbut(0, NUM|FLO, "Limit:", 0.1, 1000.0, &limit[0], NULL); + if (!do_clever_numbuts("Stitch UVs", 1, REDRAW)) + return; limit[0]= limit[1]= limit[0]/256.0; if(G.sima->image) { @@ -1244,20 +1326,20 @@ void stitch_uv_tface(int mode) if(vmap == NULL) return; - if(mode==0) { - for(a=0, ev= em->verts.first; ev; a++, ev= ev->next) { - v = get_uv_map_vert_EM(vmap, a); - - if(v == NULL) - continue; + for(a=0, ev= em->verts.first; ev; a++, ev= ev->next) { + vlist= get_uv_map_vert_EM(vmap, a); + while(vlist) { newuv[0]= 0; newuv[1]= 0; vtot= 0; - for(iterv=v; iterv; iterv=iterv->next) { + for(iterv=vlist; iterv; iterv=iterv->next) { + if((iterv != vlist) && iterv->separate) + break; efa = EM_get_face_for_index(iterv->f); tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if (tf->flag & TF_SEL_MASK(iterv->tfindex)) { + + if (tf[iterv->f].flag & TF_SEL_MASK(iterv->tfindex)) { newuv[0] += tf->uv[iterv->tfindex][0]; newuv[1] += tf->uv[iterv->tfindex][1]; vtot++; @@ -1267,7 +1349,9 @@ void stitch_uv_tface(int mode) if (vtot > 1) { newuv[0] /= vtot; newuv[1] /= vtot; - for(iterv=v; iterv; iterv=iterv->next) { + for(iterv=vlist; iterv; iterv=iterv->next) { + if((iterv != vlist) && iterv->separate) + break; efa = EM_get_face_for_index(iterv->f); tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); if (tf->flag & TF_SEL_MASK(iterv->tfindex)) { @@ -1276,44 +1360,7 @@ void stitch_uv_tface(int mode) } } } - } - } else if(mode==1) { - for(a=0, ev= em->verts.first; ev; a++, ev= ev->next) { - vlist= get_uv_map_vert_EM(vmap, a); - - while(vlist) { - newuv[0]= 0; newuv[1]= 0; - vtot= 0; - - for(iterv=vlist; iterv; iterv=iterv->next) { - if((iterv != vlist) && iterv->separate) - break; - efa = EM_get_face_for_index(iterv->f); - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - if (tf[iterv->f].flag & TF_SEL_MASK(iterv->tfindex)) { - newuv[0] += tf->uv[iterv->tfindex][0]; - newuv[1] += tf->uv[iterv->tfindex][1]; - vtot++; - } - } - - if (vtot > 1) { - newuv[0] /= vtot; newuv[1] /= vtot; - - for(iterv=vlist; iterv; iterv=iterv->next) { - if((iterv != vlist) && iterv->separate) - break; - efa = EM_get_face_for_index(iterv->f); - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if (tf->flag & TF_SEL_MASK(iterv->tfindex)) { - tf->uv[iterv->tfindex][0]= newuv[0]; - tf->uv[iterv->tfindex][1]= newuv[1]; - } - } - } - vlist= iterv; - } + vlist= iterv; } } diff --git a/source/blender/src/header_image.c b/source/blender/src/header_image.c index c9cde5436e8..86a53ba2b3d 100644 --- a/source/blender/src/header_image.c +++ b/source/blender/src/header_image.c @@ -970,10 +970,10 @@ static void do_image_uvsmenu(void *arg, int event) else G.sima->flag |= SI_CLIP_UV; break; case 3: /* Limit Stitch UVs */ - stitch_uv_tface(1); + stitch_limit_uv_tface(); break; case 4: /* Stitch UVs */ - stitch_uv_tface(0); + stitch_vert_uv_tface(); break; case 5: /* Proportional Edit (toggle) */ if(G.scene->proportional) diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 8bc7d8e464a..a7448f53574 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -4901,10 +4901,10 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt) } break; case VKEY: - if(G.qual==LR_SHIFTKEY) - stitch_uv_tface(0); + if(G.qual == 0) + stitch_vert_uv_tface(); else if(G.qual==LR_SHIFTKEY) - stitch_uv_tface(1); + stitch_limit_uv_tface(); else if(G.qual==LR_CTRLKEY) minimize_stretch_tface_uv(); break; From 6833fa41489d46b5da1c337e1f59e436cc4ea97b Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 30 Sep 2007 11:43:16 +0000 Subject: [PATCH 17/22] == IPO Editor Transform Refactor == As with the Action and NLA editors, I've refactored the transform code for the IPO editor to get rid of the special (and clunky) transform loop that had been created. The approach this time is closer to the one taken for the UV/Image editor. What's New/Will-be-possible-in-the-future: * Numeric input now works for the IPO editor * Proportional Edit support for the IPO editor will eventually be added. * Rotation (hopefully), once some hotkeys have been remapped Known Problems: * If a keyframe moves past neighbouring keyframes and the transform gets cancelled, it doesn't get restored correctly. This problem is quite icky to resolve (I've got a large hack for this, but that currently segfaults randomly). * When scaling, the dashed-line (helpline) is drawn from the wrong starting co-ordinates. This does not affect the actual scaling though * Trying to scale BezTriples with autohandles still doesn't work if either of the handles haven't been transformed yet. This behaviour was already present prior to this commit. --- source/blender/include/BSE_editipo.h | 9 +- source/blender/include/transform.h | 6 +- source/blender/src/editipo.c | 670 +++++++-------------- source/blender/src/transform.c | 14 +- source/blender/src/transform_conversions.c | 48 +- source/blender/src/transform_generics.c | 65 +- 6 files changed, 350 insertions(+), 462 deletions(-) diff --git a/source/blender/include/BSE_editipo.h b/source/blender/include/BSE_editipo.h index 617710e1b28..37cae858656 100644 --- a/source/blender/include/BSE_editipo.h +++ b/source/blender/include/BSE_editipo.h @@ -44,6 +44,7 @@ struct Object; struct IpoKey; struct TransOb; struct Tex; +struct TransInfo; void remake_object_ipos(struct Object *ob); char *getname_ac_ei(int nr); @@ -138,11 +139,13 @@ void movekey_ipo(int dir); void movekey_obipo(int dir); void nextkey_ipo(int dir); void nextkey_obipo(int dir); -void remake_ipo_transverts(struct TransVert *transmain, float *dvec, int tot); -void transform_ipo(int mode); void filter_sampledata(float *data, int sfra, int efra); void sampledata_to_ipocurve(float *data, int sfra, int efra, struct IpoCurve *icu); -void ipo_record(void); +void ipo_record(void); + +void make_ipo_transdata(struct TransInfo *t); +void remake_ipo_transdata(struct TransInfo *t); +void transform_ipo(int mode); void actstrip_map_ipo_keys(struct Object *ob, struct Ipo *ipo, short restore, short only_keys); diff --git a/source/blender/include/transform.h b/source/blender/include/transform.h index b81ec202210..5ee4f9e84fe 100644 --- a/source/blender/include/transform.h +++ b/source/blender/include/transform.h @@ -265,9 +265,10 @@ typedef struct TransInfo { #define TD_NOTCONNECTED 8 #define TD_SINGLESIZE 16 /* used for scaling of MetaElem->rad */ #ifdef WITH_VERSE -#define TD_VERSE_OBJECT 32 -#define TD_VERSE_VERT 64 + #define TD_VERSE_OBJECT 32 + #define TD_VERSE_VERT 64 #endif +#define TD_TIMEONLY 128 /* transsnap->status */ #define SNAP_ON 1 @@ -350,6 +351,7 @@ int TimeScale(TransInfo *t, short mval[2]); /*********************** transform_conversions.c ********** */ struct ListBase; +void flushTransIpoData(TransInfo *t); void flushTransUVs(TransInfo *t); int clipUVTransform(TransInfo *t, float *vec, int resize); diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c index 75cded52010..a1439df8e7c 100644 --- a/source/blender/src/editipo.c +++ b/source/blender/src/editipo.c @@ -117,6 +117,7 @@ #include "blendef.h" #include "mydevice.h" +#include "transform.h" extern int ob_ar[]; extern int ma_ar[]; @@ -4763,483 +4764,252 @@ void movekey_obipo(int dir) /* only call external from view3d queue */ } /* **************************************************** */ +/* IPO TRANSFORM TOOLS + * + * Only the helper functions are stored here these days. They are here as + * there are heaps of ugly globals which the IPO editor relies on. + * However, the actual transforms go through the transform system these days. + */ - -void remake_ipo_transverts(TransVert *transmain, float *dvec, int tot) +/* Helper function for make_ipo_transdata, which is reponsible for associating + * source data with transform data + */ +static void bezt_to_transdata (TransData *td, TransData2D *td2d, float *loc, float *cent, short selected, short onlytime) { + /* New location from td gets dumped onto the old-location of td2d, which then + * gets copied to the actual data at td2d->loc2d (bezt->vec[n]) + * + * Due to NLA scaling, we apply NLA scaling to some of the verts here, + * and then that scaling will be undone after transform is done. + */ + + if (NLA_IPO_SCALED) { + td2d->loc[0] = get_action_frame_inv(OBACT, loc[0]); + td2d->loc[1] = loc[1]; + td2d->loc[2] = 0.0f; + td2d->loc2d = loc; + + td->flag = 0; + td->loc = td2d->loc; + VECCOPY(td->center, cent); + VECCOPY(td->iloc, td->loc); + } + else { + td2d->loc[0] = loc[0]; + td2d->loc[1] = loc[1]; + td2d->loc[2] = 0.0f; + td2d->loc2d = loc; + + td->flag = 0; + td->loc = td2d->loc; + VECCOPY(td->center, cent); + VECCOPY(td->iloc, td->loc); + } + + memset(td->axismtx, 0, sizeof(td->axismtx)); + td->axismtx[2][2] = 1.0f; + + td->ext= NULL; td->tdi= NULL; td->val= NULL; + + if (selected) { + td->flag |= TD_SELECTED; + td->dist= 0.0; + } + else + td->dist= MAXFLOAT; + + if (onlytime) + td->flag |= TD_TIMEONLY; + + Mat3One(td->mtx); + Mat3One(td->smtx); +} + +/* This function is called by createTransIpoData and remake_ipo_transdata to + * create the TransData and TransData2D arrays for transform. The costly counting + * stage is only performed for createTransIpoData case, and is indicated by t->total==-1; + */ +void make_ipo_transdata (TransInfo *t) +{ + TransData *td = NULL; + TransData2D *td2d = NULL; + EditIpo *ei; - TransVert *tv; BezTriple *bezt; int a, b; - ei= G.sipo->editipo; - for(a=0; atotipo; a++, ei++) { + /* countsel and propmode are used for proportional edit, which is not yet available */ + int count=0/*, countsel=0*/; + /*int propmode = t->flag & T_PROP_EDIT;*/ + + /* count data and allocate memory (if needed) */ + if (t->total == 0) { + /* count data first */ + if (totipo_vertsel) { + /* we're probably in editmode, so only selected verts */ + count= totipo_vertsel; + } + else if (totipo_edit==0 && totipo_sel!=0) { + /* we're not in editmode, so entire curves get moved */ + ei= G.sipo->editipo; + for (a=0; atotipo; a++, ei++) { + if (ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu)) { + if (ei->icu->bezt && ei->icu->ipo==IPO_BEZ) + count+= 3*ei->icu->totvert; + else + count+= ei->icu->totvert; + } + } + if (count==0) return; + } + else { + /* this case should not happen */ + return; + } + /* memory allocation */ + /*t->total= (propmode)? count: countsel;*/ + t->total= count; + t->data= MEM_callocN(t->total*sizeof(TransData), "TransData (IPO Editor)"); + /* for each 2d vert a 3d vector is allocated, so that they can be treated just as if they were 3d verts */ + t->data2d= MEM_callocN(t->total*sizeof(TransData2D), "TransData2D (IPO Editor)"); + } + + td= t->data; + td2d= t->data2d; + + /* add verts */ + if (totipo_vertsel) { + /* we're probably in editmode, so only selected verts */ + ei= G.sipo->editipo; + for (a=0; atotipo; a++, ei++) { + /* only consider those curves that are visible and are being edited/used for showkeys */ + if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) { + if ( (ei->flag & IPO_EDIT) || G.sipo->showkey) { + if (ei->icu->bezt) { + bezt= ei->icu->bezt; + + for (b=0; b < ei->icu->totvert; b++, bezt++) { + /* only include handles if selected, and interpolaton mode uses beztriples */ + if (ei->icu->ipo==IPO_BEZ) { + if (bezt->f1 & 1) + bezt_to_transdata(td++, td2d++, bezt->vec[0], bezt->vec[1], 1, (ei->disptype==IPO_DISPBITS)); + if (bezt->f3 & 1) + bezt_to_transdata(td++, td2d++, bezt->vec[2], bezt->vec[1], 1, (ei->disptype==IPO_DISPBITS)); + } + + /* only include main vert if selected */ + if (bezt->f2 & 1) { + bezt_to_transdata(td++, td2d++, bezt->vec[1], bezt->vec[1], 1, (ei->disptype==IPO_DISPBITS)); + } + } + } + } + } + } + } + else if (totipo_edit==0 && totipo_sel!=0) { + /* we're not in editmode, so entire curves get moved */ + ei= G.sipo->editipo; + for (a=0; atotipo; a++, ei++) { + /* only include curves that are visible and selected */ + if (ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu)) { + if (ei->icu->bezt) { + bezt= ei->icu->bezt; + b= ei->icu->totvert; + for (b=0; b < ei->icu->totvert; b++, bezt++) { + /* only include handles if interpolation mode is bezier not bpoint */ + if (ei->icu->ipo==IPO_BEZ) { + bezt_to_transdata(td++, td2d++, bezt->vec[0], bezt->vec[1], 1, (ei->disptype==IPO_DISPBITS)); + bezt_to_transdata(td++, td2d++, bezt->vec[2], bezt->vec[1], 1, (ei->disptype==IPO_DISPBITS)); + } + + /* always include the main handle */ + bezt_to_transdata(td++, td2d++, bezt->vec[1], bezt->vec[1], 1, (ei->disptype==IPO_DISPBITS)); + } + } + } + } + } +} + + +/* This function is called by recalcData during the Transform loop to recalculate + * the handles of curves and sort the keyframes so that the curves draw correctly. + * It is only called if some keyframes have moved out of order. + */ +/* FIXME! There's a bug with this, which causes 'old-loc' values to get overridden. + ("mapping" hack is possible, but needs more debugging... in the meantime, this is used) */ +void remake_ipo_transdata (TransInfo *t) +{ + EditIpo *ei; + int a; + + /* bubble-sort the beztriples */ + ei= G.sipo->editipo; + for (a=0; atotipo; a++, ei++) { if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) { - - if(ei->icu->bezt) { + if (ei->icu->bezt) { sort_time_ipocurve(ei->icu); } } } - - ei= G.sipo->editipo; - tv= transmain; - for(a=0; atotipo; a++, ei++) { - - if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) { - if( (ei->flag & IPO_EDIT) || G.sipo->showkey) { - if(ei->icu->bezt) { - bezt= ei->icu->bezt; - b= ei->icu->totvert; - while(b--) { - if(ei->icu->ipo==IPO_BEZ) { - if(bezt->f1 & 1) { - tv->loc= bezt->vec[0]; - tv++; - } - if(bezt->f3 & 1) { - tv->loc= bezt->vec[2]; - tv++; - } - } - if(bezt->f2 & 1) { - tv->loc= bezt->vec[1]; - tv++; - } - - bezt++; - } - testhandles_ipocurve(ei->icu); - } - } - } - } - if(G.sipo->showkey) make_ipokey(); + /* remake transdata - bad! */ + make_ipo_transdata(t); - if(dvec==0) return; - - tv= transmain; - for(a=0; aoldloc[0] = get_action_frame_inv(OBACT, tv->loc[0]); - tv->oldloc[0]-= dvec[0]; - tv->oldloc[0] = get_action_frame(OBACT, tv->oldloc[0]); - } - else { - tv->oldloc[0]= tv->loc[0]-dvec[0]; - } - tv->oldloc[1]= tv->loc[1]-dvec[1]; - } + /* remake ipokeys */ + if (G.sipo->showkey) make_ipokey(); } -#define CLAMP_OFF 0 -#define CLAMP_X 1 -#define CLAMP_Y 2 - -void transform_ipo(int mode) +/* This function acts as the entrypoint for transforms in the IPO editor (as for + * the Action and NLA editors). The actual transform loop is not here anymore. + */ +void transform_ipo (int mode) { - EditIpo *ei; - BezTriple *bezt; - TransVert *transmain = NULL, *tv; - float dx, dy, dvec[2], min[3], max[3], vec[2], div, cent[2], size[2], sizefac; - int tot=0, a, b, firsttime=1, afbreek=0, dosort, clampAxis=CLAMP_OFF; - unsigned short event = 0; - short mval[2], val, xo, yo, xn, yn, xc, yc; - char str[64]; + short tmode; - if(G.sipo->ipo && G.sipo->ipo->id.lib) return; - if(G.sipo->editipo==0) return; - if(mode=='r') return; /* from gesture */ + /* data-validation */ + if (G.sipo->ipo && G.sipo->ipo->id.lib) return; + if (G.sipo->editipo==0) return; - INIT_MINMAX(min, max); + /* convert ascii-based mode to transform system constants (mode) */ + switch (mode) { + case 'g': + tmode= TFM_TRANSLATION; + break; + case 'r': + tmode= TFM_ROTATION; + break; + case 's': + tmode= TFM_RESIZE; + break; + default: + tmode= 0; + return; + } - /* which vertices are involved */ + /* the transform system method involved depends on the selection */ get_status_editipo(); - if(totipo_vertsel) { - tot= totipo_vertsel; - tv=transmain= MEM_callocN(tot*sizeof(TransVert), "transmain"); - - ei= G.sipo->editipo; - for(a=0; atotipo; a++, ei++) { - - if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) { - if( (ei->flag & IPO_EDIT) || G.sipo->showkey) { - - - if(ei->icu->bezt) { - bezt= ei->icu->bezt; - b= ei->icu->totvert; - while(b--) { - if(ei->icu->ipo==IPO_BEZ) { - if(bezt->f1 & 1) { - tv->loc= bezt->vec[0]; - VECCOPY(tv->oldloc, tv->loc); - if(ei->disptype==IPO_DISPBITS) tv->flag= 1; - - /* we take the middle vertex */ - DO_MINMAX2(bezt->vec[1], min, max); - - tv++; - } - if(bezt->f3 & 1) { - tv->loc= bezt->vec[2]; - VECCOPY(tv->oldloc, tv->loc); - if(ei->disptype==IPO_DISPBITS) tv->flag= 1; - - /* we take the middle vertex */ - DO_MINMAX2(bezt->vec[1], min, max); - - tv++; - } - } - if(bezt->f2 & 1) { - tv->loc= bezt->vec[1]; - VECCOPY(tv->oldloc, tv->loc); - if(ei->disptype==IPO_DISPBITS) tv->flag= 1; - DO_MINMAX2(bezt->vec[1], min, max); - tv++; - } - bezt++; - } - } - } - } - } - + if (totipo_vertsel) { + /* we're probably in editmode, so only selected verts - transform system */ + initTransform(tmode, CTX_NONE); + Transform(); } - else if(totipo_edit==0 && totipo_sel!=0) { - - ei= G.sipo->editipo; - for(a=0; atotipo; a++, ei++) { - if (ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu)) { - if(ei->icu->bezt && ei->icu->ipo==IPO_BEZ) tot+= 3*ei->icu->totvert; - else tot+= ei->icu->totvert; - } - } - if(tot==0) return; - - tv=transmain= MEM_callocN(tot*sizeof(TransVert), "transmain"); - - ei= G.sipo->editipo; - for(a=0; atotipo; a++, ei++) { - if (ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu)) { - if(ei->icu->bezt) { - - bezt= ei->icu->bezt; - b= ei->icu->totvert; - while(b--) { - if(ei->icu->ipo==IPO_BEZ) { - tv->loc= bezt->vec[0]; - VECCOPY(tv->oldloc, tv->loc); - if(ei->disptype==IPO_DISPBITS) tv->flag= 1; - tv++; - - tv->loc= bezt->vec[2]; - VECCOPY(tv->oldloc, tv->loc); - if(ei->disptype==IPO_DISPBITS) tv->flag= 1; - tv++; - } - tv->loc= bezt->vec[1]; - VECCOPY(tv->oldloc, tv->loc); - if(ei->disptype==IPO_DISPBITS) tv->flag= 1; - - DO_MINMAX2(bezt->vec[1], min, max); - - tv++; - - bezt++; - } - } - } - } - + else if (totipo_edit==0 && totipo_sel!=0) { + /* we're not in editmode, so entire curves get moved - transform system*/ + initTransform(tmode, CTX_NONE); + Transform(); } - - if(tot==0) { - if(totipo_edit==0) move_keys(OBACT); + else { + /* shapekey mode? special transform code */ + if (totipo_edit==0) + move_keys(OBACT); return; } - - cent[0]= (float)((min[0]+max[0])/2.0); - cent[1]= (float)((min[1]+max[1])/2.0); - - if(G.sipo->showkey) { - clampAxis = CLAMP_Y; - } - ipoco_to_areaco(G.v2d, cent, mval); - xc= mval[0]; - yc= mval[1]; - - getmouseco_areawin(mval); - xo= xn= mval[0]; - yo= yn= mval[1]; - dvec[0]= dvec[1]= 0.0; - - sizefac= (float)(sqrt( (float)((yc-yn)*(yc-yn)+(xn-xc)*(xn-xc)) )); - if(sizefac<2.0) sizefac= 2.0; - - while(afbreek==0) { - getmouseco_areawin(mval); - if(mval[0]!=xo || mval[1]!=yo || firsttime) { - - if(mode=='g') { - - dx= (float)(mval[0]- xo); - dy= (float)(mval[1]- yo); - - div= (float)(G.v2d->mask.xmax-G.v2d->mask.xmin); - dvec[0]+= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/div; - - div= (float)(G.v2d->mask.ymax-G.v2d->mask.ymin); - dvec[1]+= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/div; - - if(clampAxis) dvec[clampAxis-1]= 0.0; - - /* vec is reused below: remake_ipo_transverts */ - vec[0]= dvec[0]; - vec[1]= dvec[1]; - - apply_keyb_grid(vec, 0.0, (float)1.0, (float)0.1, U.flag & USER_AUTOGRABGRID); - apply_keyb_grid(vec+1, 0.0, (float)1.0, (float)0.1, 0); - - tv= transmain; - for(a=0; aloc[0] = get_action_frame_inv(OBACT, tv->oldloc[0]); - tv->loc[0]+= vec[0]; - tv->loc[0] = get_action_frame(OBACT, tv->loc[0]); - } - else { - tv->loc[0]= tv->oldloc[0]+vec[0]; - } - - if(tv->flag==0) tv->loc[1]= tv->oldloc[1]+vec[1]; - } - - if (clampAxis == CLAMP_Y) - sprintf(str, "X: %.3f ", vec[0]); - else if (clampAxis == CLAMP_X) - sprintf(str, "Y: %.3f ", vec[1]); - else - sprintf(str, "X: %.3f Y: %.3f ", vec[0], vec[1]); - - headerprint(str); - } - else if(mode=='s') { - - size[0]=size[1]=(float)( (sqrt( (float)((yc-mval[1])*(yc-mval[1])+(mval[0]-xc)*(mval[0]-xc)) ))/sizefac); - - if(clampAxis) size[clampAxis-1]= 1.0; - - apply_keyb_grid(size, 0.0, (float)0.2, (float)0.1, U.flag & USER_AUTOSIZEGRID); - apply_keyb_grid(size+1, 0.0, (float)0.2, (float)0.1, U.flag & USER_AUTOSIZEGRID); - - tv= transmain; - - for(a=0; aloc[0] = get_action_frame_inv(OBACT, tv->oldloc[0]) - get_action_frame_inv(OBACT, cent[0]); - tv->loc[0]*= size[0]; - tv->loc[0]+= get_action_frame_inv(OBACT, cent[0]); - tv->loc[0] = get_action_frame(OBACT, tv->loc[0]); - } - else { - tv->loc[0]= size[0]*(tv->oldloc[0]-cent[0])+ cent[0]; - } - - if(tv->flag==0) tv->loc[1]= size[1]*(tv->oldloc[1]-cent[1])+ cent[1]; - } - - if (clampAxis == CLAMP_Y) - sprintf(str, "scaleX: %.3f ", size[0]); - else if (clampAxis == CLAMP_X) - sprintf(str, "scaleY: %.3f ", size[1]); - else - sprintf(str, "scaleX: %.3f scaleY: %.3f ", size[0], size[1]); - - headerprint(str); - - } - - xo= mval[0]; - yo= mval[1]; - - dosort= 0; - ei= G.sipo->editipo; - for(a=0; atotipo; a++, ei++) { - if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) { - - /* watch it: if the time is wrong: do not correct handles */ - if (test_time_ipocurve(ei->icu) ) dosort++; - else testhandles_ipocurve(ei->icu); - } - } - - if(dosort) { - if(mode=='g') remake_ipo_transverts(transmain, vec, tot); - else remake_ipo_transverts(transmain, 0, tot); - } - if(G.sipo->showkey) update_ipokey_val(); - - calc_ipo(G.sipo->ipo, (float)CFRA); - - /* update realtime */ - if(G.sipo->lock) { - if(G.sipo->blocktype==ID_MA || G.sipo->blocktype==ID_TE) { - do_ipo(G.sipo->ipo); - force_draw_plus(SPACE_BUTS, 0); - } - else if(G.sipo->blocktype==ID_CA) { - do_ipo(G.sipo->ipo); - force_draw_plus(SPACE_VIEW3D, 0); - } - else if(G.sipo->blocktype==ID_KE) { - Object *ob= OBACT; - if(ob) { - ob->shapeflag &= ~OB_SHAPE_TEMPLOCK; - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - } - force_draw_plus(SPACE_VIEW3D, 0); - } - else if(G.sipo->blocktype==ID_PO) { - Object *ob= OBACT; - if(ob && ob->pose) { - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - } - force_draw_plus(SPACE_VIEW3D, 0); - } - else if(G.sipo->blocktype==ID_OB) { - Base *base= FIRSTBASE; - - while(base) { - if(base->object->ipo==G.sipo->ipo) { - do_ob_ipo(base->object); - base->object->recalc |= OB_RECALC_OB; - } - base= base->next; - } - DAG_scene_flush_update(G.scene, screen_view3d_layers()); - force_draw_plus(SPACE_VIEW3D, 0); - } - else force_draw(0); - } - else { - force_draw(0); - } - firsttime= 0; - } - else BIF_wait_for_statechange(); - - while(qtest()) { - event= extern_qread(&val); - if(val) { - switch(event) { - case ESCKEY: - case LEFTMOUSE: - case RIGHTMOUSE: - case SPACEKEY: - case RETKEY: - afbreek= 1; - break; - case MIDDLEMOUSE: - if(G.sipo->showkey==0) { - if (clampAxis == CLAMP_OFF) - { - if( abs(mval[0]-xn) > abs(mval[1]-yn)) - clampAxis = CLAMP_Y; - else - clampAxis = CLAMP_X; - } - else - { - clampAxis = CLAMP_OFF; - } - firsttime= 1; - } - break; - case XKEY: - /* clampAxis is the axis that will be Zeroed out, which is why we clamp - * on Y when pressing X - */ - if (clampAxis == CLAMP_Y) - clampAxis = CLAMP_OFF; // Clamp Off if already on Y - else - clampAxis = CLAMP_Y; // On otherwise - firsttime= 1; - break; - case YKEY: - /* clampAxis is the axis that will be Zeroed out, which is why we clamp - * on X when pressing Y - */ - if (clampAxis == CLAMP_X) - clampAxis = CLAMP_OFF; // Clamp Off if already on X - else - clampAxis = CLAMP_X; // On otherwise - firsttime= 1; - break; - case LEFTCTRLKEY: - case RIGHTCTRLKEY: - firsttime= 1; - break; - default: - if(mode=='g') { - if(G.qual & LR_CTRLKEY) { - if(event==LEFTARROWKEY) {dvec[0]-= 1.0; firsttime= 1;} - else if(event==RIGHTARROWKEY) {dvec[0]+= 1.0; firsttime= 1;} - else if(event==UPARROWKEY) {dvec[1]+= 1.0; firsttime= 1;} - else if(event==DOWNARROWKEY) {dvec[1]-= 1.0; firsttime= 1;} - } - else arrows_move_cursor(event); - } - else arrows_move_cursor(event); - } - } - if(afbreek) break; - } - } - - if(event==ESCKEY || event==RIGHTMOUSE) { - tv= transmain; - for(a=0; aloc[0]= tv->oldloc[0]; - tv->loc[1]= tv->oldloc[1]; - } - - dosort= 0; - ei= G.sipo->editipo; - for(a=0; atotipo; a++, ei++) { - if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) { - if( (ei->flag & IPO_EDIT) || G.sipo->showkey) { - if( test_time_ipocurve(ei->icu)) { - dosort= 1; - break; - } - } - } - } - - if(dosort) remake_ipo_transverts(transmain, 0, tot); - - ei= G.sipo->editipo; - for(a=0; atotipo; a++, ei++) { - if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) { - if( (ei->flag & IPO_EDIT) || G.sipo->showkey) { - testhandles_ipocurve(ei->icu); - } - } - } - calc_ipo(G.sipo->ipo, (float)CFRA); - } - else BIF_undo_push("Transform Ipo"); - + /* cleanup */ editipo_changed(G.sipo, 1); - - MEM_freeN(transmain); } void filter_sampledata(float *data, int sfra, int efra) diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c index 00d987142fd..92468b40359 100644 --- a/source/blender/src/transform.c +++ b/source/blender/src/transform.c @@ -295,13 +295,17 @@ void projectIntView(TransInfo *t, float *vec, int *adr) project_int(vec, adr); else if(t->spacetype==SPACE_IMAGE) { float aspx, aspy, v[2]; - + transform_aspect_ratio_tface_uv(&aspx, &aspy); v[0]= vec[0]/aspx; v[1]= vec[1]/aspy; - + uvco_to_areaco_noclip(v, adr); } + else if(t->spacetype==SPACE_IPO) { + adr[0]= vec[0]; + adr[1]= vec[1]; + } } void projectFloatView(TransInfo *t, float *vec, float *adr) @@ -315,6 +319,10 @@ void projectFloatView(TransInfo *t, float *vec, float *adr) adr[0]= a[0]; adr[1]= a[1]; } + else if(t->spacetype==SPACE_IPO) { + adr[0]= vec[0]; + adr[1]= vec[1]; + } } void convertVecToDisplayNum(float *vec, float *num) @@ -1731,7 +1739,7 @@ int Resize(TransInfo *t, short mval[2]) ElementResize(t, td, mat); } - /* evil hack - redo resize if cliiping needeed */ + /* evil hack - redo resize if cliping needed */ if (t->flag & T_CLIP_UV && clipUVTransform(t, size, 1)) { SizeToMat3(size, mat); diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index d7bd3154ba1..414759c8505 100644 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -1881,7 +1881,7 @@ static void createTransUVs(TransInfo *t) t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(UV Editing)"); /* for each 2d uv coord a 3d vector is allocated, so that they can be treated just as if they were 3d verts */ - t->data2d= MEM_mallocN(t->total*sizeof(TransData2D), "TransObData2D(UV Editing)"); + t->data2d= MEM_callocN(t->total*sizeof(TransData2D), "TransObData2D(UV Editing)"); if(G.sima->flag & SI_CLIP_UV) t->flag |= T_CLIP_UV; @@ -1987,6 +1987,39 @@ int clipUVTransform(TransInfo *t, float *vec, int resize) return (clipx || clipy); } +/* ********************* IPO EDITOR ************************* */ + +/* for IPO Editor transform - but actual creation of transform structures is not performed here + * due to bad globals that would need to be imported specially for this + */ +static void createTransIpoData(TransInfo *t) +{ + /* in editipo.c due to some globals that are defined in that file... */ + make_ipo_transdata(t); +} + +/* this function is called on recalcData to apply the transforms applied + * to the transdata on to the actual keyframe data + */ +void flushTransIpoData(TransInfo *t) +{ + TransData2D *td; + int a; + + /* flush to 2d vector from internally used 3d vector */ + for (a=0, td= t->data2d; atotal; a++, td++) { + /* we need to unapply the nla-scaling from the time in some situations */ + if (NLA_IPO_SCALED) + td->loc2d[0]= get_action_frame(OBACT, td->loc[0]); + else + td->loc2d[0]= td->loc[0]; + + /* when the icu that point comes from is a bitflag holder, don't allow adjusting values */ + if ((t->data[a].flag & TD_TIMEONLY)==0) + td->loc2d[1]= td->loc[1]; + } +} + /* ********************* ACTION/NLA EDITOR ****************** */ @@ -2109,7 +2142,7 @@ static void createTransActionData(TransInfo *t) BLI_freelistN(&act_data); } -static void createTransNLAData(TransInfo *t) +static void createTransNlaData(TransInfo *t) { Base *base; bActionStrip *strip; @@ -2997,7 +3030,16 @@ void createTransData(TransInfo *t) } else if (t->spacetype == SPACE_NLA) { t->flag |= T_POINTS|T_2D_EDIT; - createTransNLAData(t); + createTransNlaData(t); + } + else if (t->spacetype == SPACE_IPO) { + t->flag |= T_POINTS|T_2D_EDIT; + createTransIpoData(t); + if (t->data && (t->flag & T_PROP_EDIT)) { + sort_trans_data(t); // makes selected become first in array + set_prop_dist(t, 1); + sort_trans_data_dist(t); + } } else if (G.obedit) { t->ext = NULL; diff --git a/source/blender/src/transform_generics.c b/source/blender/src/transform_generics.c index 562277ecff5..cb5b2d057c5 100644 --- a/source/blender/src/transform_generics.c +++ b/source/blender/src/transform_generics.c @@ -62,6 +62,9 @@ #include "BIF_meshtools.h" #include "BIF_retopo.h" +#include "BSE_editipo.h" +#include "BSE_editipo_types.h" + #ifdef WITH_VERSE #include "BIF_verse.h" #endif @@ -228,7 +231,7 @@ void recalcData(TransInfo *t) /* determine what type of data we are operating on */ data = get_action_context(&context); if (data == NULL) return; - + if (G.saction->lock) { if (context == ACTCONT_ACTION) { if(ob) { @@ -259,6 +262,66 @@ void recalcData(TransInfo *t) DAG_scene_flush_update(G.scene, screen_view3d_layers()); } } + else if (t->spacetype == SPACE_IPO) { + EditIpo *ei; + int dosort = 0; + int a; + + /* do the flush first */ + flushTransIpoData(t); + + /* now test if there is a need to re-sort */ + ei= G.sipo->editipo; + for (a=0; atotipo; a++, ei++) { + if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) { + + /* watch it: if the time is wrong: do not correct handles */ + if (test_time_ipocurve(ei->icu) ) dosort++; + else testhandles_ipocurve(ei->icu); + } + } + + /* do resort and other updates? */ + if (dosort) remake_ipo_transdata(t); + if (G.sipo->showkey) update_ipokey_val(); + + calc_ipo(G.sipo->ipo, (float)CFRA); + + /* update realtime - not working? */ + if (G.sipo->lock) { + if (G.sipo->blocktype==ID_MA || G.sipo->blocktype==ID_TE) { + do_ipo(G.sipo->ipo); + } + else if(G.sipo->blocktype==ID_CA) { + do_ipo(G.sipo->ipo); + } + else if(G.sipo->blocktype==ID_KE) { + Object *ob= OBACT; + if(ob) { + ob->shapeflag &= ~OB_SHAPE_TEMPLOCK; + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + } + } + else if(G.sipo->blocktype==ID_PO) { + Object *ob= OBACT; + if(ob && ob->pose) { + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + } + } + else if(G.sipo->blocktype==ID_OB) { + Base *base= FIRSTBASE; + + while(base) { + if(base->object->ipo==G.sipo->ipo) { + do_ob_ipo(base->object); + base->object->recalc |= OB_RECALC_OB; + } + base= base->next; + } + DAG_scene_flush_update(G.scene, screen_view3d_layers()); + } + } + } else if (G.obedit) { if (G.obedit->type == OB_MESH) { if(t->spacetype==SPACE_IMAGE) { From 4205924168e9cdea62997bda3a2f6d9502f807d4 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 1 Oct 2007 03:11:11 +0000 Subject: [PATCH 18/22] == IPO Editor Transform - Bugfix == This commit fixes one of the bugs mentioned yesterday. Now cancelling a transform will result in the right behaviour. --- source/blender/src/editipo.c | 152 +++++++++++++++++++++++++++++++++-- 1 file changed, 145 insertions(+), 7 deletions(-) diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c index a1439df8e7c..025dfcc7886 100644 --- a/source/blender/src/editipo.c +++ b/source/blender/src/editipo.c @@ -4933,31 +4933,167 @@ void make_ipo_transdata (TransInfo *t) } } +/* ------------------------ */ + +/* struct for use in re-sorting BezTriples during IPO transform */ +typedef struct BeztMap { + BezTriple *bezt; + int oldIndex; + int newIndex; + short handles; +} BeztMap; + +#define BEZM_FLIPH 1 +#define BEZM_CLEARH1 2 +#define BEZM_CLEARH2 4 + +/* This function converts an IpoCurve's BezTriple array to a BeztMap array + * NOTE: this allocates memory that will need to get freed later + */ +static BeztMap *bezt_to_beztmaps (BezTriple *bezts, int totvert) +{ + BezTriple *bezt= bezts; + BeztMap *bezm, *bezms; + int i; + + /* allocate memory for this array */ + if (totvert==0 || bezts==NULL) + return NULL; + bezm= bezms= MEM_callocN(sizeof(BeztMap)*totvert, "BeztMaps"); + + /* assign beztriples to beztmaps */ + for (i=0; i < totvert; i++, bezm++, bezt++) { + bezm->bezt= bezt; + bezm->oldIndex= i; + bezm->newIndex= i; + } + + return bezms; +} + +/* This function copies the code of sort_time_ipocurve, but acts on BeztMap structs instead */ +static void sort_time_beztmaps (BeztMap *bezms, int totvert) +{ + BeztMap *bezm; + int i, ok= 1; + + /* keep repeating the process until nothing is out of place anymore */ + while (ok) { + ok= 0; + + bezm= bezms; + i= totvert; + while (i--) { + /* is current bezm out of order (i.e. occurs later than next)? */ + if (i > 0) { + if ( bezm->bezt->vec[1][0] > (bezm+1)->bezt->vec[1][0]) { + bezm->newIndex++; + (bezm+1)->newIndex--; + + SWAP(BeztMap, *bezm, *(bezm+1)); + + ok= 1; + } + } + + /* swap order of handles or snap handles to centre-point? */ + if (bezm->bezt->vec[0][0]>bezm->bezt->vec[1][0] && bezm->bezt->vec[2][0]bezt->vec[1][0]) { + bezm->handles ^= BEZM_FLIPH; + } + else { + if (bezm->bezt->vec[0][0]>bezm->bezt->vec[1][0]) bezm->handles ^= BEZM_CLEARH1; + if (bezm->bezt->vec[2][0]bezt->vec[1][0]) bezm->handles ^= BEZM_CLEARH2; + } + + bezm++; + } + } +} + +/* This function firstly adjusts the pointers that the transdata has to each BezTriple*/ +static void beztmap_to_data (TransInfo *t, EditIpo *ei, BeztMap *bezms, int totvert) +{ + BezTriple *bezts = ei->icu->bezt; + BeztMap *bezm; + TransData2D *td; + int i, j; + + /* for each beztmap item, find if it is used anywhere */ + bezm= bezms; + for (i= 0; i < totvert; i++, bezm++) { + /* loop through transdata, testing if we have a hit */ + td= t->data2d; + for (j= 0; j < t->total; j++, td++) { + if (totipo_vertsel) { + /* only selected verts */ + if (ei->icu->ipo==IPO_BEZ) { + if (bezm->bezt->f1 & 1) { + if (td->loc2d == bezm->bezt->vec[0]) + td->loc2d= (bezts + bezm->newIndex)->vec[0]; + } + if (bezm->bezt->f3 & 1) { + if (td->loc2d == bezm->bezt->vec[2]) + td->loc2d= (bezts + bezm->newIndex)->vec[2]; + } + } + if (bezm->bezt->f2 & 1) { + if (td->loc2d == bezm->bezt->vec[1]) + td->loc2d= (bezts + bezm->newIndex)->vec[1]; + } + } + else { + /* whole curve */ + if (ei->icu->ipo==IPO_BEZ) { + if (td->loc2d == bezm->bezt->vec[0]) { + td->loc2d= (bezts + bezm->newIndex)->vec[0]; + } + + if (td->loc2d == bezm->bezt->vec[2]) { + td->loc2d= (bezts + bezm->newIndex)->vec[2]; + } + } + if (td->loc2d == bezm->bezt->vec[1]) { + td->loc2d= (bezts + bezm->newIndex)->vec[1]; + } + } + } + + } +} /* This function is called by recalcData during the Transform loop to recalculate * the handles of curves and sort the keyframes so that the curves draw correctly. * It is only called if some keyframes have moved out of order. */ -/* FIXME! There's a bug with this, which causes 'old-loc' values to get overridden. - ("mapping" hack is possible, but needs more debugging... in the meantime, this is used) */ void remake_ipo_transdata (TransInfo *t) { EditIpo *ei; int a; - /* bubble-sort the beztriples */ + /* sort and reassign verts */ ei= G.sipo->editipo; for (a=0; atotipo; a++, ei++) { if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) { if (ei->icu->bezt) { + BeztMap *bezm; + + /* adjust transform-data pointers */ + bezm= bezt_to_beztmaps(ei->icu->bezt, ei->icu->totvert); + sort_time_beztmaps(bezm, ei->icu->totvert); + beztmap_to_data(t, ei, bezm, ei->icu->totvert); + + /* re-sort actual beztriples (perhaps this could be done using the beztmaps to save time?) */ sort_time_ipocurve(ei->icu); + + /* free mapping stuff */ + MEM_freeN(bezm); + + /* make sure handles are all set correctly */ + testhandles_ipocurve(ei->icu); } } } - - /* remake transdata - bad! */ - make_ipo_transdata(t); - + /* remake ipokeys */ if (G.sipo->showkey) make_ipokey(); } @@ -5012,6 +5148,8 @@ void transform_ipo (int mode) editipo_changed(G.sipo, 1); } +/**************************************************/ + void filter_sampledata(float *data, int sfra, int efra) { float *da; From 2182f53a9a5e69c76d9efbbee46134935df242a6 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 1 Oct 2007 07:10:50 +0000 Subject: [PATCH 19/22] == IPO Editor Transform == * It is now possible to rotate the Bezier controls for the IPO Editor (RKEY) * IPO Record has now been remapped to Ctrl R. --- source/blender/src/header_ipo.c | 10 +++++++--- source/blender/src/space.c | 4 +++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/source/blender/src/header_ipo.c b/source/blender/src/header_ipo.c index 44812b074b3..16420f1536b 100644 --- a/source/blender/src/header_ipo.c +++ b/source/blender/src/header_ipo.c @@ -262,7 +262,10 @@ static void do_ipo_editmenu_transformmenu(void *arg, int event) case 0: /* grab/move */ transform_ipo('g'); break; - case 1: /* scale */ + case 1: /* rotate */ + transform_ipo('r'); + break; + case 2: /* scale */ transform_ipo('s'); break; } @@ -277,7 +280,8 @@ static uiBlock *ipo_editmenu_transformmenu(void *arg_unused) uiBlockSetButmFunc(block, do_ipo_editmenu_transformmenu, NULL); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Move|G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Scale|S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Rotate|R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Scale|S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, ""); uiBlockSetDirection(block, UI_RIGHT); uiTextBoundsBlock(block, 60); @@ -639,7 +643,7 @@ static uiBlock *ipo_editmenu(void *arg_unused) uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Duplicate|Shift D", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Record Mouse Movement|R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Record Mouse Movement|Ctrl R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Clean IPO Curves|O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Smooth IPO Curves|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete|X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, ""); diff --git a/source/blender/src/space.c b/source/blender/src/space.c index a7448f53574..23bcea7470d 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -2876,8 +2876,10 @@ static void winqreadipospace(ScrArea *sa, void *spacedata, BWinEvent *evt) allqueue(REDRAWIPO, 0); break; case RKEY: - if (G.qual==0) + if (G.qual==LR_CTRLKEY) ipo_record(); + else + transform_ipo('r'); break; case SKEY: if (G.qual==LR_SHIFTKEY) { From 5b1d6690068876843c5bec284056b17db3af9f0b Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Mon, 1 Oct 2007 08:03:11 +0000 Subject: [PATCH 20/22] == Sequencer == This patch adds prefetch buffering to the sequencer (see the tracker for additional details: https://projects.blender.org/tracker/?func=detail&aid=7307&group_id=9&atid=127 ) We create seperate render threads (currently one, because of the fact, that sequence rendering modifies global structures...), that render up to the defined userpref value "Prefetch frames" in advance. (Pressing Alt-A will _first_ fill the buffer and then start playing.) Bassam and I did some extensive testing, so it should work. If you don't configure your number of prefetch frames, prefetching is disabled! (Sane defaults... :) Also: if the machine is definitely too slow and runs out of the prefetch area, prefetching is disabled automatically and we are back to good old frame skipping mode. My Dual Athlon is able to handle 4 parallel DV streams at once (sometimes a little bit choppy, but prefetching is never disabled!) I fixed also a long standing bug in the audio code, that made playback run backwards at the beginning... --- source/blender/include/BIF_drawseq.h | 1 + source/blender/include/BIF_space.h | 1 + source/blender/include/BIF_spacetypes.h | 3 +- source/blender/include/BSE_sequence.h | 9 + source/blender/makesdna/DNA_userdef_types.h | 2 +- source/blender/src/drawseq.c | 21 +- source/blender/src/drawview.c | 186 +++++++++-- source/blender/src/editscreen.c | 4 +- source/blender/src/header_seq.c | 20 +- source/blender/src/seqaudio.c | 13 +- source/blender/src/sequence.c | 325 +++++++++++++++++++- source/blender/src/space.c | 45 +-- source/blender/src/spacetypes.c | 15 +- 13 files changed, 578 insertions(+), 67 deletions(-) diff --git a/source/blender/include/BIF_drawseq.h b/source/blender/include/BIF_drawseq.h index 986044d9c7e..4571267a09c 100644 --- a/source/blender/include/BIF_drawseq.h +++ b/source/blender/include/BIF_drawseq.h @@ -36,6 +36,7 @@ struct ScrArea; struct Sequence; +void drawprefetchseqspace(struct ScrArea *sa, void *spacedata); void drawseqspace(struct ScrArea *sa, void *spacedata); void set_special_seq_update(int val); diff --git a/source/blender/include/BIF_space.h b/source/blender/include/BIF_space.h index 7c88610cf3a..855773b3497 100644 --- a/source/blender/include/BIF_space.h +++ b/source/blender/include/BIF_space.h @@ -94,6 +94,7 @@ struct SpaceOops; #define B_RECALCLIGHT 3310 +void scrarea_do_winprefetchdraw (struct ScrArea *sa); void scrarea_do_windraw (struct ScrArea *sa); void scrarea_do_winchange (struct ScrArea *sa); void scrarea_do_winhandle (struct ScrArea *sa, struct BWinEvent *evt); diff --git a/source/blender/include/BIF_spacetypes.h b/source/blender/include/BIF_spacetypes.h index e825acf676f..6125cfd5926 100644 --- a/source/blender/include/BIF_spacetypes.h +++ b/source/blender/include/BIF_spacetypes.h @@ -35,6 +35,7 @@ struct BWinEvent; typedef struct _SpaceType SpaceType; +typedef void (*SpacePrefetchDrawFP) (struct ScrArea *sa, void *spacedata); typedef void (*SpaceDrawFP) (struct ScrArea *sa, void *spacedata); typedef void (*SpaceChangeFP) (struct ScrArea *sa, void *spacedata); typedef void (*SpaceHandleFP) (struct ScrArea *sa, void *spacedata, struct BWinEvent *evt); @@ -43,7 +44,7 @@ typedef void (*SpaceHandleFP) (struct ScrArea *sa, void *spacedata, struct BWinE SpaceType* spacetype_new (char *name); -void spacetype_set_winfuncs (SpaceType *st, SpaceDrawFP draw, SpaceChangeFP change, SpaceHandleFP handle); +void spacetype_set_winfuncs (SpaceType *st, SpacePrefetchDrawFP prefetch, SpaceDrawFP draw, SpaceChangeFP change, SpaceHandleFP handle); /***/ diff --git a/source/blender/include/BSE_sequence.h b/source/blender/include/BSE_sequence.h index c975e8de8ff..47a09e154df 100644 --- a/source/blender/include/BSE_sequence.h +++ b/source/blender/include/BSE_sequence.h @@ -60,6 +60,15 @@ void set_meta_stripdata(struct Sequence *seqm); struct ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chansel); /* chansel: render this channel. Default=0 (renders end result)*/ +/* sequence prefetch API */ +void seq_start_threads(); +void seq_stop_threads(); +void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown); +void seq_wait_for_prefetch_ready(); +struct ImBuf * give_ibuf_threaded(int rectx, int recty, int cfra, + int chanshown); + + void free_imbuf_seq_except(int cfra); void free_imbuf_seq_with_ipo(struct Ipo * ipo); void free_imbuf_seq(void); diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 5860ca13a5d..7aa4dbdcf78 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -171,6 +171,7 @@ typedef struct UserDef { short tw_hotspot, tw_flag, tw_handlesize, tw_size; int textimeout, texcollectrate; int memcachelimit; + int prefetchframes; short frameserverport; short pad_rot_angle; /*control the rotation step of the view when PAD2,PAD4,PAD6&PAD8 is use*/ short obcenter_dia; @@ -181,7 +182,6 @@ typedef struct UserDef { short recent_files; /* maximum number of recently used files to remember */ short smooth_viewtx; /* miliseconds to spend spinning the view */ short glreslimit; - char pad[4]; } UserDef; extern UserDef U; /* from usiblender.c !!!! */ diff --git a/source/blender/src/drawseq.c b/source/blender/src/drawseq.c index aaef04283b0..86246759a3b 100644 --- a/source/blender/src/drawseq.c +++ b/source/blender/src/drawseq.c @@ -51,6 +51,7 @@ #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_view2d_types.h" +#include "DNA_userdef_types.h" #include "BKE_global.h" #include "BKE_plugin_types.h" @@ -788,7 +789,11 @@ static void draw_image_seq(ScrArea *sa) return; else { recursive= 1; - ibuf= (ImBuf *)give_ibuf_seq(rectx, recty, (G.scene->r.cfra), sseq->chanshown); + if (!U.prefetchframes || (G.f & G_PLAYANIM) == 0) { + ibuf= (ImBuf *)give_ibuf_seq(rectx, recty, (G.scene->r.cfra), sseq->chanshown); + } else { + ibuf= (ImBuf *)give_ibuf_threaded(rectx, recty, (G.scene->r.cfra), sseq->chanshown); + } recursive= 0; /* HURMF! the give_ibuf_seq can call image display in this window */ @@ -1276,6 +1281,20 @@ static void seq_blockhandlers(ScrArea *sa) } +void drawprefetchseqspace(ScrArea *sa, void *spacedata) +{ + SpaceSeq *sseq= sa->spacedata.first; + int rectx, recty; + + rectx= (G.scene->r.size*G.scene->r.xsch)/100; + recty= (G.scene->r.size*G.scene->r.ysch)/100; + + if(sseq->mainb) { + give_ibuf_prefetch_request( + rectx, recty, (G.scene->r.cfra), sseq->chanshown); + } +} + void drawseqspace(ScrArea *sa, void *spacedata) { SpaceSeq *sseq= sa->spacedata.first; diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index de4a81abb95..2bcc7ed76a7 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -136,6 +136,7 @@ #include "BSE_filesel.h" #include "BSE_headerbuttons.h" #include "BSE_seqaudio.h" +#include "BSE_sequence.h" #include "BSE_trans_types.h" #include "BSE_time.h" #include "BSE_view.h" @@ -3172,13 +3173,20 @@ void drawview3d_render(struct View3D *v3d, int winx, int winy) double tottime = 0.0; +static ScrArea *oldsa; +static double swaptime; +static int curmode; int update_time(void) { static double ltime; double time; - if ((U.mixbufsize)&&(audiostream_pos() != CFRA)&&(G.scene->audio.flag & AUDIO_SYNC)) return 0; + if ((U.mixbufsize) + && (audiostream_pos() != CFRA) + && (G.scene->audio.flag & AUDIO_SYNC)) { + return 0; + } time = PIL_check_seconds_timer(); @@ -3187,12 +3195,71 @@ int update_time(void) return (tottime < 0.0); } +static void inner_play_prefetch_frame(int mode, int cfra) +{ + ScrArea *sa; + int oldcfra = CFRA; + ScrArea *oldcurarea = curarea; + + if (!U.prefetchframes) { + return; + } + + CFRA = cfra; + + sa= G.curscreen->areabase.first; + while(sa) { + if(sa==oldsa) { + scrarea_do_winprefetchdraw(sa); + } + else if(mode & 1) { /* all view3d and seq spaces */ + if ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_SEQ) { + scrarea_do_winprefetchdraw(sa); + } + } + else if(mode & 4) { /* all seq spaces */ + if (sa->spacetype == SPACE_SEQ) { + scrarea_do_winprefetchdraw(sa); + } + } + + sa= sa->next; + } + + CFRA = oldcfra; + curarea = oldcurarea; +} + +static void inner_play_prefetch_startup(int mode) +{ + int i; + + if (!U.prefetchframes) { + return; + } + + seq_start_threads(); + + for (i = 0; i <= U.prefetchframes; i++) { + int cfra = CFRA + i; + inner_play_prefetch_frame(mode, cfra); + } + + seq_wait_for_prefetch_ready(); +} + +static void inner_play_prefetch_shutdown(int mode) +{ + if (!U.prefetchframes) { + return; + } + seq_stop_threads(); +} + void inner_play_anim_loop(int init, int mode) { ScrArea *sa; - static ScrArea *oldsa; - static double swaptime; - static int curmode; + static int last_cfra = -1; /* init */ if(init) { @@ -3200,47 +3267,97 @@ void inner_play_anim_loop(int init, int mode) swaptime= 1.0/(float)G.scene->r.frs_sec; tottime= 0.0; curmode= mode; + last_cfra = -1; return; } - set_timecursor(CFRA); + if (CFRA != last_cfra) { + int pf; + set_timecursor(CFRA); - update_for_newframe_nodraw(1); /* adds no events in UI */ + update_for_newframe_nodraw(1); /* adds no events in UI */ - sa= G.curscreen->areabase.first; - while(sa) { - if(sa==oldsa) { - scrarea_do_windraw(sa); - } - else if(curmode & 1) { /* all view3d and seq spaces */ - if ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_SEQ) { + sa= G.curscreen->areabase.first; + while(sa) { + if(sa==oldsa) { scrarea_do_windraw(sa); } - } - else if(curmode & 4) { /* all seq spaces */ - if (sa->spacetype == SPACE_SEQ) { - scrarea_do_windraw(sa); + else if(curmode & 1) { /* all view3d and seq spaces */ + if ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_SEQ) { + scrarea_do_windraw(sa); + } } - } + else if(curmode & 4) { /* all seq spaces */ + if (sa->spacetype == SPACE_SEQ) { + scrarea_do_windraw(sa); + } + } - sa= sa->next; + sa= sa->next; + } + + if (last_cfra == -1) { + last_cfra = CFRA - 1; + } + + if (U.prefetchframes) { + pf = last_cfra; + + if (CFRA - last_cfra >= U.prefetchframes || + CFRA - last_cfra < 0) { + pf = CFRA - U.prefetchframes; + fprintf(stderr, + "SEQ-THREAD: Lost sync, " + "stopping threads, " + "back to skip mode...\n"); + seq_stop_threads(); + } else { + while (pf < CFRA) { + int c; + pf++; + c = pf + U.prefetchframes; + if (c >= PEFRA) { + c -= PEFRA; + c += PSFRA; + } + + inner_play_prefetch_frame(curmode, c); + } + } + + } } - + + last_cfra = CFRA; + /* make sure that swaptime passed by */ tottime -= swaptime; - while (update_time()) PIL_sleep_ms(1); - - if(CFRA>=PEFRA) { - if (tottime > 0.0) tottime = 0.0; - CFRA= PSFRA; + while (update_time()) { + PIL_sleep_ms(1); + } + + if (CFRA >= PEFRA) { + if (tottime > 0.0) { + tottime = 0.0; + } + CFRA = PSFRA; audiostream_stop(); audiostream_start( CFRA ); + } else { + if (U.mixbufsize + && (G.scene->audio.flag & AUDIO_SYNC)) { + CFRA = audiostream_pos(); + } else { + CFRA++; + } + if (CFRA < last_cfra) { + fprintf(stderr, + "SEQ-THREAD: CFRA running backwards: %d\n", + CFRA); + } } - else { - if (U.mixbufsize && (G.scene->audio.flag & AUDIO_SYNC)) CFRA = audiostream_pos(); - else CFRA++; - } + } /* play_anim: 'mode' defines where to play and if repeat is on (now bitfield): @@ -3261,22 +3378,24 @@ int play_anim(int mode) if(PSFRA>PEFRA) return 0; - update_time(); - /* waitcursor(1); */ G.f |= G_PLAYANIM; /* in sequence.c and view.c this is handled */ cfraont= CFRA; oldsa= curarea; - audiostream_start( CFRA ); - if (curarea && curarea->spacetype == SPACE_SEQ) { SpaceSeq *sseq = curarea->spacedata.first; if (sseq->mainb == 0) mode |= 4; } + + inner_play_prefetch_startup(mode); + + update_time(); inner_play_anim_loop(1, mode); /* 1==init */ + + audiostream_start( CFRA ); /* forces all buffers to be OK for current frame (otherwise other windows get redrawn with CFRA+1) */ curarea->win_swap= WIN_BACK_OK; @@ -3317,6 +3436,7 @@ int play_anim(int mode) if(event==SPACEKEY); else CFRA= cfraont; + inner_play_prefetch_shutdown(mode); audiostream_stop(); if(oldsa!=curarea) areawinset(oldsa->win); diff --git a/source/blender/src/editscreen.c b/source/blender/src/editscreen.c index 9ae46998cbc..ff70ff74d70 100644 --- a/source/blender/src/editscreen.c +++ b/source/blender/src/editscreen.c @@ -1119,7 +1119,9 @@ static void animated_screen(bScreen *sc, short val) } if(val & TIME_ALL_ANIM_WIN) allqueue(REDRAWANIM, 0); if(val & TIME_ALL_BUTS_WIN) allqueue(REDRAWBUTSALL, 0); - if(val & TIME_SEQ) allqueue(REDRAWSEQ, 0); + if(val & TIME_SEQ) { + allqueue(REDRAWSEQ, 0); + } allqueue(REDRAWTIME, 0); } diff --git a/source/blender/src/header_seq.c b/source/blender/src/header_seq.c index ffa810f6eb8..da2581e36df 100644 --- a/source/blender/src/header_seq.c +++ b/source/blender/src/header_seq.c @@ -115,10 +115,22 @@ static uiBlock *seq_viewmenu(void *arg_unused) block= uiNewBlock(&curarea->uiblocks, "seq_viewmenu", UI_EMBOSSP, UI_HELV, curarea->headwin); uiBlockSetButmFunc(block, do_seq_viewmenu, NULL); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Back Animation|Alt A", 0, yco-=20, - menuwidth, 19, NULL, 0.0, 0.0, 1, 1, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Back Animation in 3D View|Alt Shift A", 0, yco-=20, - menuwidth, 19, NULL, 0.0, 0.0, 1, 2, ""); + if (sseq->mainb == 0) { + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, + "Play Back Animation " + "in all Sequence Areas|Alt A", 0, yco-=20, + menuwidth, 19, NULL, 0.0, 0.0, 1, 1, ""); + } else { + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, + "Play Back Animation " + "in this window|Alt A", 0, yco-=20, + menuwidth, 19, NULL, 0.0, 0.0, 1, 1, ""); + } + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, + "Play Back Animation in all " + "3D Views and Sequence Areas|Alt Shift A", + 0, yco-=20, + menuwidth, 19, NULL, 0.0, 0.0, 1, 2, ""); uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); diff --git a/source/blender/src/seqaudio.c b/source/blender/src/seqaudio.c index 4bac7fdb250..f050906efa5 100644 --- a/source/blender/src/seqaudio.c +++ b/source/blender/src/seqaudio.c @@ -95,6 +95,7 @@ static int audio_pos; static int audio_scrub=0; static int audio_playing=0; static int audio_initialised=0; +static int audio_startframe=0; ///// // /* local protos ------------------- */ @@ -506,8 +507,9 @@ void audiostream_play(Uint32 startframe, Uint32 duration, int mixdown) } } - audio_pos = ( ((int)( (((float)startframe) - /(float)G.scene->r.frs_sec) + audio_startframe = startframe; + audio_pos = ( ((int)( (( (double)startframe) + /(double)G.scene->r.frs_sec) *(G.scene->audio.mixrate)*4 )) & (~3) ); audio_scrub = duration; @@ -537,8 +539,11 @@ int audiostream_pos(void) { int pos; - pos = (int) ( ((float)(audio_pos-U.mixbufsize)/( G.scene->audio.mixrate*4 ))*(float)G.scene->r.frs_sec ); - if (pos<1) pos=1; + pos = (int) (((double)(audio_pos-U.mixbufsize) + / ( G.scene->audio.mixrate*4 )) + * (double)G.scene->r.frs_sec ); + + if (pos < audio_startframe) pos = audio_startframe; return ( pos ); } diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c index aad0ebf5c5f..333f3d24e6e 100644 --- a/source/blender/src/sequence.c +++ b/source/blender/src/sequence.c @@ -70,6 +70,7 @@ #include "RE_pipeline.h" // talks to entire render API #include "blendef.h" +#include int seqrectx, seqrecty; @@ -1179,6 +1180,325 @@ ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chanshown) } +/* threading api */ + +static ListBase running_threads; +static ListBase prefetch_wait; +static ListBase prefetch_done; + +static pthread_mutex_t queue_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t wakeup_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t wakeup_cond = PTHREAD_COND_INITIALIZER; + +static pthread_mutex_t prefetch_ready_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t prefetch_ready_cond = PTHREAD_COND_INITIALIZER; + +static pthread_mutex_t frame_done_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t frame_done_cond = PTHREAD_COND_INITIALIZER; + +static volatile int seq_thread_shutdown = FALSE; +static volatile int seq_last_given_monoton_cfra = 0; +static int monoton_cfra = 0; + +typedef struct PrefetchThread { + struct PrefetchThread *next, *prev; + struct PrefetchQueueElem *current; + pthread_t pthread; + int running; +} PrefetchThread; + +typedef struct PrefetchQueueElem { + struct PrefetchQueueElem *next, *prev; + + int rectx; + int recty; + int cfra; + int chanshown; + + int monoton_cfra; + + struct ImBuf * ibuf; +} PrefetchQueueElem; + + +static void * seq_prefetch_thread(void * This_) +{ + PrefetchThread * This = This_; + + while (!seq_thread_shutdown) { + PrefetchQueueElem * e; + int s_last; + + pthread_mutex_lock(&queue_lock); + e = prefetch_wait.first; + if (e) { + BLI_remlink(&prefetch_wait, e); + } + s_last = seq_last_given_monoton_cfra; + + This->current = e; + + pthread_mutex_unlock(&queue_lock); + + if (!e) { + pthread_mutex_lock(&prefetch_ready_lock); + + This->running = FALSE; + + pthread_cond_signal(&prefetch_ready_cond); + pthread_mutex_unlock(&prefetch_ready_lock); + + pthread_mutex_lock(&wakeup_lock); + if (!seq_thread_shutdown) { + pthread_cond_wait(&wakeup_cond, &wakeup_lock); + } + pthread_mutex_unlock(&wakeup_lock); + continue; + } + + This->running = TRUE; + + if (e->cfra >= s_last) { + e->ibuf = give_ibuf_seq(e->rectx, e->recty, e->cfra, + e->chanshown); + } + + if (e->ibuf) { + IMB_cache_limiter_ref(e->ibuf); + } + + pthread_mutex_lock(&queue_lock); + + BLI_addtail(&prefetch_done, e); + + for (e = prefetch_wait.first; e; e = e->next) { + if (s_last > e->monoton_cfra) { + BLI_remlink(&prefetch_wait, e); + MEM_freeN(e); + } + } + + for (e = prefetch_done.first; e; e = e->next) { + if (s_last > e->monoton_cfra) { + if (e->ibuf) { + IMB_cache_limiter_unref(e->ibuf); + } + BLI_remlink(&prefetch_done, e); + MEM_freeN(e); + } + } + + pthread_mutex_unlock(&queue_lock); + + pthread_mutex_lock(&frame_done_lock); + pthread_cond_signal(&frame_done_cond); + pthread_mutex_unlock(&frame_done_lock); + } + return 0; +} + +void seq_start_threads() +{ + int i; + + running_threads.first = running_threads.last = NULL; + prefetch_wait.first = prefetch_wait.last = NULL; + prefetch_done.first = prefetch_done.last = NULL; + + seq_thread_shutdown = FALSE; + seq_last_given_monoton_cfra = monoton_cfra = 0; + + /* since global structures are modified during the processing + of one frame, only one render thread is currently possible... + + (but we code, in the hope, that we can remove this restriction + soon...) + */ + + fprintf(stderr, "SEQ-THREAD: seq_start_threads\n"); + + for (i = 0; i < 1; i++) { + PrefetchThread *t = MEM_callocN(sizeof(PrefetchThread), + "prefetch_thread"); + t->running = TRUE; + BLI_addtail(&running_threads, t); + + pthread_create(&t->pthread, NULL, seq_prefetch_thread, t); + } +} + +void seq_stop_threads() +{ + PrefetchThread *tslot; + PrefetchQueueElem * e; + + fprintf(stderr, "SEQ-THREAD: seq_stop_threads()\n"); + + if (seq_thread_shutdown) { + fprintf(stderr, "SEQ-THREAD: ... already stopped\n"); + return; + } + + pthread_mutex_lock(&wakeup_lock); + + seq_thread_shutdown = TRUE; + + pthread_cond_broadcast(&wakeup_cond); + pthread_mutex_unlock(&wakeup_lock); + + for(tslot = running_threads.first; tslot; tslot= tslot->next) { + pthread_join(tslot->pthread, NULL); + } + + + for (e = prefetch_wait.first; e; e = e->next) { + BLI_remlink(&prefetch_wait, e); + MEM_freeN(e); + } + + for (e = prefetch_done.first; e; e = e->next) { + if (e->ibuf) { + IMB_cache_limiter_unref(e->ibuf); + } + BLI_remlink(&prefetch_done, e); + MEM_freeN(e); + } + + BLI_freelistN(&running_threads); +} + +void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown) +{ + PrefetchQueueElem * e; + if (seq_thread_shutdown) { + return; + } + + e = MEM_callocN(sizeof(PrefetchQueueElem), "prefetch_queue_elem"); + e->rectx = rectx; + e->recty = recty; + e->cfra = cfra; + e->chanshown = chanshown; + e->monoton_cfra = monoton_cfra++; + + pthread_mutex_lock(&queue_lock); + BLI_addtail(&prefetch_wait, e); + pthread_mutex_unlock(&queue_lock); + + pthread_mutex_lock(&wakeup_lock); + pthread_cond_signal(&wakeup_cond); + pthread_mutex_unlock(&wakeup_lock); +} + +void seq_wait_for_prefetch_ready() +{ + if (seq_thread_shutdown) { + return; + } + + fprintf(stderr, "SEQ-THREAD: rendering prefetch frames...\n"); + + PrefetchThread *tslot; + + pthread_mutex_lock(&prefetch_ready_lock); + + for(;;) { + for(tslot = running_threads.first; tslot; tslot= tslot->next) { + if (tslot->running) { + break; + } + } + if (!tslot) { + break; + } + pthread_cond_wait(&prefetch_ready_cond, &prefetch_ready_lock); + } + + pthread_mutex_unlock(&prefetch_ready_lock); + + fprintf(stderr, "SEQ-THREAD: prefetch done\n"); +} + +ImBuf * give_ibuf_threaded(int rectx, int recty, int cfra, int chanshown) +{ + PrefetchQueueElem * e = 0; + int found_something = FALSE; + + if (seq_thread_shutdown) { + return give_ibuf_seq(rectx, recty, cfra, chanshown); + } + + while (!e) { + int success = FALSE; + pthread_mutex_lock(&queue_lock); + + for (e = prefetch_done.first; e; e = e->next) { + if (cfra == e->cfra && + chanshown == e->chanshown && + rectx == e->rectx && + recty == e->recty) { + success = TRUE; + found_something = TRUE; + break; + } + } + + if (!e) { + for (e = prefetch_wait.first; e; e = e->next) { + if (cfra == e->cfra && + chanshown == e->chanshown && + rectx == e->rectx && + recty == e->recty) { + found_something = TRUE; + break; + } + } + } + + if (!e) { + PrefetchThread *tslot; + + for(tslot = running_threads.first; + tslot; tslot= tslot->next) { + if (tslot->current && + cfra == tslot->current->cfra && + chanshown == tslot->current->chanshown && + rectx == tslot->current->rectx && + recty == tslot->current->recty) { + found_something = TRUE; + break; + } + } + } + + /* e->ibuf is unrefed by render thread on next round. */ + + if (e) { + seq_last_given_monoton_cfra = e->monoton_cfra; + } + + pthread_mutex_unlock(&queue_lock); + + if (!success) { + e = NULL; + + if (!found_something) { + fprintf(stderr, + "SEQ-THREAD: Requested frame " + "not in queue ???\n"); + break; + } + pthread_mutex_lock(&frame_done_lock); + pthread_cond_wait(&frame_done_cond, &frame_done_lock); + pthread_mutex_unlock(&frame_done_lock); + } + } + + return e ? e->ibuf : 0; +} + + + /* Functions to free imbuf and anim data on changes */ static void free_imbuf_strip_elem(StripElem *se) @@ -1371,11 +1691,12 @@ void do_render_seq(RenderResult *rr, int cfra) */ { extern int mem_in_use; + extern int mmap_in_use; int max = MEM_CacheLimiter_get_maximum(); - if (max != 0 && mem_in_use > max) { + if (max != 0 && mem_in_use + mmap_in_use > max) { fprintf(stderr, "mem_in_use = %d, max = %d\n", - mem_in_use, max); + mem_in_use + mmap_in_use, max); fprintf(stderr, "Cleaning up, please wait...\n" "If this happens very often,\n" "consider " diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 23bcea7470d..5eceb5ee433 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -3160,8 +3160,8 @@ void drawinfospace(ScrArea *sa, void *spacedata) uiBlock *block; static short cur_light=0; float fac, col[3]; - short xpos, ypos, ypostab, buth, rspace, dx, y1, y2, y3, y4, y5, y6; - short y2label, y3label, y4label, y5label, y6label; + short xpos, ypos, ypostab, buth, rspace, dx, y1, y2, y3, y4, y5, y6, y7; + short y2label, y3label, y4label, y5label, y6label, y7label; short spref, mpref, lpref, smfileselbut; short edgsp, midsp; char naam[32]; @@ -3212,6 +3212,7 @@ void drawinfospace(ScrArea *sa, void *spacedata) y4 = ypos+3*(buth+rspace); y5 = ypos+4*(buth+rspace); y6 = ypos+5*(buth+rspace); + y7 = ypos+6*(buth+rspace); y2label = y2-2; /* adjustments to offset the labels down to align better */ @@ -3219,6 +3220,7 @@ void drawinfospace(ScrArea *sa, void *spacedata) y4label = y4-2; y5label = y5-2; y6label = y6-2; + y7label = y7-2; /* set the color to blue and draw the main 'tab' controls */ @@ -3810,8 +3812,13 @@ void drawinfospace(ScrArea *sa, void *spacedata) uiDefBut(block, LABEL,0,"System:", - (xpos+edgsp+(4*midsp)+(4*mpref)),y6label,mpref,buth, + (xpos+edgsp+(4*midsp)+(4*mpref)),y7label,mpref,buth, 0, 0, 0, 0, 0, ""); + uiDefButI(block, NUM, B_REDR, "Prefetch frames ", + (xpos+edgsp+(4*mpref)+(4*midsp)), y6, mpref, buth, + &U.prefetchframes, 0.0, 50.0, 20, 2, + "Number of frames to render ahead during playback."); + uiDefButI(block, NUM, B_MEMCACHELIMIT, "MEM Cache Limit ", (xpos+edgsp+(4*mpref)+(4*midsp)), y5, mpref, buth, &U.memcachelimit, 0.0, 1024.0, 30, 2, @@ -6274,7 +6281,7 @@ SpaceType *spaceaction_get_type(void) if (!st) { st= spacetype_new("Action"); - spacetype_set_winfuncs(st, drawactionspace, changeactionspace, winqreadactionspace); + spacetype_set_winfuncs(st, NULL, drawactionspace, changeactionspace, winqreadactionspace); } return st; @@ -6285,7 +6292,7 @@ SpaceType *spacebuts_get_type(void) if (!st) { st= spacetype_new("Buts"); - spacetype_set_winfuncs(st, drawbutspace, changebutspace, winqreadbutspace); + spacetype_set_winfuncs(st, NULL, drawbutspace, changebutspace, winqreadbutspace); } return st; @@ -6296,7 +6303,7 @@ SpaceType *spacefile_get_type(void) if (!st) { st= spacetype_new("File"); - spacetype_set_winfuncs(st, drawfilespace, NULL, winqreadfilespace); + spacetype_set_winfuncs(st, NULL, drawfilespace, NULL, winqreadfilespace); } return st; @@ -6307,7 +6314,7 @@ SpaceType *spaceimage_get_type(void) if (!st) { st= spacetype_new("Image"); - spacetype_set_winfuncs(st, drawimagespace, changeimagepace, winqreadimagespace); + spacetype_set_winfuncs(st, NULL, drawimagespace, changeimagepace, winqreadimagespace); } return st; @@ -6318,7 +6325,7 @@ SpaceType *spaceimasel_get_type(void) if (!st) { st= spacetype_new("Imasel"); - spacetype_set_winfuncs(st, drawimaselspace, changeimaselspace, winqreadimaselspace); + spacetype_set_winfuncs(st, NULL, drawimaselspace, changeimaselspace, winqreadimaselspace); } return st; @@ -6329,7 +6336,7 @@ SpaceType *spaceinfo_get_type(void) if (!st) { st= spacetype_new("Info"); - spacetype_set_winfuncs(st, drawinfospace, NULL, winqreadinfospace); + spacetype_set_winfuncs(st, NULL, drawinfospace, NULL, winqreadinfospace); } return st; @@ -6340,7 +6347,7 @@ SpaceType *spaceipo_get_type(void) if (!st) { st= spacetype_new("Ipo"); - spacetype_set_winfuncs(st, drawipospace, changeview2dspace, winqreadipospace); + spacetype_set_winfuncs(st, NULL, drawipospace, changeview2dspace, winqreadipospace); } return st; @@ -6351,7 +6358,7 @@ SpaceType *spacenla_get_type(void) if (!st) { st= spacetype_new("Nla"); - spacetype_set_winfuncs(st, drawnlaspace, changeview2dspace, winqreadnlaspace); + spacetype_set_winfuncs(st, NULL, drawnlaspace, changeview2dspace, winqreadnlaspace); } return st; @@ -6362,7 +6369,7 @@ SpaceType *spaceoops_get_type(void) if (!st) { st= spacetype_new("Oops"); - spacetype_set_winfuncs(st, drawoopsspace, changeview2dspace, winqreadoopsspace); + spacetype_set_winfuncs(st, NULL, drawoopsspace, changeview2dspace, winqreadoopsspace); } return st; @@ -6373,7 +6380,7 @@ SpaceType *spaceseq_get_type(void) if (!st) { st= spacetype_new("Sequence"); - spacetype_set_winfuncs(st, drawseqspace, changeview2dspace, winqreadseqspace); + spacetype_set_winfuncs(st, drawprefetchseqspace, drawseqspace, changeview2dspace, winqreadseqspace); } return st; @@ -6384,7 +6391,7 @@ SpaceType *spacesound_get_type(void) if (!st) { st= spacetype_new("Sound"); - spacetype_set_winfuncs(st, drawsoundspace, changeview2dspace, winqreadsoundspace); + spacetype_set_winfuncs(st, NULL, drawsoundspace, changeview2dspace, winqreadsoundspace); } return st; @@ -6395,7 +6402,7 @@ SpaceType *spacetext_get_type(void) if (!st) { st= spacetype_new("Text"); - spacetype_set_winfuncs(st, drawtextspace, NULL, winqreadtextspace); + spacetype_set_winfuncs(st, NULL, drawtextspace, NULL, winqreadtextspace); } return st; @@ -6419,7 +6426,7 @@ SpaceType *spacescript_get_type(void) if (!st) { st = spacetype_new("Script"); - spacetype_set_winfuncs(st, drawscriptspace, spacescript_change, winqreadscriptspace); + spacetype_set_winfuncs(st, NULL, drawscriptspace, spacescript_change, winqreadscriptspace); } return st; @@ -6430,7 +6437,7 @@ SpaceType *spaceview3d_get_type(void) if (!st) { st= spacetype_new("View3D"); - spacetype_set_winfuncs(st, drawview3dspace, changeview3dspace, winqreadview3dspace); + spacetype_set_winfuncs(st, NULL, drawview3dspace, changeview3dspace, winqreadview3dspace); } return st; @@ -6441,7 +6448,7 @@ SpaceType *spacetime_get_type(void) if (!st) { st= spacetype_new("Time"); - spacetype_set_winfuncs(st, drawtimespace, NULL, winqreadtimespace); + spacetype_set_winfuncs(st, NULL, drawtimespace, NULL, winqreadtimespace); } return st; @@ -6453,7 +6460,7 @@ SpaceType *spacenode_get_type(void) if (!st) { st= spacetype_new("Node"); - spacetype_set_winfuncs(st, drawnodespace, changeview2dspace, winqreadnodespace); + spacetype_set_winfuncs(st, NULL, drawnodespace, changeview2dspace, winqreadnodespace); } return st; diff --git a/source/blender/src/spacetypes.c b/source/blender/src/spacetypes.c index ea0d680e852..4a0375f2366 100644 --- a/source/blender/src/spacetypes.c +++ b/source/blender/src/spacetypes.c @@ -52,6 +52,7 @@ struct _SpaceType { char name[32]; + SpacePrefetchDrawFP winprefetchdraw; SpaceDrawFP windraw; SpaceChangeFP winchange; SpaceHandleFP winhandle; @@ -70,8 +71,9 @@ SpaceType *spacetype_new(char *name) return st; } -void spacetype_set_winfuncs(SpaceType *st, SpaceDrawFP draw, SpaceChangeFP change, SpaceHandleFP handle) +void spacetype_set_winfuncs(SpaceType *st, SpacePrefetchDrawFP prefetchdraw, SpaceDrawFP draw, SpaceChangeFP change, SpaceHandleFP handle) { + st->winprefetchdraw = prefetchdraw; st->windraw= draw; st->winchange= change; st->winhandle= handle; @@ -105,6 +107,17 @@ static SpaceType *spacetype_from_area(ScrArea *area) } } +void scrarea_do_winprefetchdraw(ScrArea *area) +{ + SpaceType *st= spacetype_from_area(area); + + areawinset(area->win); + + if(area->win && st->winprefetchdraw) { + st->winprefetchdraw(area, area->spacedata.first); + } +} + void scrarea_do_windraw(ScrArea *area) { SpaceType *st= spacetype_from_area(area); From 387d05aaefd526d4aeab1d8e8bdd29aace88be30 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 1 Oct 2007 08:10:08 +0000 Subject: [PATCH 21/22] IPO Editor Transform - More bugfixes: * Rotation/Scaling now use the correct center-point. The helpline is now drawn correctly too for this * For Rotation in UV/IPO editors, constraints are now disabled as they didn't make sense --- source/blender/src/transform.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c index 92468b40359..b58d5d05735 100644 --- a/source/blender/src/transform.c +++ b/source/blender/src/transform.c @@ -303,8 +303,11 @@ void projectIntView(TransInfo *t, float *vec, int *adr) uvco_to_areaco_noclip(v, adr); } else if(t->spacetype==SPACE_IPO) { - adr[0]= vec[0]; - adr[1]= vec[1]; + short out[2] = {0.0f, 0.0f}; + + ipoco_to_areaco(G.v2d, vec, out); + adr[0]= out[0]; + adr[1]= out[1]; } } @@ -314,14 +317,17 @@ void projectFloatView(TransInfo *t, float *vec, float *adr) project_float(vec, adr); else if(t->spacetype==SPACE_IMAGE) { int a[2]; - + projectIntView(t, vec, a); adr[0]= a[0]; adr[1]= a[1]; } else if(t->spacetype==SPACE_IPO) { - adr[0]= vec[0]; - adr[1]= vec[1]; + int a[2]; + + projectIntView(t, vec, a); + adr[0]= a[0]; + adr[1]= a[1]; } } @@ -1861,6 +1867,9 @@ void initRotation(TransInfo *t) t->snap[1] = (float)((5.0/180)*M_PI); t->snap[2] = t->snap[1] * 0.2f; t->fac = 0; + + if (t->flag & T_2D_EDIT) + t->flag |= T_NO_CONSTRAINT; } static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) { From dff627671111c9645deb5a8795ca3da4af8544a7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 1 Oct 2007 09:51:45 +0000 Subject: [PATCH 22/22] made changing mesh vert/edge/face modes redraw the image view since, draw verts and faces in UV mode when face select is enabled but syncing with the mesh selection is not. --- source/blender/src/drawimage.c | 7 ++++--- source/blender/src/header_view3d.c | 3 +++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/source/blender/src/drawimage.c b/source/blender/src/drawimage.c index ab675e5dce2..27862091a45 100644 --- a/source/blender/src/drawimage.c +++ b/source/blender/src/drawimage.c @@ -451,7 +451,7 @@ static int draw_uvs_face_check(void) if (G.sima==NULL) return 0; if (G.sima->flag & SI_SYNC_UVSEL && G.scene->selectmode == SCE_SELECT_FACE) - return 1; + return 2; if (G.sima->flag & SI_SELACTFACE) return 1; return 0; @@ -753,8 +753,9 @@ void draw_uvs_sima(void) } } bglEnd(); - } else { - + } + + if (drawface != 2) { /* 2 means Mesh Face Mode */ /* unselected uv's */ BIF_ThemeColor(TH_VERTEX); pointsize = BIF_GetThemeValuef(TH_VERTEX_SIZE); diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c index bd708e0aac2..add58a2a2ef 100644 --- a/source/blender/src/header_view3d.c +++ b/source/blender/src/header_view3d.c @@ -4715,6 +4715,7 @@ void do_view3d_buttons(short event) countall(); BIF_undo_push("Selectmode Set: Vertex"); allqueue(REDRAWVIEW3D, 1); + allqueue(REDRAWIMAGE, 0); /* only needed in cases where mesh and UV selection are in sync */ break; case B_SEL_EDGE: if( (G.qual & LR_SHIFTKEY)==0 || G.scene->selectmode==0){ @@ -4727,6 +4728,7 @@ void do_view3d_buttons(short event) countall(); BIF_undo_push("Selectmode Set: Edge"); allqueue(REDRAWVIEW3D, 1); + allqueue(REDRAWIMAGE, 0); /* only needed in cases where mesh and UV selection are in sync */ break; case B_SEL_FACE: if( (G.qual & LR_SHIFTKEY)==0 || G.scene->selectmode==0){ @@ -4739,6 +4741,7 @@ void do_view3d_buttons(short event) countall(); BIF_undo_push("Selectmode Set: Face"); allqueue(REDRAWVIEW3D, 1); + allqueue(REDRAWIMAGE, 0); /* only needed in cases where mesh and UV selection are in sync */ break; case B_MAN_TRANS: