From 9c33c9522f8ba632e1eddf8c4a3ab8366d4b0722 Mon Sep 17 00:00:00 2001 From: Kent Mein Date: Mon, 5 Nov 2007 16:46:48 +0000 Subject: [PATCH 1/9] Tweak for MSVC2005 people: http://www.blender.org/forum/viewtopic.php?t=12408 Kent --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f513b8028f..0227c51f39d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -240,7 +240,11 @@ IF(WIN32) SET(OPENEXR ${LIBDIR}/openexr) SET(OPENEXR_INC ${OPENEXR}/include ${OPENEXR}/include/IlmImf ${OPENEXR}/include/Iex ${OPENEXR}/include/Imath) SET(OPENEXR_LIB Iex Half IlmImf Imath IlmThread) + IF (MSVC80) + SET(OPENEXR_LIBPATH ${OPENEXR}/lib_vs2005) + ELSE (MSVC80) SET(OPENEXR_LIBPATH ${OPENEXR}/lib_msvc) + ENDIF(MSVC80) SET(QUICKTIME ${LIBDIR}/QTDevWin) SET(QUICKTIME_INC ${QUICKTIME}/CIncludes) From 86278584f3fb28941705eff2f6a885e6ef06357c Mon Sep 17 00:00:00 2001 From: Kent Mein Date: Mon, 5 Nov 2007 17:27:11 +0000 Subject: [PATCH 2/9] Tweaks I needed to get blender compiling on my new macbook running leopard. Kent --- extern/bFTGL/src/FTVectoriser.cpp | 8 ++++++-- .../RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/extern/bFTGL/src/FTVectoriser.cpp b/extern/bFTGL/src/FTVectoriser.cpp index bb133d025b4..82dcb0c0f51 100644 --- a/extern/bFTGL/src/FTVectoriser.cpp +++ b/extern/bFTGL/src/FTVectoriser.cpp @@ -5,8 +5,12 @@ #define CALLBACK #endif -#ifdef __APPLE_CC__ - typedef GLvoid (*GLUTesselatorFunction)(...); +#if defined(__APPLE_CC__) + #if __APPLE_CC__ >= 5465 + typedef GLvoid (*GLUTesselatorFunction)(); + #else + typedef GLvoid (*GLUTesselatorFunction)(...); + #endif #elif defined( __mips ) || defined( __linux__ ) || defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __sun ) || defined (__CYGWIN__) typedef GLvoid (*GLUTesselatorFunction)(); #elif defined ( WIN32) diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp index c8ed2dd6960..26b00f02e7d 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp @@ -108,7 +108,7 @@ static OSStatus bglInitEntryPoints (void) // Frameworks directory/folder err = FindFolder (kSystemDomain, kFrameworksFolderType, false, - &fileRefParam.ioVRefNum, &fileRefParam.ioDirID); + &fileRefParam.ioVRefNum, (SInt32*)&fileRefParam.ioDirID); if (noErr != err) { DebugStr ((unsigned char *)"\pCould not find frameworks folder"); return err; From 7d70dd98d625e4f08a750877e4242032bac38305 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 5 Nov 2007 17:38:07 +0000 Subject: [PATCH 3/9] Bugfix: Dual quaternions + armature modifier vgroup didn't work together correct. --- source/blender/blenkernel/intern/armature.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index d5eb43fa12e..e362bdbd2dd 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -849,7 +849,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, for(i = 0; i < numVerts; i++) { MDeformVert *dvert; DualQuat sumdq, *dq = NULL; - float *co = vertexCos[i]; + float *co = vertexCos[i], dco[3]; float sumvec[3], summat[3][3]; float *vec = NULL, (*smat)[3] = NULL; float contrib = 0.0f; @@ -938,7 +938,17 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, if(contrib > 0.0001f) { if(use_quaternion) { DQuatNormalize(dq, contrib, armature_weight); - DQuatMulVecfl(dq, co, (defMats)? summat: NULL); + + if(armature_weight != 1.0f) { + VECCOPY(dco, co); + DQuatMulVecfl(dq, dco, (defMats)? summat: NULL); + VecSubf(dco, dco, co); + VecMulf(dco, armature_weight); + VecAddf(co, co, dco); + } + else + DQuatMulVecfl(dq, co, (defMats)? summat: NULL); + smat = summat; } else { From 63c5dbe745c951472cc196b4d7a5e10ad1f84670 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 5 Nov 2007 18:44:42 +0000 Subject: [PATCH 4/9] Bugfix: B-bones didn't work well with non-uniform scaling applied to them. The code to solve this is not too pretty, but don't know how to do it simpler, and at least it makes that stretchy spine work. --- source/blender/blenkernel/intern/armature.c | 42 ++++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index e362bdbd2dd..40f4ae7298e 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -411,12 +411,31 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest) Mat4 *result_array= (rest)? bbone_rest_array: bbone_array; bPoseChannel *next, *prev; Bone *bone= pchan->bone; - float h1[3], h2[3], length, hlength1, hlength2, roll1=0.0f, roll2; - float mat3[3][3], imat[4][4]; + float h1[3], h2[3], scale[3], length, hlength1, hlength2, roll1=0.0f, roll2; + float mat3[3][3], imat[4][4], posemat[4][4], scalemat[4][4], iscalemat[4][4]; float data[MAX_BBONE_SUBDIV+1][4], *fp; - int a; - + int a, doscale= 0; + length= bone->length; + + if(!rest) { + /* check if we need to take non-uniform bone scaling into account */ + scale[0]= VecLength(pchan->pose_mat[0]); + scale[1]= VecLength(pchan->pose_mat[1]); + scale[2]= VecLength(pchan->pose_mat[2]); + + if(fabs(scale[0] - scale[1]) > 1e-6f || fabs(scale[1] - scale[2]) > 1e-6f) { + Mat4One(scalemat); + scalemat[0][0]= scale[0]; + scalemat[1][1]= scale[1]; + scalemat[2][2]= scale[2]; + Mat4Invert(iscalemat, scalemat); + + length *= scale[1]; + doscale = 1; + } + } + hlength1= bone->ease1*length*0.390464f; // 0.5*sqrt(2)*kappa, the handle length for near-perfect circles hlength2= bone->ease2*length*0.390464f; @@ -432,8 +451,14 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest) first point = (0,0,0) last point = (0, length, 0) */ - if(rest) + if(rest) { Mat4Invert(imat, pchan->bone->arm_mat); + } + else if(doscale) { + Mat4CpyMat4(posemat, pchan->pose_mat); + Mat4Ortho(posemat); + Mat4Invert(imat, posemat); + } else Mat4Invert(imat, pchan->pose_mat); @@ -527,8 +552,15 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest) for(a=0, fp= data[0]; asegments; a++, fp+=4) { VecSubf(h1, fp+4, fp); vec_roll_to_mat3(h1, fp[3], mat3); // fp[3] is roll + Mat4CpyMat3(result_array[a].mat, mat3); VECCOPY(result_array[a].mat[3], fp); + + if(doscale) { + /* correct for scaling when this matrix is used in scaled space */ + Mat4MulSerie(result_array[a].mat, iscalemat, result_array[a].mat, + scalemat, NULL, NULL, NULL, NULL, NULL); + } } return result_array; From 8d10ab61c612f16f96d551d46811244ae72a1ae4 Mon Sep 17 00:00:00 2001 From: Andrea Weikert Date: Mon, 5 Nov 2007 20:16:23 +0000 Subject: [PATCH 5/9] == MSVC 7.1 projectfiles == - added missing CMP_crop.c --- projectfiles_vc7/blender/nodes/nodes.vcproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/projectfiles_vc7/blender/nodes/nodes.vcproj b/projectfiles_vc7/blender/nodes/nodes.vcproj index d5fe5328df3..04403630664 100644 --- a/projectfiles_vc7/blender/nodes/nodes.vcproj +++ b/projectfiles_vc7/blender/nodes/nodes.vcproj @@ -239,6 +239,9 @@ + + From f1c6a69aad1f94f406cfa5172b7ddb941e80649d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 5 Nov 2007 21:06:27 +0000 Subject: [PATCH 6/9] sequencer snap was crashing when no last selected was available (own mistake) material names spelling was odd - HalveGreen -> HalfGreen --- source/blender/blenkernel/intern/material.c | 6 +++--- source/blender/src/editseq.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index d70cd683237..49d3021090e 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -757,9 +757,9 @@ int material_in_material(Material *parmat, Material *mat) /* ****************** */ char colname_array[125][20]= { -"Black","DarkRed","HalveRed","Red","Red", +"Black","DarkRed","HalfRed","Red","Red", "DarkGreen","DarkOlive","Brown","Chocolate","OrangeRed", -"HalveGreen","GreenOlive","DryOlive","Goldenrod","DarkOrange", +"HalfGreen","GreenOlive","DryOlive","Goldenrod","DarkOrange", "LightGreen","Chartreuse","YellowGreen","Yellow","Gold", "Green","LawnGreen","GreenYellow","LightOlive","Yellow", "DarkBlue","DarkPurple","HotPink","VioletPink","RedPink", @@ -767,7 +767,7 @@ char colname_array[125][20]= { "SeaGreen","PaleGreen","GreenKhaki","LightBrown","LightSalmon", "SpringGreen","PaleGreen","MediumOlive","YellowBrown","LightGold", "LightGreen","LightGreen","LightGreen","GreenYellow","PaleYellow", -"HalveBlue","DarkSky","HalveMagenta","VioletRed","DeepPink", +"HalfBlue","DarkSky","HalfMagenta","VioletRed","DeepPink", "SteelBlue","SkyBlue","Orchid","LightHotPink","HotPink", "SeaGreen","SlateGray","MediumGrey","Burlywood","LightPink", "SpringGreen","Aquamarine","PaleGreen","Khaki","PaleOrange", diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c index fafb5081ef0..eed3145284c 100644 --- a/source/blender/src/editseq.c +++ b/source/blender/src/editseq.c @@ -2956,13 +2956,13 @@ void transform_seq(int mode, int context) } /* check seq's next to the active also - nice for quick snapping */ - if (snap_dist && seq_tx_check_left(last_seq)) { + if (snap_dist && last_seq && seq_tx_check_left(last_seq)) { seq = find_next_prev_sequence(last_seq, 1, 0); /* left */ if(seq && !seq_tx_check_right(seq)) TESTSNAP(seq_tx_get_final_right(seq)); } - if (snap_dist && seq_tx_check_right(last_seq)) { + if (snap_dist && last_seq && seq_tx_check_right(last_seq)) { seq = find_next_prev_sequence(last_seq, 2, 0); /* right */ if(seq && !seq_tx_check_left(seq)) TESTSNAP(seq_tx_get_final_left(seq)); From e2504c2ff1aa3bfb2df446e007ee9fae0993a9ee Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 6 Nov 2007 09:44:34 +0000 Subject: [PATCH 7/9] Mesh Deform Modifier ==================== Added a button to invert the vertex group influence, to make blending between mdef and armature deform easier. --- source/blender/blenkernel/intern/modifier.c | 35 ++++++++++++-------- source/blender/makesdna/DNA_modifier_types.h | 4 ++- source/blender/src/buttons_editing.c | 3 +- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 243a24bc3b8..b805e3827d2 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -5067,7 +5067,28 @@ static void meshdeformModifier_do( } /* do deformation */ + fac= 1.0f; + for(b=0; bflag & MOD_MDEF_INVERT_VGROUP) { + if(!dw) fac= 1.0f; + else if(dw->weight == 0.0f) continue; + else fac=1.0f-dw->weight; + } + else { + if(!dw) continue; + else fac= dw->weight; + } + } + totweight= 0.0f; co[0]= co[1]= co[2]= 0.0f; @@ -5080,20 +5101,6 @@ static void meshdeformModifier_do( } if(totweight > 0.0f) { - if(dvert) { - for(dw=NULL, a=0; aweight; - } - else - fac= 1.0f; - VecMulf(co, fac/totweight); Mat3MulVecfl(icmat, co); VECADD(vertexCos[b], vertexCos[b], co); diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index c8dcba4fae7..42016ad1c16 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -348,6 +348,8 @@ typedef struct BooleanModifierData { int operation, pad; } BooleanModifierData; +#define MOD_MDEF_INVERT_VGROUP (1<<0) + typedef struct MeshDeformModifierData { ModifierData modifier; @@ -356,7 +358,7 @@ typedef struct MeshDeformModifierData { float *bindweights, *bindcos; /* computed binding weights */ short gridsize, needbind; - int pad; + short flag, pad; int totvert, totcagevert; } MeshDeformModifierData; diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 40e2643a390..c9bc9a4b296 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -2120,8 +2120,9 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco uiBlockBeginAlign(block); uiDefIDPoinBut(block, test_meshobpoin_but, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &mmd->object, "Mesh object to be use as cage"); - but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &mmd->defgrp_name, 0.0, 31.0, 0, 0, "Vertex Group name to control overall meshdeform influence"); + but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-19), buttonWidth-40,19, &mmd->defgrp_name, 0.0, 31.0, 0, 0, "Vertex Group name to control overall meshdeform influence"); uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob); + uiDefButBitS(block, TOG, MOD_MDEF_INVERT_VGROUP, B_MODIFIER_RECALC, "Inv", lx+buttonWidth-40, (cy-=19), 40,19, &mmd->flag, 0.0, 31.0, 0, 0, "Invert vertex group influence"); uiBlockBeginAlign(block); if(mmd->bindweights) { From f66aeb7a742a1668ebe9cdd7b06cc83606bb55f4 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 6 Nov 2007 11:25:48 +0000 Subject: [PATCH 8/9] Bugfix: Mesh deform modifier crashed when applied to lattices. --- source/blender/blenkernel/intern/modifier.c | 24 ++++++++++----------- source/blender/src/buttons_editing.c | 9 ++++++-- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index b805e3827d2..8e60964c28d 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -5118,15 +5118,15 @@ static void meshdeformModifier_deformVerts( { DerivedMesh *dm; - if(derivedData) dm = CDDM_copy(derivedData); - else dm = CDDM_from_mesh(ob->data, ob); - - CDDM_apply_vert_coords(dm, vertexCos); - CDDM_calc_normals(dm); + if(!derivedData && ob->type==OB_MESH) + dm= CDDM_from_mesh(ob->data, ob); + else + dm= derivedData; meshdeformModifier_do(md, ob, dm, vertexCos, numVerts); - dm->release(dm); + if(dm != derivedData) + dm->release(dm); } static void meshdeformModifier_deformVertsEM( @@ -5135,15 +5135,15 @@ static void meshdeformModifier_deformVertsEM( { DerivedMesh *dm; - if(derivedData) dm = CDDM_copy(derivedData); - else dm = CDDM_from_editmesh(editData, ob->data); - - CDDM_apply_vert_coords(dm, vertexCos); - CDDM_calc_normals(dm); + if(!derivedData && ob->type == OB_MESH) + dm = CDDM_from_editmesh(editData, ob->data); + else + dm = derivedData; meshdeformModifier_do(md, ob, dm, vertexCos, numVerts); - dm->release(dm); + if(dm != derivedData) + dm->release(dm); } /***/ diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index c9bc9a4b296..faa4ae4c445 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -1486,8 +1486,13 @@ static void modifiers_bindMeshDeform(void *ob_v, void *md_v) mmd->needbind= 1; mmd->modifier.mode |= eModifierMode_Realtime; - dm= mesh_create_derived_view(ob, 0); - dm->release(dm); + if(ob->type == OB_MESH) { + dm= mesh_create_derived_view(ob, 0); + dm->release(dm); + } + else if(ob->type == OB_LATTICE) { + lattice_calc_modifiers(ob); + } mmd->needbind= 0; mmd->modifier.mode= mode; From 9cd76a66096491e8994090e1992bb54d19c61950 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 6 Nov 2007 11:41:09 +0000 Subject: [PATCH 9/9] == "Extend" Transform Mode for Action + NLA Editors == Peach Request: Now the Action and NLA editors have the "Extend" transform mode first seen in the Sequence Editor. Just use the EKEY to start transforming. It works like Grab, except it only moves the keyframes/side of NLA-strip that was on the same side of the current-frame marker as the mouse was when transform started. --- source/blender/include/BIF_transform.h | 1 + source/blender/src/editaction.c | 13 +- source/blender/src/editnla.c | 13 ++ source/blender/src/header_action.c | 10 +- source/blender/src/header_nla.c | 16 ++- source/blender/src/transform.c | 5 + source/blender/src/transform_conversions.c | 155 +++++++++++++++++---- 7 files changed, 175 insertions(+), 38 deletions(-) diff --git a/source/blender/include/BIF_transform.h b/source/blender/include/BIF_transform.h index eeb465135de..26900b06c52 100644 --- a/source/blender/include/BIF_transform.h +++ b/source/blender/include/BIF_transform.h @@ -58,6 +58,7 @@ #define TFM_TIME_TRANSLATE 19 #define TFM_TIME_SLIDE 20 #define TFM_TIME_SCALE 21 +#define TFM_TIME_EXTEND 22 /* TRANSFORM CONTEXTS */ #define CTX_NONE 0 diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c index 3957b107814..48a39875cc2 100644 --- a/source/blender/src/editaction.c +++ b/source/blender/src/editaction.c @@ -739,6 +739,12 @@ void transform_action_keys (int mode, int dummy) Transform(); } break; + case 'e': + { + initTransform(TFM_TIME_EXTEND, CTX_NONE); + Transform(); + } + break; } } @@ -2645,7 +2651,12 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt) duplicate_action_keys(); } break; - + + case EKEY: + if (mval[0] >= ACTWIDTH) + transform_action_keys('e', 0); + break; + case GKEY: if (G.qual & LR_CTRLKEY) { transform_markers('g', 0); diff --git a/source/blender/src/editnla.c b/source/blender/src/editnla.c index 13423424f90..ec3b1c834e5 100644 --- a/source/blender/src/editnla.c +++ b/source/blender/src/editnla.c @@ -995,6 +995,12 @@ void transform_nlachannel_keys(int mode, int dummy) Transform(); } break; + case 'e': + { + initTransform(TFM_TIME_EXTEND, CTX_NONE); + Transform(); + } + break; } } @@ -1791,6 +1797,13 @@ void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt) break; + case EKEY: + if (mval[0] >= NLAWIDTH) { + transform_nlachannel_keys ('e', 0); + update_for_newframe_muted(); + } + break; + case GKEY: if (mval[0]>=NLAWIDTH) { if (G.qual & LR_CTRLKEY) { diff --git a/source/blender/src/header_action.c b/source/blender/src/header_action.c index c6d1b88c95c..4a803926a94 100644 --- a/source/blender/src/header_action.c +++ b/source/blender/src/header_action.c @@ -114,7 +114,6 @@ enum { enum { ACTMENU_KEY_DUPLICATE = 0, ACTMENU_KEY_DELETE, - ACTMENU_KEY_BAKE, ACTMENU_KEY_CLEAN }; @@ -128,7 +127,8 @@ enum { enum { ACTMENU_KEY_TRANSFORM_MOVE = 0, ACTMENU_KEY_TRANSFORM_SCALE, - ACTMENU_KEY_TRANSFORM_SLIDE + ACTMENU_KEY_TRANSFORM_SLIDE, + ACTMENU_KEY_TRANSFORM_EXTEND }; enum { @@ -594,6 +594,9 @@ static void do_action_keymenu_transformmenu(void *arg, int event) case ACTMENU_KEY_TRANSFORM_SLIDE: transform_action_keys('t', 0); break; + case ACTMENU_KEY_TRANSFORM_EXTEND: + transform_action_keys('e', 0); + break; } scrarea_queue_winredraw(curarea); @@ -611,6 +614,9 @@ static uiBlock *action_keymenu_transformmenu(void *arg_unused) uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Move|G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, ACTMENU_KEY_TRANSFORM_MOVE, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, + "Grab/Extend from Frame|E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, + ACTMENU_KEY_TRANSFORM_EXTEND, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Scale|S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, ACTMENU_KEY_TRANSFORM_SCALE, ""); diff --git a/source/blender/src/header_nla.c b/source/blender/src/header_nla.c index 3a3d3dfdb49..96ea6c3d792 100644 --- a/source/blender/src/header_nla.c +++ b/source/blender/src/header_nla.c @@ -269,12 +269,16 @@ static void do_nla_strip_transformmenu(void *arg, int event) { switch(event) { case 0: /* grab/move */ - transform_nlachannel_keys ('g', 0); - update_for_newframe_muted(); + transform_nlachannel_keys('g', 0); + update_for_newframe_muted(); break; case 1: /* scale */ - transform_nlachannel_keys ('s', 0); - update_for_newframe_muted(); + transform_nlachannel_keys('s', 0); + update_for_newframe_muted(); + break; + case 2: /* extend */ + transform_nlachannel_keys('e', 0); + update_for_newframe_muted(); break; } allqueue(REDRAWVIEW3D, 0); @@ -289,8 +293,10 @@ static uiBlock *nla_strip_transformmenu(void *arg_unused) uiBlockSetButmFunc(block, do_nla_strip_transformmenu, NULL); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Move|G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Extend from Frame|E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Scale|S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, ""); - + + uiBlockSetDirection(block, UI_RIGHT); uiTextBoundsBlock(block, 60); return block; diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c index 321a56c5ebd..2a7f744f219 100644 --- a/source/blender/src/transform.c +++ b/source/blender/src/transform.c @@ -938,6 +938,7 @@ void initTransform(int mode, int context) { /* EVIL! posemode code can switch translation to rotate when 1 bone is selected. will be removed (ton) */ /* EVIL2: we gave as argument also texture space context bit... was cleared */ + /* EVIL3: extend mode for animation editors also switches modes... but is best way to avoid duplicate code */ mode = Trans.mode; calculatePropRatio(&Trans); @@ -1004,6 +1005,10 @@ void initTransform(int mode, int context) { case TFM_TIME_SCALE: initTimeScale(&Trans); break; + case TFM_TIME_EXTEND: + /* now that transdata has been made, do like for TFM_TIME_TRANSLATE */ + initTimeTranslate(&Trans); + break; } } diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index b0e2d8144e8..820d79eb809 100644 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -113,6 +113,7 @@ #include "BIF_toolbox.h" #include "BSE_view.h" +#include "BSE_drawipo.h" #include "BSE_edit.h" #include "BSE_editipo.h" #include "BSE_editipo_types.h" @@ -2049,7 +2050,48 @@ void flushTransIpoData(TransInfo *t) /* ********************* ACTION/NLA EDITOR ****************** */ +/* This function tests if a point is on the "mouse" side of the cursor/frame-marking */ +static short FrameOnMouseSide(char side, float frame, float cframe) +{ + /* both sides, so it doesn't matter */ + if (side == 'B') return 1; + + /* only on the named side */ + if (side == 'R') + return (frame >= cframe) ? 1 : 0; + else + return (frame <= cframe) ? 1 : 0; +} +/* fully select selected beztriples, but only include if it's on the right side of cfra */ +static int count_ipo_keys(Ipo *ipo, char side, float cfra) +{ + IpoCurve *icu; + BezTriple *bezt; + int i, count = 0; + + if (ipo == NULL) + return count; + + /* only include points that occur on the right side of cfra */ + for (icu= ipo->curve.first; icu; icu= icu->next) { + for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) { + if (bezt->f2) { + /* fully select the other two keys */ + bezt->f1 |= 1; + bezt->f3 |= 1; + + /* increment by 3, as there are 3 points (3 * x-coordinates) that need transform */ + if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) + count += 3; + } + } + } + + return count; +} + +/* This function assigns the information to transdata */ static void TimeToTransData(TransData *td, float *time, Object *ob) { /* memory is calloc'ed, so that should zero everything nicely for us */ @@ -2065,9 +2107,12 @@ static void TimeToTransData(TransData *td, float *time, Object *ob) /* This function advances the address to which td points to, so it must return * the new address so that the next time new transform data is added, it doesn't - * overwrite the existing ones... i.e. td = IpoToTransData(td, ipo, ob); + * overwrite the existing ones... i.e. td = IpoToTransData(td, ipo, ob, side, cfra); + * + * The 'side' argument is needed for the extend mode. 'B' = both sides, 'R'/'L' mean only data + * on the named side are used. */ -static TransData *IpoToTransData(TransData *td, Ipo *ipo, Object *ob) +static TransData *IpoToTransData(TransData *td, Ipo *ipo, Object *ob, char side, float cfra) { IpoCurve *icu; BezTriple *bezt; @@ -2077,18 +2122,21 @@ static TransData *IpoToTransData(TransData *td, Ipo *ipo, Object *ob) return td; for (icu= ipo->curve.first; icu; icu= icu->next) { - /* only add selected keyframes (for now, proportional edit is not enabled) */ for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) { + /* only add selected keyframes (for now, proportional edit is not enabled) */ if (BEZSELECTED(bezt)) { - /* each control point needs to be added separetely */ - TimeToTransData(td, bezt->vec[0], ob); - td++; - - TimeToTransData(td, bezt->vec[1], ob); - td++; - - TimeToTransData(td, bezt->vec[2], ob); - td++; + /* only add if on the right 'side' of the current frame */ + if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) { + /* each control point needs to be added separetely */ + TimeToTransData(td, bezt->vec[0], ob); + td++; + + TimeToTransData(td, bezt->vec[1], ob); + td++; + + TimeToTransData(td, bezt->vec[2], ob); + td++; + } } } } @@ -2108,6 +2156,8 @@ static void createTransActionData(TransInfo *t) int filter; int count=0; + float cfra; + char side; /* determine what type of data we are operating on */ data = get_action_context(&datatype); @@ -2120,10 +2170,31 @@ static void createTransActionData(TransInfo *t) /* is the action scaled? if so, the it should belong to the active object */ if (NLA_ACTION_SCALED) ob= OBACT; + + /* which side of the current frame should be allowed */ + if (t->mode == TFM_TIME_EXTEND) { + /* only side on which mouse is gets transformed */ + float xmouse, ymouse; + + areamouseco_to_ipoco(G.v2d, t->imval, &xmouse, &ymouse); + side = (xmouse > CFRA) ? 'R' : 'L'; + } + else { + /* normal transform - both sides of current frame are considered */ + side = 'B'; + } + + /* convert current-frame to action-time (slightly less accurate, espcially under + * higher scaling ratios, but is faster than converting all points) + */ + if (ob) + cfra = get_action_frame(ob, CFRA); + else + cfra = CFRA; /* loop 1: fully select ipo-keys and count how many BezTriples are selected */ for (ale= act_data.first; ale; ale= ale->next) - count += fullselect_ipo_keys(ale->key_data); + count += count_ipo_keys(ale->key_data, side, cfra); /* stop if trying to build list if nothing selected */ if (count == 0) { @@ -2143,7 +2214,7 @@ static void createTransActionData(TransInfo *t) for (ale= act_data.first; ale; ale= ale->next) { Ipo *ipo= (Ipo *)ale->key_data; - td= IpoToTransData(td, ipo, ob); + td= IpoToTransData(td, ipo, ob, side, cfra); } /* check if we're supposed to be setting minx/maxx for TimeSlide */ @@ -2178,17 +2249,32 @@ static void createTransNlaData(TransInfo *t) TransData *td = NULL; int count=0, i; + float cfra; + char side; + + /* which side of the current frame should be allowed */ + if (t->mode == TFM_TIME_EXTEND) { + /* only side on which mouse is gets transformed */ + float xmouse, ymouse; + + areamouseco_to_ipoco(G.v2d, t->imval, &xmouse, &ymouse); + side = (xmouse > CFRA) ? 'R' : 'L'; + } + else { + /* normal transform - both sides of current frame are considered */ + side = 'B'; + } /* Ensure that partial selections result in beztriple selections */ for (base=G.scene->base.first; base; base=base->next) { /* Check object ipos */ - i= fullselect_ipo_keys(base->object->ipo); + i= count_ipo_keys(base->object->ipo, side, CFRA); if (i) base->flag |= BA_HAS_RECALC_OB; count += i; /* Check object constraint ipos */ for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next) - count += fullselect_ipo_keys(conchan->ipo); + count += count_ipo_keys(conchan->ipo, side, CFRA); /* skip actions and nlastrips if object is collapsed */ if (base->object->nlaflag & OB_NLA_COLLAPSED) @@ -2203,9 +2289,11 @@ static void createTransNlaData(TransInfo *t) break; } if (strip==NULL) { + cfra = get_action_frame(base->object, CFRA); + for (achan=base->object->action->chanbase.first; achan; achan=achan->next) { if (EDITABLE_ACHAN(achan)) { - i= fullselect_ipo_keys(achan->ipo); + i= count_ipo_keys(achan->ipo, side, cfra); if (i) base->flag |= BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA; count += i; @@ -2213,7 +2301,7 @@ static void createTransNlaData(TransInfo *t) if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) { for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) { if (EDITABLE_CONCHAN(conchan)) - count += fullselect_ipo_keys(conchan->ipo); + count += count_ipo_keys(conchan->ipo, side, cfra); } } } @@ -2225,7 +2313,9 @@ static void createTransNlaData(TransInfo *t) for (strip=base->object->nlastrips.first; strip; strip=strip->next) { if (strip->flag & ACTSTRIP_SELECT) { base->flag |= BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA; - count += 2; + + if (FrameOnMouseSide(side, strip->start, CFRA)) count++; + if (FrameOnMouseSide(side, strip->end, CFRA)) count++; } } } @@ -2243,12 +2333,12 @@ static void createTransNlaData(TransInfo *t) for (base=G.scene->base.first; base; base=base->next) { /* Manipulate object ipos */ /* - no scaling of keyframe times is allowed here */ - td= IpoToTransData(td, base->object->ipo, NULL); + td= IpoToTransData(td, base->object->ipo, NULL, side, CFRA); /* Manipulate object constraint ipos */ /* - no scaling of keyframe times is allowed here */ for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next) - td= IpoToTransData(td, conchan->ipo, NULL); + td= IpoToTransData(td, conchan->ipo, NULL, side, CFRA); /* skip actions and nlastrips if object collapsed */ if (base->object->nlaflag & OB_NLA_COLLAPSED) @@ -2265,15 +2355,17 @@ static void createTransNlaData(TransInfo *t) /* can include if no strip found */ if (strip==NULL) { + cfra = get_action_frame(base->object, CFRA); + for (achan=base->object->action->chanbase.first; achan; achan=achan->next) { if (EDITABLE_ACHAN(achan)) { - td= IpoToTransData(td, achan->ipo, base->object); + td= IpoToTransData(td, achan->ipo, base->object, side, cfra); /* Manipulate action constraint ipos */ if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) { for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) { if (EDITABLE_CONCHAN(conchan)) - td= IpoToTransData(td, conchan->ipo, base->object); + td= IpoToTransData(td, conchan->ipo, base->object, side, cfra); } } } @@ -2285,13 +2377,16 @@ static void createTransNlaData(TransInfo *t) for (strip=base->object->nlastrips.first; strip; strip=strip->next) { if (strip->flag & ACTSTRIP_SELECT) { /* first TransData is the start, second is the end */ - td->val = &strip->start; - td->ival = strip->start; - td++; - - td->val = &strip->end; - td->ival = strip->end; - td++; + if (FrameOnMouseSide(side, strip->start, CFRA)) { + td->val = &strip->start; + td->ival = strip->start; + td++; + } + if (FrameOnMouseSide(side, strip->end, CFRA)) { + td->val = &strip->end; + td->ival = strip->end; + td++; + } } } }