diff options
Diffstat (limited to 'source/blender/src')
25 files changed, 1114 insertions, 371 deletions
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 3ea7788f87c..c5087bd2ba5 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -4067,13 +4067,13 @@ static void editing_panel_armature_type(Object *ob, bArmature *arm) uiBlockBeginAlign(block); for(a=0; a<8; a++) { short dx= 18; - but= uiDefButBitS(block, BUT_TOGDUAL, 1<<a, REDRAWVIEW3D, "", 10+a*dx, 115, dx, 15, &arm->layer, 0, 0, 0, 0, ""); + but= uiDefButBitS(block, BUT_TOGDUAL, 1<<a, REDRAWVIEW3D, "", 10+a*dx, 115, dx, 15, &arm->layer, 0, 0, 0, 0, "Armature layer (Hold Ctrl for locking in a proxy instance)"); uiButSetFunc(but, armature_layer_cb, &arm->layer, (void *)(1<<a)); } uiBlockBeginAlign(block); for(a=8; a<16; a++) { short dx= 18; - but= uiDefButBitS(block, BUT_TOGDUAL, 1<<a, REDRAWVIEW3D, "", 18+a*dx, 115, dx, 15, &arm->layer, 0, 0, 0, 0, ""); + but= uiDefButBitS(block, BUT_TOGDUAL, 1<<a, REDRAWVIEW3D, "", 18+a*dx, 115, dx, 15, &arm->layer, 0, 0, 0, 0, "Armature layer (Hold Ctrl for locking in a proxy instance)"); uiButSetFunc(but, armature_layer_cb, &arm->layer, (void *)(1<<a)); } /* quite bad here, but I don't know a better place for copy... */ diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index e6046203c4f..0ec60685981 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -584,12 +584,14 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s uiBlockSetEmboss(block, UI_EMBOSS); } else { - short prev_proxylock; + short prev_proxylock, show_upbut, show_downbut; /* Up/Down buttons: * Proxy-constraints are not allowed to occur after local (non-proxy) constraints * as that poses problems when restoring them, so disable the "up" button where - * it may cause this situation. + * it may cause this situation. + * + * Up/Down buttons should only be shown (or not greyed - todo) if they serve some purpose. */ if (proxylocked_constraints_owner(ob, pchan)) { if (con->prev) { @@ -600,21 +602,25 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s } else prev_proxylock= 0; - - uiBlockBeginAlign(block); - uiBlockSetEmboss(block, UI_EMBOSS); - - /* only show buttons that will do anything valid */ - if ((prev_proxylock==0) && (con->prev)) { - but = uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_UP, *xco+width-50, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move constraint up in constraint stack"); - uiButSetFunc(but, constraint_moveUp, ob, con); - } - if (con->next) { - but = uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_DOWN, *xco+width-50+18, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move constraint down in constraint stack"); - uiButSetFunc(but, constraint_moveDown, ob, con); - } - uiBlockEndAlign(block); + show_upbut= ((prev_proxylock == 0) && (con->prev)); + show_downbut= (con->next) ? 1 : 0; + + if (show_upbut || show_downbut) { + uiBlockBeginAlign(block); + uiBlockSetEmboss(block, UI_EMBOSS); + + if (show_upbut) { + but = uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_UP, *xco+width-50, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move constraint up in constraint stack"); + uiButSetFunc(but, constraint_moveUp, ob, con); + } + + if (show_downbut) { + but = uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_DOWN, *xco+width-50+18, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move constraint down in constraint stack"); + uiButSetFunc(but, constraint_moveDown, ob, con); + } + uiBlockEndAlign(block); + } /* Close 'button' - emboss calls here disable drawing of 'button' behind X */ @@ -3734,7 +3740,7 @@ static void object_softbodies_solver(Object *ob) uiBlockEndAlign(block); uiBlockBeginAlign(block); - uiDefBut(block, LABEL, 0, "Diagnosis stuff",10,60,300,20, NULL, 0.0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Diagnosis",10,60,300,20, NULL, 0.0, 0, 0, 0, ""); uiDefButBitS(block, TOG, SBSO_MONITOR, B_DIFF,"Print Performance to Console", 10,40,300,20, &sb->solverflags, 0, 0, 0, 0, "Turn on SB diagnose console prints"); uiBlockEndAlign(block); } @@ -3920,15 +3926,15 @@ static void object_softbodies(Object *ob) uiDefButBitS(block, TOG, OB_SB_QUADS, B_SOFTBODY_CHANGE, "Stiff Quads", 110,50,90,20, softflag, 0, 0, 0, 0, "Adds diagonal springs on 4-gons"); uiDefButBitS(block, TOG, OB_SB_EDGECOLL, B_DIFF, "CEdge", 220,50,45,20, softflag, 0, 0, 0, 0, "Edge collide too"); uiDefButBitS(block, TOG, OB_SB_FACECOLL, B_DIFF, "CFace", 265,50,45,20, softflag, 0, 0, 0, 0, "Faces collide too SLOOOOOW warning "); - uiDefButF(block, NUM, B_DIFF, "E Pull:", 10,30,100,20, &sb->inspring, 0.0, 0.999, 10, 0, "Edge spring stiffness"); - uiDefButF(block, NUM, B_DIFF, "E Push:", 110,30,100,20, &sb->inpush, 0.0, 0.999, 10, 0, "Edge spring stiffness"); + uiDefButF(block, NUM, B_DIFF, "E Pull:", 10,30,100,20, &sb->inspring, 0.0, 0.999, 10, 0, "Edge spring stiffness when longer than rest length"); + uiDefButF(block, NUM, B_DIFF, "E Push:", 110,30,100,20, &sb->inpush, 0.0, 0.999, 10, 0, "Edge spring stiffness when shorter than rest length"); uiDefButF(block, NUM, B_DIFF, "E Damp:", 210,30,100,20, &sb->infrict, 0.0, 50.0, 10, 0, "Edge spring friction"); - uiDefButBitS(block, TOG,OB_SB_AERO_ANGLE,B_SOFTBODY_CHANGE, "N",10,10,20,20, softflag, 0, 0, 0, 0, "New aero(uses angle and lenght)"); + uiDefButBitS(block, TOG,OB_SB_AERO_ANGLE,B_SOFTBODY_CHANGE, "N",10,10,20,20, softflag, 0, 0, 0, 0, "New aero(uses angle and length)"); uiDefButS(block, NUM, B_DIFF, "Aero:", 30,10,80,20, &sb->aeroedge, 0.00, 30000.0, 10, 0, "Make edges 'sail'"); if(ob->type==OB_MESH) { uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "Bend:", 110,10,100,20, &sb->secondspring, 0.0, 10.0, 10, 0, "Strenght of Springs over 2 Edges"); if (*softflag & OB_SB_QUADS){ - uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "Shear:", 210,10,100,20, &sb->shearstiff, 0.0, 1.0, 10, 0, "Strenght of Springs over 2 Edges"); + uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "Shear:", 210,10,100,20, &sb->shearstiff, 0.0, 1.0, 10, 0, "Strenght of diagonal Springs"); } } else sb->secondspring = 0; diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index d06028b09bc..ca9a1b31f88 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -514,6 +514,43 @@ static char* seq_panel_blend_modes() return string; } +static char* seq_panel_scenes() +{ + static char rstr[8192]; + char * str; + + IDnames_to_pupstring(&str, NULL, NULL, + &G.main->scene, (ID *)G.scene, NULL); + + strncpy(rstr, str, 8192); + MEM_freeN(str); + + return rstr; +} + +static void seq_update_scenenr(Sequence * seq) +{ + Scene * sce; + int nr; + if (seq->type != SEQ_SCENE) { + return; + } + + seq->scenenr = 0; + + sce = G.main->scene.first; + nr = 1; + while(sce) { + if (sce == seq->scene) { + seq->scenenr = nr; + break; + } + nr++; + sce = sce->id.next; + } +} + + static void seq_panel_editing() { Sequence *last_seq = get_last_seq(); @@ -543,12 +580,10 @@ static void seq_panel_editing() 10, 120, 120, 19, &last_seq->blend_mode, 0,0,0,0, "Strip Blend Mode"); - if (last_seq->blend_mode > 0) { - uiDefButF(block, NUM, B_SEQ_BUT_RELOAD, "Blend:", - 130, 120, 120, 19, &last_seq->blend_opacity, - 0.0, 100.0, 100.0, 0, - "Blend opacity"); - } + uiDefButF(block, NUM, B_SEQ_BUT_RELOAD, "Blend:", + 130, 120, 120, 19, &last_seq->blend_opacity, + 0.0, 100.0, 100.0, 0, + "Blend opacity"); uiDefButBitI(block, TOG, SEQ_MUTE, B_SEQ_BUT_RELOAD_ALL, "Mute", @@ -585,27 +620,24 @@ static void seq_panel_editing() 130, 60, 120, 19, &last_seq->endstill, 0.0, MAXFRAMEF, 0.0, 0.0, "End still"); } else { - if (last_seq->type == SEQ_IMAGE) { - uiDefButI(block, NUM, - B_SEQ_BUT_TRANSFORM, "Start-Still", - 10, 60, 120, 20, &last_seq->startstill, - 0.0, MAXFRAMEF, 0.0, 0.0, "Start still"); - uiDefButI(block, NUM, - B_SEQ_BUT_TRANSFORM, "End-Still", - 130, 60, 120, 19, &last_seq->endstill, - 0.0, MAXFRAMEF, 0.0, 0.0, "End still"); - } else { - uiDefButI(block, NUM, - B_SEQ_BUT_TRANSFORM, "Start-Ofs", - 10, 60, 120, 20, &last_seq->startofs, - 0.0, last_seq->len - last_seq->endofs, - 0.0, 0.0, "Start offset"); - uiDefButI(block, NUM, - B_SEQ_BUT_TRANSFORM, "End-Ofs", - 130, 60, 120, 19, &last_seq->endofs, - 0.0, last_seq->len - last_seq->startofs, - 0.0, 0.0, "End offset"); - } + uiDefButI(block, NUM, + B_SEQ_BUT_TRANSFORM, "Start-Still", + 10, 60, 120, 20, &last_seq->startstill, + 0.0, MAXFRAMEF, 0.0, 0.0, "Start still"); + uiDefButI(block, NUM, + B_SEQ_BUT_TRANSFORM, "End-Still", + 130, 60, 120, 19, &last_seq->endstill, + 0.0, MAXFRAMEF, 0.0, 0.0, "End still"); + uiDefButI(block, NUM, + B_SEQ_BUT_TRANSFORM, "Start-Ofs", + 10, 40, 120, 20, &last_seq->startofs, + 0.0, last_seq->len - last_seq->endofs, + 0.0, 0.0, "Start offset"); + uiDefButI(block, NUM, + B_SEQ_BUT_TRANSFORM, "End-Ofs", + 130, 40, 120, 19, &last_seq->endofs, + 0.0, last_seq->len - last_seq->startofs, + 0.0, 0.0, "End offset"); } } @@ -683,14 +715,14 @@ static void seq_panel_editing() } str = strdata; - yco = 40; + yco = 20; while ((p = strchr(str, '\n'))) { *p = 0; - uiDefBut(block, LABEL, 0, str, 10,yco,240,19, 0, + uiDefBut(block, LABEL, 0, str, 10,yco,240,17, 0, 0, 0, 0, 0, ""); str = p+1; - yco -= 20; + yco -= 18; } } @@ -719,7 +751,7 @@ static void seq_panel_input() if (se) { uiDefBut(block, TEX, B_SEQ_BUT_RELOAD_FILE, "File: ", - 10, 120, 240,19, se->name, + 10, 120, 190,19, se->name, 0.0, 80.0, 100, 0, ""); } @@ -728,10 +760,21 @@ static void seq_panel_input() last_seq->type == SEQ_RAM_SOUND) { uiDefBut(block, TEX, B_SEQ_BUT_RELOAD_FILE, "File: ", - 10,120,240,19, last_seq->strip->stripdata->name, + 10,120,190,19, last_seq->strip->stripdata->name, 0.0, 80.0, 100, 0, ""); + } else if (last_seq->type == SEQ_SCENE) { + seq_update_scenenr(last_seq); + uiDefButI(block, MENU, B_SEQ_BUT_RELOAD_FILE, + seq_panel_scenes(), + 10, 120, 190, 19, &last_seq->scenenr, + 0,0,0,0, "Linked Scene"); } + uiDefBut(block, BUT, B_SEQ_BUT_RELOAD_FILE, + "Reload", + 200,120,50,19, 0, 0, 0, 0, 0, + "Reload files/scenes from disk and update strip length."); + if (last_seq->type == SEQ_MOVIE || last_seq->type == SEQ_IMAGE || last_seq->type == SEQ_SCENE) { @@ -1837,28 +1880,27 @@ static void render_panel_output(void) uiBlockEndAlign(block); uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, R_TOUCH, B_NOP, "Touch", 10, 142, 50, 20, &G.scene->r.mode, 0.0, 0.0, 0, 0, "Create an empty file before rendering each frame, remove if cancelled (and empty)"); + uiDefButBitI(block, TOG, R_TOUCH, B_NOP, "Touch", 10, 142, 50, 20, &G.scene->r.mode, 0.0, 0.0, 0, 0, "Create an empty file before rendering each frame, remove if cancelled (and empty)"); uiDefButBitI(block, TOG, R_NO_OVERWRITE, B_NOP, "No Overwrite", 60, 142, 90, 20, &G.scene->r.mode, 0.0, 0.0, 0, 0, "Skip rendering frames when the file exists (image output only)"); uiBlockEndAlign(block); + uiDefButBitS(block, TOG, R_BACKBUF, B_NOP,"Backbuf", 160, 142, 80, 20, &G.scene->r.bufflag, 0, 0, 0, 0, "Enable/Disable use of Backbuf image"); /* SET BUTTON */ uiBlockBeginAlign(block); id= (ID *)G.scene->set; IDnames_to_pupstring(&strp, NULL, NULL, &(G.main->scene), id, &(G.buts->menunr)); if(strp[0]) - uiDefButS(block, MENU, B_SETBROWSE, strp, 10, 114, 20, 20, &(G.buts->menunr), 0, 0, 0, 0, "Scene to link as a Set"); + uiDefButS(block, MENU, B_SETBROWSE, strp, 10, 114, 20, 20, &(G.buts->menunr), 0, 0, 0, 0, "Scene to link as a Set"); MEM_freeN(strp); if(G.scene->set) { uiSetButLock(1, NULL); - uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, B_NOP, "", 31, 120, 100, 20, &(G.scene->set), "Name of the Set"); + uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, B_NOP, "", 31, 114, 100, 20, &(G.scene->set), "Name of the Set"); uiClearButLock(); - uiDefIconBut(block, BUT, B_CLEARSET, ICON_X, 132, 120, 20, 20, 0, 0, 0, 0, 0, "Remove Set link"); + uiDefIconBut(block, BUT, B_CLEARSET, ICON_X, 132, 114, 20, 20, 0, 0, 0, 0, 0, "Remove Set link"); } uiBlockEndAlign(block); - uiBlockSetCol(block, TH_BUT_SETTING1); - uiDefButBitS(block, TOG, R_BACKBUF, B_NOP,"Backbuf", 10, 89, 80, 20, &G.scene->r.bufflag, 0, 0, 0, 0, "Enable/Disable use of Backbuf image"); uiDefButS(block, NUM, B_NOP, "Threads:", 10, 63, 100, 20, &G.scene->r.threads, 1, BLENDER_MAX_THREADS, 0, 0, "Amount of threads for render (takes advantage of multi-core and multi-processor computers)"); uiBlockSetCol(block, TH_AUTO); @@ -1866,9 +1908,12 @@ static void render_panel_output(void) for(b=2; b>=0; b--) for(a=0; a<3; a++) uiDefButBitS(block, TOG, 1<<(3*b+a), 800,"", (short)(10+18*a),(short)(10+14*b),16,12, &G.winpos, 0, 0, 0, 0, "Render window placement on screen"); - uiBlockEndAlign(block); - uiDefButBitS(block, TOG, R_EXR_TILE_FILE, B_NOP, "Save Buffers", 72, 31, 120, 19, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Save the tiles for all RenderLayers and used SceneNodes to files, to save memory"); + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, R_EXR_TILE_FILE, B_REDR, "Save Buffers", 72, 31, 120, 19, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Save the tiles for all RenderLayers and used SceneNodes to files, to save memory"); + if(G.scene->r.scemode & R_EXR_TILE_FILE) + uiDefButBitS(block, TOG, R_FULL_SAMPLE, B_REDR, "FullSample", 192, 31, 118, 19, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Saves for every OSA sample the entire RenderLayer results"); + uiBlockEndAlign(block); uiDefButS(block, MENU, B_REDR, "Render Display %t|Render Window %x1|Image Editor %x0|Full Screen %x2", 72, 10, 120, 19, &G.displaymode, 0.0, (float)R_DISPLAYWIN, 0, 0, "Sets render output display"); @@ -1876,12 +1921,12 @@ static void render_panel_output(void) uiDefButBitS(block, TOG, R_EXTENSION, B_NOP, "Extensions", 205, 10, 105, 19, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Adds filetype extensions to the filename when rendering animations"); /* Dither control */ - uiDefButF(block, NUM,B_DIFF, "Dither:", 205,31,105,19, &G.scene->r.dither_intensity, 0.0, 2.0, 0, 0, "The amount of dithering noise present in the output image (0.0 = no dithering)"); + uiDefButF(block, NUM,B_DIFF, "Dither:", 10,89,100,19, &G.scene->r.dither_intensity, 0.0, 2.0, 0, 0, "The amount of dithering noise present in the output image (0.0 = no dithering)"); /* Toon shading buttons */ uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, R_EDGE, B_NOP,"Edge", 100, 89, 70, 20, &G.scene->r.mode, 0, 0, 0, 0, "Enable Toon Edge-enhance"); - uiDefBlockBut(block, edge_render_menu, NULL, "Edge Settings", 170, 89, 140, 20, "Display Edge settings"); + uiDefButBitI(block, TOG, R_EDGE, B_NOP,"Edge", 115, 89, 60, 20, &G.scene->r.mode, 0, 0, 0, 0, "Enable Toon Edge-enhance"); + uiDefBlockBut(block, edge_render_menu, NULL, "Edge Settings", 175, 89, 135, 20, "Display Edge settings"); uiBlockEndAlign(block); uiBlockBeginAlign(block); @@ -1957,7 +2002,10 @@ static void render_panel_render(void) #endif /* disable yafray */ uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, R_OSA, B_DIFF, "OSA", 369,109,122,20,&G.scene->r.mode, 0, 0, 0, 0, "Enables Oversampling (Anti-aliasing)"); + if((G.scene->r.scemode & R_FULL_SAMPLE) && (G.scene->r.scemode & R_EXR_TILE_FILE)) + uiDefButBitI(block, TOG, R_OSA, B_DIFF, "FSA", 369,109,122,20,&G.scene->r.mode, 0, 0, 0, 0, "Saves all samples, then composites, and then merges (for best Anti-aliasing)"); + else + uiDefButBitI(block, TOG, R_OSA, B_DIFF, "OSA", 369,109,122,20,&G.scene->r.mode, 0, 0, 0, 0, "Enables Oversampling (Anti-aliasing)"); uiDefButS(block, ROW,B_DIFF,"5", 369,88,29,20,&G.scene->r.osa,2.0,5.0, 0, 0, "Render 5 samples per pixel for smooth edges (Fast)"); uiDefButS(block, ROW,B_DIFF,"8", 400,88,29,20,&G.scene->r.osa,2.0,8.0, 0, 0, "Render 8 samples per pixel for smooth edges (Recommended)"); uiDefButS(block, ROW,B_DIFF,"11", 431,88,29,20,&G.scene->r.osa,2.0,11.0, 0, 0, "Render 11 samples per pixel for smooth edges (High Quality)"); @@ -2304,11 +2352,7 @@ static void render_panel_format(void) if(G.scene->r.quality==0) G.scene->r.quality= 90; -#ifdef WITH_QUICKTIME if (G.scene->r.imtype == R_AVICODEC || G.scene->r.imtype == R_QUICKTIME) { -#else /* WITH_QUICKTIME */ - if (0) { -#endif if(G.scene->r.imtype == R_QUICKTIME) { #ifdef WITH_QUICKTIME #if defined (_WIN32) || defined (__APPLE__) @@ -2651,12 +2695,12 @@ static void render_panel_layers(void) uiDefButBitI(block, TOG, SCE_PASS_RGBA, B_SET_PASS,"Col", 10, 10, 35, 20, &srl->passflag, 0, 0, 0, 0, "Deliver shade-less Color pass"); uiDefButBitI(block, TOG, SCE_PASS_DIFFUSE, B_SET_PASS,"Diff", 45, 10, 35, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass"); - uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_SPEC, B_SET_PASS,"Spec", 80, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Specular pass"); - uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_SHADOW, B_SET_PASS,"Shad", 120, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Shadow pass"); - uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_AO, B_SET_PASS,"AO", 160, 10, 30, 20, &srl->passflag, 0, 0, 0, 0, "Deliver AO pass"); - uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_REFLECT, B_SET_PASS,"Refl", 190, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Raytraced Reflection pass"); - uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_REFRACT, B_SET_PASS,"Refr", 230, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Raytraced Refraction pass"); - uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_RADIO, B_SET_PASS,"Rad", 270, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Radiosity pass"); + uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_SPEC, B_SET_PASS,"Spec", 80, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Specular pass (Hold Ctrl to exclude from combined)"); + uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_SHADOW, B_SET_PASS,"Shad", 120, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Shadow pass (Hold Ctrl to exclude from combined)"); + uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_AO, B_SET_PASS,"AO", 160, 10, 30, 20, &srl->passflag, 0, 0, 0, 0, "Deliver AO pass (Hold Ctrl to exclude from combined)"); + uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_REFLECT, B_SET_PASS,"Refl", 190, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Raytraced Reflection pass (Hold Ctrl to exclude from combined)"); + uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_REFRACT, B_SET_PASS,"Refr", 230, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Raytraced Refraction pass (Hold Ctrl to exclude from combined)"); + uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_RADIO, B_SET_PASS,"Rad", 270, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Radiosity pass (Hold Ctrl to exclude from combined)"); } void render_panels() diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index be307a649b3..76a4f024f26 100644 --- a/source/blender/src/buttons_shading.c +++ b/source/blender/src/buttons_shading.c @@ -1175,13 +1175,13 @@ void uiblock_image_panel(uiBlock *block, Image **ima_pp, ImageUser *iuser, /* fields */ uiBlockBeginAlign(block); - but= uiDefButBitS(block, TOG, IMA_FIELDS, imagechanged, "Fields", 10, 90, 65, 20, &ima->flag, 0, 0, 0, 0, "Click to enable use of fields in Image"); + but= uiDefButBitS(block, TOG, IMA_FIELDS, imagechanged, "Fields", 10, 70, 65, 20, &ima->flag, 0, 0, 0, 0, "Click to enable use of fields in Image"); uiButSetFunc(but, image_field_test, ima, iuser); - uiDefButBitS(block, TOG, IMA_STD_FIELD, B_NOP, "Odd", 75, 90, 45, 20, &ima->flag, 0, 0, 0, 0, "Standard Field Toggle"); + uiDefButBitS(block, TOG, IMA_STD_FIELD, B_NOP, "Odd", 75, 70, 45, 20, &ima->flag, 0, 0, 0, 0, "Standard Field Toggle"); uiBlockSetFunc(block, image_reload_cb, ima, iuser); - uiDefButBitS(block, TOG, IMA_ANTIALI, B_NOP, "Anti", 10, 70, 45, 20, &ima->flag, 0, 0, 0, 0, "Toggles Image anti-aliasing, only works with solid colors"); - uiDefButBitS(block, TOG, IMA_DO_PREMUL, imagechanged, "Premul", 55, 70, 65, 20, &ima->flag, 0, 0, 0, 0, "Toggles premultiplying alpha"); + uiDefButBitS(block, TOG, IMA_ANTIALI, B_NOP, "Anti", 10, 50, 45, 20, &ima->flag, 0, 0, 0, 0, "Toggles Image anti-aliasing, only works with solid colors"); + uiDefButBitS(block, TOG, IMA_DO_PREMUL, imagechanged, "Premul", 55, 50, 65, 20, &ima->flag, 0, 0, 0, 0, "Toggles premultiplying alpha"); uiBlockEndAlign(block); if( ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { @@ -1189,21 +1189,21 @@ void uiblock_image_panel(uiBlock *block, Image **ima_pp, ImageUser *iuser, uiBlockBeginAlign(block); uiBlockSetFunc(block, image_user_change, iuser, NULL); - uiDefButBitS(block, TOG, IMA_ANIM_ALWAYS, B_NOP, "Auto Refresh", 120, 90, 190, 20, &iuser->flag, 0, 0, 0, 0, "Always refresh Image on frame changes"); + uiDefButBitS(block, TOG, IMA_ANIM_ALWAYS, B_NOP, "Auto Refresh", 120, 70, 190, 20, &iuser->flag, 0, 0, 0, 0, "Always refresh Image on frame changes"); if(ima->anim) { - uiDefButI(block, NUM, imagechanged, str, 120, 70,170, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use"); - but= uiDefBut(block, BUT, redraw, "<", 290, 70, 20, 20, 0, 0, 0, 0, 0, "Copies number of frames in movie file to Frames: button"); + uiDefButI(block, NUM, imagechanged, str, 120, 50,170, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use"); + but= uiDefBut(block, BUT, redraw, "<", 290, 50, 20, 20, 0, 0, 0, 0, 0, "Copies number of frames in movie file to Frames: button"); uiButSetFunc(but, set_frames_cb, ima, iuser); } else - uiDefButI(block, NUM, imagechanged, str, 120, 70,190, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use"); + uiDefButI(block, NUM, imagechanged, str, 120, 50,190, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use"); - uiDefButI(block, NUM, imagechanged, "Offs:", 120,50,100,20, &iuser->offset, -MAXFRAMEF, MAXFRAMEF, 0, 0, "Offsets the number of the frame to use in the animation"); - uiDefButS(block, NUM, imagechanged, "Fie/Ima:", 220,50,90,20, &iuser->fie_ima, 1.0, 200.0, 0, 0, "The number of fields per rendered frame (2 fields is 1 image)"); + uiDefButI(block, NUM, imagechanged, "Offs:", 120,30,100,20, &iuser->offset, -MAXFRAMEF, MAXFRAMEF, 0, 0, "Offsets the number of the frame to use in the animation"); + uiDefButS(block, NUM, imagechanged, "Fie/Ima:", 220,30,90,20, &iuser->fie_ima, 1.0, 200.0, 0, 0, "The number of fields per rendered frame (2 fields is 1 image)"); - uiDefButI(block, NUM, imagechanged, "StartFr:", 120,30,100,20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Sets the global starting frame of the movie"); - uiDefButS(block, TOG, imagechanged, "Cyclic", 220,30,90,20, &iuser->cycl, 0.0, 1.0, 0, 0, "Cycle the images in the movie"); + uiDefButI(block, NUM, imagechanged, "StartFr:", 120,10,100,20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Sets the global starting frame of the movie"); + uiDefButS(block, TOG, imagechanged, "Cyclic", 220,10,90,20, &iuser->cycl, 0.0, 1.0, 0, 0, "Cycle the images in the movie"); uiBlockSetFunc(block, NULL, iuser, NULL); } @@ -1211,9 +1211,9 @@ void uiblock_image_panel(uiBlock *block, Image **ima_pp, ImageUser *iuser, uiBlockBeginAlign(block); uiBlockSetFunc(block, image_generated_change_cb, ima, iuser); - uiDefButS(block, NUM, imagechanged, "SizeX:", 120,90,100,20, &ima->gen_x, 1.0, 5000.0, 0, 0, "Image size x"); - uiDefButS(block, NUM, imagechanged, "SizeY:", 220,90,90,20, &ima->gen_y, 1.0, 5000.0, 0, 0, "Image size y"); - uiDefButS(block, TOG, imagechanged, "UV Test grid",120,70,190,20, &ima->gen_type, 0.0, 1.0, 0, 0, ""); + uiDefButS(block, NUM, imagechanged, "SizeX:", 120,70,100,20, &ima->gen_x, 1.0, 5000.0, 0, 0, "Image size x"); + uiDefButS(block, NUM, imagechanged, "SizeY:", 220,70,90,20, &ima->gen_y, 1.0, 5000.0, 0, 0, "Image size y"); + uiDefButS(block, TOG, imagechanged, "UV Test grid",120,50,190,20, &ima->gen_type, 0.0, 1.0, 0, 0, ""); uiBlockSetFunc(block, NULL, NULL, NULL); } } diff --git a/source/blender/src/drawaction.c b/source/blender/src/drawaction.c index 3339385d565..64af3041155 100644 --- a/source/blender/src/drawaction.c +++ b/source/blender/src/drawaction.c @@ -816,8 +816,7 @@ static void draw_channel_strips(void) /* Draw keyframes * 1) Only channels that are visible in the Action Editor get drawn/evaluated. * This is to try to optimise this for heavier data sets - * 2) Keyframes which are out of view horizontally could be disregarded (probably as - * option - 'drop-frames' or so). Todo... + * 2) Keyframes which are out of view horizontally are disregarded */ y = 0.0; for (ale= act_data.first; ale; ale= ale->next) { @@ -1241,12 +1240,36 @@ static void draw_keylist(gla2DDrawInfo *di, ListBase *keys, ListBase *blocks, fl glDisable(GL_BLEND); } + +static ActKeysInc *init_aki_data() +{ + static ActKeysInc aki; + + /* init data of static struct here */ + if ((curarea->spacetype == SPACE_ACTION) && NLA_ACTION_SCALED) + aki.ob= OBACT; + else if (curarea->spacetype == SPACE_NLA) + aki.ob= NULL; // FIXME + else + aki.ob= NULL; + + aki.start= G.v2d->cur.xmin - 10; + aki.end= G.v2d->cur.xmax + 10; + + /* only pass pointer for Action Editor (for now) */ + if (curarea->spacetype == SPACE_ACTION) + return &aki; + else + return NULL; +} + void draw_object_channel(gla2DDrawInfo *di, Object *ob, float ypos) { ListBase keys = {0, 0}; ListBase blocks = {0, 0}; + ActKeysInc *aki = init_aki_data(); - ob_to_keylist(ob, &keys, &blocks); + ob_to_keylist(ob, &keys, &blocks, aki); draw_keylist(di, &keys, &blocks, ypos); BLI_freelistN(&keys); @@ -1257,8 +1280,9 @@ void draw_ipo_channel(gla2DDrawInfo *di, Ipo *ipo, float ypos) { ListBase keys = {0, 0}; ListBase blocks = {0, 0}; + ActKeysInc *aki = init_aki_data(); - ipo_to_keylist(ipo, &keys, &blocks); + ipo_to_keylist(ipo, &keys, &blocks, aki); draw_keylist(di, &keys, &blocks, ypos); BLI_freelistN(&keys); @@ -1269,8 +1293,9 @@ void draw_icu_channel(gla2DDrawInfo *di, IpoCurve *icu, float ypos) { ListBase keys = {0, 0}; ListBase blocks = {0, 0}; + ActKeysInc *aki = init_aki_data(); - icu_to_keylist(icu, &keys, &blocks); + icu_to_keylist(icu, &keys, &blocks, aki); draw_keylist(di, &keys, &blocks, ypos); BLI_freelistN(&keys); @@ -1281,8 +1306,9 @@ void draw_agroup_channel(gla2DDrawInfo *di, bActionGroup *agrp, float ypos) { ListBase keys = {0, 0}; ListBase blocks = {0, 0}; + ActKeysInc *aki = init_aki_data(); - agroup_to_keylist(agrp, &keys, &blocks); + agroup_to_keylist(agrp, &keys, &blocks, aki); draw_keylist(di, &keys, &blocks, ypos); BLI_freelistN(&keys); BLI_freelistN(&blocks); @@ -1291,27 +1317,28 @@ void draw_agroup_channel(gla2DDrawInfo *di, bActionGroup *agrp, float ypos) void draw_action_channel(gla2DDrawInfo *di, bAction *act, float ypos) { ListBase keys = {0, 0}; + ActKeysInc *aki = init_aki_data(); - action_to_keylist(act, &keys, NULL); + action_to_keylist(act, &keys, NULL, aki); draw_keylist(di, &keys, NULL, ypos); BLI_freelistN(&keys); } /* --------------- Conversion: data -> keyframe list ------------------ */ -void ob_to_keylist(Object *ob, ListBase *keys, ListBase *blocks) +void ob_to_keylist(Object *ob, ListBase *keys, ListBase *blocks, ActKeysInc *aki) { bConstraintChannel *conchan; if (ob) { /* Add object keyframes */ if (ob->ipo) - ipo_to_keylist(ob->ipo, keys, blocks); + ipo_to_keylist(ob->ipo, keys, blocks, aki); /* Add constraint keyframes */ - for (conchan=ob->constraintChannels.first; conchan; conchan=conchan->next){ + for (conchan=ob->constraintChannels.first; conchan; conchan=conchan->next) { if(conchan->ipo) - ipo_to_keylist(conchan->ipo, keys, blocks); + ipo_to_keylist(conchan->ipo, keys, blocks, aki); } /* Add object data keyframes */ @@ -1319,7 +1346,24 @@ void ob_to_keylist(Object *ob, ListBase *keys, ListBase *blocks) } } -void icu_to_keylist(IpoCurve *icu, ListBase *keys, ListBase *blocks) +static short bezt_in_aki_range (ActKeysInc *aki, BezTriple *bezt) +{ + /* when aki == NULL, we don't care about range */ + if (aki == NULL) + return 1; + + /* if nla-scaling is in effect, apply appropriate scaling adjustments */ + if (aki->ob) { + float frame= get_action_frame_inv(aki->ob, bezt->vec[1][0]); + return IN_RANGE(frame, aki->start, aki->end); + } + else { + /* check if in range */ + return IN_RANGE(bezt->vec[1][0], aki->start, aki->end); + } +} + +void icu_to_keylist(IpoCurve *icu, ListBase *keys, ListBase *blocks, ActKeysInc *aki) { BezTriple *bezt; ActKeyColumn *ak; @@ -1331,8 +1375,11 @@ void icu_to_keylist(IpoCurve *icu, ListBase *keys, ListBase *blocks) bezt= icu->bezt; for (v=0; v<icu->totvert; v++, bezt++) { - add_bezt_to_keycolumnslist(keys, bezt); - if (blocks) add_bezt_to_keyblockslist(blocks, icu, v); + /* only if keyframe is in range (optimisation) */ + if (bezt_in_aki_range(aki, bezt)) { + add_bezt_to_keycolumnslist(keys, bezt); + if (blocks) add_bezt_to_keyblockslist(blocks, icu, v); + } } /* update the number of curves that elements have appeared in */ @@ -1355,17 +1402,17 @@ void icu_to_keylist(IpoCurve *icu, ListBase *keys, ListBase *blocks) } } -void ipo_to_keylist(Ipo *ipo, ListBase *keys, ListBase *blocks) +void ipo_to_keylist(Ipo *ipo, ListBase *keys, ListBase *blocks, ActKeysInc *aki) { IpoCurve *icu; if (ipo) { for (icu= ipo->curve.first; icu; icu= icu->next) - icu_to_keylist(icu, keys, blocks); + icu_to_keylist(icu, keys, blocks, aki); } } -void agroup_to_keylist(bActionGroup *agrp, ListBase *keys, ListBase *blocks) +void agroup_to_keylist(bActionGroup *agrp, ListBase *keys, ListBase *blocks, ActKeysInc *aki) { bActionChannel *achan; bConstraintChannel *conchan; @@ -1375,18 +1422,18 @@ void agroup_to_keylist(bActionGroup *agrp, ListBase *keys, ListBase *blocks) for (achan= agrp->channels.first; achan && achan!=agrp->channels.last; achan= achan->next) { /* firstly, add keys from action channel's ipo block */ if (achan->ipo) - ipo_to_keylist(achan->ipo, keys, blocks); + ipo_to_keylist(achan->ipo, keys, blocks, aki); /* then, add keys from constraint channels */ for (conchan= achan->constraintChannels.first; conchan; conchan= conchan->next) { if (conchan->ipo) - ipo_to_keylist(conchan->ipo, keys, blocks); + ipo_to_keylist(conchan->ipo, keys, blocks, aki); } } } } -void action_to_keylist(bAction *act, ListBase *keys, ListBase *blocks) +void action_to_keylist(bAction *act, ListBase *keys, ListBase *blocks, ActKeysInc *aki) { bActionChannel *achan; bConstraintChannel *conchan; @@ -1396,12 +1443,12 @@ void action_to_keylist(bAction *act, ListBase *keys, ListBase *blocks) for (achan= act->chanbase.first; achan; achan= achan->next) { /* firstly, add keys from action channel's ipo block */ if (achan->ipo) - ipo_to_keylist(achan->ipo, keys, blocks); + ipo_to_keylist(achan->ipo, keys, blocks, aki); /* then, add keys from constraint channels */ for (conchan= achan->constraintChannels.first; conchan; conchan= conchan->next) { if (conchan->ipo) - ipo_to_keylist(conchan->ipo, keys, blocks); + ipo_to_keylist(conchan->ipo, keys, blocks, aki); } } } diff --git a/source/blender/src/drawarmature.c b/source/blender/src/drawarmature.c index abe22a1804d..f7bbfffe153 100644 --- a/source/blender/src/drawarmature.c +++ b/source/blender/src/drawarmature.c @@ -276,7 +276,7 @@ static short set_pchan_glColor (short colCode, int armflag, int boneflag, int co case PCHAN_COLOR_LINEBONE: { /* inner part in background color or constraint */ - if ((bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS)) { + if ( (constflag) && ((bcolor==NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS)) ) { if (constflag & PCHAN_HAS_STRIDE) glColor3ub(0, 0, 200); else if (constflag & PCHAN_HAS_TARGET) glColor3ub(255, 150, 0); else if (constflag & PCHAN_HAS_IK) glColor3ub(255, 255, 0); @@ -2111,7 +2111,7 @@ static void draw_pose_paths(Object *ob) if (act) { achan= get_action_channel(act, pchan->name); if (achan) - ipo_to_keylist(achan->ipo, &keys, NULL); + ipo_to_keylist(achan->ipo, &keys, NULL, NULL); } /* Draw slightly-larger yellow dots at each keyframe */ @@ -2257,17 +2257,18 @@ static void draw_ghost_poses_keys(Base *base) bArmature *arm= ob->data; bPose *posen, *poseo; ListBase keys= {NULL, NULL}; + ActKeysInc aki = {0, 0, 0}; ActKeyColumn *ak, *akn; float start, end, range, colfac, i; int cfrao, flago, ipoflago; - start = arm->ghostsf; - end = arm->ghostef; + aki.start= start = arm->ghostsf; + aki.end= end = arm->ghostef; if (end <= start) return; /* get keyframes - then clip to only within range */ - action_to_keylist(act, &keys, NULL); + action_to_keylist(act, &keys, NULL, &aki); range= 0; for (ak= keys.first; ak; ak= akn) { akn= ak->next; diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index 6696fd3cfe3..349432d87a1 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -3814,7 +3814,9 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys) glDisable(GL_LIGHTING); glDisableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); +#if 0 /* If this is needed, it cant be enabled in wire mode, since it messes up the view - Campbell */ glEnable(GL_DEPTH_TEST); +#endif if(states) MEM_freeN(states); diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index c7955fda2fc..344fda5eef9 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -2295,7 +2295,12 @@ static void view3d_panel_transform_spaces(short cntrl) for (index = V3D_MANIP_CUSTOM, ts = transform_spaces->first ; ts ; ts = ts->next, index++) { BIF_ThemeColor(TH_BUT_ACTION); - but = uiDefIconButS(block,ROW, REDRAWHEADERS, ICON_RIGHTARROW_THIN, xco,yco,XIC,YIC, &G.vd->twmode, 5.0, (float)index, 0, 0, "Use this Custom Transform Orientation"); + if (G.vd->twmode == index) { + but = uiDefIconButS(block,ROW, REDRAWHEADERS, ICON_CHECKBOX_HLT, xco,yco,XIC,YIC, &G.vd->twmode, 5.0, (float)index, 0, 0, "Use this Custom Transform Orientation"); + } + else { + but = uiDefIconButS(block,ROW, REDRAWHEADERS, ICON_CHECKBOX_DEHLT, xco,yco,XIC,YIC, &G.vd->twmode, 5.0, (float)index, 0, 0, "Use this Custom Transform Orientation"); + } uiButSetFunc(but, selectTransformOrientation_func, ts, NULL); uiDefBut(block, TEX, 0, "", xco+=XIC, yco,100+XIC,20, &ts->name, 0, 30, 0, 0, "Edits the name of this Transform Orientation"); but = uiDefIconBut(block, BUT, REDRAWVIEW3D, ICON_X, xco+=100+XIC,yco,XIC,YIC, 0, 0, 0, 0, 0, "Deletes this Transform Orientation"); diff --git a/source/blender/src/edit.c b/source/blender/src/edit.c index 138f0a438fd..11837cc3433 100644 --- a/source/blender/src/edit.c +++ b/source/blender/src/edit.c @@ -1518,6 +1518,58 @@ void snap_curs_to_sel() allqueue(REDRAWVIEW3D, 0); } +void snap_curs_to_active() +{ + float *curs; + curs = give_cursor(); + + if (G.obedit) + { + if (G.obedit->type == OB_MESH) + { + /* check active */ + if (G.editMesh->selected.last) { + EditSelection *ese = G.editMesh->selected.last; + if ( ese->type == EDITVERT ) { + EditVert *eve = (EditVert *)ese->data; + VECCOPY(curs, eve->co); + } + else if ( ese->type == EDITEDGE ) { + EditEdge *eed = (EditEdge *)ese->data; + VecAddf(curs, eed->v1->co, eed->v2->co); + VecMulf(curs, 0.5f); + } + else if ( ese->type == EDITFACE ) { + EditFace *efa = (EditFace *)ese->data; + + if (efa->v4) + { + VecAddf(curs, efa->v1->co, efa->v2->co); + VecAddf(curs, curs, efa->v3->co); + VecAddf(curs, curs, efa->v4->co); + VecMulf(curs, 0.25f); + } + else + { + VecAddf(curs, efa->v1->co, efa->v2->co); + VecAddf(curs, curs, efa->v3->co); + VecMulf(curs, 1/3.0f); + } + } + } + Mat4MulVecfl(G.obedit->obmat, curs); + } + } + else + { + if (BASACT) + { + VECCOPY(curs, BASACT->object->obmat[3]); + } + } + allqueue(REDRAWVIEW3D, 0); +} + void snap_curs_to_firstsel() { TransVert *tv; @@ -1776,7 +1828,7 @@ void snapmenu() { short event; - event = pupmenu("Snap %t|Selection -> Grid%x1|Selection -> Cursor%x2|Cursor-> Grid%x3|Cursor-> Selection%x4|Selection-> Center%x5"); + event = pupmenu("Snap %t|Selection -> Grid%x1|Selection -> Cursor%x2|Cursor-> Grid%x3|Cursor-> Selection%x4|Selection-> Center%x5|Cursor-> Active%x6"); switch (event) { case 1: /*Selection to grid*/ @@ -1797,6 +1849,10 @@ void snapmenu() snap_to_center(); BIF_undo_push("Snap selection to center"); break; + case 6: /*Cursor to Active*/ + snap_curs_to_active(); + BIF_undo_push("Snap selection to center"); + break; } } diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c index 1c091ed39d9..94019cb02aa 100644 --- a/source/blender/src/editaction.c +++ b/source/blender/src/editaction.c @@ -682,20 +682,20 @@ static void *get_nearest_action_key (float *selx, short *sel, short *ret_type, b case ALE_IPO: { Ipo *ipo= (Ipo *)ale->key_data; - ipo_to_keylist(ipo, &act_keys, NULL); + ipo_to_keylist(ipo, &act_keys, NULL, NULL); } break; case ALE_ICU: { IpoCurve *icu= (IpoCurve *)ale->key_data; - icu_to_keylist(icu, &act_keys, NULL); + icu_to_keylist(icu, &act_keys, NULL, NULL); } break; } } else if (ale->type == ACTTYPE_GROUP) { bActionGroup *agrp= (bActionGroup *)ale->data; - agroup_to_keylist(agrp, &act_keys, NULL); + agroup_to_keylist(agrp, &act_keys, NULL, NULL); } /* loop through keyframes, finding one that was clicked on */ @@ -1130,7 +1130,7 @@ void transform_action_keys (int mode, int dummy) } break; } -} +} /* ----------------------------------------- */ diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c index 45711bc1cfa..763d9744064 100644 --- a/source/blender/src/editarmature.c +++ b/source/blender/src/editarmature.c @@ -3603,13 +3603,37 @@ void armature_flip_names(void) allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSEDIT, 0); allqueue(REDRAWBUTSOBJECT, 0); - allqueue (REDRAWACTION, 0); + allqueue(REDRAWACTION, 0); allqueue(REDRAWOOPS, 0); BIF_undo_push("Flip names"); +} + +/* context: edtimode armature */ +void armature_autoside_names(short axis) +{ + bArmature *arm= G.obedit->data; + EditBone *ebone; + char newname[32]; + for (ebone = G.edbo.first; ebone; ebone=ebone->next) { + if (arm->layer & ebone->layer) { + if (ebone->flag & BONE_SELECTED) { + BLI_strncpy(newname, ebone->name, sizeof(newname)); + bone_autoside_name(newname, 1, axis, ebone->head[axis], ebone->tail[axis]); + armature_bone_rename(G.obedit->data, ebone->name, newname); + } + } + } + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWBUTSOBJECT, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWOOPS, 0); + BIF_undo_push("Auto-side name"); } -/* context; editmode armature */ +/* context: editmode armature */ EditBone *armature_bone_get_mirrored(EditBone *ebo) { EditBone *eboflip= NULL; diff --git a/source/blender/src/editdeform.c b/source/blender/src/editdeform.c index b4206a510aa..6ab3d5c17c6 100644 --- a/source/blender/src/editdeform.c +++ b/source/blender/src/editdeform.c @@ -779,7 +779,7 @@ void remove_verts_defgroup (int allverts) case OB_MESH: for (eve=G.editMesh->verts.first; eve; eve=eve->next){ dvert= CustomData_em_get(&G.editMesh->vdata, eve->data, CD_MDEFORMVERT); - + if (dvert && dvert->dw && ((eve->f & 1) || allverts)){ for (i=0; i<dvert->totweight; i++){ /* Find group */ @@ -825,6 +825,36 @@ void remove_verts_defgroup (int allverts) } } +/* Only available in editmode */ +/* removes from all defgroup, if allverts==0 only selected vertices */ +void remove_verts_defgroups(int allverts) +{ + Object *ob; + int actdef, defCount; + + if (multires_level1_test()) return; + + ob= G.obedit; + if (ob == NULL) return; + + actdef= ob->actdef; + defCount= BLI_countlist(&ob->defbase); + + if (defCount == 0) { + error("Object has no vertex groups"); + return; + } + + /* To prevent code redundancy, we just use remove_verts_defgroup, but that + * only operates on the active vgroup. So we iterate through all groups, by changing + * active group index + */ + for (ob->actdef= 1; ob->actdef <= defCount; ob->actdef++) + remove_verts_defgroup(allverts); + + ob->actdef= actdef; +} + void vertexgroup_select_by_name(Object *ob, char *name) { bDeformGroup *curdef; @@ -859,7 +889,7 @@ void vgroup_assign_with_menu(void) /* give user choices of adding to current/new or removing from current */ if (defCount && ob->actdef) - mode = pupmenu("Vertex Groups %t|Add Selected to New Group %x1|Add Selected to Active Group %x2|Remove Selected from Active Group %x3"); + mode = pupmenu("Vertex Groups %t|Add Selected to New Group %x1|Add Selected to Active Group %x2|Remove Selected from Active Group %x3|Remove Selected from All Groups %x4"); else mode= pupmenu("Vertex Groups %t|Add Selected to New Group %x1"); @@ -881,6 +911,11 @@ void vgroup_assign_with_menu(void) allqueue(REDRAWVIEW3D, 1); BIF_undo_push("Remove from vertex group"); break; + case 4: /* remove from all groups */ + remove_verts_defgroups(0); + allqueue(REDRAWVIEW3D, 1); + BIF_undo_push("Remove from all vertex groups"); + break; } } diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c index b3ea3e1931c..fce7fab779d 100644 --- a/source/blender/src/editipo.c +++ b/source/blender/src/editipo.c @@ -2624,10 +2624,10 @@ void insertkey_smarter(ID *id, int blocktype, char *actname, char *constname, in /* delete keyframe immediately before/after newly added */ switch (insert_mode) { case KEYNEEDED_DELPREV: - delete_icu_key(icu, icu->totvert-2); + delete_icu_key(icu, icu->totvert-2, 1); break; case KEYNEEDED_DELNEXT: - delete_icu_key(icu, 1); + delete_icu_key(icu, 1, 1); break; } } @@ -5642,22 +5642,25 @@ void remake_object_ipos(Object *ob) /* Only delete the nominated keyframe from provided ipo-curve. * Not recommended to be used many times successively. For that - * there is delete_ipo_keys(). */ -void delete_icu_key(IpoCurve *icu, int index) + * there is delete_ipo_keys(). + */ +void delete_icu_key(IpoCurve *icu, int index, short do_recalc) { /* firstly check that index is valid */ if (index < 0) index *= -1; + if (icu == NULL) + return; if (index >= icu->totvert) return; - if (!icu) return; /* Delete this key */ - memcpy (&icu->bezt[index], &icu->bezt[index+1], sizeof (BezTriple)*(icu->totvert-index-1)); + memcpy(&icu->bezt[index], &icu->bezt[index+1], sizeof(BezTriple)*(icu->totvert-index-1)); icu->totvert--; - /* recalc handles */ - calchandles_ipocurve(icu); + /* recalc handles - only if it won't cause problems */ + if (do_recalc) + calchandles_ipocurve(icu); } void delete_ipo_keys(Ipo *ipo) diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index a7b8400fb9d..269c1db4649 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -2554,7 +2554,7 @@ void special_editmenu(void) DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); } else if(G.obedit->type==OB_ARMATURE) { - nr= pupmenu("Specials%t|Subdivide %x1|Subdivide Multi%x2|Flip Left-Right Names%x3"); + nr= pupmenu("Specials%t|Subdivide %x1|Subdivide Multi%x2|Flip Left-Right Names%x3|%l|AutoName Left-Right%x4|AutoName Front-Back%x5|AutoName Top-Bottom%x6"); if(nr==1) subdivide_armature(1); if(nr==2) { @@ -2564,6 +2564,9 @@ void special_editmenu(void) } else if(nr==3) armature_flip_names(); + else if(ELEM3(nr, 4, 5, 6)) { + armature_autoside_names(nr-4); + } } else if(G.obedit->type==OB_LATTICE) { static float weight= 1.0f; diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c index a3bdbd0f7ab..e5e5a960f0c 100644 --- a/source/blender/src/editseq.c +++ b/source/blender/src/editseq.c @@ -1458,6 +1458,50 @@ static void add_sound_strip_hd(char *name) transform_seq_nomarker('g', 0); } +static void add_scene_strip(short event) +{ + Sequence *seq; + Strip *strip; + float x, y; + int cfra, machine; + short mval[2]; + + if(event> -1) { + int nr= 1; + Scene * sce= G.main->scene.first; + while(sce) { + if( event==nr) break; + nr++; + sce= sce->id.next; + } + if(sce) { + + deselect_all_seq(); + + /* where ? */ + getmouseco_areawin(mval); + areamouseco_to_ipoco(G.v2d, mval, &x, &y); + cfra= (int)(x+0.5); + machine= (int)(y+0.5); + + seq= alloc_sequence(((Editing *)G.scene->ed)->seqbasep, cfra, machine); + seq->type= SEQ_SCENE; + seq->scene= sce; + seq->sfra= sce->r.sfra; + seq->len= sce->r.efra - sce->r.sfra + 1; + + seq->strip= strip= MEM_callocN(sizeof(Strip), "strip"); + strncpy(seq->name + 2, sce->id.name + 2, + sizeof(seq->name) - 2); + strip->len= seq->len; + strip->us= 1; + + BIF_undo_push("Add Scene Strip, Sequencer"); + transform_seq_nomarker('g', 0); + } + } +} + #if 0 static void reload_sound_strip(char *name) { @@ -1713,12 +1757,7 @@ static void load_plugin_seq(char *str) /* called from fileselect */ void add_sequence(int type) { Editing *ed; - Sequence *seq; - Strip *strip; - Scene *sce; - float x, y; - int cfra, machine; - short nr, event, mval[2]; + short event; char *str; if (type >= 0){ @@ -1844,43 +1883,8 @@ void add_sequence(int type) /* new menu: */ IDnames_to_pupstring(&str, NULL, NULL, &G.main->scene, (ID *)G.scene, NULL); - event= pupmenu_col(str, 20); + add_scene_strip(pupmenu_col(str, 20)); - if(event> -1) { - nr= 1; - sce= G.main->scene.first; - while(sce) { - if( event==nr) break; - nr++; - sce= sce->id.next; - } - if(sce) { - - deselect_all_seq(); - - /* where ? */ - getmouseco_areawin(mval); - areamouseco_to_ipoco(G.v2d, mval, &x, &y); - cfra= (int)(x+0.5); - machine= (int)(y+0.5); - - seq= alloc_sequence(((Editing *)G.scene->ed)->seqbasep, cfra, machine); - seq->type= SEQ_SCENE; - seq->scene= sce; - seq->sfra= sce->r.sfra; - seq->len= sce->r.efra - sce->r.sfra + 1; - - seq->strip= strip= MEM_callocN(sizeof(Strip), "strip"); - strncpy(seq->name + 2, sce->id.name + 2, - sizeof(seq->name) - 2); - strip->len= seq->len; - strip->us= 1; - if(seq->len>0) strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem"); - - BIF_undo_push("Add Scene Strip, Sequencer"); - transform_seq_nomarker('g', 0); - } - } MEM_freeN(str); break; @@ -2161,81 +2165,60 @@ void del_seq(void) allqueue(REDRAWSEQ, 0); } -static Sequence *dupli_seq(Sequence *seq) { - Sequence *seqn = NULL; +static Sequence *dupli_seq(Sequence *seq) +{ + Sequence *seqn = MEM_dupallocN(seq); + + seq->tmp = seqn; + + seqn->strip= MEM_dupallocN(seq->strip); + + if(seqn->ipo) seqn->ipo->id.us++; + + seqn->strip->tstripdata = 0; + seqn->strip->tstripdata_startstill = 0; + seqn->strip->tstripdata_endstill = 0; + + if (seq->strip->crop) { + seqn->strip->crop = MEM_dupallocN(seq->strip->crop); + } + + if (seq->strip->transform) { + seqn->strip->transform = MEM_dupallocN(seq->strip->transform); + } + + if (seq->strip->proxy) { + seqn->strip->proxy = MEM_dupallocN(seq->strip->proxy); + } if(seq->type==SEQ_META) { - seqn= MEM_dupallocN(seq); - seq->tmp= seqn; - - seqn->strip= MEM_dupallocN(seq->strip); seqn->strip->stripdata = 0; - seqn->strip->tstripdata = 0; seqn->seqbase.first= seqn->seqbase.last= 0; /* WATCH OUT!!! - This metastrip is not recursively duplicated here - do this after!!! */ /* - recurs_dupli_seq(&seq->seqbase,&seqn->seqbase);*/ - } - else if(seq->type == SEQ_SCENE) { - seqn= MEM_dupallocN(seq); - seq->tmp= seqn; - - seqn->strip= MEM_dupallocN(seq->strip); + } else if(seq->type == SEQ_SCENE) { seqn->strip->stripdata = 0; - seqn->strip->tstripdata = 0; - } - else if(seq->type == SEQ_MOVIE) { - seqn= MEM_dupallocN(seq); - seq->tmp= seqn; - - seqn->strip= MEM_dupallocN(seq->strip); + } else if(seq->type == SEQ_MOVIE) { seqn->strip->stripdata = MEM_dupallocN(seq->strip->stripdata); - seqn->strip->tstripdata = 0; seqn->anim= 0; - } - else if(seq->type == SEQ_RAM_SOUND) { - seqn= MEM_dupallocN(seq); - seq->tmp= seqn; - - seqn->strip= MEM_dupallocN(seq->strip); + } else if(seq->type == SEQ_RAM_SOUND) { seqn->strip->stripdata = MEM_dupallocN(seq->strip->stripdata); - seqn->strip->tstripdata = 0; - - seqn->anim= 0; seqn->sound->id.us++; - if(seqn->ipo) seqn->ipo->id.us++; - } - else if(seq->type == SEQ_HD_SOUND) { - seqn= MEM_dupallocN(seq); - seq->tmp= seqn; - - seqn->strip= MEM_dupallocN(seq->strip); + } else if(seq->type == SEQ_HD_SOUND) { seqn->strip->stripdata = MEM_dupallocN(seq->strip->stripdata); - seqn->strip->tstripdata = 0; - seqn->anim= 0; seqn->hdaudio = 0; - if(seqn->ipo) seqn->ipo->id.us++; } else if(seq->type == SEQ_IMAGE) { - seqn= MEM_dupallocN(seq); - seq->tmp= seqn; - - seqn->strip= MEM_dupallocN(seq->strip); seqn->strip->stripdata = MEM_dupallocN(seq->strip->stripdata); - seqn->strip->tstripdata = 0; } else if(seq->type >= SEQ_EFFECT) { - seqn= MEM_dupallocN(seq); - seq->tmp= seqn; - if(seq->seq1 && seq->seq1->tmp) seqn->seq1= seq->seq1->tmp; if(seq->seq2 && seq->seq2->tmp) seqn->seq2= seq->seq2->tmp; if(seq->seq3 && seq->seq3->tmp) seqn->seq3= seq->seq3->tmp; - if(seqn->ipo) seqn->ipo->id.us++; - if (seq->type & SEQ_EFFECT) { struct SeqEffectHandle sh; sh = get_sequence_effect(seq); @@ -2243,27 +2226,13 @@ static Sequence *dupli_seq(Sequence *seq) { sh.copy(seq, seqn); } - seqn->strip= MEM_dupallocN(seq->strip); seqn->strip->stripdata = 0; - seqn->strip->tstripdata = 0; } else { fprintf(stderr, "Aiiiiekkk! sequence type not " "handled in duplicate!\nExpect a crash" " now...\n"); } - - if (seq->strip->crop) { - seqn->strip->crop = MEM_dupallocN(seq->strip->crop); - } - - if (seq->strip->transform) { - seqn->strip->transform = MEM_dupallocN(seq->strip->transform); - } - - if (seq->strip->proxy) { - seqn->strip->proxy = MEM_dupallocN(seq->strip->proxy); - } return seqn; } diff --git a/source/blender/src/editsima.c b/source/blender/src/editsima.c index 0c29bceba37..73ff70436f3 100644 --- a/source/blender/src/editsima.c +++ b/source/blender/src/editsima.c @@ -240,17 +240,12 @@ void transform_width_height_tface_uv(int *width, int *height) } } -void mirror_tface_uv(char mirroraxis) -{ - if (mirroraxis == 'x') - Mirror(1); /* global x */ - else if (mirroraxis == 'y') - Mirror(2); /* global y */ -} - void mirrormenu_tface_uv(void) { + float mat[3][3]; short mode= 0; + + Mat3One(mat); if( is_uv_tface_editing_allowed()==0 ) return; @@ -258,8 +253,16 @@ void mirrormenu_tface_uv(void) if(mode==-1) return; - if(mode==1) mirror_tface_uv('x'); - else if(mode==2) mirror_tface_uv('y'); + if (mode == 1) { + initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM); + BIF_setSingleAxisConstraint(mat[0], " on X axis"); + Transform(); + } + else { + initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM); + BIF_setSingleAxisConstraint(mat[1], " on Y axis"); + Transform(); + } BIF_undo_push("Mirror UV"); } diff --git a/source/blender/src/header_action.c b/source/blender/src/header_action.c index f9a3fb08bd8..c48e646af4c 100644 --- a/source/blender/src/header_action.c +++ b/source/blender/src/header_action.c @@ -98,7 +98,8 @@ enum { ACTMENU_VIEW_NOHIDE, ACTMENU_VIEW_OPENLEVELS, ACTMENU_VIEW_CLOSELEVELS, - ACTMENU_VIEW_EXPANDALL + ACTMENU_VIEW_EXPANDALL, + ACTMENU_VIEW_TRANSDELDUPS }; enum { @@ -333,6 +334,9 @@ static void do_action_viewmenu(void *arg, int event) case ACTMENU_VIEW_EXPANDALL: /* Expands all channels */ expand_all_action(); break; + case ACTMENU_VIEW_TRANSDELDUPS: /* Don't delete duplicate/overlapping keyframes after transform */ + G.saction->flag ^= SACTION_NOTRANSKEYCULL; + break; } allqueue(REDRAWVIEW3D, 0); } @@ -378,7 +382,14 @@ static uiBlock *action_viewmenu(void *arg_unused) "Show Hidden Channels|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_VIEW_NOHIDE, ""); - + + // this option may get removed in future... + uiDefIconTextBut(block, BUTM, 1, (G.saction->flag & SACTION_NOTRANSKEYCULL)?ICON_CHECKBOX_DEHLT:ICON_CHECKBOX_HLT, + "AfterTrans Delete Dupli-Frames|", 0, yco-=20, + menuwidth, 19, NULL, 0.0, 0.0, 1, + ACTMENU_VIEW_TRANSDELDUPS, ""); + + uiDefIconTextBut(block, BUTM, 1, (G.v2d->flag & V2D_VIEWLOCK)?ICON_CHECKBOX_HLT:ICON_CHECKBOX_DEHLT, "Lock Time to Other Windows|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, diff --git a/source/blender/src/header_image.c b/source/blender/src/header_image.c index 5b8c33309a0..1ec54423ab6 100644 --- a/source/blender/src/header_image.c +++ b/source/blender/src/header_image.c @@ -52,6 +52,7 @@ #include "DNA_userdef_types.h" #include "DNA_customdata_types.h" /* for UV layer menu */ +#include "BLI_arithb.h" #include "BLI_blenlib.h" #include "BDR_drawmesh.h" @@ -870,12 +871,20 @@ static uiBlock *image_uvs_transformmenu(void *arg_unused) static void do_image_uvs_mirrormenu(void *arg, int event) { + float mat[3][3]; + + Mat3One(mat); + switch(event) { case 0: /* X axis */ - mirror_tface_uv('x'); + initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM); + BIF_setSingleAxisConstraint(mat[0], " on global X axis"); + Transform(); break; case 1: /* Y axis */ - mirror_tface_uv('y'); + initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM); + BIF_setSingleAxisConstraint(mat[1], " on global Y axis"); + Transform(); break; } diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c index 4cbad8a9758..4b95cc9e42a 100644 --- a/source/blender/src/header_view3d.c +++ b/source/blender/src/header_view3d.c @@ -3789,7 +3789,6 @@ static void do_view3d_edit_armaturemenu(void *arg, int event) static short numcuts= 2; switch(event) { - case 0: /* Undo Editing */ remake_editArmature(); break; @@ -3836,6 +3835,11 @@ static void do_view3d_edit_armaturemenu(void *arg, int event) case 18: /* merge bones */ merge_armature(); break; + case 19: /* auto-extensions */ + case 20: + case 21: + armature_autoside_names(event-19); + break; } allqueue(REDRAWVIEW3D, 0); @@ -3915,6 +3919,9 @@ static uiBlock *view3d_edit_armaturemenu(void *arg_unused) uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Subdivide|W, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Subdivide Multi|W, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Flip Left & Right Names|W, 3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "AutoName Left-Right|W, 4", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 19, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "AutoName Front-Back|W, 5", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 20, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "AutoName Top-Bottom|W, 6", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 21, ""); uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); @@ -4201,7 +4208,6 @@ static void do_view3d_pose_armaturemenu(void *arg, int event) ob=OBACT; switch(event) { - case 0: /* transform properties */ mainqenter(NKEY, 1); break; @@ -4239,6 +4245,11 @@ static void do_view3d_pose_armaturemenu(void *arg, int event) case 15: pose_relax(); break; + case 16: /* auto-extensions for bones */ + case 17: + case 18: + pose_autoside_names(event-16); + break; } allqueue(REDRAWVIEW3D, 0); @@ -4282,6 +4293,10 @@ static uiBlock *view3d_pose_armaturemenu(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, "AutoName Left-Right|W", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 16, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "AutoName Front-Back|W", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "AutoName Top-Bottom|W", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Flip L/R Names|W", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Copy Attributes...|Ctrl C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, ""); diff --git a/source/blender/src/poselib.c b/source/blender/src/poselib.c index 44277e17804..351ba93fa59 100644 --- a/source/blender/src/poselib.c +++ b/source/blender/src/poselib.c @@ -218,7 +218,7 @@ void poselib_validate_act (bAction *act) } /* determine which frames have keys */ - action_to_keylist(act, &keys, NULL); + action_to_keylist(act, &keys, NULL, NULL); /* for each key, make sure there is a correspnding pose */ for (ak= keys.first; ak; ak= ak->next) { @@ -455,7 +455,7 @@ void poselib_remove_pose (Object *ob, TimeMarker *marker) for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) { /* check if remove... */ if (IS_EQ(bezt->vec[1][0], marker->frame)) { - delete_icu_key(icu, i); + delete_icu_key(icu, i, 1); break; } } @@ -534,7 +534,7 @@ typedef struct tPoseLib_PreviewData { short state; /* state of main loop */ short redraw; /* redraw/update settings during main loop */ - short firsttime; /* first loop... (no restore) */ + short flag; /* flags for various settings */ int selcount; /* number of selected elements to work on */ int totcount; /* total number of elements to work on */ @@ -562,6 +562,12 @@ enum { PL_PREVIEW_REDRAWHEADER, }; +/* defines for tPoseLib_PreviewData->flag values */ +enum { + PL_PREVIEW_FIRSTTIME = (1<<0), + PL_PREVIEW_SHOWORIGINAL = (1<<1) +}; + /* ---------------------------- */ /* simple struct for storing backup info */ @@ -890,6 +896,49 @@ static void poselib_preview_handle_event (tPoseLib_PreviewData *pld, unsigned sh */ strcpy(pld->searchold, pld->searchstr); + /* if we're currently showing the original pose, only certain events are handled */ + if (pld->flag & PL_PREVIEW_SHOWORIGINAL) { + switch (event) { + /* exit - cancel */ + case ESCKEY: + case RIGHTMOUSE: + pld->state= PL_PREVIEW_CANCEL; + break; + + /* exit - confirm */ + case LEFTMOUSE: + case RETKEY: + case PADENTER: + case SPACEKEY: + pld->state= PL_PREVIEW_CONFIRM; + break; + + /* view manipulation */ + case MIDDLEMOUSE: + // there's a little bug here that causes the normal header to get drawn while view is manipulated + handle_view_middlemouse(); + pld->redraw= PL_PREVIEW_REDRAWHEADER; + break; + + /* view manipulation, or searching */ + case PAD0: case PAD1: case PAD2: case PAD3: case PAD4: + case PAD5: case PAD6: case PAD7: case PAD8: case PAD9: + case PADPLUSKEY: case PADMINUS: + persptoetsen(event); + pld->redraw= PL_PREVIEW_REDRAWHEADER; + break; + + case TABKEY: + pld->flag &= ~PL_PREVIEW_SHOWORIGINAL; + pld->redraw= PL_PREVIEW_REDRAWALL; + break; + } + + /* EXITS HERE... */ + return; + } + + /* NORMAL EVENT HANDLING... */ /* searching takes priority over normal activity */ switch (event) { /* exit - cancel */ @@ -905,6 +954,12 @@ static void poselib_preview_handle_event (tPoseLib_PreviewData *pld, unsigned sh case SPACEKEY: pld->state= PL_PREVIEW_CONFIRM; break; + + /* toggle between original pose and poselib pose*/ + case TABKEY: + pld->flag |= PL_PREVIEW_SHOWORIGINAL; + pld->redraw= PL_PREVIEW_REDRAWALL; + break; /* change to previous pose (cyclic) */ case PAGEUPKEY: @@ -1064,7 +1119,7 @@ static void poselib_preview_init_data (tPoseLib_PreviewData *pld, Object *ob, sh /* set flags for running */ pld->state= (apply_active) ? PL_PREVIEW_RUNONCE : PL_PREVIEW_RUNNING; pld->redraw= PL_PREVIEW_REDRAWALL; - pld->firsttime= 1; + pld->flag= PL_PREVIEW_FIRSTTIME; /* set depsgraph flags */ /* make sure the lock is set OK, unlock can be accidentally saved? */ @@ -1177,13 +1232,14 @@ void poselib_preview_poses (Object *ob, short apply_active) /* only recalc pose (and its dependencies) if pose has changed */ if (pld.redraw == PL_PREVIEW_REDRAWALL) { /* don't clear pose if firsttime */ - if (pld.firsttime == 0) + if ((pld.flag & PL_PREVIEW_FIRSTTIME)==0) poselib_backup_restore(&pld); else - pld.firsttime = 0; + pld.flag &= ~PL_PREVIEW_FIRSTTIME; - /* pose should be the right one to draw */ - poselib_apply_pose(&pld); + /* pose should be the right one to draw (unless we're temporarily not showing it) */ + if ((pld.flag & PL_PREVIEW_SHOWORIGINAL)==0) + poselib_apply_pose(&pld); /* old optimize trick... this enforces to bypass the depgraph * - note: code copied from transform_generics.c -> recalcData() @@ -1205,7 +1261,11 @@ void poselib_preview_poses (Object *ob, short apply_active) /* do header print - if interactively previewing */ if (pld.state == PL_PREVIEW_RUNNING) { - if (pld.searchstr[0]) { + if (pld.flag & PL_PREVIEW_SHOWORIGINAL) { + sprintf(pld.headerstr, "PoseLib Previewing Pose: [Showing Original Pose] | Use Tab to start previewing poses again"); + headerprint(pld.headerstr); + } + else if (pld.searchstr[0]) { char tempstr[65]; char markern[64]; short index; diff --git a/source/blender/src/poseobject.c b/source/blender/src/poseobject.c index 42640465e12..e187530d25f 100644 --- a/source/blender/src/poseobject.c +++ b/source/blender/src/poseobject.c @@ -490,7 +490,7 @@ void pose_special_editmenu(void) if(!ob && !ob->pose) return; if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return; - nr= pupmenu("Specials%t|Select Constraint Target%x1|Flip Left-Right Names%x2|Calculate Paths%x3|Clear Paths%x4|Clear User Transform %x5|Relax Pose %x6"); + nr= pupmenu("Specials%t|Select Constraint Target%x1|Flip Left-Right Names%x2|Calculate Paths%x3|Clear Paths%x4|Clear User Transform %x5|Relax Pose %x6|%l|AutoName Left-Right%x7|AutoName Front-Back%x8|AutoName Top-Bottom%x9"); if(nr==1) { pose_select_constraint_target(); } @@ -511,6 +511,9 @@ void pose_special_editmenu(void) else if(nr==6) { pose_relax(); } + else if(ELEM3(nr, 7, 8, 9)) { + pose_autoside_names(nr-7); + } } void pose_add_IK(void) @@ -1154,7 +1157,39 @@ void pose_flip_names(void) allqueue (REDRAWACTION, 0); allqueue(REDRAWOOPS, 0); BIF_undo_push("Flip names"); +} + +/* context active object */ +void pose_autoside_names(short axis) +{ + Object *ob= OBACT; + bArmature *arm= ob->data; + bPoseChannel *pchan; + char newname[32]; + + /* paranoia checks */ + if (ELEM(NULL, ob, ob->pose)) return; + if (ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return; + if (pose_has_protected_selected(ob, 0)) + return; + + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + if(arm->layer & pchan->bone->layer) { + if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) { + BLI_strncpy(newname, pchan->name, sizeof(newname)); + bone_autoside_name(newname, 1, axis, pchan->bone->head[axis], pchan->bone->tail[axis]); + armature_bone_rename(ob->data, pchan->name, newname); + } + } + } + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWBUTSOBJECT, 0); + allqueue (REDRAWACTION, 0); + allqueue(REDRAWOOPS, 0); + BIF_undo_push("Flip names"); } /* context active object, or weightpainted object with armature in posemode */ diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c index fce967973cd..003c2c0e491 100644 --- a/source/blender/src/sequence.c +++ b/source/blender/src/sequence.c @@ -129,6 +129,8 @@ void free_strip(Strip *strip) } free_tstripdata(strip->len, strip->tstripdata); + free_tstripdata(strip->endstill, strip->tstripdata_endstill); + free_tstripdata(strip->startstill, strip->tstripdata_startstill); MEM_freeN(strip); } @@ -136,11 +138,16 @@ void free_strip(Strip *strip) void new_tstripdata(Sequence *seq) { if(seq->strip) { - if (seq->strip->tstripdata) { - free_tstripdata(seq->strip->len, - seq->strip->tstripdata); - } + free_tstripdata(seq->strip->len, seq->strip->tstripdata); + free_tstripdata(seq->strip->endstill, + seq->strip->tstripdata_endstill); + free_tstripdata(seq->strip->startstill, + seq->strip->tstripdata_startstill); + seq->strip->tstripdata= 0; + seq->strip->tstripdata_endstill= 0; + seq->strip->tstripdata_startstill= 0; + seq->strip->len= seq->len; } } @@ -394,8 +401,10 @@ void reload_sequence_new_file(Sequence * seq) return; } - strncpy(str, seq->strip->dir, FILE_MAXDIR-1); - strncat(str, seq->strip->stripdata->name, FILE_MAXFILE-1); + if (seq->type != SEQ_SCENE) { + strncpy(str, seq->strip->dir, FILE_MAXDIR-1); + strncat(str, seq->strip->stripdata->name, FILE_MAXFILE-1); + } if (seq->type == SEQ_MOVIE) { if(seq->anim) IMB_free_anim(seq->anim); @@ -426,6 +435,23 @@ void reload_sequence_new_file(Sequence * seq) seq->strip->len = seq->len = sound_hdaudio_get_duration(seq->hdaudio, FPS); } else if (seq->type == SEQ_SCENE) { + Scene * sce = G.main->scene.first; + int nr = 1; + while(sce) { + if(nr == seq->scenenr) { + break; + } + nr++; + sce= sce->id.next; + } + + if (sce) { + seq->scene = sce; + } + + strncpy(seq->name + 2, sce->id.name + 2, + sizeof(seq->name) - 2); + seq->len= seq->scene->r.efra - seq->scene->r.sfra + 1; seq->len -= seq->anim_startofs; seq->len -= seq->anim_endofs; @@ -765,6 +791,16 @@ static int give_stripelem_index(Sequence *seq, int cfra) return nr; } +static TStripElem* alloc_tstripdata(int len, const char * name) +{ + int i; + TStripElem *se = MEM_callocN(len * sizeof(TStripElem), name); + for (i = 0; i < len; i++) { + se[i].ok = STRIPELEM_OK; + } + return se; +} + TStripElem *give_tstripelem(Sequence *seq, int cfra) { TStripElem *se; @@ -772,21 +808,67 @@ TStripElem *give_tstripelem(Sequence *seq, int cfra) se = seq->strip->tstripdata; if (se == 0 && seq->len > 0) { - int i; - se = seq->strip->tstripdata = MEM_callocN( - seq->len*sizeof(TStripElem), "tstripelems"); - for (i = 0; i < seq->len; i++) { - se[i].ok = STRIPELEM_OK; - } + se = seq->strip->tstripdata = alloc_tstripdata(seq->len, + "tstripelems"); } nr = give_stripelem_index(seq, cfra); if (nr == -1) return 0; if (se == 0) return 0; + + se += nr; + + /* if there are IPOs with blend modes active, one has to watch out + for startstill + endstill area: we can't use the same tstripelem + here for all ibufs, since then, blending with IPOs won't work! + + Rather common case, if you use a single image and try to fade + it in and out... + + Performance TODO: seperate give_tstripelem for ibuf from + give_tstripelem for ibuf_comp, so that caching works here again... + */ + if (seq->ipo && seq->ipo->curve.first && !(seq->type & SEQ_EFFECT)) { + Strip * s = seq->strip; + if (cfra < seq->start) { + se = s->tstripdata_startstill; + if (seq->startstill > s->startstill) { + free_tstripdata(s->startstill, + s->tstripdata_startstill); + se = 0; + } + + if (se == 0) { + s->startstill = seq->startstill; + se = seq->strip->tstripdata_startstill + = alloc_tstripdata( + s->startstill, + "tstripelems_startstill"); + } + se += seq->start - cfra - 1; + + } else if (cfra > seq->start + seq->len-1) { + se = s->tstripdata_endstill; + if (seq->endstill > s->endstill) { + free_tstripdata(s->endstill, + s->tstripdata_endstill); + se = 0; + } + + if (se == 0) { + s->endstill = seq->endstill; + se = seq->strip->tstripdata_endstill + = alloc_tstripdata( + s->endstill, + "tstripelems_endstill"); + } + se += cfra - (seq->start + seq->len-1) - 1; + } + } + - se+= nr; se->nr= nr; - + return se; } @@ -1022,11 +1104,14 @@ static void input_preprocess(Sequence * seq, TStripElem* se, int cfra) mul = seq->mul; - if(seq->blend_mode == SEQ_BLEND_REPLACE - && seq->ipo && seq->ipo->curve.first) { - do_seq_ipo(seq, cfra); - mul *= seq->facf0; + if(seq->blend_mode == SEQ_BLEND_REPLACE) { + if (seq->ipo && seq->ipo->curve.first) { + do_seq_ipo(seq, cfra); + mul *= seq->facf0; + } + mul *= seq->blend_opacity / 100.0; } + if(mul != 1.0) { multibuf(se->ibuf, mul); } @@ -2066,9 +2151,24 @@ void free_imbuf_seq_except(int cfra) if(seq->strip) { TStripElem * curelem = give_tstripelem(seq, cfra); - for(a=0, se= seq->strip->tstripdata; a<seq->len; a++, se++) - if(se != curelem) + for(a = 0, se = seq->strip->tstripdata; + a < seq->strip->len && se; a++, se++) { + if(se != curelem) { free_imbuf_strip_elem(se); + } + } + for(a = 0, se = seq->strip->tstripdata_startstill; + a < seq->strip->startstill && se; a++, se++) { + if(se != curelem) { + free_imbuf_strip_elem(se); + } + } + for(a = 0, se = seq->strip->tstripdata_endstill; + a < seq->strip->endstill && se; a++, se++) { + if(se != curelem) { + free_imbuf_strip_elem(se); + } + } if(seq->type==SEQ_MOVIE) if(seq->startdisp > cfra || seq->enddisp < cfra) @@ -2089,9 +2189,17 @@ void free_imbuf_seq() WHILE_SEQ(&ed->seqbase) { if(seq->strip) { - if (seq->strip->tstripdata) { - for(a=0, se= seq->strip->tstripdata; a<seq->len; a++, se++) - free_imbuf_strip_elem(se); + for(a = 0, se = seq->strip->tstripdata; + a < seq->strip->len && se; a++, se++) { + free_imbuf_strip_elem(se); + } + for(a = 0, se = seq->strip->tstripdata_startstill; + a < seq->strip->startstill && se; a++, se++) { + free_imbuf_strip_elem(se); + } + for(a = 0, se = seq->strip->tstripdata_endstill; + a < seq->strip->endstill && se; a++, se++) { + free_imbuf_strip_elem(se); } if(seq->type==SEQ_MOVIE) diff --git a/source/blender/src/space.c b/source/blender/src/space.c index b1d274d670e..e90c2e99d0a 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -3155,6 +3155,9 @@ static void info_user_theme_colsets_buts(uiBlock *block, short y1, short y2, sho /* Extra 'Options' */ uiDefButBitS(block, TOG, TH_WIRECOLOR_CONSTCOLS, B_UPDATE_THEME, "Use 'Constraint' Colouring", 885,y2,200,20, &col_set->flag, 0, 0, 0, 0, "Allow the use of colors indicating constraints/keyed status"); + + /* 'Debug' Tools */ + // TODO... dump current colours } static void info_user_themebuts(uiBlock *block, short y1, short y2, short y3, short y4) diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c index 1855ad3d147..f9cc7244789 100644 --- a/source/blender/src/transform.c +++ b/source/blender/src/transform.c @@ -193,10 +193,10 @@ int manageObjectSpace(int confirm, int set) { return -1; if (confirm == 0) { - if (set && pupmenu("Custome Space %t|Add and Use Active Object%x1") != 1) { + if (set && pupmenu("Custom Space %t|Add and Use Active Object%x1") != 1) { return -1; } - else if (set == 0 && pupmenu("Custome Space %t|Add Active Object%x1") != 1) { + else if (set == 0 && pupmenu("Custom Space %t|Add Active Object%x1") != 1) { return -1; } } @@ -204,127 +204,328 @@ int manageObjectSpace(int confirm, int set) { return addObjectSpace(base->object); } +/* return 1 on confirm */ +int confirmSpace(int set, char text[]) +{ + char menu[64]; + + if (set) { + sprintf(menu, "Custom Space %%t|Add and Use %s%%x1", text); + } + else { + sprintf(menu, "Custom Space %%t|Add %s%%x1", text); + } + + if (pupmenu(menu) == 1) { + return 1; + } + else { + return 0; + } +} + + int manageMeshSpace(int confirm, int set) { EditMesh *em = G.editMesh; - float mat[3][3], vec[3] = {0.0f, 0.0f, 1.0f}; - int index; + float mat[3][3]; char name[36] = ""; + int index; - if (G.scene->selectmode & SCE_SELECT_VERTEX && G.totvertsel == 1) { - EditVert *eve; - - if (confirm == 0) { - if (set && pupmenu("Custome Space %t|Add and Use Vertex%x1") != 1) { + /* Vertice Selected */ + if (G.scene->selectmode & SCE_SELECT_VERTEX && (G.totvertsel == 1 || G.totvertsel == 2 || G.totvertsel == 3)) { + if (G.totvertsel == 1) { + EditSelection *ese; + EditVert *eve = NULL; + float normal[3]; + + for (ese = em->selected.first; ese; ese = ese->next) + { + if ( ese->type == EDITVERT ) { + eve = (EditVert *)ese->data; + break; + } + } + + if (eve == NULL) + return -1; + + if (confirm == 0 && confirmSpace(set, "vertex") == 0) { return -1; } - else if (set == 0 && pupmenu("Custome Space %t|Add Vertex%x1") != 1) { + + VECCOPY(normal, eve->no); + Mat4Mul3Vecfl(G.obedit->obmat, normal); + + if (createSpaceNormal(mat, normal) == 0) { + error("Cannot use vertex with zero-length normal"); return -1; } + + strcpy(name, "Vertex"); } - - for(eve = em->verts.first; eve; eve= eve->next) { - if(eve->h == 0 && (eve->f & SELECT)) - break; + else if (G.totvertsel == 2) { + EditSelection *ese; + EditVert *v1 = NULL, *v2 = NULL; + float normal[3]; + + for (ese = em->selected.first; ese; ese = ese->next) + { + if ( ese->type == EDITVERT ) { + if (v1 == NULL) { + v1 = (EditVert *)ese->data; + } + else { + v2 = (EditVert *)ese->data; + break; + } + } + } + + if (v2 == NULL) + return -1; + + if (confirm == 0 && confirmSpace(set, "Edge") == 0) { + return -1; + } + + VecSubf(normal, v2->co, v1->co); + Mat4Mul3Vecfl(G.obedit->obmat, normal); + + if (createSpaceNormal(mat, normal) == 0) { + error("Cannot use zero-length edge"); + return -1; + } + + strcpy(name, "Edge"); } - - if (eve == NULL) - return -1; - - VECCOPY(mat[2], eve->no); - if (Normalize(mat[2]) == 0.0f) { - error("Cannot use vertex with zero-length normal"); - return -1; + else if (G.totvertsel == 3) { + EditSelection *ese; + EditVert *v1 = NULL, *v2 = NULL, *v3 = NULL; + float normal[3], tangent[3], cotangent[3]; + + for (ese = em->selected.first; ese; ese = ese->next) + { + if ( ese->type == EDITVERT ) { + if (v1 == NULL) { + v1 = (EditVert *)ese->data; + } + else if (v2 == NULL) { + v2 = (EditVert *)ese->data; + } + else { + v3 = (EditVert *)ese->data; + break; + } + } + } + + if (v3 == NULL) + return -1; + + if (confirm == 0 && confirmSpace(set, "Face") == 0) { + return -1; + } + + VecSubf(tangent, v2->co, v1->co); + VecSubf(cotangent, v3->co, v2->co); + Crossf(normal, cotangent, tangent); + + Mat4Mul3Vecfl(G.obedit->obmat, normal); + Mat4Mul3Vecfl(G.obedit->obmat, tangent); + + if (createSpaceNormal(mat, normal) == 0) { + error("Cannot use zero-area face"); + return -1; + } + + strcpy(name, "Face"); } - - strcpy(name, "Vertex"); + } - else if(G.scene->selectmode & SCE_SELECT_EDGE && G.totedgesel == 1) { - EditEdge *eed; - - if (confirm == 0) { - if (set && pupmenu("Custome Space %t|Add and Use Edge%x1") != 1) { + /* Edge Selected */ + else if(G.scene->selectmode & SCE_SELECT_EDGE && (G.totedgesel == 1 || G.totedgesel == 2)) { + if (G.totedgesel == 1) { + EditSelection *ese; + EditEdge *eed = NULL; + float normal[3]; + + for (ese = em->selected.first; ese; ese = ese->next) + { + if ( ese->type == EDITEDGE ) { + eed = (EditEdge *)ese->data; + break; + } + } + + if (eed == NULL) + return -1; + + if (confirm == 0 && confirmSpace(set, "Edge") == 0) { return -1; } - else if (set == 0 && pupmenu("Custome Space %t|Add Edge%x1") != 1) { + + VecSubf(normal, eed->v2->co, eed->v1->co); + Mat4Mul3Vecfl(G.obedit->obmat, normal); + + if (createSpaceNormal(mat, normal) == 0) { + error("Cannot use zero-length edge"); return -1; } + + strcpy(name, "Edge"); } - - for(eed = em->edges.first; eed; eed= eed->next) { - if(eed->h == 0 && (eed->f & SELECT)) - break; - } - - if (eed == NULL) - return -1; - - VecSubf(mat[2], eed->v2->co, eed->v1->co); - if (Normalize(mat[2]) == 0.0f) { - error("Cannot use zero-length edges"); - return -1; - } - - strcpy(name, "Edge"); - } - else if(G.scene->selectmode & SCE_SELECT_FACE && G.totfacesel == 1) { - EditFace *efa; - - if (confirm == 0) { - if (set && pupmenu("Custome Space %t|Add and Use Face%x1") != 1) { + /* If selected edges form a triangle */ + else if (G.totedgesel == 2 && G.totvertsel == 3) { + EditSelection *ese; + EditEdge *e1 = NULL, *e2 = NULL; + EditVert *v1 = NULL, *v2 = NULL, *v3 = NULL; + float normal[3], tangent[3], cotangent[3]; + + for (ese = em->selected.first; ese; ese = ese->next) + { + if ( ese->type == EDITEDGE ) { + if (e1 == NULL) { + e1 = (EditEdge *)ese->data; + } + else { + e2 = (EditEdge *)ese->data; + break; + } + } + } + + if (e1->v1 == e2->v1) { + v1 = e1->v2; + v2 = e1->v1; + v3 = e2->v2; + } + else if (e1->v1 == e2->v2) { + v1 = e1->v2; + v2 = e1->v1; + v3 = e2->v1; + } + else if (e1->v2 == e2->v1) { + v1 = e1->v1; + v2 = e1->v2; + v3 = e2->v2; + } + else if (e1->v2 == e2->v2) { + v1 = e1->v1; + v2 = e1->v2; + v3 = e2->v1; + } + + if (v1 == NULL) + return -1; + + if (confirm == 0 && confirmSpace(set, "Face") == 0) { return -1; } - else if (set == 0 && pupmenu("Custome Space %t|Add Face%x1") != 1) { + + VecSubf(tangent, v2->co, v1->co); + VecSubf(cotangent, v3->co, v2->co); + Crossf(normal, cotangent, tangent); + + Mat4Mul3Vecfl(G.obedit->obmat, normal); + Mat4Mul3Vecfl(G.obedit->obmat, tangent); + + if (createSpaceNormal(mat, normal) == 0) { + error("Cannot use zero-area face"); return -1; } + + strcpy(name, "Face"); } + + } + /* Face Selected */ + else if(G.scene->selectmode & SCE_SELECT_FACE && G.totfacesel == 1) { + EditSelection *ese; + EditFace *efa = NULL; + float normal[3], tangent[3]; - for(efa = em->faces.first; efa; efa= efa->next) { - if(efa->h == 0 && (efa->f & SELECT)) - break; + if (confirm == 0 && confirmSpace(set, "Face") == 0) { + return -1; + } + + for (ese = em->selected.first; ese; ese = ese->next) + { + if ( ese->type == EDITFACE ) { + efa = (EditFace *)ese->data; + break; + } } if (efa == NULL) return -1; - VECCOPY(mat[2], efa->n); - if (Normalize(mat[2]) == 0.0f) { - error("Cannot use face with zero-length normal"); + VECCOPY(normal, efa->n); + VecSubf(tangent, efa->v2->co, efa->v1->co); + + Mat4Mul3Vecfl(G.obedit->obmat, normal); + Mat4Mul3Vecfl(G.obedit->obmat, tangent); + + if (createSpaceNormalTangent(mat, normal, tangent) == 0) { + error("Cannot use zero-area face"); return -1; } - VecSubf(vec, efa->v2->co, efa->v1->co); - strcpy(name, "Face"); } else { - notice("You need to select only one vertex, edge or face"); return -1; } - /* Applying matrix for global space */ - Mat4Mul3Vecfl(G.obedit->obmat, mat[2]); - Mat4Mul3Vecfl(G.obedit->obmat, vec); + /* Input name */ + sbutton(name, 1, 35, "name: "); + + index = addMatrixSpace(mat, name); + return index; +} - /* Calculating the other axis */ +int createSpaceNormal(float mat[3][3], float normal[3]) +{ + float tangent[3] = {0.0f, 0.0f, 1.0f}; - Crossf(mat[0], mat[2], vec); - if (Normalize(mat[0]) == 0.0f) { - vec[0] = 1.0f; - vec[1] = vec[2] = 0.0f; - Crossf(mat[0], vec, mat[2]); + VECCOPY(mat[2], normal); + if (Normalize(mat[2]) == 0.0f) { + return 0; /* error return */ + } + + Crossf(mat[0], mat[2], tangent); + if (Inpf(mat[0], mat[0]) == 0.0f) { + tangent[0] = 1.0f; + tangent[1] = tangent[2] = 0.0f; + Crossf(mat[0], tangent, mat[2]); } Crossf(mat[1], mat[2], mat[0]); Mat3Ortho(mat); + + return 1; +} - /* Input name */ - sbutton(name, 1, 35, "name: "); +int createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]) +{ + VECCOPY(mat[2], normal); + if (Normalize(mat[2]) == 0.0f) { + return 0; /* error return */ + } - index = addMatrixSpace(mat, name); - return index; + Crossf(mat[0], mat[2], tangent); + if (Normalize(mat[0]) == 0.0f) { + return 0; /* error return */ + } + + Crossf(mat[1], mat[2], mat[0]); + + Mat3Ortho(mat); + + return 1; } + int addObjectSpace(Object *ob) { float mat[3][3]; char name[36] = ""; diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index e69fabdd926..1534ab9c951 100644 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -2347,6 +2347,102 @@ void flushTransIpoData(TransInfo *t) /* ********************* ACTION/NLA EDITOR ****************** */ +/* Called by special_aftertrans_update to make sure selected keyframes replace + * any other keyframes which may reside on that frame (that is not selected). + */ +static void posttrans_ipo_clean (Ipo *ipo) +{ + IpoCurve *icu; + int i; + + /* delete any keyframes that occur on same frame as selected keyframe, but is not selected */ + for (icu= ipo->curve.first; icu; icu= icu->next) { + float *selcache; /* cache for frame numbers of selected frames (icu->totvert*sizeof(float)) */ + int len, index; /* number of frames in cache, item index */ + + /* allocate memory for the cache */ + // TODO: investigate using GHash for this instead? + if (icu->totvert == 0) + continue; + selcache= MEM_callocN(sizeof(float)*icu->totvert, "IcuSelFrameNums"); + len= 0; + index= 0; + + /* We do 2 loops, 1 for marking keyframes for deletion, one for deleting + * as there is no guarantee what order the keyframes are exactly, even though + * they have been sorted by time. + */ + + /* Loop 1: find selected keyframes */ + for (i = 0; i < icu->totvert; i++) { + BezTriple *bezt= &icu->bezt[i]; + + if (BEZSELECTED(bezt)) { + selcache[index]= bezt->vec[1][0]; + index++; + len++; + } + } + + /* Loop 2: delete unselected keyframes on the same frames (if any keyframes were found) */ + if (len) { + for (i = 0; i < icu->totvert; i++) { + BezTriple *bezt= &icu->bezt[i]; + + if (BEZSELECTED(bezt) == 0) { + /* check beztriple should be removed according to cache */ + for (index= 0; index < len; index++) { + if (IS_EQ(bezt->vec[1][0], selcache[index])) { + delete_icu_key(icu, i, 0); + break; + } + else if (bezt->vec[1][0] > selcache[index]) + break; + } + } + } + + testhandles_ipocurve(icu); + } + + /* free cache */ + MEM_freeN(selcache); + } +} + +/* Called by special_aftertrans_update to make sure selected keyframes replace + * any other keyframes which may reside on that frame (that is not selected). + * remake_action_ipos should have already been called + */ +static void posttrans_action_clean (bAction *act) +{ + ListBase act_data = {NULL, NULL}; + bActListElem *ale; + int filter; + + /* filter data */ + filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS); + actdata_filter(&act_data, filter, act, ACTCONT_ACTION); + + /* loop through relevant data, removing keyframes from the ipo-blocks that were attached + * - all keyframes are converted in/out of global time + */ + for (ale= act_data.first; ale; ale= ale->next) { + if (NLA_ACTION_SCALED) { + actstrip_map_ipo_keys(OBACT, ale->key_data, 0, 1); + posttrans_ipo_clean(ale->key_data); + actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1); + } + else + posttrans_ipo_clean(ale->key_data); + } + + /* free temp data */ + BLI_freelistN(&act_data); +} + +/* ----------------------------- */ + /* 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) { @@ -3003,9 +3099,9 @@ short autokeyframe_cfra_can_key(Object *ob) /* get keyframes that object has (bone anim is stored on ob too) */ if (ob->action) - action_to_keylist(ob->action, &keys, NULL); + action_to_keylist(ob->action, &keys, NULL, NULL); else if (ob->ipo) - ipo_to_keylist(ob->ipo, &keys, NULL); + ipo_to_keylist(ob->ipo, &keys, NULL, NULL); else return 0; @@ -3294,7 +3390,6 @@ void special_aftertrans_update(TransInfo *t) ob = OBACT; if (datatype == ACTCONT_ACTION) { - /* Update the curve */ /* Depending on the lock status, draw necessary views */ if (ob) { ob->ctime= -1234567.0f; @@ -3305,8 +3400,13 @@ void special_aftertrans_update(TransInfo *t) DAG_object_flush_update(G.scene, ob, OB_RECALC_OB); } + /* Do curve updates */ remake_action_ipos((bAction *)data); + /* Do curve cleanups? */ + if ((G.saction->flag & SACTION_NOTRANSKEYCULL)==0) + posttrans_action_clean((bAction *)data); + G.saction->flag &= ~SACTION_MOVING; } else if (datatype == ACTCONT_SHAPEKEY) { @@ -3319,6 +3419,9 @@ void special_aftertrans_update(TransInfo *t) sort_time_ipocurve(icu); testhandles_ipocurve(icu); } + + if ((G.saction->flag & SACTION_NOTRANSKEYCULL)==0) + posttrans_ipo_clean(key->ipo); } DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); |