diff options
author | Joseph Eagar <joeedh@gmail.com> | 2011-02-27 09:19:40 +0300 |
---|---|---|
committer | Joseph Eagar <joeedh@gmail.com> | 2011-02-27 09:19:40 +0300 |
commit | f01261d040be27337db9f9996d648a279c89b7c4 (patch) | |
tree | c448230939b3c90d53ce8852dd00925d6052e3a4 /source/blender/editors/space_view3d | |
parent | dcaeda5c4e3a0687251b8511de4f2e8b85ef75c0 (diff) | |
parent | 2198cfdb2deec8b2e85e242c74a032f43d0b26ca (diff) |
merge with/from trunk at r35190
Diffstat (limited to 'source/blender/editors/space_view3d')
20 files changed, 3549 insertions, 3088 deletions
diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt index 733c81676d1..3e611ab406e 100644 --- a/source/blender/editors/space_view3d/CMakeLists.txt +++ b/source/blender/editors/space_view3d/CMakeLists.txt @@ -19,33 +19,49 @@ # # ***** END GPL LICENSE BLOCK ***** -FILE(GLOB SRC *.c) - -SET(INC +set(INC ../include ../../blenfont ../../blenkernel + ../../blenloader ../../blenlib ../../bmesh ../../gpu ../../imbuf - ../../../../intern/guardedalloc - ../../../../intern/smoke/extern ../../makesdna ../../makesrna - ../../render/extern/include ../../windowmanager + ../../render/extern/include + ../../../../intern/guardedalloc + ../../../../intern/smoke/extern ) -IF(WITH_GAMEENGINE) - SET(INC ${INC} ../../../kernel/gen_system) - ADD_DEFINITIONS(-DGAMEBLENDER) -ENDIF(WITH_GAMEENGINE) +set(SRC + drawanimviz.c + drawarmature.c + drawmesh.c + drawobject.c + drawvolume.c + space_view3d.c + view3d_buttons.c + view3d_draw.c + view3d_edit.c + view3d_fly.c + view3d_header.c + view3d_ops.c + view3d_select.c + view3d_snap.c + view3d_toolbar.c + view3d_view.c + + view3d_intern.h +) -IF(WIN32) - SET(INC ${INC} ${PTHREADS_INC}) -ENDIF(WIN32) +if(WITH_GAMEENGINE) + list(APPEND INC ../../../kernel/gen_system) + add_definitions(-DWITH_GAMEENGINE) +endif() -ADD_DEFINITIONS(-DGLEW_STATIC) +add_definitions(-DGLEW_STATIC) -BLENDERLIB(bf_editor_space_view3d "${SRC}" "${INC}") +blender_add_lib(bf_editor_space_view3d "${SRC}" "${INC}") diff --git a/source/blender/editors/space_view3d/Makefile b/source/blender/editors/space_view3d/Makefile deleted file mode 100644 index 58d88194c22..00000000000 --- a/source/blender/editors/space_view3d/Makefile +++ /dev/null @@ -1,61 +0,0 @@ -# -# $Id$ -# -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# The Original Code is Copyright (C) 2007 Blender Foundation -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): none yet. -# -# ***** END GPL LICENSE BLOCK ***** -# -# Makes module object directory and bounces make to subdirectories. - -LIBNAME = ed_view3d -DIR = $(OCGDIR)/blender/$(LIBNAME) - -include nan_compile.mk - -CFLAGS += $(LEVEL_1_C_WARNINGS) - -CPPFLAGS += -I$(NAN_GLEW)/include -CPPFLAGS += -I$(OPENGL_HEADERS) - - -# not very neat.... -CPPFLAGS += -I../../windowmanager -CPPFLAGS += -I../../blenloader -CPPFLAGS += -I../../blenkernel -CPPFLAGS += -I../../blenlib -CPPFLAGS += -I../../makesdna -CPPFLAGS += -I../../imbuf -CPPFLAGS += -I../../python -CPPFLAGS += -I../../gpu -CPPFLAGS += -I../../makesrna -CPPFLAGS += -I../../render/extern/include -CPPFLAGS += -I../../blenfont -CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include -CPPFLAGS += -I$(NAN_SMOKE)/include -ifneq ($(NAN_NO_KETSJI),true) - CPPFLAGS += -I../../../kernel/gen_system -endif - -# own include -CPPFLAGS += -I../include diff --git a/source/blender/editors/space_view3d/SConscript b/source/blender/editors/space_view3d/SConscript index 907afc12020..9c1c03ff373 100644 --- a/source/blender/editors/space_view3d/SConscript +++ b/source/blender/editors/space_view3d/SConscript @@ -6,14 +6,14 @@ defs = [ 'GLEW_STATIC' ] incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf' incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' -incs += ' ../../render/extern/include' +incs += ' ../../render/extern/include ../../blenloader' incs += ' ../../gpu ../../makesrna ../../blenfont ../../bmesh' incs += ' #/intern/smoke/extern' incs += ' #source/kernel/gen_system' if env['WITH_BF_GAMEENGINE']: - defs.append('GAMEBLENDER=1') + defs.append('WITH_GAMEENGINE') if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): - incs += ' ' + env['BF_PTHREADS_INC'] + incs += ' ' + env['BF_PTHREADS_INC'] env.BlenderLib ( 'bf_editors_space_view3d', sources, Split(incs), defines = defs, libtype=['core'], priority=[40] ) diff --git a/source/blender/editors/space_view3d/drawanimviz.c b/source/blender/editors/space_view3d/drawanimviz.c index fb271556a9c..3c72547bd66 100644 --- a/source/blender/editors/space_view3d/drawanimviz.c +++ b/source/blender/editors/space_view3d/drawanimviz.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -31,6 +31,7 @@ #include <string.h> #include <math.h> +#include "BLO_sys_types.h" #include "DNA_anim_types.h" #include "DNA_armature_types.h" @@ -64,7 +65,7 @@ // - include support for editing the path verts /* Set up drawing environment for drawing motion paths */ -void draw_motion_paths_init(Scene *scene, View3D *v3d, ARegion *ar) +void draw_motion_paths_init(View3D *v3d, ARegion *ar) { RegionView3D *rv3d= ar->regiondata; @@ -78,8 +79,7 @@ void draw_motion_paths_init(Scene *scene, View3D *v3d, ARegion *ar) * - assumes that the viewport has already been initialised properly * i.e. draw_motion_paths_init() has been called */ -// FIXME: the text is still drawn in the wrong space - it includes the current transforms of the object still... -void draw_motion_path_instance(Scene *scene, View3D *v3d, ARegion *ar, +void draw_motion_path_instance(Scene *scene, Object *ob, bPoseChannel *pchan, bAnimVizSettings *avs, bMotionPath *mpath) { //RegionView3D *rv3d= ar->regiondata; @@ -201,15 +201,24 @@ void draw_motion_path_instance(Scene *scene, View3D *v3d, ARegion *ar, UI_ThemeColor(TH_TEXT_HI); } + // XXX, this isnt up to date but probably should be kept so. + invert_m4_m4(ob->imat, ob->obmat); + /* Draw frame numbers at each framestep value */ if (avs->path_viewflag & MOTIONPATH_VIEW_FNUMS) { + unsigned char col[4]; + UI_GetThemeColor3ubv(TH_TEXT_HI, col); + col[3]= 255; + for (i=0, mpv=mpv_start; i < len; i+=stepsize, mpv+=stepsize) { char str[32]; + float co[3]; /* only draw framenum if several consecutive highlighted points don't occur on same point */ if (i == 0) { sprintf(str, "%d", (i+sfra)); - view3d_cached_text_draw_add(mpv->co[0], mpv->co[1], mpv->co[2], str, 0, 0); + mul_v3_m4v3(co, ob->imat, mpv->co); + view3d_cached_text_draw_add(co, str, 0, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII, col); } else if ((i > stepsize) && (i < len-stepsize)) { bMotionPathVert *mpvP = (mpv - stepsize); @@ -217,7 +226,8 @@ void draw_motion_path_instance(Scene *scene, View3D *v3d, ARegion *ar, if ((equals_v3v3(mpv->co, mpvP->co)==0) || (equals_v3v3(mpv->co, mpvN->co)==0)) { sprintf(str, "%d", (sfra+i)); - view3d_cached_text_draw_add(mpv->co[0], mpv->co[1], mpv->co[2], str, 0, 0); + mul_v3_m4v3(co, ob->imat, mpv->co); + view3d_cached_text_draw_add(co, str, 0, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII, col); } } } @@ -225,6 +235,8 @@ void draw_motion_path_instance(Scene *scene, View3D *v3d, ARegion *ar, /* Keyframes - dots and numbers */ if (avs->path_viewflag & MOTIONPATH_VIEW_KFRAS) { + unsigned char col[4]; + AnimData *adt= BKE_animdata_from_id(&ob->id); DLRBT_Tree keys; @@ -250,8 +262,11 @@ void draw_motion_path_instance(Scene *scene, View3D *v3d, ARegion *ar, } /* Draw slightly-larger yellow dots at each keyframe */ - UI_ThemeColor(TH_VERTEX_SELECT); + UI_GetThemeColor3ubv(TH_VERTEX_SELECT, col); + col[3]= 255; + glPointSize(4.0f); // XXX perhaps a bit too big + glColor3ubv(col); glBegin(GL_POINTS); for (i=0, mpv=mpv_start; i < len; i++, mpv++) { @@ -266,6 +281,7 @@ void draw_motion_path_instance(Scene *scene, View3D *v3d, ARegion *ar, /* Draw frame numbers of keyframes */ if (avs->path_viewflag & MOTIONPATH_VIEW_KFNOS) { + float co[3]; for (i=0, mpv=mpv_start; i < len; i++, mpv++) { float mframe= (float)(sfra + i); @@ -273,7 +289,8 @@ void draw_motion_path_instance(Scene *scene, View3D *v3d, ARegion *ar, char str[32]; sprintf(str, "%d", (sfra+i)); - view3d_cached_text_draw_add(mpv->co[0], mpv->co[1], mpv->co[2], str, 0, 0); + mul_v3_m4v3(co, ob->imat, mpv->co); + view3d_cached_text_draw_add(co, str, 0, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII, col); } } } @@ -283,7 +300,7 @@ void draw_motion_path_instance(Scene *scene, View3D *v3d, ARegion *ar, } /* Clean up drawing environment after drawing motion paths */ -void draw_motion_paths_cleanup(Scene *scene, View3D *v3d, ARegion *ar) +void draw_motion_paths_cleanup(View3D *v3d) { if (v3d->zbuf) glEnable(GL_DEPTH_TEST); glPopMatrix(); diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index 1d86e0d074f..93a08af6903 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -43,6 +43,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_dlrbTree.h" +#include "BLI_utildefines.h" #include "BKE_animsys.h" #include "BKE_action.h" @@ -50,7 +51,7 @@ #include "BKE_global.h" #include "BKE_modifier.h" #include "BKE_nla.h" -#include "BKE_utildefines.h" + #include "BIF_gl.h" #include "BIF_glutil.h" @@ -140,7 +141,7 @@ static void cp_shade_color3ub (char cp[], int offset) } /* This function sets the gl-color for coloring a certain bone (based on bcolor) */ -static short set_pchan_glColor (short colCode, int armflag, int boneflag, int constflag) +static short set_pchan_glColor (short colCode, int boneflag, int constflag) { switch (colCode) { case PCHAN_COLOR_NORMAL: @@ -150,6 +151,9 @@ static short set_pchan_glColor (short colCode, int armflag, int boneflag, int co if (boneflag & BONE_DRAW_ACTIVE) { VECCOPY(cp, bcolor->active); + if(!(boneflag & BONE_SELECTED)) { + cp_shade_color3ub(cp, -80); + } } else if (boneflag & BONE_SELECTED) { VECCOPY(cp, bcolor->select); @@ -163,7 +167,8 @@ static short set_pchan_glColor (short colCode, int armflag, int boneflag, int co glColor3ub(cp[0], cp[1], cp[2]); } else { - if (boneflag & BONE_DRAW_ACTIVE) UI_ThemeColorShade(TH_BONE_POSE, 40); + if (boneflag & BONE_DRAW_ACTIVE && boneflag & BONE_SELECTED) UI_ThemeColorShade(TH_BONE_POSE, 40); + else if (boneflag & BONE_DRAW_ACTIVE) UI_ThemeColorBlend(TH_WIRE, TH_BONE_POSE, 0.15f); /* unselected active */ else if (boneflag & BONE_SELECTED) UI_ThemeColor(TH_BONE_POSE); else UI_ThemeColor(TH_WIRE); } @@ -284,6 +289,13 @@ static short set_pchan_glColor (short colCode, int armflag, int boneflag, int co return 0; } +static void set_ebone_glColor(const unsigned int boneflag) +{ + if (boneflag & BONE_DRAW_ACTIVE && boneflag & BONE_SELECTED) UI_ThemeColor(TH_EDGE_SELECT); + else if (boneflag & BONE_DRAW_ACTIVE) UI_ThemeColorBlend(TH_WIRE, TH_EDGE_SELECT, 0.15f); /* unselected active */ + else if (boneflag & BONE_SELECTED) UI_ThemeColorShade(TH_EDGE_SELECT, -20); + else UI_ThemeColor(TH_WIRE); +} /* *************** Armature drawing, helper calls for parts ******************* */ @@ -310,7 +322,7 @@ static void drawsolidcube_size(float xsize, float ysize, float zsize) if(displist==0) { displist= glGenLists(1); - glNewList(displist, GL_COMPILE_AND_EXECUTE); + glNewList(displist, GL_COMPILE); glBegin(GL_QUADS); n[0]= -1.0; @@ -340,19 +352,17 @@ static void drawsolidcube_size(float xsize, float ysize, float zsize) glEndList(); } - else glCallList(displist); - + + glCallList(displist); } static void drawcube_size(float xsize, float ysize, float zsize) { static GLuint displist=0; - glScalef(xsize, ysize, zsize); - if(displist == 0) { displist= glGenLists(1); - glNewList(displist, GL_COMPILE_AND_EXECUTE); + glNewList(displist, GL_COMPILE); glBegin(GL_LINE_STRIP); glVertex3fv(cube[0]); glVertex3fv(cube[1]);glVertex3fv(cube[2]); glVertex3fv(cube[3]); @@ -368,7 +378,9 @@ static void drawcube_size(float xsize, float ysize, float zsize) glEndList(); } - else glCallList(displist); + + glScalef(xsize, ysize, zsize); + glCallList(displist); } @@ -381,7 +393,7 @@ static void draw_bonevert(void) GLUquadricObj *qobj; displist= glGenLists(1); - glNewList(displist, GL_COMPILE_AND_EXECUTE); + glNewList(displist, GL_COMPILE); glPushMatrix(); @@ -400,8 +412,8 @@ static void draw_bonevert(void) glPopMatrix(); glEndList(); } - else - glCallList(displist); + + glCallList(displist); } static void draw_bonevert_solid(void) @@ -412,7 +424,7 @@ static void draw_bonevert_solid(void) GLUquadricObj *qobj; displist= glGenLists(1); - glNewList(displist, GL_COMPILE_AND_EXECUTE); + glNewList(displist, GL_COMPILE); qobj = gluNewQuadric(); gluQuadricDrawStyle(qobj, GLU_FILL); @@ -423,11 +435,11 @@ static void draw_bonevert_solid(void) glEndList(); } - else - glCallList(displist); + + glCallList(displist); } -static void draw_bone_octahedral() +static void draw_bone_octahedral(void) { static GLuint displist=0; @@ -435,7 +447,7 @@ static void draw_bone_octahedral() float vec[6][3]; displist= glGenLists(1); - glNewList(displist, GL_COMPILE_AND_EXECUTE); + glNewList(displist, GL_COMPILE); vec[0][0]= vec[0][1]= vec[0][2]= 0.0f; vec[5][0]= vec[5][2]= 0.0f; vec[5][1]= 1.0f; @@ -467,8 +479,8 @@ static void draw_bone_octahedral() glEndList(); } - else - glCallList(displist); + + glCallList(displist); } static void draw_bone_solid_octahedral(void) @@ -479,7 +491,7 @@ static void draw_bone_solid_octahedral(void) float vec[6][3], nor[3]; displist= glGenLists(1); - glNewList(displist, GL_COMPILE_AND_EXECUTE); + glNewList(displist, GL_COMPILE); vec[0][0]= vec[0][1]= vec[0][2]= 0.0f; vec[5][0]= vec[5][2]= 0.0f; vec[5][1]= 1.0f; @@ -529,8 +541,8 @@ static void draw_bone_solid_octahedral(void) glEndList(); } - else - glCallList(displist); + + glCallList(displist); } /* *************** Armature drawing, bones ******************* */ @@ -551,7 +563,7 @@ static void draw_bone_points(int dt, int armflag, unsigned int boneflag, int id) } else { if (armflag & ARM_POSEMODE) - set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, 0); + set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, 0); else UI_ThemeColor(TH_BONE_SOLID); } @@ -574,7 +586,7 @@ static void draw_bone_points(int dt, int armflag, unsigned int boneflag, int id) } else { if (armflag & ARM_POSEMODE) - set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, 0); + set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, 0); else UI_ThemeColor(TH_BONE_SOLID); } @@ -616,17 +628,17 @@ static float co[16] ={ /* smat, imat = mat & imat to draw screenaligned */ -static void draw_sphere_bone_dist(float smat[][4], float imat[][4], int boneflag, bPoseChannel *pchan, EditBone *ebone) +static void draw_sphere_bone_dist(float smat[][4], float imat[][4], bPoseChannel *pchan, EditBone *ebone) { - float head, tail, length, dist; + float head, tail, dist /*, length*/; float *headvec, *tailvec, dirvec[3]; /* figure out the sizes of spheres */ if (ebone) { /* this routine doesn't call get_matrix_editbone() that calculates it */ ebone->length = len_v3v3(ebone->head, ebone->tail); - - length= ebone->length; + + /*length= ebone->length;*/ /*UNUSED*/ tail= ebone->rad_tail; dist= ebone->dist; if (ebone->parent && (ebone->flag & BONE_CONNECTED)) @@ -637,7 +649,7 @@ static void draw_sphere_bone_dist(float smat[][4], float imat[][4], int boneflag tailvec= ebone->tail; } else { - length= pchan->bone->length; + /*length= pchan->bone->length;*/ /*UNUSED*/ tail= pchan->bone->rad_tail; dist= pchan->bone->dist; if (pchan->parent && (pchan->bone->flag & BONE_CONNECTED)) @@ -655,6 +667,26 @@ static void draw_sphere_bone_dist(float smat[][4], float imat[][4], int boneflag mul_mat3_m4_v3(smat, dirvec); /* clear zcomp */ dirvec[2]= 0.0f; + + if(head != tail) { + /* correcyion when viewing along the bones axis + * it pops in and out but better then artifacts, [#23841] */ + float view_dist= len_v2(dirvec); + + if(head - view_dist > tail) { + tailvec= headvec; + tail = head; + zero_v3(dirvec); + dirvec[0]= 0.00001; // XXX. weak but ok + } + else if(tail - view_dist > head) { + headvec= tailvec; + head = tail; + zero_v3(dirvec); + dirvec[0]= 0.00001; // XXX. weak but ok + } + } + /* move vector back */ mul_mat3_m4_v3(imat, dirvec); @@ -728,7 +760,7 @@ static void draw_sphere_bone_dist(float smat[][4], float imat[][4], int boneflag /* smat, imat = mat & imat to draw screenaligned */ static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag, int boneflag, int constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone) { - float head, tail, length; + float head, tail /*, length*/; float *headvec, *tailvec, dirvec[3]; /* figure out the sizes of spheres */ @@ -736,7 +768,7 @@ static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag, /* this routine doesn't call get_matrix_editbone() that calculates it */ ebone->length = len_v3v3(ebone->head, ebone->tail); - length= ebone->length; + /*length= ebone->length;*/ /*UNUSED*/ tail= ebone->rad_tail; if (ebone->parent && (boneflag & BONE_CONNECTED)) head= ebone->parent->rad_tail; @@ -746,7 +778,7 @@ static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag, tailvec= ebone->tail; } else { - length= pchan->bone->length; + /*length= pchan->bone->length;*/ /*UNUSED*/ tail= pchan->bone->rad_tail; if ((pchan->parent) && (boneflag & BONE_CONNECTED)) head= pchan->parent->bone->rad_tail; @@ -762,7 +794,7 @@ static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag, else UI_ThemeColor(TH_VERTEX); } else if (armflag & ARM_POSEMODE) - set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag); + set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag); /* Draw root point if we are not connected */ if ((boneflag & BONE_CONNECTED)==0) { @@ -883,7 +915,7 @@ static void draw_sphere_bone(int dt, int armflag, int boneflag, int constflag, u else UI_ThemeColorShade(TH_BONE_SOLID, -30); } else if (armflag & ARM_POSEMODE) - set_pchan_glColor(PCHAN_COLOR_SPHEREBONE_END, armflag, boneflag, constflag); + set_pchan_glColor(PCHAN_COLOR_SPHEREBONE_END, boneflag, constflag); else if (dt==OB_SOLID) UI_ThemeColorShade(TH_BONE_SOLID, -30); @@ -913,7 +945,7 @@ static void draw_sphere_bone(int dt, int armflag, int boneflag, int constflag, u else UI_ThemeColor(TH_BONE_SOLID); } else if (armflag & ARM_POSEMODE) - set_pchan_glColor(PCHAN_COLOR_SPHEREBONE_BASE, armflag, boneflag, constflag); + set_pchan_glColor(PCHAN_COLOR_SPHEREBONE_BASE, boneflag, constflag); else if (dt == OB_SOLID) UI_ThemeColor(TH_BONE_SOLID); @@ -983,7 +1015,7 @@ static void draw_line_bone(int armflag, int boneflag, int constflag, unsigned in if (armflag & (ARM_EDITMODE|ARM_POSEMODE)) { glLineWidth(4.0f); if (armflag & ARM_POSEMODE) - set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag); + set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag); else if (armflag & ARM_EDITMODE) { UI_ThemeColor(TH_WIRE); } @@ -1028,7 +1060,7 @@ static void draw_line_bone(int armflag, int boneflag, int constflag, unsigned in glLoadName(id & 0xFFFF); /* object tag, for bordersel optim */ if (armflag & ARM_POSEMODE) - set_pchan_glColor(PCHAN_COLOR_LINEBONE, armflag, boneflag, constflag); + set_pchan_glColor(PCHAN_COLOR_LINEBONE, boneflag, constflag); } glLineWidth(2.0); @@ -1127,15 +1159,13 @@ static void draw_b_bone(int dt, int armflag, int boneflag, int constflag, unsign /* colors for modes */ if (armflag & ARM_POSEMODE) { if (dt <= OB_WIRE) - set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag); + set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag); else - set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, constflag); + set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, constflag); } else if (armflag & ARM_EDITMODE) { if (dt==OB_WIRE) { - if (boneflag & BONE_DRAW_ACTIVE) UI_ThemeColor(TH_EDGE_SELECT); - else if (boneflag & BONE_SELECTED) UI_ThemeColorShade(TH_EDGE_SELECT, -20); - else UI_ThemeColor(TH_WIRE); + set_ebone_glColor(boneflag); } else UI_ThemeColor(TH_BONE_SOLID); @@ -1151,7 +1181,7 @@ static void draw_b_bone(int dt, int armflag, int boneflag, int constflag, unsign glEnable(GL_LIGHTING); if (armflag & ARM_POSEMODE) - set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, constflag); + set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, constflag); else UI_ThemeColor(TH_BONE_SOLID); @@ -1166,7 +1196,7 @@ static void draw_b_bone(int dt, int armflag, int boneflag, int constflag, unsign if (armflag & ARM_POSEMODE) { if (constflag) { /* set constraint colors */ - if (set_pchan_glColor(PCHAN_COLOR_CONSTS, armflag, boneflag, constflag)) { + if (set_pchan_glColor(PCHAN_COLOR_CONSTS, boneflag, constflag)) { glEnable(GL_BLEND); draw_b_bone_boxes(OB_SOLID, pchan, xwidth, length, zwidth); @@ -1175,7 +1205,7 @@ static void draw_b_bone(int dt, int armflag, int boneflag, int constflag, unsign } /* restore colors */ - set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag); + set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag); } } @@ -1201,9 +1231,9 @@ static void draw_bone(int dt, int armflag, int boneflag, int constflag, unsigned /* colors for posemode */ if (armflag & ARM_POSEMODE) { if (dt <= OB_WIRE) - set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag); + set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag); else - set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, constflag); + set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, constflag); } @@ -1218,14 +1248,12 @@ static void draw_bone(int dt, int armflag, int boneflag, int constflag, unsigned if (dt <= OB_WIRE) { /* colors */ if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_DRAW_ACTIVE) UI_ThemeColor(TH_EDGE_SELECT); - else if (boneflag & BONE_SELECTED) UI_ThemeColorShade(TH_EDGE_SELECT, -20); - else UI_ThemeColor(TH_WIRE); + set_ebone_glColor(boneflag); } else if (armflag & ARM_POSEMODE) { if (constflag) { /* draw constraint colors */ - if (set_pchan_glColor(PCHAN_COLOR_CONSTS, armflag, boneflag, constflag)) { + if (set_pchan_glColor(PCHAN_COLOR_CONSTS, boneflag, constflag)) { glEnable(GL_BLEND); draw_bone_solid_octahedral(); @@ -1234,7 +1262,7 @@ static void draw_bone(int dt, int armflag, int boneflag, int constflag, unsigned } /* restore colors */ - set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag); + set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag); } } draw_bone_octahedral(); @@ -1242,7 +1270,7 @@ static void draw_bone(int dt, int armflag, int boneflag, int constflag, unsigned else { /* solid */ if (armflag & ARM_POSEMODE) - set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, constflag); + set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, constflag); else UI_ThemeColor(TH_BONE_SOLID); draw_bone_solid_octahedral(); @@ -1263,7 +1291,7 @@ static void draw_custom_bone(Scene *scene, View3D *v3d, RegionView3D *rv3d, Obje /* colors for posemode */ if (armflag & ARM_POSEMODE) { - set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, 0); + set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, 0); } if (id != -1) { @@ -1545,7 +1573,7 @@ static void bone_matrix_translate_y(float mat[][4], float y) } /* assumes object is Armature with pose */ -static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt) +static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, short ghost) { RegionView3D *rv3d= ar->regiondata; Object *ob= base->object; @@ -1558,6 +1586,9 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, short do_dashed= 3, draw_wire= 0; short flag, constflag; + /* being set below */ + arm->layer_used= 0; + /* hacky... prevent outline select from drawing dashed helplines */ glGetFloatv(GL_LINE_WIDTH, &tmp); if (tmp > 1.1) do_dashed &= ~1; @@ -1582,7 +1613,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, if (bone && !(bone->flag & (BONE_HIDDEN_P|BONE_NO_DEFORM|BONE_HIDDEN_PG))) { if (bone->flag & (BONE_SELECTED)) { if (bone->layer & arm->layer) - draw_sphere_bone_dist(smat, imat, bone->flag, pchan, NULL); + draw_sphere_bone_dist(smat, imat, pchan, NULL); } } } @@ -1604,6 +1635,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { bone= pchan->bone; + arm->layer_used |= bone->layer; if ( (bone) && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG)) ) { if (bone->layer & arm->layer) { @@ -1622,7 +1654,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, flag &= ~BONE_CONNECTED; /* set temporary flag for drawing bone as active, but only if selected */ - if ((bone == arm->act_bone) && (bone->flag & BONE_SELECTED)) + if (bone == arm->act_bone) flag |= BONE_DRAW_ACTIVE; /* set color-set to use */ @@ -1686,9 +1718,11 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, } /* prepare colors */ - if (arm->flag & ARM_POSEMODE) + if(ghost) { + /* 13 October 2009, Disabled this to make ghosting show the right colors (Aligorith) */ + } + else if (arm->flag & ARM_POSEMODE) set_pchan_colorset(ob, pchan); -#if 0 // XXX - 13 October 2009, Disabled this to make ghosting show the right colors (Aligorith) else { if ((scene->basact)==base) { if (base->flag & (SELECT+BA_WAS_SEL)) UI_ThemeColor(TH_ACTIVE); @@ -1699,7 +1733,6 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, else UI_ThemeColor(TH_WIRE); } } -#endif /* catch exception for bone with hidden parent */ flag= bone->flag; @@ -1707,7 +1740,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, flag &= ~BONE_CONNECTED; /* set temporary flag for drawing bone as active, but only if selected */ - if ((bone == arm->act_bone) && (bone->flag & BONE_SELECTED)) + if (bone == arm->act_bone) flag |= BONE_DRAW_ACTIVE; draw_custom_bone(scene, v3d, rv3d, pchan->custom, OB_WIRE, arm->flag, flag, index, bone->length); @@ -1721,8 +1754,8 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, if (index != -1) index+= 0x10000; // pose bones count in higher 2 bytes only } - - if (draw_wire) { + /* stick bones have not been drawn yet so dont clear object selection in this case */ + if ((arm->drawtype != ARM_LINE) && draw_wire) { /* object tag, for bordersel optim */ glLoadName(index & 0xFFFF); index= -1; @@ -1748,10 +1781,11 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { bone= pchan->bone; + arm->layer_used |= bone->layer; if ((bone) && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))) { if (bone->layer & arm->layer) { - if ((do_dashed & 1) && (bone->parent)) { + if ((do_dashed & 1) && (pchan->parent)) { /* Draw a line from our root to the parent's tip * - only if V3D_HIDE_HELPLINES is enabled... */ @@ -1802,7 +1836,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, flag &= ~BONE_CONNECTED; /* set temporary flag for drawing bone as active, but only if selected */ - if ((bone == arm->act_bone) && (bone->flag & BONE_SELECTED)) + if (bone == arm->act_bone) flag |= BONE_DRAW_ACTIVE; /* extra draw service for pose mode */ @@ -1853,6 +1887,12 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, /* patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing */ if ((G.f & G_PICKSEL) == 0) { float vec[3]; + + unsigned char col[4]; + float col_f[3]; + glGetFloatv(GL_CURRENT_COLOR, col_f); /* incase this is not set below */ + rgb_float_to_byte(col_f, col); + col[3]= 255; if (v3d->zbuf) glDisable(GL_DEPTH_TEST); @@ -1861,17 +1901,16 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, if (pchan->bone->layer & arm->layer) { if (arm->flag & (ARM_EDITMODE|ARM_POSEMODE)) { bone= pchan->bone; - - if (bone->flag & BONE_SELECTED) UI_ThemeColor(TH_TEXT_HI); - else UI_ThemeColor(TH_TEXT); + UI_GetThemeColor3ubv((bone->flag & BONE_SELECTED) ? TH_TEXT_HI : TH_TEXT, col); } - else if (dt > OB_WIRE) - UI_ThemeColor(TH_TEXT); - + else if (dt > OB_WIRE) { + UI_GetThemeColor3ubv(TH_TEXT, col); + } + /* Draw names of bone */ if (arm->flag & ARM_DRAWNAMES) { mid_v3_v3v3(vec, pchan->pose_head, pchan->pose_tail); - view3d_cached_text_draw_add(vec[0], vec[1], vec[2], pchan->name, 10, 0); + view3d_cached_text_draw_add(vec, pchan->name, 10, 0, col); } /* Draw additional axes on the bone tail */ @@ -1880,8 +1919,9 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, copy_m4_m4(bmat, pchan->pose_mat); bone_matrix_translate_y(bmat, pchan->bone->length); glMultMatrixf(bmat); - - drawaxes(pchan->bone->length*0.25f, 0, OB_ARROWS); + + glColor3ubv(col); + drawaxes(pchan->bone->length*0.25f, OB_ARROWS); glPopMatrix(); } @@ -1920,6 +1960,9 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, int dt) unsigned int index; int flag; + /* being set in code below */ + arm->layer_used= 0; + /* envelope (deform distance) */ if(arm->drawtype==ARM_ENVELOPE) { /* precalc inverse matrix for drawing screen aligned */ @@ -1933,11 +1976,11 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, int dt) if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - for (eBone=arm->edbo->first, index=0; eBone; eBone=eBone->next, index++) { + for (eBone=arm->edbo->first; eBone; eBone=eBone->next) { if (eBone->layer & arm->layer) { if ((eBone->flag & (BONE_HIDDEN_A|BONE_NO_DEFORM))==0) { if (eBone->flag & (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL)) - draw_sphere_bone_dist(smat, imat, eBone->flag, NULL, eBone); + draw_sphere_bone_dist(smat, imat, NULL, eBone); } } } @@ -1949,7 +1992,6 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, int dt) /* if solid we draw it first */ if ((dt > OB_WIRE) && (arm->drawtype!=ARM_LINE)) { - index= 0; for (eBone=arm->edbo->first, index=0; eBone; eBone=eBone->next, index++) { if (eBone->layer & arm->layer) { if ((eBone->flag & BONE_HIDDEN_A)==0) { @@ -1959,11 +2001,11 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, int dt) /* catch exception for bone with hidden parent */ flag= eBone->flag; - if ( (eBone->parent) && ((eBone->parent->flag & BONE_HIDDEN_A) || (eBone->parent->layer & arm->layer)==0) ) + if ( (eBone->parent) && !EBONE_VISIBLE(arm, eBone->parent)) flag &= ~BONE_CONNECTED; /* set temporary flag for drawing bone as active, but only if selected */ - if ((eBone == arm->act_edbone) && (eBone->flag & BONE_SELECTED)) + if (eBone == arm->act_edbone) flag |= BONE_DRAW_ACTIVE; if (arm->drawtype==ARM_ENVELOPE) @@ -1993,16 +2035,17 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, int dt) index= 0; /* do selection codes */ for (eBone=arm->edbo->first; eBone; eBone=eBone->next) { + arm->layer_used |= eBone->layer; if (eBone->layer & arm->layer) { if ((eBone->flag & BONE_HIDDEN_A)==0) { /* catch exception for bone with hidden parent */ flag= eBone->flag; - if ( (eBone->parent) && ((eBone->parent->flag & BONE_HIDDEN_A) || (eBone->parent->layer & arm->layer)==0) ) + if ( (eBone->parent) && !EBONE_VISIBLE(arm, eBone->parent)) flag &= ~BONE_CONNECTED; /* set temporary flag for drawing bone as active, but only if selected */ - if ((eBone == arm->act_edbone) && (eBone->flag & BONE_SELECTED)) + if (eBone == arm->act_edbone) flag |= BONE_DRAW_ACTIVE; if (arm->drawtype == ARM_ENVELOPE) { @@ -2043,6 +2086,7 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, int dt) } /* restore */ + if(index!=-1) glLoadName(-1); if (arm->drawtype==ARM_LINE); else if (dt>OB_WIRE) bglPolygonOffset(rv3d->dist, 0.0f); @@ -2051,21 +2095,22 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, int dt) // patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing if ((G.f & G_PICKSEL) == 0) { float vec[3]; + unsigned char col[4]; + col[3]= 255; if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - for (eBone=arm->edbo->first, index=0; eBone; eBone=eBone->next, index++) { + for (eBone=arm->edbo->first; eBone; eBone=eBone->next) { if(eBone->layer & arm->layer) { if ((eBone->flag & BONE_HIDDEN_A)==0) { - - if (eBone->flag & BONE_SELECTED) UI_ThemeColor(TH_TEXT_HI); - else UI_ThemeColor(TH_TEXT); - + + UI_GetThemeColor3ubv((eBone->flag & BONE_SELECTED) ? TH_TEXT_HI : TH_TEXT, col); + /* Draw name */ if (arm->flag & ARM_DRAWNAMES) { mid_v3_v3v3(vec, eBone->head, eBone->tail); glRasterPos3fv(vec); - view3d_cached_text_draw_add(vec[0], vec[1], vec[2], eBone->name, 10, 0); + view3d_cached_text_draw_add(vec, eBone->name, 10, 0, col); } /* Draw additional axes */ if (arm->flag & ARM_DRAWAXES) { @@ -2073,8 +2118,9 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, int dt) get_matrix_editbone(eBone, bmat); bone_matrix_translate_y(bmat, eBone->length); glMultMatrixf(bmat); - - drawaxes(eBone->length*0.25f, 0, OB_ARROWS); + + glColor3ubv(col); + drawaxes(eBone->length*0.25f, OB_ARROWS); glPopMatrix(); } @@ -2102,16 +2148,16 @@ static void draw_pose_paths(Scene *scene, View3D *v3d, ARegion *ar, Object *ob) bPoseChannel *pchan; /* setup drawing environment for paths */ - draw_motion_paths_init(scene, v3d, ar); + draw_motion_paths_init(v3d, ar); /* draw paths where they exist and they releated bone is visible */ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { if ((pchan->bone->layer & arm->layer) && (pchan->mpath)) - draw_motion_path_instance(scene, v3d, ar, ob, pchan, avs, pchan->mpath); + draw_motion_path_instance(scene, ob, pchan, avs, pchan->mpath); } /* cleanup after drawing */ - draw_motion_paths_cleanup(scene, v3d, ar); + draw_motion_paths_cleanup(v3d); } @@ -2191,7 +2237,7 @@ static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL); where_is_pose(scene, ob); - draw_pose_bones(scene, v3d, ar, base, OB_WIRE); + draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE); } glDisable(GL_BLEND); if (v3d->zbuf) glEnable(GL_DEPTH_TEST); @@ -2270,7 +2316,7 @@ static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, ARegion *ar, Base * BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL); where_is_pose(scene, ob); - draw_pose_bones(scene, v3d, ar, base, OB_WIRE); + draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE); } glDisable(GL_BLEND); if (v3d->zbuf) glEnable(GL_DEPTH_TEST); @@ -2340,7 +2386,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base) if (CFRA != cfrao) { BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL); where_is_pose(scene, ob); - draw_pose_bones(scene, v3d, ar, base, OB_WIRE); + draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE); } } @@ -2355,7 +2401,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base) if (CFRA != cfrao) { BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL); where_is_pose(scene, ob); - draw_pose_bones(scene, v3d, ar, base, OB_WIRE); + draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE); } } } @@ -2389,7 +2435,7 @@ int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, in /* we use color for solid lighting */ glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR); glEnable(GL_COLOR_MATERIAL); - glColor3ub(0,0,0); // clear spec + glColor3ub(255,0,255); // clear spec glDisable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); @@ -2438,7 +2484,7 @@ int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, in } } } - draw_pose_bones(scene, v3d, ar, base, dt); + draw_pose_bones(scene, v3d, ar, base, dt, FALSE); arm->flag &= ~ARM_POSEMODE; if(ob->mode & OB_MODE_POSE) diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index 9acb7443a8f..030f368aaa2 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -34,7 +34,7 @@ #include "BLI_math.h" #include "BLI_edgehash.h" #include "BLI_editVert.h" - +#include "BLI_utildefines.h" #include "DNA_material_types.h" #include "DNA_meshdata_types.h" @@ -51,9 +51,9 @@ #include "BKE_material.h" #include "BKE_paint.h" #include "BKE_property.h" -#include "BKE_utildefines.h" #include "BKE_tessmesh.h" + #include "BIF_gl.h" #include "BIF_glutil.h" @@ -95,13 +95,10 @@ static EdgeHash *get_tface_mesh_marked_edge_info(Mesh *me) EdgeHash *eh = BLI_edgehash_new(); int i; MFace *mf; - MTFace *tf = NULL; for (i=0; i<me->totface; i++) { mf = &me->mface[i]; - if (me->mtface) - tf = &me->mtface[i]; - + if (mf->v3) { if (!(mf->flag&ME_HIDE)) { unsigned int flags = eEdge_Visible; @@ -170,6 +167,7 @@ static int draw_tfaces3D__setSelectOpts(void *userData, int index) return flags & eEdge_Select; } +#if 0 static int draw_tfaces3D__setActiveOpts(void *userData, int index) { struct { Mesh *me; EdgeHash *eh; } *data = userData; @@ -193,8 +191,21 @@ static int draw_tfaces3D__drawFaceOpts(void *userData, int index) else return 0; } +#endif + +/* draws unselected */ +static int draw_tfaces3D__drawFaceOptsInv(void *userData, int index) +{ + Mesh *me = (Mesh*)userData; + + MFace *mface = &me->mface[index]; + if (!(mface->flag&ME_HIDE) && !(mface->flag&ME_FACE_SEL)) + return 2; /* Don't set color */ + else + return 0; +} -static void draw_tfaces3D(RegionView3D *rv3d, Object *ob, Mesh *me, DerivedMesh *dm) +static void draw_tfaces3D(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm, short draw_seams) { struct { Mesh *me; EdgeHash *eh; } data; @@ -205,17 +216,17 @@ static void draw_tfaces3D(RegionView3D *rv3d, Object *ob, Mesh *me, DerivedMesh glDisable(GL_LIGHTING); bglPolygonOffset(rv3d->dist, 1.0); - /* Draw (Hidden) Edges */ + /* Draw (Hidden) Edges */ + setlinestyle(1); UI_ThemeColor(TH_EDGE_FACESEL); dm->drawMappedEdges(dm, draw_tfaces3D__setHiddenOpts, &data); + setlinestyle(0); - /* Draw Seams */ - if(me->drawflag & ME_DRAWSEAMS) { + /* Draw Seams */ + if(draw_seams && me->drawflag & ME_DRAWSEAMS) { UI_ThemeColor(TH_EDGE_SEAM); glLineWidth(2); - dm->drawMappedEdges(dm, draw_tfaces3D__setSeamOpts, &data); - glLineWidth(1); } @@ -223,10 +234,16 @@ static void draw_tfaces3D(RegionView3D *rv3d, Object *ob, Mesh *me, DerivedMesh if(me->drawflag & ME_DRAWFACES) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +#if 0 UI_ThemeColor4(TH_FACE_SELECT); dm->drawMappedFacesTex(dm, draw_tfaces3D__drawFaceOpts, (void*)me); - +#else + /* dull unselected faces so as not to get in the way of seeing color */ + glColor4ub(96, 96, 96, 64); + dm->drawMappedFacesTex(dm, draw_tfaces3D__drawFaceOptsInv, (void*)me); +#endif + glDisable(GL_BLEND); } @@ -238,8 +255,6 @@ static void draw_tfaces3D(RegionView3D *rv3d, Object *ob, Mesh *me, DerivedMesh dm->drawMappedEdges(dm, draw_tfaces3D__setSelectOpts, &data); setlinestyle(0); - dm->drawMappedEdges(dm, draw_tfaces3D__setActiveOpts, &data); - bglPolygonOffset(rv3d->dist, 0.0); // resets correctly now, even after calling accumulated offsets BLI_edgehash_free(data.eh, NULL); @@ -327,7 +342,7 @@ static int set_draw_settings_cached(int clearcache, int textured, MTFace *texfac /* Icky globals, fix with userdata parameter */ -struct TextureDrawState { +static struct TextureDrawState { Object *ob; int islit, istex; int color_profile; @@ -367,7 +382,7 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O glShadeModel(GL_SMOOTH); } -static void draw_textured_end() +static void draw_textured_end(void) { /* switch off textures */ GPU_set_tpage(NULL, 0); @@ -561,17 +576,18 @@ static int draw_em_tf_mapped__set_draw(void *userData, int index) static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmooth_r) { Mesh *me = (Mesh*)userData; - MTFace *tface = (me->mtface)? &me->mtface[index]: NULL; - MFace *mface = (me->mface)? &me->mface[index]: NULL; - - if ((mface->flag&ME_HIDE) || (tface && (tface->mode&TF_INVISIBLE))) - return 0; - + + if ( (me->mface && me->mface[index].flag & ME_HIDE) || + (me->mtface && (me->mtface[index].mode & TF_INVISIBLE)) + ) { + return 0; + } + *drawSmooth_r = 1; return 1; } -void draw_mesh_text(Scene *scene, Object *ob, int glsl) +static void draw_mesh_text(Scene *scene, Object *ob, int glsl) { Mesh *me = ob->data; DerivedMesh *ddm; @@ -667,20 +683,20 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *o /* draw the textured mesh */ draw_textured_begin(scene, v3d, rv3d, ob); + glColor4f(1.0f,1.0f,1.0f,1.0f); + if(ob->mode & OB_MODE_EDIT) { - glColor4f(1.0f,1.0f,1.0f,1.0f); dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, me->edit_btmesh); } else if(faceselect) { if(ob->mode & OB_MODE_WEIGHT_PAINT) - dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me, 1); + dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me, 1, GPU_enable_material); else - dm->drawMappedFacesTex(dm, draw_tface_mapped__set_draw, me); + dm->drawMappedFacesTex(dm, me->mface ? draw_tface_mapped__set_draw : NULL, me); } else { if( GPU_buffer_legacy(dm) ) dm->drawFacesTex(dm, draw_tface__set_draw_legacy); else { - glColor4f(1.0f,1.0f,1.0f,1.0f); if( !CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL) ) add_tface_color_layer(dm); dm->drawFacesTex(dm, draw_tface__set_draw); @@ -695,7 +711,7 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *o /* draw edges and selected faces over textured mesh */ if(!(ob == scene->obedit) && faceselect) - draw_tfaces3D(rv3d, ob, me, dm); + draw_tfaces3D(rv3d, me, dm, ob->mode & OB_MODE_WEIGHT_PAINT); /* reset from negative scale correction */ glFrontFace(GL_CCW); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 6b3d9abf181..a87cbd0530d 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -47,6 +47,7 @@ #include "BLI_editVert.h" #include "BLI_edgehash.h" #include "BLI_rand.h" +#include "BLI_utildefines.h" #include "BKE_anim.h" //for the where_on_path function #include "BKE_constraint.h" // for the get_constraint_target function @@ -67,7 +68,7 @@ #include "BKE_particle.h" #include "BKE_pointcache.h" #include "BKE_unit.h" -#include "BKE_utildefines.h" + #include "BKE_tessmesh.h" #include "smoke_API.h" @@ -318,12 +319,16 @@ static float cosval[32] ={ 1.00000000 }; -static void draw_xyz_wire(float *c, float size, int axis) +static void draw_xyz_wire(const float c[3], float size, int axis) { float v1[3]= {0.f, 0.f, 0.f}, v2[3] = {0.f, 0.f, 0.f}; float dim = size * 0.1; - float dx[3]={dim, 0.0, 0.0}, dy[3]={0.0, dim, 0.0}, dz[3]={0.0, 0.0, dim}; - + float dx[3], dy[3], dz[3]; + + dx[0]=dim; dx[1]=0.f; dx[2]=0.f; + dy[0]=0.f; dy[1]=dim; dy[2]=0.f; + dz[0]=0.f; dz[1]=0.f; dz[2]=dim; + switch(axis) { case 0: /* x axis */ glBegin(GL_LINES); @@ -400,8 +405,7 @@ static void draw_xyz_wire(float *c, float size, int axis) } -/* flag is same as for draw_object */ -void drawaxes(float size, int flag, char drawtype) +void drawaxes(float size, char drawtype) { int axis; float v1[3]= {0.0, 0.0, 0.0}; @@ -412,16 +416,16 @@ void drawaxes(float size, int flag, char drawtype) case OB_PLAINAXES: for (axis=0; axis<3; axis++) { - float v1[3]= {0.0, 0.0, 0.0}; - float v2[3]= {0.0, 0.0, 0.0}; - glBegin(GL_LINES); v1[axis]= size; v2[axis]= -size; glVertex3fv(v1); glVertex3fv(v2); - + + /* reset v1 & v2 to zero */ + v1[axis]= v2[axis]= 0.0f; + glEnd(); } break; @@ -477,10 +481,8 @@ void drawaxes(float size, int flag, char drawtype) case OB_ARROWS: default: for (axis=0; axis<3; axis++) { - float v1[3]= {0.0, 0.0, 0.0}; - float v2[3]= {0.0, 0.0, 0.0}; - int arrow_axis= (axis==0)?1:0; - + const int arrow_axis= (axis==0) ? 1:0; + glBegin(GL_LINES); v2[axis]= size; @@ -501,12 +503,16 @@ void drawaxes(float size, int flag, char drawtype) v2[axis]+= size*0.125; draw_xyz_wire(v2, size, axis); + + + /* reset v1 & v2 to zero */ + v1[arrow_axis]= v1[axis]= v2[axis]= 0.0f; } break; } } -void drawcircball(int mode, float *cent, float rad, float tmat[][4]) +void drawcircball(int mode, const float cent[3], float rad, float tmat[][4]) { float vec[3], vx[3], vy[3]; int a, tot=32; @@ -525,12 +531,9 @@ void drawcircball(int mode, float *cent, float rad, float tmat[][4]) } /* circle for object centers, special_color is for library or ob users */ -static void drawcentercircle(View3D *v3d, RegionView3D *rv3d, float *vec, int selstate, int special_color) +static void drawcentercircle(View3D *v3d, RegionView3D *rv3d, const float co[3], int selstate, int special_color) { - float size; - - size= rv3d->persmat[0][3]*vec[0]+ rv3d->persmat[1][3]*vec[1]+ rv3d->persmat[2][3]*vec[2]+ rv3d->persmat[3][3]; - size*= rv3d->pixsize*((float)U.obcenter_dia*0.5f); + const float size= view3d_pixel_size(rv3d, co) * (float)U.obcenter_dia * 0.5f; /* using gldepthfunc guarantees that it does write z values, but not checks for it, so centers remain visible independt order of drawing */ if(v3d->zbuf) glDepthFunc(GL_ALWAYS); @@ -546,10 +549,10 @@ static void drawcentercircle(View3D *v3d, RegionView3D *rv3d, float *vec, int se else if (selstate == SELECT) UI_ThemeColorShadeAlpha(TH_SELECT, 0, -80); else if (selstate == DESELECT) UI_ThemeColorShadeAlpha(TH_TRANSFORM, 0, -80); } - drawcircball(GL_POLYGON, vec, size, rv3d->viewinv); + drawcircball(GL_POLYGON, co, size, rv3d->viewinv); UI_ThemeColorShadeAlpha(TH_WIRE, 0, -30); - drawcircball(GL_LINE_LOOP, vec, size, rv3d->viewinv); + drawcircball(GL_LINE_LOOP, co, size, rv3d->viewinv); glDisable(GL_BLEND); if(v3d->zbuf) glDepthFunc(GL_LEQUAL); @@ -561,33 +564,38 @@ static int CachedTextLevel= 0; typedef struct ViewCachedString { struct ViewCachedString *next, *prev; - float vec[3], col[4]; - char str[128]; + float vec[3]; + union { + unsigned char ub[4]; + int pack; + } col; short mval[2]; short xoffs; short flag; + /* str is allocated past the end */ } ViewCachedString; -void view3d_cached_text_draw_begin() +void view3d_cached_text_draw_begin(void) { ListBase *strings= &CachedText[CachedTextLevel]; strings->first= strings->last= NULL; CachedTextLevel++; } -void view3d_cached_text_draw_add(float x, float y, float z, char *str, short xoffs, short flag) +void view3d_cached_text_draw_add(const float co[3], const char *str, short xoffs, short flag, const unsigned char col[4]) { + int alloc_len= strlen(str) + 1; ListBase *strings= &CachedText[CachedTextLevel-1]; - ViewCachedString *vos= MEM_callocN(sizeof(ViewCachedString), "ViewCachedString"); + ViewCachedString *vos= MEM_callocN(sizeof(ViewCachedString) + alloc_len, "ViewCachedString"); BLI_addtail(strings, vos); - BLI_strncpy(vos->str, str, 128); - vos->vec[0]= x; - vos->vec[1]= y; - vos->vec[2]= z; - glGetFloatv(GL_CURRENT_COLOR, vos->col); + copy_v3_v3(vos->vec, co); + vos->col.pack= *((int *)col); vos->xoffs= xoffs; vos->flag= flag; + + /* allocate past the end */ + memcpy(++vos, str, alloc_len); } void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[][4]) @@ -607,6 +615,8 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa } if(tot) { + int col_pack_prev= 0; + #if 0 bglMats mats; /* ZBuffer depth vars */ double ux, uy, uz; @@ -641,8 +651,18 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa } #endif if(vos->mval[0]!=IS_CLIPPED) { - glColor3fv(vos->col); - BLF_draw_default((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], (depth_write)? 0.0f: 2.0f, vos->str); + const char *str= (char *)(vos+1); + + if(col_pack_prev != vos->col.pack) { + glColor3ubv(vos->col.ub); + col_pack_prev= vos->col.pack; + } + if(vos->flag & V3D_CACHE_TEXT_ASCII) { + BLF_draw_default_ascii((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], (depth_write)? 0.0f: 2.0f, str, 65535); /* XXX, use real length */ + } + else { + BLF_draw_default((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], (depth_write)? 0.0f: 2.0f, str, 65535); /* XXX, use real length */ + } } } @@ -782,7 +802,9 @@ static void spotvolume(float *lvec, float *vvec, float inp) cross_v3_v3v3(temp,vvec,lvec); /* equation for a plane through vvec en lvec */ cross_v3_v3v3(plane,lvec,temp); /* a plane perpendicular to this, parrallel with lvec */ - normalize_v3(plane); + /* vectors are exactly aligned, use the X axis, this is arbitrary */ + if(normalize_v3(plane) == 0.0f) + plane[1]= 1.0f; /* now we've got two equations: one of a cone and one of a plane, but we have three unknowns. We remove one unkown by rotating the plane to z=0 (the plane normal) */ @@ -894,13 +916,17 @@ static void draw_transp_spot_volume(Lamp *la, float x, float z) static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt, int flag) { Object *ob= base->object; + const float pixsize= view3d_pixel_size(rv3d, ob->obmat[3]); Lamp *la= ob->data; float vec[3], lvec[3], vvec[3], circrad, x,y,z; - float pixsize, lampsize; + float lampsize; float imat[4][4], curcol[4]; - char col[4]; - int drawcone= (dt>OB_WIRE && !(G.f & G_PICKSEL) && la->type == LA_SPOT && (la->mode & LA_SHOW_CONE)); - + unsigned char col[4]; + /* cone can't be drawn for duplicated lamps, because duplilist would be freed to */ + /* the moment of view3d_draw_transp() call */ + const short is_view= (rv3d->persp==RV3D_CAMOB && v3d->camera == base->object); + const short drawcone= (dt>OB_WIRE && !(G.f & G_PICKSEL) && (la->type == LA_SPOT) && (la->mode & LA_SHOW_CONE) && !(base->flag & OB_FROMDUPLI) && !is_view); + if(drawcone && !v3d->transp) { /* in this case we need to draw delayed */ add_view3d_after(&v3d->afterdraw_transp, base, flag); @@ -912,14 +938,15 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, glLoadMatrixf(rv3d->viewmat); /* lets calculate the scale: */ - pixsize= rv3d->persmat[0][3]*ob->obmat[3][0]+ rv3d->persmat[1][3]*ob->obmat[3][1]+ rv3d->persmat[2][3]*ob->obmat[3][2]+ rv3d->persmat[3][3]; - pixsize*= rv3d->pixsize; lampsize= pixsize*((float)U.obcenter_dia*0.5f); /* and view aligned matrix: */ copy_m4_m4(imat, rv3d->viewinv); normalize_v3(imat[0]); normalize_v3(imat[1]); + + /* lamp center */ + copy_v3_v3(vec, ob->obmat[3]); /* for AA effects */ glGetFloatv(GL_CURRENT_COLOR, curcol); @@ -934,7 +961,6 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, } /* Inner Circle */ - copy_v3_v3(vec, ob->obmat[3]); glEnable(GL_BLEND); drawcircball(GL_LINE_LOOP, vec, lampsize, imat); glDisable(GL_BLEND); @@ -1004,7 +1030,10 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, glPopMatrix(); /* back in object space */ zero_v3(vec); - if ((la->type==LA_SPOT) || (la->type==LA_YF_PHOTON)) { + if(is_view) { + /* skip drawing extra info */ + } + else if ((la->type==LA_SPOT) || (la->type==LA_YF_PHOTON)) { lvec[0]=lvec[1]= 0.0; lvec[2] = 1.0; x = rv3d->persmat[0][2]; @@ -1147,12 +1176,12 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, setlinestyle(0); - if(la->type==LA_SPOT && (la->mode & LA_SHAD_BUF) ) { + if((la->type == LA_SPOT) && (la->mode & LA_SHAD_BUF) && (is_view == FALSE)) { drawshadbuflimits(la, ob->obmat); } UI_GetThemeColor4ubv(TH_LAMP, col); - glColor4ub(col[0], col[1], col[2], col[3]); + glColor4ubv(col); glEnable(GL_BLEND); @@ -1212,10 +1241,15 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob { /* a standing up pyramid with (0,0,0) as top */ Camera *cam; - World *wrld; - float nobmat[4][4], vec[8][4], fac, facx, facy, depth, aspx, aspy, caspx, caspy; + float vec[8][4], facx, facy, depth, aspx, aspy, caspx, caspy, shx, shy; int i; + float drawsize; + const short is_view= (rv3d->persp==RV3D_CAMOB && ob==v3d->camera); + const float scax= 1.0f / len_v3(ob->obmat[0]); + const float scay= 1.0f / len_v3(ob->obmat[1]); + const float scaz= 1.0f / len_v3(ob->obmat[2]); + cam= ob->data; aspx= (float) scene->r.xsch*scene->r.xasp; aspy= (float) scene->r.ysch*scene->r.yasp; @@ -1232,36 +1266,55 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob glDisable(GL_LIGHTING); glDisable(GL_CULL_FACE); - if(rv3d->persp>=2 && cam->type==CAM_ORTHO && ob==v3d->camera) { - facx= 0.5*cam->ortho_scale*caspx; - facy= 0.5*cam->ortho_scale*caspy; - depth= -cam->clipsta-0.1; + if(cam->type==CAM_ORTHO) { + facx= 0.5f * cam->ortho_scale * caspx * scax; + facy= 0.5f * cam->ortho_scale * caspy * scay; + shx= cam->shiftx * cam->ortho_scale * scax; + shy= cam->shifty * cam->ortho_scale * scay; + depth= is_view ? -((cam->clipsta * scaz) + 0.1f) : - cam->drawsize * cam->ortho_scale * scaz; + + drawsize= 0.5f * cam->ortho_scale; } else { - fac= cam->drawsize; - if(rv3d->persp>=2 && ob==v3d->camera) fac= cam->clipsta+0.1; /* that way it's always visible */ - - depth= - fac*cam->lens/16.0; - facx= fac*caspx; - facy= fac*caspy; + /* that way it's always visible - clipsta+0.1 */ + float fac; + drawsize= cam->drawsize / ((scax + scay + scaz) / 3.0f); + + if(is_view) { + /* fixed depth, variable size (avoids exceeding clipping range) */ + depth = -(cam->clipsta + 0.1); + fac = depth / (cam->lens/-16.0f * scaz); + } + else { + /* fixed size, variable depth (stays a reasonable size in the 3D view) */ + depth= drawsize * cam->lens/-16.0f * scaz; + fac= drawsize; + } + + facx= fac * caspx * scax; + facy= fac * caspy * scay; + shx= cam->shiftx*fac*2 * scax; + shy= cam->shifty*fac*2 * scay; } - vec[0][0]= 0.0; vec[0][1]= 0.0; vec[0][2]= 0.001; /* GLBUG: for picking at iris Entry (well thats old!) */ - vec[1][0]= facx; vec[1][1]= facy; vec[1][2]= depth; - vec[2][0]= facx; vec[2][1]= -facy; vec[2][2]= depth; - vec[3][0]= -facx; vec[3][1]= -facy; vec[3][2]= depth; - vec[4][0]= -facx; vec[4][1]= facy; vec[4][2]= depth; + vec[0][0]= 0.0; vec[0][1]= 0.0; vec[0][2]= 0.0; + vec[1][0]= shx + facx; vec[1][1]= shy + facy; vec[1][2]= depth; + vec[2][0]= shx + facx; vec[2][1]= shy - facy; vec[2][2]= depth; + vec[3][0]= shx - facx; vec[3][1]= shy - facy; vec[3][2]= depth; + vec[4][0]= shx - facx; vec[4][1]= shy + facy; vec[4][2]= depth; + /* camera frame */ glBegin(GL_LINE_LOOP); glVertex3fv(vec[1]); glVertex3fv(vec[2]); glVertex3fv(vec[3]); glVertex3fv(vec[4]); glEnd(); - - if(rv3d->persp>=2 && ob==v3d->camera) return; - + if(is_view) + return; + + /* center point to camera frame */ glBegin(GL_LINE_STRIP); glVertex3fv(vec[2]); glVertex3fv(vec[0]); @@ -1275,7 +1328,7 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob /* arrow on top */ vec[0][2]= depth; - + /* draw an outline arrow for inactive cameras and filled * for active cameras. We actually draw both outline+filled * for active cameras so the wire can be seen side-on */ @@ -1283,24 +1336,26 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob if (i==0) glBegin(GL_LINE_LOOP); else if (i==1 && (ob == v3d->camera)) glBegin(GL_TRIANGLES); else break; + + vec[0][0]= shx + ((-0.7 * drawsize) * scax); + vec[0][1]= shy + ((drawsize * (caspy + 0.1)) * scay); + glVertex3fv(vec[0]); /* left */ - vec[0][0]= -0.7*cam->drawsize*caspx; - vec[0][1]= 1.1*cam->drawsize*caspy; - glVertex3fv(vec[0]); - - vec[0][0]= 0.0; - vec[0][1]= 1.8*cam->drawsize*caspy; - glVertex3fv(vec[0]); + vec[0][0]= shx + ((0.7 * drawsize) * scax); + glVertex3fv(vec[0]); /* right */ - vec[0][0]= 0.7*cam->drawsize*caspx; - vec[0][1]= 1.1*cam->drawsize*caspy; - glVertex3fv(vec[0]); + vec[0][0]= shx; + vec[0][1]= shy + ((1.1 * drawsize * (caspy + 0.7)) * scay); + glVertex3fv(vec[0]); /* top */ glEnd(); } if(flag==0) { if(cam->flag & (CAM_SHOWLIMITS+CAM_SHOWMIST)) { + float nobmat[4][4]; + World *wrld; + /* draw in normalized object matrix space */ copy_m4_m4(nobmat, ob->obmat); normalize_m4(nobmat); @@ -1465,7 +1520,7 @@ static void drawlattice(Scene *scene, View3D *v3d, Object *ob) * if not, ED_view3d_init_mats_rv3d() can be used for selection tools * but would not give correct results with dupli's for eg. which dont * use the object matrix in the useual way */ -static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s) +static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s)) { struct { void (*func)(void *userData, BMVert *eve, int x, int y, int index); void *userData; ViewContext vc; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData; BMVert *eve = EDBM_get_vert_for_index(data->vc.em, index); @@ -1561,7 +1616,7 @@ void mesh_foreachScreenEdge(ViewContext *vc, void (*func)(void *userData, BMEdge dm->release(dm); } -static void mesh_foreachScreenFace__mapFunc(void *userData, int index, float *cent, float *no) +static void mesh_foreachScreenFace__mapFunc(void *userData, int index, float *cent, float *UNUSED(no)) { struct { void (*func)(void *userData, BMFace *efa, int x, int y, int index); void *userData; ViewContext vc; float pmat[4][4], vmat[4][4]; } *data = userData; float cent2[3]; @@ -1679,7 +1734,7 @@ static void draw_dm_face_normals(BMEditMesh *em, Scene *scene, DerivedMesh *dm) glEnd(); } -static void draw_dm_face_centers__mapFunc(void *userData, int index, float *cent, float *no) +static void draw_dm_face_centers__mapFunc(void *userData, int index, float *cent, float *UNUSED(no)) { BMFace *efa = EDBM_get_face_for_index(((void **)userData)[0], index); BMEditMesh *em = ((void **)userData)[0]; @@ -1785,7 +1840,7 @@ static void draw_dm_vert_pins(BMEditMesh *em, DerivedMesh *dm, Mesh *me) } /* Draw verts with color set based on selection */ -static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s) +static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s)) { struct { BMEditMesh *em; int sel; BMVert *eve_act; } *data = userData; BMVert *eve = EDBM_get_vert_for_index(data->em, index); @@ -1955,6 +2010,8 @@ static int draw_dm_edges_pins__setDrawOptions(void *userData, int index) else { return pin; } } + + return 0; } static void draw_dm_edges_pins(BMEditMesh *em, DerivedMesh *dm, Mesh *me) @@ -1982,7 +2039,7 @@ static void draw_dm_edges_sharp(BMEditMesh *em, DerivedMesh *dm) /* Draw faces with color set based on selection * return 2 for the active face so it renders with stipple enabled */ -static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *drawSmooth_r) +static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *UNUSED(drawSmooth_r)) { struct { unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; Mesh *me;} *data = userData; BMFace *efa = EDBM_get_face_for_index(data->em, index); @@ -2035,7 +2092,7 @@ static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *ba data.efa_act = efa_act; data.me = me; - dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, &data, 0); + dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, &data, 0, GPU_enable_material); } static int draw_dm_creases__setDrawOptions(void *userData, int index) @@ -2077,7 +2134,7 @@ static int draw_dm_bweights__setDrawOptions(void *userData, int index) return 0; } } -static void draw_dm_bweights__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s) +static void draw_dm_bweights__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s)) { BMEditMesh *em = userData; BMVert *eve = EDBM_get_vert_for_index(userData, index); @@ -2126,7 +2183,7 @@ static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, if(v3d->zbuf) glDepthMask(0); // disable write in zbuffer, zbuf select for (sel=0; sel<2; sel++) { - char col[4], fcol[4]; + unsigned char col[4], fcol[4]; int pass; UI_GetThemeColor3ubv(sel?TH_VERTEX_SELECT:TH_VERTEX, col); @@ -2154,13 +2211,13 @@ static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, if(ts->selectmode & SCE_SELECT_VERTEX) { glPointSize(size); - glColor4ubv((GLubyte *)col); + glColor4ubv(col); draw_dm_verts(em, cageDM, sel, eve_act); } if(check_ob_drawface_dot(scene, v3d, obedit->dt)) { glPointSize(fsize); - glColor4ubv((GLubyte *)fcol); + glColor4ubv(fcol); draw_dm_face_centers(em, cageDM, sel); } @@ -2184,9 +2241,9 @@ static void draw_em_fancy_edges(BMEditMesh *em, Scene *scene, View3D *v3d, unsigned char wireCol[4], selCol[4], actCol[4]; /* since this function does transparant... */ - UI_GetThemeColor4ubv(TH_EDGE_SELECT, (char *)selCol); - UI_GetThemeColor4ubv(TH_WIRE, (char *)wireCol); - UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, (char *)actCol); + UI_GetThemeColor4ubv(TH_EDGE_SELECT, selCol); + UI_GetThemeColor4ubv(TH_WIRE, wireCol); + UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, actCol); /* when sel only is used, dont render wire, only selected, this is used for * textured draw mode when the 'edges' option is disabled */ @@ -2245,42 +2302,30 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, float v1[3], v2[3], v3[3], v4[3], vmid[3]; float fvec[3]; char val[32]; /* Stores the measurement display text here */ - char conv_float[5]; /* Use a float conversion matching the grid size */ - float area, col[3]; /* area of the face, color of the text to draw */ + const char *conv_float; /* Use a float conversion matching the grid size */ + unsigned char col[3]; /* color of the text to draw */ + float area; /* area of the face */ float grid= unit->system ? unit->scale_length : v3d->grid; const int do_split= unit->flag & USER_UNIT_OPT_SPLIT; const int do_global= v3d->flag & V3D_GLOBAL_STATS; const int do_moving= G.moving; - if(v3d->flag2 & V3D_RENDER_OVERRIDE) - return; - /* make the precision of the pronted value proportionate to the gridsize */ - if (grid < 0.01f) - strcpy(conv_float, "%.6f"); - else if (grid < 0.1f) - strcpy(conv_float, "%.5f"); - else if (grid < 1.0f) - strcpy(conv_float, "%.4f"); - else if (grid < 10.0f) - strcpy(conv_float, "%.3f"); - else - strcpy(conv_float, "%.2f"); - - + if (grid < 0.01f) conv_float= "%.6g"; + else if (grid < 0.1f) conv_float= "%.5g"; + else if (grid < 1.0f) conv_float= "%.4g"; + else if (grid < 10.0f) conv_float= "%.3g"; + else conv_float= "%.2g"; + if(v3d->zbuf && (v3d->flag & V3D_ZBUF_SELECT)==0) glDisable(GL_DEPTH_TEST); if(v3d->zbuf) bglPolygonOffset(rv3d->dist, 5.0f); - if(me->drawflag & ME_DRAW_EDGELEN) { - UI_GetThemeColor3fv(TH_TEXT, col); - /* make color a bit more red */ - if(col[0]> 0.5f) {col[1]*=0.7f; col[2]*= 0.7f;} - else col[0]= col[0]*0.7f + 0.3f; - glColor3fv(col); - + if(me->drawflag & ME_DRAWEXTRA_EDGELEN) { + UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGELEN, col); + for(eed= em->edges.first; eed; eed= eed->next) { /* draw non fgon edges, or selected edges, or edges next to selected verts while draging */ if((eed->h != EM_FGON) && ((eed->f & SELECT) || (do_moving && ((eed->v1->f & SELECT) || (eed->v2->f & SELECT)) ))) { @@ -2298,19 +2343,14 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, else sprintf(val, conv_float, len_v3v3(v1, v2)); - view3d_cached_text_draw_add(vmid[0], vmid[1], vmid[2], val, 0, 0); + view3d_cached_text_draw_add(vmid, val, 0, V3D_CACHE_TEXT_ASCII, col); } } } - if(me->drawflag & ME_DRAW_FACEAREA) { + if(me->drawflag & ME_DRAWEXTRA_FACEAREA) { // XXX extern int faceselectedOR(EditFace *efa, int flag); // editmesh.h shouldn't be in this file... ok for now? - - UI_GetThemeColor3fv(TH_TEXT, col); - /* make color a bit more green */ - if(col[1]> 0.5f) {col[0]*=0.7f; col[2]*= 0.7f;} - else col[1]= col[1]*0.7f + 0.3f; - glColor3fv(col); + UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEAREA, col); for(efa= em->faces.first; efa; efa= efa->next) { if((efa->f & SELECT)) { // XXX || (do_moving && faceselectedOR(efa, SELECT)) ) { @@ -2337,20 +2377,14 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, else sprintf(val, conv_float, area); - view3d_cached_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0, 0); + view3d_cached_text_draw_add(efa->cent, val, 0, V3D_CACHE_TEXT_ASCII, col); } } } - if(me->drawflag & ME_DRAW_EDGEANG) { + if(me->drawflag & ME_DRAWEXTRA_FACEANG) { EditEdge *e1, *e2, *e3, *e4; - - UI_GetThemeColor3fv(TH_TEXT, col); - /* make color a bit more blue */ - if(col[2]> 0.5f) {col[0]*=0.7f; col[1]*= 0.7f;} - else col[2]= col[2]*0.7f + 0.3f; - glColor3fv(col); - + UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col); for(efa= em->faces.first; efa; efa= efa->next) { copy_v3_v3(v1, efa->v1->co); copy_v3_v3(v2, efa->v2->co); @@ -2377,31 +2411,31 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, if( (e4->f & e1->f & SELECT) || (do_moving && (efa->v1->f & SELECT)) ) { /* Vec 1 */ - sprintf(val,"%.3f", RAD2DEG(angle_v3v3v3(v4, v1, v2))); + sprintf(val,"%.3g", RAD2DEG(angle_v3v3v3(v4, v1, v2))); interp_v3_v3v3(fvec, efa->cent, efa->v1->co, 0.8f); - view3d_cached_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0, 0); + view3d_cached_text_draw_add(fvec, val, 0, V3D_CACHE_TEXT_ASCII, col); } if( (e1->f & e2->f & SELECT) || (do_moving && (efa->v2->f & SELECT)) ) { /* Vec 2 */ - sprintf(val,"%.3f", RAD2DEG(angle_v3v3v3(v1, v2, v3))); + sprintf(val,"%.3g", RAD2DEG(angle_v3v3v3(v1, v2, v3))); interp_v3_v3v3(fvec, efa->cent, efa->v2->co, 0.8f); - view3d_cached_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0, 0); + view3d_cached_text_draw_add(fvec, val, 0, V3D_CACHE_TEXT_ASCII, col); } if( (e2->f & e3->f & SELECT) || (do_moving && (efa->v3->f & SELECT)) ) { /* Vec 3 */ if(efa->v4) - sprintf(val,"%.3f", RAD2DEG(angle_v3v3v3(v2, v3, v4))); + sprintf(val,"%.3g", RAD2DEG(angle_v3v3v3(v2, v3, v4))); else - sprintf(val,"%.3f", RAD2DEG(angle_v3v3v3(v2, v3, v1))); + sprintf(val,"%.3g", RAD2DEG(angle_v3v3v3(v2, v3, v1))); interp_v3_v3v3(fvec, efa->cent, efa->v3->co, 0.8f); - view3d_cached_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0, 0); + view3d_cached_text_draw_add(fvec, val, 0, V3D_CACHE_TEXT_ASCII, col); } /* Vec 4 */ if(efa->v4) { if( (e3->f & e4->f & SELECT) || (do_moving && (efa->v4->f & SELECT)) ) { - sprintf(val,"%.3f", RAD2DEG(angle_v3v3v3(v3, v4, v1))); + sprintf(val,"%.3g", RAD2DEG(angle_v3v3v3(v3, v4, v1))); interp_v3_v3v3(fvec, efa->cent, efa->v4->co, 0.8f); - view3d_cached_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0, 0); + view3d_cached_text_draw_add(fvec, val, 0, V3D_CACHE_TEXT_ASCII, col); } } } @@ -2414,7 +2448,7 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, #endif } -static int draw_em_fancy__setFaceOpts(void *userData, int index, int *drawSmooth_r) +static int draw_em_fancy__setFaceOpts(void *userData, int index, int *UNUSED(drawSmooth_r)) { BMFace *efa = EDBM_get_face_for_index(userData, index); @@ -2477,7 +2511,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object glEnable(GL_LIGHTING); glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW); - finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, me->edit_btmesh, 0); + finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, me->edit_btmesh, 0, GPU_enable_material); glFrontFace(GL_CCW); glDisable(GL_LIGHTING); @@ -2497,12 +2531,12 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object } } - if((me->drawflag & (ME_DRAWFACES)) || paint_facesel_test(ob)) { /* transp faces */ + if(me->drawflag & ME_DRAWFACES) { /* transp faces */ unsigned char col1[4], col2[4], col3[4]; - UI_GetThemeColor4ubv(TH_FACE, (char *)col1); - UI_GetThemeColor4ubv(TH_FACE_SELECT, (char *)col2); - UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, (char *)col3); + UI_GetThemeColor4ubv(TH_FACE, col1); + UI_GetThemeColor4ubv(TH_FACE_SELECT, col2); + UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, col3); glEnable(GL_BLEND); glDepthMask(0); // disable write in zbuffer, needed for nice transp @@ -2521,7 +2555,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object * */ unsigned char col1[4], col2[4], col3[4]; col1[3] = col2[3] = 0; /* dont draw */ - UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, (char *)col3); + UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, col3); glEnable(GL_BLEND); glDepthMask(0); // disable write in zbuffer, needed for nice transp @@ -2598,7 +2632,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object draw_dm_vert_pins(em, cageDM, me); } - if(me->drawflag & (ME_DRAW_EDGELEN|ME_DRAW_FACEAREA|ME_DRAW_EDGEANG)) + if(me->drawflag & (ME_DRAWEXTRA_EDGELEN|ME_DRAWEXTRA_FACEAREA|ME_DRAWEXTRA_FACEANG) && !((v3d->flag2 & V3D_RENDER_OVERRIDE))) draw_em_measure_stats(v3d, rv3d, ob, em, &scene->unit); } @@ -2637,7 +2671,7 @@ static void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm) } } -static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmooth_r) +static int wpaint__setSolidDrawOptions(void *userData, int UNUSED(index), int *drawSmooth_r) { *drawSmooth_r = 1; return 1; @@ -2648,11 +2682,12 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D Object *ob= base->object; Mesh *me = ob->data; Material *ma= give_current_material(ob, 1); - int hasHaloMat = (ma && (ma->material_type == MA_TYPE_HALO)); + const short hasHaloMat = (ma && (ma->material_type == MA_TYPE_HALO)); + const short is_paint_sel= (ob==OBACT && paint_facesel_test(ob)); int draw_wire = 0; - int totvert, totedge, totface; + int /* totvert,*/ totedge, totface; DispList *dl; - DerivedMesh *dm= mesh_get_derived_final(scene, ob, v3d->customdata_mask); + DerivedMesh *dm= mesh_get_derived_final(scene, ob, scene->customdata_mask); if(!dm) return; @@ -2661,7 +2696,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D draw_wire = 2; /* draw wire after solid using zoffset and depth buffer adjusment */ } - totvert = dm->getNumVerts(dm); + /* totvert = dm->getNumVerts(dm); */ /*UNUSED*/ totedge = dm->getNumEdges(dm); totface = dm->getNumTessFaces(dm); @@ -2670,7 +2705,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW); // Unwanted combination. - if (ob==OBACT && paint_facesel_test(ob)) draw_wire = 0; + if (is_paint_sel) draw_wire = 0; if(dt==OB_BOUNDBOX) { if((v3d->flag2 & V3D_RENDER_OVERRIDE && v3d->drawtype >= OB_WIRE)==0) @@ -2684,11 +2719,10 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D else if(dt==OB_WIRE || totface==0) { draw_wire = 1; /* draw wire only, no depth buffer stuff */ } - else if( (ob==OBACT && (ob->mode & OB_MODE_TEXTURE_PAINT || paint_facesel_test(ob))) || + else if( (is_paint_sel || (ob==OBACT && ob->mode & OB_MODE_TEXTURE_PAINT)) || CHECK_OB_DRAWTEXTURE(v3d, dt)) { - int faceselect= (ob==OBACT && paint_facesel_test(ob)); - if ((v3d->flag&V3D_SELECT_OUTLINE) && ((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) && (base->flag&SELECT) && !(G.f&G_PICKSEL || paint_facesel_test(ob)) && !draw_wire) { + if ((v3d->flag&V3D_SELECT_OUTLINE) && ((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) && (base->flag&SELECT) && !(G.f&G_PICKSEL || is_paint_sel) && !draw_wire) { draw_mesh_object_outline(v3d, ob, dm); } @@ -2703,10 +2737,10 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D glFrontFace(GL_CCW); } else { - draw_mesh_textured(scene, v3d, rv3d, ob, dm, faceselect); + draw_mesh_textured(scene, v3d, rv3d, ob, dm, is_paint_sel); } - if(!faceselect) { + if(!is_paint_sel) { if(base->flag & SELECT) UI_ThemeColor((ob==OBACT)?TH_ACTIVE:TH_SELECT); else @@ -2721,25 +2755,26 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D /* weight paint in solid mode, special case. focus on making the weights clear * rather then the shading, this is also forced in wire view */ GPU_enable_material(0, NULL); - dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me->mface, 1); - + dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me->mface, 1, GPU_enable_material); + bglPolygonOffset(rv3d->dist, 1.0); glDepthMask(0); // disable write in zbuffer, selected edge wires show better glEnable(GL_BLEND); - glColor4ub(196, 196, 196, 196); + glColor4ub(255, 255, 255, 96); glEnable(GL_LINE_STIPPLE); - glLineStipple(1, 0x8888); + glLineStipple(1, 0xAAAA); - dm->drawEdges(dm, 1, 0); + dm->drawEdges(dm, 1, 1); bglPolygonOffset(rv3d->dist, 0.0); glDepthMask(1); glDisable(GL_LINE_STIPPLE); GPU_disable_material(); - - + + /* since we already draw wire as wp guide, dont draw over the top */ + draw_wire= 0; } else { Paint *p; @@ -2803,7 +2838,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D glEnable(GL_LIGHTING); glEnable(GL_COLOR_MATERIAL); - dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me->mface, 1); + dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me->mface, 1, GPU_enable_material); glDisable(GL_COLOR_MATERIAL); glDisable(GL_LIGHTING); @@ -2811,10 +2846,10 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D } else if(ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_TEXTURE_PAINT)) { if(me->mcol) - dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 1); + dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 1, GPU_enable_material); else { glColor3f(1.0f, 1.0f, 1.0f); - dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 0); + dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 0, GPU_enable_material); } } else do_draw= 1; @@ -2827,7 +2862,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D dm->release(dm); shadeDispList(scene, base); dl = find_displist(&ob->disp, DL_VERTCOL); - dm= mesh_get_derived_final(scene, ob, v3d->customdata_mask); + dm= mesh_get_derived_final(scene, ob, scene->customdata_mask); } if ((v3d->flag&V3D_SELECT_OUTLINE) && ((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) && (base->flag&SELECT) && !draw_wire) { @@ -2936,7 +2971,7 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D finalDM = cageDM = editbmesh_get_derived_base(ob, em); else cageDM = editbmesh_get_derived_cage_and_final(scene, ob, em, &finalDM, - v3d->customdata_mask); + scene->customdata_mask); if(dt>OB_WIRE) { // no transp in editmode, the fancy draw over goes bad then @@ -3277,12 +3312,15 @@ static int drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d, B int glsl = draw_glsl_material(scene, ob, v3d, dt); GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL); - if (!glsl) + if(!glsl) { glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0); + glEnable(GL_LIGHTING); + dm->drawFacesSolid(dm, NULL, 0, GPU_enable_material); + glDisable(GL_LIGHTING); + } + else + dm->drawFacesGLSL(dm, GPU_enable_material); - glEnable(GL_LIGHTING); - dm->drawFacesSolid(dm, NULL, 0, GPU_enable_material); - glDisable(GL_LIGHTING); GPU_end_object_materials(); } else { if((v3d->flag2 & V3D_RENDER_OVERRIDE && v3d->drawtype >= OB_SOLID)==0) @@ -3312,7 +3350,7 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas case OB_CURVE: cu= ob->data; - lb= &cu->disp; + lb= &ob->disp; if(solid) { dl= lb->first; @@ -3359,7 +3397,7 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas break; case OB_SURF: - lb= &((Curve *)ob->data)->disp; + lb= &ob->disp; if(solid) { dl= lb->first; @@ -3452,16 +3490,22 @@ static void draw_particle_arrays(int draw_as, int totpoint, int ob_dt, int selec static void draw_particle(ParticleKey *state, int draw_as, short draw, float pixsize, float imat[4][4], float *draw_line, ParticleBillboardData *bb, ParticleDrawData *pdd) { float vec[3], vec2[3]; - float *vd = pdd->vd; - float *cd = pdd->cd; + float *vd = NULL; + float *cd = NULL; float ma_r=0.0f; float ma_g=0.0f; float ma_b=0.0f; - if(pdd->ma_r) { - ma_r = *pdd->ma_r; - ma_g = *pdd->ma_g; - ma_b = *pdd->ma_b; + /* null only for PART_DRAW_CIRC */ + if(pdd) { + vd = pdd->vd; + cd = pdd->cd; + + if(pdd->ma_r) { + ma_r = *pdd->ma_r; + ma_g = *pdd->ma_g; + ma_b = *pdd->ma_b; + } } switch(draw_as){ @@ -3485,13 +3529,15 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix vec[1]=vec[2]=0.0; mul_qt_v3(state->rot,vec); if(draw_as==PART_DRAW_AXIS) { - cd[1]=cd[2]=cd[4]=cd[5]=0.0; - cd[0]=cd[3]=1.0; - cd[6]=cd[8]=cd[9]=cd[11]=0.0; - cd[7]=cd[10]=1.0; - cd[13]=cd[12]=cd[15]=cd[16]=0.0; - cd[14]=cd[17]=1.0; - pdd->cd+=18; + if(cd) { + cd[1]=cd[2]=cd[4]=cd[5]=0.0; + cd[0]=cd[3]=1.0; + cd[6]=cd[8]=cd[9]=cd[11]=0.0; + cd[7]=cd[10]=1.0; + cd[13]=cd[12]=cd[15]=cd[16]=0.0; + cd[14]=cd[17]=1.0; + pdd->cd+=18; + } copy_v3_v3(vec2,state->co); } @@ -3553,8 +3599,6 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix } case PART_DRAW_CIRC: { - if(pdd->ma_r) - glColor3f(ma_r,ma_g,ma_b); drawcircball(GL_LINE_LOOP, state->co, pixsize, imat); break; } @@ -3607,24 +3651,24 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, ParticleSystem *psys, int ob_dt) { Object *ob=base->object; - ParticleSystemModifierData *psmd; ParticleEditSettings *pset = PE_settings(scene); ParticleSettings *part; ParticleData *pars, *pa; ParticleKey state, *states=0; ParticleBillboardData bb; - ParticleSimulationData sim = {scene, ob, psys, NULL}; + ParticleSimulationData sim= {0}; ParticleDrawData *pdd = psys->pdd; Material *ma; float vel[3], imat[4][4]; float timestep, pixsize=1.0, pa_size, r_tilt, r_length; float pa_time, pa_birthtime, pa_dietime, pa_health; - float cfra= bsystem_time(scene, ob,(float)CFRA,0.0); + float cfra; float ma_r=0.0f, ma_g=0.0f, ma_b=0.0f; int a, totpart, totpoint=0, totve=0, drawn, draw_as, totchild=0; int select=ob->flag&SELECT, create_cdata=0, need_v=0; GLint polygonmode[2]; char val[32]; + unsigned char tcol[4]= {0, 0, 0, 255}; /* 1. */ if(psys==0) @@ -3651,7 +3695,10 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv return; /* 2. */ - sim.psmd = psmd = psys_get_modifier(ob,psys); + sim.scene= scene; + sim.ob= ob; + sim.psys= psys; + sim.psmd = psys_get_modifier(ob,psys); if(part->phystype==PART_PHYS_KEYED){ if(psys->flag&PSYS_KEYED){ @@ -3679,20 +3726,14 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv if(v3d->zbuf) glDepthMask(1); if((ma) && (part->draw&PART_DRAW_MAT_COL)) { - glColor3f(ma->r,ma->g,ma->b); + rgb_float_to_byte(&(ma->r), tcol); ma_r = ma->r; ma_g = ma->g; ma_b = ma->b; } - else - cpack(0); - if(pdd) { - pdd->ma_r = &ma_r; - pdd->ma_g = &ma_g; - pdd->ma_b = &ma_b; - } + glColor3ubv(tcol); timestep= psys_get_timestep(&sim); @@ -3729,8 +3770,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv case PART_DRAW_CROSS: case PART_DRAW_AXIS: /* lets calculate the scale: */ - pixsize= rv3d->persmat[0][3]*ob->obmat[3][0]+ rv3d->persmat[1][3]*ob->obmat[3][1]+ rv3d->persmat[2][3]*ob->obmat[3][2]+ rv3d->persmat[3][3]; - pixsize*= rv3d->pixsize; + pixsize= view3d_pixel_size(rv3d, ob->obmat[3]); + if(part->draw_size==0.0) pixsize*=2.0; else @@ -3846,12 +3887,24 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv pdd->nd= pdd->ndata; pdd->tot_vec_size= tot_vec_size; } + else if(psys->pdd) { + psys_free_pdd(psys); + MEM_freeN(psys->pdd); + pdd = psys->pdd = NULL; + } + + if(pdd) { + pdd->ma_r = &ma_r; + pdd->ma_g = &ma_g; + pdd->ma_b = &ma_b; + } psys->lattice= psys_get_lattice(&sim); - if(pdd && draw_as!=PART_DRAW_PATH){ + /* circles don't use drawdata, so have to add a special case here */ + if((pdd || draw_as==PART_DRAW_CIRC) && draw_as!=PART_DRAW_PATH){ /* 5. */ - if((pdd->flag & PARTICLE_DRAW_DATA_UPDATED) + if(pdd && (pdd->flag & PARTICLE_DRAW_DATA_UPDATED) && (pdd->vedata || part->draw & (PART_DRAW_SIZE|PART_DRAW_NUM|PART_DRAW_HEALTH))==0) { totpoint = pdd->totpoint; /* draw data is up to date */ } @@ -3997,7 +4050,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv if(drawn) { /* additional things to draw for each particle */ /* (velocity, size and number) */ - if((part->draw & PART_DRAW_VEL) && pdd->vedata){ + if((part->draw & PART_DRAW_VEL) && pdd && pdd->vedata){ copy_v3_v3(pdd->ved,state.co); pdd->ved += 3; mul_v3_v3fl(vel, state.vel, timestep); @@ -4019,16 +4072,24 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv char *val_pos= val; val[0]= '\0'; - if(part->draw&PART_DRAW_NUM) - val_pos += sprintf(val, "%i", a); - - if((part->draw & PART_DRAW_HEALTH) && a < totpart && part->phystype==PART_PHYS_BOIDS) - sprintf(val_pos, (val_pos==val) ? "%.2f" : ":%.2f", pa_health); + if(part->draw&PART_DRAW_NUM) { + if(a < totpart && (part->draw & PART_DRAW_HEALTH) && (part->phystype==PART_PHYS_BOIDS)) { + sprintf(val_pos, "%d:%.2f", a, pa_health); + } + else { + sprintf(val_pos, "%d", a); + } + } + else { + if(a < totpart && (part->draw & PART_DRAW_HEALTH) && (part->phystype==PART_PHYS_BOIDS)) { + sprintf(val_pos, "%.2f", pa_health); + } + } /* in path drawing state.co is the end point */ /* use worldspace beause object matrix is already applied */ mul_v3_m4v3(vec_txt, ob->imat, state.co); - view3d_cached_text_draw_add(vec_txt[0], vec_txt[1], vec_txt[2], val, 10, V3D_CACHE_TEXT_WORLDSPACE); + view3d_cached_text_draw_add(vec_txt, val, 10, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII, tcol); } } } @@ -4117,12 +4178,10 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv for(a=0, pa=psys->particles; a<totpart; a++, pa++){ float vec_txt[3]; - val[0]= '\0'; - sprintf(val, "%i", a); /* use worldspace beause object matrix is already applied */ mul_v3_m4v3(vec_txt, ob->imat, cache[a]->co); - view3d_cached_text_draw_add(vec_txt[0], vec_txt[1], vec_txt[2], val, 10, V3D_CACHE_TEXT_WORLDSPACE); + view3d_cached_text_draw_add(vec_txt, val, 10, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII, tcol); } } } @@ -4214,8 +4273,14 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv psys->lattice= NULL; } - if( (base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP) ) + if(pdd) { + /* drop references to stack memory */ + pdd->ma_r= pdd->ma_g= pdd->ma_b= NULL; + } + + if( (base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP) ) { glLoadMatrixf(rv3d->viewmat); + } } static void draw_update_ptcache_edit(Scene *scene, Object *ob, PTCacheEdit *edit) @@ -4228,7 +4293,7 @@ static void draw_update_ptcache_edit(Scene *scene, Object *ob, PTCacheEdit *edit psys_cache_edit_paths(scene, ob, edit, CFRA); } -static void draw_ptcache_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, PTCacheEdit *edit, int dt) +static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit) { ParticleCacheKey **cache, *path, *pkey; PTCacheEditPoint *point; @@ -4263,8 +4328,8 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Obj glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); - glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); glShadeModel(GL_SMOOTH); if(pset->brushtype == PE_BRUSH_WEIGHT) { @@ -4933,9 +4998,17 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, while (nr-->0) { /* accounts for empty bevel lists */ float fac= bevp->radius * ts->normalsize; - float vec_a[3] = { fac,0, 0}; // Offset perpendicular to the curve - float vec_b[3] = {-fac,0, 0}; // Delta along the curve + float vec_a[3]; // Offset perpendicular to the curve + float vec_b[3]; // Delta along the curve + + vec_a[0]= fac; + vec_a[1]= 0.0f; + vec_a[2]= 0.0f; + vec_b[0]= -fac; + vec_b[1]= 0.0f; + vec_b[2]= 0.0f; + mul_qt_v3(bevp->quat, vec_a); mul_qt_v3(bevp->quat, vec_b); add_v3_v3(vec_a, bevp->vec); @@ -4974,7 +5047,7 @@ static void draw_empty_sphere (float size) GLUquadricObj *qobj; displist= glGenLists(1); - glNewList(displist, GL_COMPILE_AND_EXECUTE); + glNewList(displist, GL_COMPILE); glPushMatrix(); @@ -4995,8 +5068,8 @@ static void draw_empty_sphere (float size) } glScalef(size, size, size); - glCallList(displist); - glScalef(1/size, 1/size, 1/size); + glCallList(displist); + glScalef(1.0f/size, 1.0f/size, 1.0f/size); } /* draw a cone for use as an empty drawtype */ @@ -5022,9 +5095,9 @@ static void draw_empty_cone (float size) } /* draw points on curve speed handles */ +#if 0 // XXX old animation system stuff static void curve_draw_speed(Scene *scene, Object *ob) { -#if 0 // XXX old animation system stuff Curve *cu= ob->data; IpoCurve *icu; BezTriple *bezt; @@ -5050,8 +5123,8 @@ static void curve_draw_speed(Scene *scene, Object *ob) glPointSize(1.0); bglEnd(); -#endif // XXX old animation system stuff } +#endif // XXX old animation system stuff static void draw_textcurs(float textcurs[][2]) @@ -5436,7 +5509,8 @@ static void draw_box(float vec[8][3]) } /* uses boundbox, function used by Ketsji */ -void get_local_bounds(Object *ob, float *center, float *size) +#if 0 +static void get_local_bounds(Object *ob, float *center, float *size) { BoundBox *bb= object_get_boundbox(ob); @@ -5454,8 +5528,7 @@ void get_local_bounds(Object *ob, float *center, float *size) center[2]= (bb->vec[0][2] + bb->vec[1][2])/2.0; } } - - +#endif static void draw_bb_quadric(BoundBox *bb, short type) { @@ -5498,7 +5571,7 @@ static void draw_bb_quadric(BoundBox *bb, short type) static void draw_bounding_volume(Scene *scene, Object *ob) { - BoundBox *bb=0; + BoundBox *bb= NULL; if(ob->type==OB_MESH) { bb= mesh_get_bb(ob); @@ -5507,10 +5580,12 @@ static void draw_bounding_volume(Scene *scene, Object *ob) bb= ob->bb ? ob->bb : ( (Curve *)ob->data )->bb; } else if(ob->type==OB_MBALL) { - bb= ob->bb; - if(bb==0) { - makeDispListMBall(scene, ob); + if(is_basis_mball(ob)) { bb= ob->bb; + if(bb==NULL) { + makeDispListMBall(scene, ob); + bb= ob->bb; + } } } else { @@ -5518,7 +5593,7 @@ static void draw_bounding_volume(Scene *scene, Object *ob) return; } - if(bb==0) return; + if(bb==NULL) return; if(ob->boundtype==OB_BOUND_BOX) draw_box(bb->vec); else draw_bb_quadric(bb, ob->boundtype); @@ -5561,7 +5636,7 @@ static void drawtexspace(Object *ob) } /* draws wire outline */ -static void drawSolidSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base) +static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base) { RegionView3D *rv3d= ar->regiondata; Object *ob= base->object; @@ -5577,7 +5652,7 @@ static void drawSolidSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base) if (dm) { hasfaces= dm->getNumFaces(dm); } else { - hasfaces= displist_has_faces(&cu->disp); + hasfaces= displist_has_faces(&ob->disp); } if (hasfaces && boundbox_clip(rv3d, ob->obmat, ob->bb ? ob->bb : cu->bb)) { @@ -5585,13 +5660,15 @@ static void drawSolidSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base) if (dm) { draw_mesh_object_outline(v3d, ob, dm); } else { - drawDispListwire(&cu->disp); + drawDispListwire(&ob->disp); } draw_index_wire= 1; } } else if (ob->type==OB_MBALL) { - if((base->flag & OB_FROMDUPLI)==0) - drawDispListwire(&ob->disp); + if(is_basis_mball(ob)) { + if((base->flag & OB_FROMDUPLI)==0) + drawDispListwire(&ob->disp); + } } else if(ob->type==OB_ARMATURE) { if(!(ob->mode & OB_MODE_POSE)) @@ -5638,14 +5715,16 @@ static void drawWireExtra(Scene *scene, RegionView3D *rv3d, Object *ob) if (ob->derivedFinal) { drawCurveDMWired(ob); } else { - drawDispListwire(&cu->disp); + drawDispListwire(&ob->disp); } if (ob->type==OB_CURVE) draw_index_wire= 1; } } else if (ob->type==OB_MBALL) { - drawDispListwire(&ob->disp); + if(is_basis_mball(ob)) { + drawDispListwire(&ob->disp); + } } glDepthMask(1); @@ -5682,34 +5761,40 @@ static void draw_hooks(Object *ob) } } -//<rcruiz> -void drawRBpivot(bRigidBodyJointConstraint *data) +static void drawRBpivot(bRigidBodyJointConstraint *data) { int axis; - float v1[3]= {data->pivX, data->pivY, data->pivZ}; - float eu[3]= {data->axX, data->axY, data->axZ}; float mat[4][4]; - eul_to_mat4(mat,eu); + /* color */ + float curcol[4]; + unsigned char tcol[4]; + glGetFloatv(GL_CURRENT_COLOR, curcol); + rgb_float_to_byte(curcol, tcol); + tcol[3]= 255; + + eul_to_mat4(mat,&data->axX); glLineWidth (4.0f); setlinestyle(2); for (axis=0; axis<3; axis++) { float dir[3] = {0,0,0}; - float v[3]= {data->pivX, data->pivY, data->pivZ}; + float v[3]; + + copy_v3_v3(v, &data->pivX); dir[axis] = 1.f; glBegin(GL_LINES); mul_m4_v3(mat,dir); add_v3_v3(v, dir); - glVertex3fv(v1); + glVertex3fv(&data->pivX); glVertex3fv(v); glEnd(); if (axis==0) - view3d_cached_text_draw_add(v[0], v[1], v[2], "px", 0, 0); + view3d_cached_text_draw_add(v, "px", 0, V3D_CACHE_TEXT_ASCII, tcol); else if (axis==1) - view3d_cached_text_draw_add(v[0], v[1], v[2], "py", 0, 0); + view3d_cached_text_draw_add(v, "py", 0, V3D_CACHE_TEXT_ASCII, tcol); else - view3d_cached_text_draw_add(v[0], v[1], v[2], "pz", 0, 0); + view3d_cached_text_draw_add(v, "pz", 0, V3D_CACHE_TEXT_ASCII, tcol); } glLineWidth (1.0f); setlinestyle(0); @@ -5847,13 +5932,13 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) bAnimVizSettings *avs= &ob->avs; /* setup drawing environment for paths */ - draw_motion_paths_init(scene, v3d, ar); + draw_motion_paths_init(v3d, ar); /* draw motion path for object */ - draw_motion_path_instance(scene, v3d, ar, ob, NULL, avs, ob->mpath); + draw_motion_path_instance(scene, ob, NULL, avs, ob->mpath); /* cleanup after drawing */ - draw_motion_paths_cleanup(scene, v3d, ar); + draw_motion_paths_cleanup(v3d); } /* multiply view with object matrix. @@ -5950,17 +6035,16 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* bad exception, solve this! otherwise outline shows too late */ if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { - cu= ob->data; /* still needed for curves hidden in other layers. depgraph doesnt handle that yet */ - if (cu->disp.first==NULL) makeDispListCurveTypes(scene, ob, 0); + if (ob->disp.first==NULL) makeDispListCurveTypes(scene, ob, 0); } - /* draw outline for selected solid objects, mesh does itself */ + /* draw outline for selected objects, mesh does itself */ if((v3d->flag & V3D_SELECT_OUTLINE) && ((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) && ob->type!=OB_MESH) { - if(dt>OB_WIRE && dt<OB_TEXTURE && (ob->mode & OB_MODE_EDIT)==0 && (flag & DRAW_SCENESET)==0) { + if(dt>OB_WIRE && (ob->mode & OB_MODE_EDIT)==0 && (flag & DRAW_SCENESET)==0) { if (!(ob->dtx&OB_DRAWWIRE) && (ob->flag&SELECT) && !(flag&DRAW_PICKING)) { - drawSolidSelect(scene, v3d, ar, base); + drawObjectSelect(scene, v3d, ar, base); } } } @@ -6077,9 +6161,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) } else if(boundbox_clip(rv3d, ob->obmat, ob->bb ? ob->bb : cu->bb)) { empty_object= drawDispList(scene, v3d, rv3d, base, dt); - - if(cu->path) - curve_draw_speed(scene, ob); + +//XXX old animsys if(cu->path) +// curve_draw_speed(scene, ob); } break; case OB_MBALL: @@ -6098,7 +6182,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) } case OB_EMPTY: if((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) - drawaxes(ob->empty_drawsize, flag, ob->empty_drawtype); + drawaxes(ob->empty_drawsize, ob->empty_drawtype); break; case OB_LAMP: if((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) { @@ -6124,7 +6208,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) break; default: if((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) { - drawaxes(1.0, flag, OB_ARROWS); + drawaxes(1.0, OB_ARROWS); } } @@ -6177,7 +6261,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) draw_new_particle_system(scene, v3d, rv3d, base, psys, dt); } - + invert_m4_m4(ob->imat, ob->obmat); view3d_cached_text_draw_end(v3d, ar, 0, NULL); glMultMatrixf(ob->obmat); @@ -6196,7 +6280,8 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) PTCacheEdit *edit = PE_create_current(scene, ob); if(edit) { glLoadMatrixf(rv3d->viewmat); - draw_ptcache_edit(scene, v3d, rv3d, ob, edit, dt); + draw_update_ptcache_edit(scene, ob, edit); + draw_ptcache_edit(scene, v3d, edit); glMultMatrixf(ob->obmat); } } @@ -6245,12 +6330,14 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) // only draw domains if(smd->domain && smd->domain->fluid) { - if(!smd->domain->wt || !(smd->domain->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) + if(CFRA < smd->domain->point_cache[0]->startframe) + ; /* don't show smoke before simulation starts, this could be made an option in the future */ + else if(!smd->domain->wt || !(smd->domain->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { // #if 0 smd->domain->tex = NULL; GPU_create_smoke(smd, 0); - draw_volume(scene, ar, v3d, base, smd->domain->tex, smd->domain->p0, smd->domain->p1, smd->domain->res, smd->domain->dx, smd->domain->tex_shadow); + draw_volume(ar, smd->domain->tex, smd->domain->p0, smd->domain->p1, smd->domain->res, smd->domain->dx, smd->domain->tex_shadow); GPU_free_smoke(smd); // #endif #if 0 @@ -6301,7 +6388,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) { smd->domain->tex = NULL; GPU_create_smoke(smd, 1); - draw_volume(scene, ar, v3d, base, smd->domain->tex, smd->domain->p0, smd->domain->p1, smd->domain->res_wt, smd->domain->dx_wt, smd->domain->tex_shadow); + draw_volume(ar, smd->domain->tex, smd->domain->p0, smd->domain->p1, smd->domain->res_wt, smd->domain->dx_wt, smd->domain->tex_shadow); GPU_free_smoke(smd); } } @@ -6324,7 +6411,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) if(dtx && (G.f & G_RENDER_OGL)==0) { if(dtx & OB_AXIS) { - drawaxes(1.0f, flag, OB_ARROWS); + drawaxes(1.0f, OB_ARROWS); } if(dtx & OB_BOUNDBOX) { if((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) @@ -6335,7 +6422,13 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing */ /* but, we also dont draw names for sets or duplicators */ if(flag == 0) { - view3d_cached_text_draw_add(0.0f, 0.0f, 0.0f, ob->id.name+2, 10, 0); + float zero[3]= {0,0,0}; + float curcol[4]; + unsigned char tcol[4]; + glGetFloatv(GL_CURRENT_COLOR, curcol); + rgb_float_to_byte(curcol, tcol); + tcol[3]= 255; + view3d_cached_text_draw_add(zero, ob->id.name+2, 10, 0, tcol); } } /*if(dtx & OB_DRAWIMAGE) drawDispListwire(&ob->disp);*/ @@ -6357,6 +6450,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) } /* return warning, this is cached text draw */ + invert_m4_m4(ob->imat, ob->obmat); view3d_cached_text_draw_end(v3d, ar, 1, NULL); glLoadMatrixf(rv3d->viewmat); @@ -6415,15 +6509,16 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) } /* Drawing the constraint lines */ - list = &ob->constraints; - if (list) { + if (ob->constraints.first) { bConstraint *curcon; bConstraintOb *cob; - char col[4], col2[4]; + unsigned char col1[4], col2[4]; + + list = &ob->constraints; - UI_GetThemeColor3ubv(TH_GRID, col); - UI_make_axis_color(col, col2, 'z'); - glColor3ubv((GLubyte *)col2); + UI_GetThemeColor3ubv(TH_GRID, col1); + UI_make_axis_color(col1, col2, 'Z'); + glColor3ubv(col2); cob= constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT); @@ -6464,7 +6559,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* ***************** BACKBUF SEL (BBS) ********* */ -static void bbs_mesh_verts__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s) +static void bbs_mesh_verts__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s)) { void **ptrs = userData; int offset = (intptr_t) ptrs[0]; @@ -6505,7 +6600,7 @@ static void bbs_mesh_wire(BMEditMesh *em, DerivedMesh *dm, int offset) dm->drawMappedEdges(dm, bbs_mesh_wire__setDrawOptions, ptrs); } -static int bbs_mesh_solid__setSolidDrawOptions(void *userData, int index, int *drawSmooth_r) +static int bbs_mesh_solid__setSolidDrawOptions(void *userData, int index, int *UNUSED(drawSmooth_r)) { if (!BM_TestHFlag(EDBM_get_face_for_index(((void**)userData)[0], index), BM_HIDDEN)) { if (((void**)userData)[1]) { @@ -6517,7 +6612,7 @@ static int bbs_mesh_solid__setSolidDrawOptions(void *userData, int index, int *d } } -static void bbs_mesh_solid__drawCenter(void *userData, int index, float *cent, float *no) +static void bbs_mesh_solid__drawCenter(void *userData, int index, float *cent, float *UNUSED(no)) { BMFace *efa = EDBM_get_face_for_index(((void**)userData)[0], index); @@ -6537,7 +6632,7 @@ static void bbs_mesh_solid_EM(BMEditMesh *em, Scene *scene, View3D *v3d, if (facecol) { ptrs[1] = (void*)(intptr_t) 1; - dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, ptrs, 0); + dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, ptrs, 0, GPU_enable_material); if(check_ob_drawface_dot(scene, v3d, ob->dt)) { glPointSize(UI_GetThemeValuef(TH_FACEDOT_SIZE)); @@ -6548,17 +6643,17 @@ static void bbs_mesh_solid_EM(BMEditMesh *em, Scene *scene, View3D *v3d, } } else { - dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, ptrs, 0); + dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, ptrs, 0, GPU_enable_material); } } -static int bbs_mesh_solid__setDrawOpts(void *userData, int index, int *drawSmooth_r) +static int bbs_mesh_solid__setDrawOpts(void *userData, int index, int *UNUSED(drawSmooth_r)) { WM_set_framebuffer_index_color(index+1); return 1; } -static int bbs_mesh_solid_hide__setDrawOpts(void *userData, int index, int *drawSmooth_r) +static int bbs_mesh_solid_hide__setDrawOpts(void *userData, int index, int *UNUSED(drawSmooth_r)) { Mesh *me = userData; @@ -6570,16 +6665,15 @@ static int bbs_mesh_solid_hide__setDrawOpts(void *userData, int index, int *draw } } -static void bbs_mesh_solid(Scene *scene, View3D *v3d, Object *ob) +static void bbs_mesh_solid(Scene *scene, Object *ob) { - DerivedMesh *dm = mesh_get_derived_final(scene, ob, v3d->customdata_mask); + DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask); Mesh *me = (Mesh*)ob->data; - int face_sel_mode = (me->flag & ME_EDIT_PAINT_MASK) ? 1:0; glColor3ub(0, 0, 0); - if(face_sel_mode) dm->drawMappedFaces(dm, bbs_mesh_solid_hide__setDrawOpts, me, 0); - else dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, me, 0); + if((me->editflag & ME_EDIT_PAINT_MASK)) dm->drawMappedFaces(dm, bbs_mesh_solid_hide__setDrawOpts, me, 0, GPU_enable_material); + else dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, me, 0, GPU_enable_material); dm->release(dm); } @@ -6629,7 +6723,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec EDBM_free_index_arrays(em); } - else bbs_mesh_solid(scene, v3d, ob); + else bbs_mesh_solid(scene, ob); } break; case OB_CURVE: @@ -6686,7 +6780,7 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r GPU_end_object_materials(); } else if(edm) - edm->drawMappedFaces(edm, NULL, NULL, 0); + edm->drawMappedFaces(edm, NULL, NULL, 0, GPU_enable_material); glDisable(GL_LIGHTING); } @@ -6705,7 +6799,7 @@ void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object draw_object_mesh_instance(scene, v3d, rv3d, ob, dt, outline); break; case OB_EMPTY: - drawaxes(ob->empty_drawsize, 0, ob->empty_drawtype); + drawaxes(ob->empty_drawsize, ob->empty_drawtype); break; } } diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index f8cd34cf849..a2eefa2aad1 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -31,10 +31,6 @@ #include "MEM_guardedalloc.h" - - - - #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_view3d_types.h" @@ -44,6 +40,7 @@ #include "BLI_editVert.h" #include "BLI_edgehash.h" #include "BLI_rand.h" +#include "BLI_utildefines.h" #include "BKE_curve.h" #include "BKE_constraint.h" // for the get_constraint_target function @@ -65,7 +62,7 @@ #include "BKE_particle.h" #include "BKE_property.h" #include "BKE_smoke.h" -#include "BKE_utildefines.h" + #include "smoke_API.h" #include "BIF_gl.h" @@ -100,7 +97,7 @@ static void tend ( void ) { QueryPerformanceCounter ( &liCurrentTime ); } -static double tval() +static double tval( void ) { return ((double)( (liCurrentTime.QuadPart - liStartTime.QuadPart)* (double)1000.0/(double)liFrequency.QuadPart )); } @@ -124,12 +121,12 @@ static double tval() t2 = ( double ) _tend.tv_sec*1000 + ( double ) _tend.tv_usec/ ( 1000 ); return t2-t1; } -#endif + #endif #endif struct GPUTexture; -int intersect_edges(float *points, float a, float b, float c, float d, float edges[12][2][3]) +static int intersect_edges(float *points, float a, float b, float c, float d, float edges[12][2][3]) { int i; float t; @@ -175,7 +172,7 @@ static int larger_pow2(int n) return n*2; } -void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture *tex, float *min, float *max, int res[3], float dx, GPUTexture *tex_shadow) +void draw_volume(ARegion *ar, GPUTexture *tex, float *min, float *max, int res[3], float dx, GPUTexture *tex_shadow) { RegionView3D *rv3d= ar->regiondata; diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 8fbe764c633..dd3b5f42b89 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -37,10 +37,13 @@ #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_rand.h" +#include "BLI_utildefines.h" +#include "BKE_object.h" #include "BKE_context.h" #include "BKE_screen.h" +#include "ED_space_api.h" #include "ED_screen.h" #include "ED_object.h" @@ -191,21 +194,24 @@ static SpaceLink *view3d_new(const bContext *C) v3d->lay= v3d->layact= scene->lay; v3d->camera= scene->camera; } - v3d->scenelock= 1; + v3d->scenelock= TRUE; v3d->grid= 1.0f; v3d->gridlines= 16; v3d->gridsubdiv = 10; - v3d->drawtype= OB_WIRE; + v3d->drawtype= OB_SOLID; v3d->gridflag |= V3D_SHOW_X; v3d->gridflag |= V3D_SHOW_Y; v3d->gridflag |= V3D_SHOW_FLOOR; v3d->gridflag &= ~V3D_SHOW_Z; + v3d->flag |= V3D_SELECT_OUTLINE; + v3d->lens= 35.0f; v3d->near= 0.01f; v3d->far= 500.0f; + v3d->twflag |= U.tw_flag & V3D_USE_MANIPULATOR; v3d->twtype= V3D_MANIP_TRANSLATE; v3d->around= V3D_CENTROID; @@ -249,8 +255,8 @@ static SpaceLink *view3d_new(const bContext *C) ar->regiondata= MEM_callocN(sizeof(RegionView3D), "region view3d"); rv3d= ar->regiondata; rv3d->viewquat[0]= 1.0f; - rv3d->persp= 1; - rv3d->view= 7; + rv3d->persp= RV3D_PERSP; + rv3d->view= RV3D_VIEW_PERSPORTHO; rv3d->dist= 10.0; return (SpaceLink *)v3d; @@ -274,7 +280,7 @@ static void view3d_free(SpaceLink *sl) /* spacetype; init callback */ -static void view3d_init(struct wmWindowManager *wm, ScrArea *sa) +static void view3d_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa)) { } @@ -316,6 +322,10 @@ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar) /* object ops. */ + /* important to be before Pose keymap since they can both be enabled at once */ + keymap= WM_keymap_find(wm->defaultconf, "Face Mask", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + /* pose is not modal, operator poll checks for this */ keymap= WM_keymap_find(wm->defaultconf, "Pose", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); @@ -331,9 +341,6 @@ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar) keymap= WM_keymap_find(wm->defaultconf, "Weight Paint", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - - keymap= WM_keymap_find(wm->defaultconf, "Face Mask", 0, 0); - WM_event_add_keymap_handler(&ar->handlers, keymap); keymap= WM_keymap_find(wm->defaultconf, "Sculpt", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); @@ -387,7 +394,7 @@ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar) } -static int view3d_ob_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) +static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event)) { if(drag->type==WM_DRAG_ID) { ID *id= (ID *)drag->poin; @@ -397,7 +404,7 @@ static int view3d_ob_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) return 0; } -static int view3d_mat_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) +static int view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event)) { if(drag->type==WM_DRAG_ID) { ID *id= (ID *)drag->poin; @@ -407,26 +414,27 @@ static int view3d_mat_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) return 0; } -static int view3d_ima_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) +static int view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event)) { - if(drag->type==WM_DRAG_ID) { - ID *id= (ID *)drag->poin; - if( GS(id->name)==ID_IM ) - return 1; - } - else if(drag->type==WM_DRAG_PATH){ - if(ELEM(drag->icon, 0, ICON_FILE_IMAGE)) /* rule might not work? */ - return 1; - } - return 0; + if(drag->type==WM_DRAG_ID) { + ID *id= (ID *)drag->poin; + if( GS(id->name)==ID_IM ) + return 1; } + else if(drag->type==WM_DRAG_PATH){ + if(ELEM(drag->icon, 0, ICON_FILE_IMAGE)) /* rule might not work? */ + return 1; + } + return 0; +} static int view3d_ima_bg_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) { if( ED_view3d_give_base_under_cursor(C, event->mval) ) { - return 0; -} + return 0; + } + return view3d_ima_drop_poll(C, drag, event); } @@ -477,7 +485,7 @@ static void view3d_dropboxes(void) WM_dropbox_add(lb, "OBJECT_OT_add_named_cursor", view3d_ob_drop_poll, view3d_ob_drop_copy); WM_dropbox_add(lb, "OBJECT_OT_drop_named_material", view3d_mat_drop_poll, view3d_id_drop_copy); WM_dropbox_add(lb, "MESH_OT_drop_named_image", view3d_ima_ob_drop_poll, view3d_id_path_drop_copy); - WM_dropbox_add(lb, "VIEW3D_OT_add_background_image", view3d_ima_bg_drop_poll, view3d_id_path_drop_copy); + WM_dropbox_add(lb, "VIEW3D_OT_background_image_add", view3d_ima_bg_drop_poll, view3d_id_path_drop_copy); } @@ -529,39 +537,40 @@ static void *view3d_main_area_duplicate(void *poin) return NULL; } -static void view3d_recalc_used_layers(ARegion *ar, wmNotifier *wmn) +static void view3d_recalc_used_layers(ARegion *ar, wmNotifier *wmn, Scene *scene) { wmWindow *win= wmn->wm->winactive; ScrArea *sa; + unsigned int lay_used= 0; + Base *base; if (!win) return; - sa= win->screen->areabase.first; - - while(sa) { - if(sa->spacetype == SPACE_VIEW3D) - if(BLI_findindex(&sa->regionbase, ar) >= 0) { - View3D *v3d= sa->spacedata.first; - Scene *scene= wmn->reference; - Base *base; + base= scene->base.first; + while(base) { + lay_used |= base->lay & ((1<<20)-1); /* ignore localview */ - v3d->lay_used= 0; - base= scene->base.first; - while(base) { - v3d->lay_used|= base->lay; + if (lay_used == (1<<20)-1) + break; - base= base->next; - } + base= base->next; + } + for(sa= win->screen->areabase.first; sa; sa= sa->next) { + if(sa->spacetype == SPACE_VIEW3D) { + if(BLI_findindex(&sa->regionbase, ar) != -1) { + View3D *v3d= sa->spacedata.first; + v3d->lay_used= lay_used; break; } - - sa= sa->next; + } } } static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) { + bScreen *sc; + /* context changes */ switch(wmn->category) { case NC_ANIMATION: @@ -584,18 +593,22 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) case NC_SCENE: switch(wmn->data) { case ND_LAYER_CONTENT: - view3d_recalc_used_layers(ar, wmn); + view3d_recalc_used_layers(ar, wmn, wmn->reference); ED_region_tag_redraw(ar); break; case ND_FRAME: case ND_TRANSFORM: case ND_OB_ACTIVE: case ND_OB_SELECT: + case ND_OB_VISIBLE: case ND_LAYER: case ND_RENDER_OPTIONS: case ND_MODE: ED_region_tag_redraw(ar); break; + case ND_WORLD: + /* handled by space_view3d_listener() for v3d access */ + break; } if (wmn->action == NA_EDITED) ED_region_tag_redraw(ar); @@ -614,6 +627,11 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) ED_region_tag_redraw(ar); break; } + switch(wmn->action) { + case NA_ADDED: + ED_region_tag_redraw(ar); + break; + } break; case NC_GEOM: switch(wmn->data) { @@ -646,8 +664,15 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) case NC_WORLD: switch(wmn->data) { case ND_WORLD_DRAW: - ED_region_tag_redraw(ar); + /* handled by space_view3d_listener() for v3d access */ break; + case ND_WORLD_STARS: + { + RegionView3D *rv3d= ar->regiondata; + if(rv3d->persp == RV3D_CAMOB) { + ED_region_tag_redraw(ar); + } + } } break; case NC_LAMP: @@ -680,16 +705,29 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) ED_region_tag_redraw(ar); break; case NC_SCREEN: - if(wmn->data == ND_GPENCIL) - ED_region_tag_redraw(ar); - else if(wmn->data==ND_ANIMPLAY) - ED_region_tag_redraw(ar); + switch(wmn->data) { + case ND_GPENCIL: + case ND_ANIMPLAY: + case ND_SKETCH: + ED_region_tag_redraw(ar); + break; + case ND_SCREENBROWSE: + case ND_SCREENDELETE: + case ND_SCREENSET: + /* screen was changed, need to update used layers due to NC_SCENE|ND_LAYER_CONTENT */ + /* updates used layers only for View3D in active screen */ + sc= wmn->reference; + view3d_recalc_used_layers(ar, wmn, sc->scene); + ED_region_tag_redraw(ar); + break; + } + break; } } /* concept is to retrieve cursor type context-less */ -static void view3d_main_area_cursor(wmWindow *win, ScrArea *sa, ARegion *ar) +static void view3d_main_area_cursor(wmWindow *win, ScrArea *UNUSED(sa), ARegion *UNUSED(ar)) { Scene *scene= win->screen->scene; @@ -725,6 +763,7 @@ static void view3d_header_area_listener(ARegion *ar, wmNotifier *wmn) case ND_FRAME: case ND_OB_ACTIVE: case ND_OB_SELECT: + case ND_OB_VISIBLE: case ND_MODE: case ND_LAYER: case ND_TOOLSETTINGS: @@ -778,6 +817,7 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn) case ND_FRAME: case ND_OB_ACTIVE: case ND_OB_SELECT: + case ND_OB_VISIBLE: case ND_MODE: case ND_LAYER: case ND_LAYER_CONTENT: @@ -871,20 +911,61 @@ static void view3d_props_area_listener(ARegion *ar, wmNotifier *wmn) } } +/*area (not region) level listener*/ +static void space_view3d_listener(struct ScrArea *sa, struct wmNotifier *wmn) +{ + View3D *v3d = sa->spacedata.first; + + /* context changes */ + switch(wmn->category) { + case NC_SCENE: + switch(wmn->data) { + case ND_WORLD: + if(v3d->flag2 & V3D_RENDER_OVERRIDE) + ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW); + break; + } + break; + case NC_WORLD: + switch(wmn->data) { + case ND_WORLD_DRAW: + if(v3d->flag2 & V3D_RENDER_OVERRIDE) + ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW); + break; + } + break; + + } + +#if 0 // removed since BKE_image_user_calc_frame is now called in draw_bgpic because screen_ops doesnt call the notifier. + if (wmn->category == NC_SCENE && wmn->data == ND_FRAME) { + View3D *v3d = area->spacedata.first; + BGpic *bgpic = v3d->bgpicbase.first; + + for (; bgpic; bgpic = bgpic->next) { + if (bgpic->ima) { + Scene *scene = wmn->reference; + BKE_image_user_calc_frame(&bgpic->iuser, scene->r.cfra, 0); + } + } + } +#endif +} + +const char *view3d_context_dir[] = { + "selected_objects", "selected_bases", "selected_editable_objects", + "selected_editable_bases", "visible_objects", "visible_bases", "selectable_objects", "selectable_bases", + "active_base", "active_object", NULL}; + static int view3d_context(const bContext *C, const char *member, bContextDataResult *result) { View3D *v3d= CTX_wm_view3d(C); Scene *scene= CTX_data_scene(C); Base *base; - int lay = v3d ? v3d->lay:scene->lay; /* fallback to the scene layer, allows duplicate and other oject operators to run outside the 3d view */ + unsigned int lay = v3d ? v3d->lay:scene->lay; /* fallback to the scene layer, allows duplicate and other oject operators to run outside the 3d view */ if(CTX_data_dir(member)) { - static const char *dir[] = { - "selected_objects", "selected_bases", "selected_editable_objects", - "selected_editable_bases", "visible_objects", "visible_bases", "selectable_objects", "selectable_bases", - "active_base", "active_object", NULL}; - - CTX_data_dir_set(result, dir); + CTX_data_dir_set(result, view3d_context_dir); } else if(CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) { int selected_objects= CTX_data_equals(member, "selected_objects"); @@ -973,23 +1054,6 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes return -1; /* found but not available */ } -/*area (not region) level listener*/ -#if 0 // removed since BKE_image_user_calc_frame is now called in draw_bgpic because screen_ops doesnt call the notifier. -void space_view3d_listener(struct ScrArea *area, struct wmNotifier *wmn) -{ - if (wmn->category == NC_SCENE && wmn->data == ND_FRAME) { - View3D *v3d = area->spacedata.first; - BGpic *bgpic = v3d->bgpicbase.first; - - for (; bgpic; bgpic = bgpic->next) { - if (bgpic->ima) { - Scene *scene = wmn->reference; - BKE_image_user_calc_frame(&bgpic->iuser, scene->r.cfra, 0); - } - } - } -} -#endif /* only called once, from space/spacetypes.c */ void ED_spacetype_view3d(void) @@ -1003,7 +1067,7 @@ void ED_spacetype_view3d(void) st->new= view3d_new; st->free= view3d_free; st->init= view3d_init; -// st->listener = space_view3d_listener; + st->listener = space_view3d_listener; st->duplicate= view3d_duplicate; st->operatortypes= view3d_operatortypes; st->keymap= view3d_keymap; diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 77172ed2c96..7c80db76e9e 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -45,6 +45,7 @@ #include "BLI_blenlib.h" #include "BLI_editVert.h" #include "BLI_rand.h" +#include "BLI_utildefines.h" #include "BKE_action.h" #include "BKE_context.h" @@ -57,7 +58,6 @@ #include "BKE_tessmesh.h" #include "BKE_deform.h" - #include "WM_api.h" #include "WM_types.h" @@ -129,7 +129,7 @@ typedef struct { /* is used for both read and write... */ -static void v3d_editvertex_buts(const bContext *C, uiLayout *layout, View3D *v3d, Object *ob, float lim) +static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim) { uiBlock *block= (layout)? uiLayoutAbsoluteBlock(layout): NULL; MDeformVert *dvert=NULL; @@ -281,32 +281,32 @@ static void v3d_editvertex_buts(const bContext *C, uiLayout *layout, View3D *v3d mul_m4_v3(ob->obmat, median); if(block) { // buttons - int but_y; - if((ob->parent) && (ob->partype == PARBONE)) but_y = 135; - else but_y = 150; - - - + uiBut *but; + memcpy(tfp->ve_median, median, sizeof(tfp->ve_median)); uiBlockBeginAlign(block); if(tot==1) { uiDefBut(block, LABEL, 0, "Vertex:", 0, 130, 200, 20, 0, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:", 0, 110, 200, 20, &(tfp->ve_median[0]), -lim, lim, 10, 3, ""); - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:", 0, 90, 200, 20, &(tfp->ve_median[1]), -lim, lim, 10, 3, ""); - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:", 0, 70, 200, 20, &(tfp->ve_median[2]), -lim, lim, 10, 3, ""); - + + but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:", 0, 110, 200, 20, &(tfp->ve_median[0]), -lim, lim, 10, 3, ""); + uiButSetUnitType(but, PROP_UNIT_LENGTH); + but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:", 0, 90, 200, 20, &(tfp->ve_median[1]), -lim, lim, 10, 3, ""); + uiButSetUnitType(but, PROP_UNIT_LENGTH); + but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:", 0, 70, 200, 20, &(tfp->ve_median[2]), -lim, lim, 10, 3, ""); + uiButSetUnitType(but, PROP_UNIT_LENGTH); + if(totw==1) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:", 0, 50, 200, 20, &(tfp->ve_median[3]), 0.01, 100.0, 10, 3, ""); + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:", 0, 50, 200, 20, &(tfp->ve_median[3]), 0.01, 100.0, 1, 3, ""); uiBlockBeginAlign(block); uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global", 0, 25, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values"); uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local", 100, 25, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values"); uiBlockEndAlign(block); if(totweight) - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 0, 0, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, ""); + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 0, 0, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 1, 3, ""); if(totradius) - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Radius:", 0, 0, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 10, 3, "Radius of curve CPs"); + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Radius:", 0, 0, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 1, 3, "Radius of curve CPs"); } else { uiBlockBeginAlign(block); @@ -322,11 +322,14 @@ static void v3d_editvertex_buts(const bContext *C, uiLayout *layout, View3D *v3d else { uiDefBut(block, LABEL, 0, "Median:", 0, 130, 200, 20, 0, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:", 0, 110, 200, 20, &(tfp->ve_median[0]), -lim, lim, 10, 3, ""); - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:", 0, 90, 200, 20, &(tfp->ve_median[1]), -lim, lim, 10, 3, ""); - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:", 0, 70, 200, 20, &(tfp->ve_median[2]), -lim, lim, 10, 3, ""); + but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:", 0, 110, 200, 20, &(tfp->ve_median[0]), -lim, lim, 10, 3, ""); + uiButSetUnitType(but, PROP_UNIT_LENGTH); + but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:", 0, 90, 200, 20, &(tfp->ve_median[1]), -lim, lim, 10, 3, ""); + uiButSetUnitType(but, PROP_UNIT_LENGTH); + but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:", 0, 70, 200, 20, &(tfp->ve_median[2]), -lim, lim, 10, 3, ""); + uiButSetUnitType(but, PROP_UNIT_LENGTH); if(totw==tot) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:", 0, 50, 200, 20, &(tfp->ve_median[3]), 0.01, 100.0, 10, 3, ""); + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:", 0, 50, 200, 20, &(tfp->ve_median[3]), 0.01, 100.0, 1, 3, ""); uiBlockEndAlign(block); uiBlockBeginAlign(block); uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global", 0, 25, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values"); @@ -344,17 +347,17 @@ static void v3d_editvertex_buts(const bContext *C, uiLayout *layout, View3D *v3d uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local", 100, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values"); uiBlockEndAlign(block); if(totweight) - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 0, 20, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "Weight is used for SoftBody Goal"); + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 0, 20, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 1, 3, "Weight is used for SoftBody Goal"); if(totradius) - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Radius:", 0, 0, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 10, 3, "Radius of curve CPs"); + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Radius:", 0, 0, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 1, 3, "Radius of curve CPs"); uiBlockEndAlign(block); } } if(totedge==1) - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Crease:", 0, 20, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 10, 3, ""); + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Crease:", 0, 20, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 1, 3, ""); else if(totedge>1) - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Mean Crease:", 0, 20, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 10, 3, ""); + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Mean Crease:", 0, 20, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 1, 3, ""); } else { // apply @@ -374,26 +377,72 @@ static void v3d_editvertex_buts(const bContext *C, uiLayout *layout, View3D *v3d Mesh *me= ob->data; BMEditMesh *em = me->edit_btmesh; BMVert *eve; - BMEdge *eed; BMIter iter; - BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { - if(BM_TestHFlag(eve, BM_SELECT)) { - add_v3_v3(eve->co, median); + if(len_v3(median) > 0.000001) { + + BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { + if(BM_TestHFlag(eve, BM_SELECT)) { + add_v3_v3(eve->co, median); + } } + + EDBM_RecalcNormals(em); } - BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) { - if(BM_TestHFlag(eed, BM_SELECT)) { - float *crease = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_CREASE); - if (!crease) continue; - - /* ensure the median can be set to zero or one */ - if(ve_median[3]==0.0f) *crease= 0.0f; - else if(ve_median[3]==1.0f) *crease= 1.0f; + if(median[3] != 0.0f) { + BMEdge *eed; + const float fixed_crease= (ve_median[3] <= 0.0f ? 0.0 : (ve_median[3] >= 1.0f ? 1.0 : FLT_MAX)); + + if(fixed_crease != FLT_MAX) { + /* simple case */ + + BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) { + if(BM_TestHFlag(eed, BM_SELECT)) { + float *crease = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_CREASE); + if (!crease) break; + + *crease= fixed_crease; + } + } + } + else { + /* scale crease to target median */ + float median_new= ve_median[3]; + float median_orig= ve_median[3] - median[3]; /* previous median value */ + + /* incase of floating point error */ + CLAMP(median_orig, 0.0, 1.0); + CLAMP(median_new, 0.0, 1.0); + + if(median_new < median_orig) { + /* scale down */ + const float sca= median_new / median_orig; + + BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) { + if(BM_TestHFlag(eed, BM_SELECT)) { + float *crease = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_CREASE); + + if (!crease) break; + + *crease *= sca; + CLAMP(*crease, 0.0, 1.0); + } + } + } else { - *crease+= median[3]; - CLAMP(*crease, 0.0, 1.0); + /* scale up */ + const float sca= (1.0f - median_new) / (1.0f - median_orig); + + BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) { + if(BM_TestHFlag(eed, BM_SELECT)) { + float *crease = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_CREASE); + if (!crease) break; + + *crease = 1.0f - ((1.0f - *crease) * sca); + CLAMP(*crease, 0.0, 1.0); + } + } } } } @@ -496,15 +545,14 @@ static void act_vert_def(Object *ob, BMVert **eve, MDeformVert **dvert) static void editvert_mirror_update(Object *ob, BMVert *eve, int def_nr, int index) { Mesh *me= ob->data; -#if 0 //BMESH_TODO use editbmesh_bvh.h code for this! see EDBM_FindNearestVertTopo. - EditMesh *em = BKE_mesh_get_editmesh(me); - EditVert *eve_mirr; + BMEditMesh *em = me->edit_btmesh; + BMVert *eve_mirr; - eve_mirr= editmesh_get_x_mirror_vert(ob, em, eve, eve->co, index); + eve_mirr= editbmesh_get_x_mirror_vert(ob, em, eve, eve->co, index); if(eve_mirr && eve_mirr != eve) { - MDeformVert *dvert_src= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); - MDeformVert *dvert_dst= CustomData_em_get(&em->vdata, eve_mirr->data, CD_MDEFORMVERT); + MDeformVert *dvert_src= CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT); + MDeformVert *dvert_dst= CustomData_bmesh_get(&em->bm->vdata, eve_mirr->head.data, CD_MDEFORMVERT); if(dvert_dst) { if(def_nr == -1) { /* all vgroups, add groups where neded */ @@ -522,7 +570,6 @@ static void editvert_mirror_update(Object *ob, BMVert *eve, int def_nr, int inde } } } -#endif } static void vgroup_adjust_active(Object *ob, int def_nr) @@ -648,7 +695,7 @@ static void vgroup_normalize_active(Object *ob) } -static void do_view3d_vgroup_buttons(bContext *C, void *arg, int event) +static void do_view3d_vgroup_buttons(bContext *C, void *UNUSED(arg), int event) { Scene *scene= CTX_data_scene(C); Object *ob= OBACT; @@ -671,11 +718,11 @@ static void do_view3d_vgroup_buttons(bContext *C, void *arg, int event) // ED_vgroup_mirror(ob, 1, 1, 0); /* default for now */ - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); } -int view3d_panel_vgroup_poll(const bContext *C, PanelType *pt) +static int view3d_panel_vgroup_poll(const bContext *C, PanelType *UNUSED(pt)) { Scene *scene= CTX_data_scene(C); Object *ob= OBACT; @@ -745,61 +792,61 @@ static void v3d_transform_butsR(uiLayout *layout, PointerRNA *ptr) uiLayoutSetActive(split, !(bone->parent && bone->flag & BONE_CONNECTED)); } colsub = uiLayoutColumn(split, 1); - uiItemR(colsub, ptr, "location", 0, "Location", 0); + uiItemR(colsub, ptr, "location", 0, "Location", ICON_NULL); colsub = uiLayoutColumn(split, 1); - uiItemL(colsub, "", 0); - uiItemR(colsub, ptr, "lock_location", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY, "", 0); + uiItemL(colsub, "", ICON_NULL); + uiItemR(colsub, ptr, "lock_location", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY, "", ICON_NULL); split = uiLayoutSplit(layout, 0.8, 0); switch(RNA_enum_get(ptr, "rotation_mode")) { case ROT_MODE_QUAT: /* quaternion */ colsub = uiLayoutColumn(split, 1); - uiItemR(colsub, ptr, "rotation_quaternion", 0, "Rotation", 0); + uiItemR(colsub, ptr, "rotation_quaternion", 0, "Rotation", ICON_NULL); colsub = uiLayoutColumn(split, 1); - uiItemR(colsub, ptr, "lock_rotations_4d", UI_ITEM_R_TOGGLE, "4L", 0); + uiItemR(colsub, ptr, "lock_rotations_4d", UI_ITEM_R_TOGGLE, "4L", ICON_NULL); if (RNA_boolean_get(ptr, "lock_rotations_4d")) - uiItemR(colsub, ptr, "lock_rotation_w", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY, "", 0); + uiItemR(colsub, ptr, "lock_rotation_w", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY, "", ICON_NULL); else - uiItemL(colsub, "", 0); - uiItemR(colsub, ptr, "lock_rotation", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY, "", 0); + uiItemL(colsub, "", ICON_NULL); + uiItemR(colsub, ptr, "lock_rotation", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY, "", ICON_NULL); break; case ROT_MODE_AXISANGLE: /* axis angle */ colsub = uiLayoutColumn(split, 1); - uiItemR(colsub, ptr, "rotation_axis_angle", 0, "Rotation", 0); + uiItemR(colsub, ptr, "rotation_axis_angle", 0, "Rotation", ICON_NULL); colsub = uiLayoutColumn(split, 1); - uiItemR(colsub, ptr, "lock_rotations_4d", UI_ITEM_R_TOGGLE, "4L", 0); + uiItemR(colsub, ptr, "lock_rotations_4d", UI_ITEM_R_TOGGLE, "4L", ICON_NULL); if (RNA_boolean_get(ptr, "lock_rotations_4d")) - uiItemR(colsub, ptr, "lock_rotation_w", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY, "", 0); + uiItemR(colsub, ptr, "lock_rotation_w", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY, "", ICON_NULL); else - uiItemL(colsub, "", 0); - uiItemR(colsub, ptr, "lock_rotation", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY, "", 0); + uiItemL(colsub, "", ICON_NULL); + uiItemR(colsub, ptr, "lock_rotation", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY, "", ICON_NULL); break; default: /* euler rotations */ colsub = uiLayoutColumn(split, 1); - uiItemR(colsub, ptr, "rotation_euler", 0, "Rotation", 0); + uiItemR(colsub, ptr, "rotation_euler", 0, "Rotation", ICON_NULL); colsub = uiLayoutColumn(split, 1); - uiItemL(colsub, "", 0); - uiItemR(colsub, ptr, "lock_rotation", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY, "", 0); + uiItemL(colsub, "", ICON_NULL); + uiItemR(colsub, ptr, "lock_rotation", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY, "", ICON_NULL); break; } - uiItemR(layout, ptr, "rotation_mode", 0, "", 0); + uiItemR(layout, ptr, "rotation_mode", 0, "", ICON_NULL); split = uiLayoutSplit(layout, 0.8, 0); colsub = uiLayoutColumn(split, 1); - uiItemR(colsub, ptr, "scale", 0, "Scale", 0); + uiItemR(colsub, ptr, "scale", 0, "Scale", ICON_NULL); colsub = uiLayoutColumn(split, 1); - uiItemL(colsub, "", 0); - uiItemR(colsub, ptr, "lock_scale", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY, "", 0); + uiItemL(colsub, "", ICON_NULL); + uiItemR(colsub, ptr, "lock_scale", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY, "", ICON_NULL); if (ptr->type == &RNA_Object) { Object *ob = ptr->data; if (ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) - uiItemR(layout, ptr, "dimensions", 0, "Dimensions", 0); + uiItemR(layout, ptr, "dimensions", 0, "Dimensions", ICON_NULL); } } -static void v3d_posearmature_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim) +static void v3d_posearmature_buts(uiLayout *layout, Object *ob) { // uiBlock *block= uiLayoutGetBlock(layout); // bArmature *arm; @@ -808,13 +855,14 @@ static void v3d_posearmature_buts(uiLayout *layout, View3D *v3d, Object *ob, flo PointerRNA pchanptr; uiLayout *col; // uiLayout *row; +// uiBut *but; pchan= get_active_posechannel(ob); // row= uiLayoutRow(layout, 0); if (!pchan) { - uiItemL(layout, "No Bone Active", 0); + uiItemL(layout, "No Bone Active", ICON_NULL); return; } @@ -846,9 +894,13 @@ static void v3d_posearmature_buts(uiLayout *layout, View3D *v3d, Object *ob, flo uiDefBut(block, LABEL, 0, "Location:", 0, 240, 100, 20, 0, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_ARMATUREPANEL2, "X:", 0, 220, 120, 19, pchan->loc, -lim, lim, 100, 3, ""); - uiDefButF(block, NUM, B_ARMATUREPANEL2, "Y:", 0, 200, 120, 19, pchan->loc+1, -lim, lim, 100, 3, ""); - uiDefButF(block, NUM, B_ARMATUREPANEL2, "Z:", 0, 180, 120, 19, pchan->loc+2, -lim, lim, 100, 3, ""); + + but= uiDefButF(block, NUM, B_ARMATUREPANEL2, "X:", 0, 220, 120, 19, pchan->loc, -lim, lim, 100, 3, ""); + uiButSetUnitType(but, PROP_UNIT_LENGTH); + but= uiDefButF(block, NUM, B_ARMATUREPANEL2, "Y:", 0, 200, 120, 19, pchan->loc+1, -lim, lim, 100, 3, ""); + uiButSetUnitType(but, PROP_UNIT_LENGTH); + but= uiDefButF(block, NUM, B_ARMATUREPANEL2, "Z:", 0, 180, 120, 19, pchan->loc+2, -lim, lim, 100, 3, ""); + uiButSetUnitType(but, PROP_UNIT_LENGTH); uiBlockEndAlign(block); uiBlockBeginAlign(block); @@ -886,22 +938,24 @@ static void v3d_posearmature_buts(uiLayout *layout, View3D *v3d, Object *ob, flo } /* assumes armature editmode */ -void validate_editbonebutton_cb(bContext *C, void *bonev, void *namev) +#if 0 +static void validate_editbonebutton_cb(bContext *C, void *bonev, void *namev) { EditBone *eBone= bonev; - char oldname[32], newname[32]; - + char oldname[sizeof(eBone->name)], newname[sizeof(eBone->name)]; + /* need to be on the stack */ - BLI_strncpy(newname, eBone->name, 32); - BLI_strncpy(oldname, (char *)namev, 32); + BLI_strncpy(newname, eBone->name, sizeof(eBone->name)); + BLI_strncpy(oldname, (char *)namev, sizeof(eBone->name)); /* restore */ - BLI_strncpy(eBone->name, oldname, 32); - + BLI_strncpy(eBone->name, oldname, sizeof(eBone->name)); + ED_armature_bone_rename(CTX_data_edit_object(C)->data, oldname, newname); // editarmature.c WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, CTX_data_edit_object(C)); // XXX fix } +#endif -static void v3d_editarmature_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim) +static void v3d_editarmature_buts(uiLayout *layout, Object *ob) { // uiBlock *block= uiLayoutGetBlock(layout); bArmature *arm= ob->data; @@ -921,21 +975,21 @@ static void v3d_editarmature_buts(uiLayout *layout, View3D *v3d, Object *ob, flo col= uiLayoutColumn(layout, 0); - uiItemR(col, &eboneptr, "head", 0, "Head", 0); + uiItemR(col, &eboneptr, "head", 0, "Head", ICON_NULL); if (ebone->parent && ebone->flag & BONE_CONNECTED ) { PointerRNA parptr = RNA_pointer_get(&eboneptr, "parent"); - uiItemR(col, &parptr, "tail_radius", 0, "Radius", 0); + uiItemR(col, &parptr, "tail_radius", 0, "Radius (Parent)", ICON_NULL); } else { - uiItemR(col, &eboneptr, "head_radius", 0, "Radius", 0); + uiItemR(col, &eboneptr, "head_radius", 0, "Radius", ICON_NULL); } - uiItemR(col, &eboneptr, "tail", 0, "Tail", 0); - uiItemR(col, &eboneptr, "tail_radius", 0, "Radius", 0); + uiItemR(col, &eboneptr, "tail", 0, "Tail", ICON_NULL); + uiItemR(col, &eboneptr, "tail_radius", 0, "Radius", ICON_NULL); - uiItemR(col, &eboneptr, "roll", 0, "Roll", 0); + uiItemR(col, &eboneptr, "roll", 0, "Roll", ICON_NULL); } -static void v3d_editmetaball_buts(uiLayout *layout, Object *ob, float lim) +static void v3d_editmetaball_buts(uiLayout *layout, Object *ob) { PointerRNA mbptr, ptr; MetaBall *mball= ob->data; @@ -951,37 +1005,37 @@ static void v3d_editmetaball_buts(uiLayout *layout, Object *ob, float lim) RNA_pointer_create(&mball->id, &RNA_MetaElement, mball->lastelem, &ptr); col= uiLayoutColumn(layout, 0); - uiItemR(col, &ptr, "location", 0, "Location", 0); + uiItemR(col, &ptr, "co", 0, "Location", ICON_NULL); - uiItemR(col, &ptr, "radius", 0, "Radius", 0); - uiItemR(col, &ptr, "stiffness", 0, "Stiffness", 0); + uiItemR(col, &ptr, "radius", 0, "Radius", ICON_NULL); + uiItemR(col, &ptr, "stiffness", 0, "Stiffness", ICON_NULL); - uiItemR(col, &ptr, "type", 0, "Type", 0); + uiItemR(col, &ptr, "type", 0, "Type", ICON_NULL); col= uiLayoutColumn(layout, 1); switch (RNA_enum_get(&ptr, "type")) { case MB_BALL: break; case MB_CUBE: - uiItemL(col, "Size:", 0); - uiItemR(col, &ptr, "size_x", 0, "X", 0); - uiItemR(col, &ptr, "size_y", 0, "Y", 0); - uiItemR(col, &ptr, "size_z", 0, "Z", 0); + uiItemL(col, "Size:", ICON_NULL); + uiItemR(col, &ptr, "size_x", 0, "X", ICON_NULL); + uiItemR(col, &ptr, "size_y", 0, "Y", ICON_NULL); + uiItemR(col, &ptr, "size_z", 0, "Z", ICON_NULL); break; case MB_TUBE: - uiItemL(col, "Size:", 0); - uiItemR(col, &ptr, "size_x", 0, "X", 0); + uiItemL(col, "Size:", ICON_NULL); + uiItemR(col, &ptr, "size_x", 0, "X", ICON_NULL); break; case MB_PLANE: - uiItemL(col, "Size:", 0); - uiItemR(col, &ptr, "size_x", 0, "X", 0); - uiItemR(col, &ptr, "size_y", 0, "Y", 0); + uiItemL(col, "Size:", ICON_NULL); + uiItemR(col, &ptr, "size_x", 0, "X", ICON_NULL); + uiItemR(col, &ptr, "size_y", 0, "Y", ICON_NULL); break; case MB_ELIPSOID: - uiItemL(col, "Size:", 0); - uiItemR(col, &ptr, "size_x", 0, "X", 0); - uiItemR(col, &ptr, "size_y", 0, "Y", 0); - uiItemR(col, &ptr, "size_z", 0, "Z", 0); + uiItemL(col, "Size:", ICON_NULL); + uiItemR(col, &ptr, "size_x", 0, "X", ICON_NULL); + uiItemR(col, &ptr, "size_y", 0, "Y", ICON_NULL); + uiItemR(col, &ptr, "size_z", 0, "Z", ICON_NULL); break; } } @@ -994,7 +1048,7 @@ static int test_parent_loop(Object *par, Object *ob) return test_parent_loop(par->parent, ob); } -static void do_view3d_region_buttons(bContext *C, void *arg, int event) +static void do_view3d_region_buttons(bContext *C, void *UNUSED(index), int event) { Main *bmain= CTX_data_main(C); Scene *scene= CTX_data_scene(C); @@ -1011,14 +1065,14 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event) return; /* no notifier! */ case B_OBJECTPANEL: - DAG_id_flush_update(&ob->id, OB_RECALC_OB); + DAG_id_tag_update(&ob->id, OB_RECALC_OB); break; case B_OBJECTPANELMEDIAN: if(ob) { - v3d_editvertex_buts(C, NULL, v3d, ob, 1.0); - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + v3d_editvertex_buts(NULL, v3d, ob, 1.0); + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); } break; @@ -1029,7 +1083,7 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event) ob->parent= NULL; else { DAG_scene_sort(bmain, scene); - DAG_id_flush_update(&ob->id, OB_RECALC_OB); + DAG_id_tag_update(&ob->id, OB_RECALC_OB); } } break; @@ -1063,12 +1117,15 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event) case B_ARMATUREPANEL2: { ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK); - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); } break; case B_TRANSFORMSPACEADD: - BIF_createTransformOrientation(C, NULL, "", 1, 0); + { + char names[sizeof(((TransformOrientation *)NULL)->name)]= ""; + BIF_createTransformOrientation(C, NULL, names, 1, 0); break; + } case B_TRANSFORMSPACECLEAR: BIF_clearTransformOrientation(C); break; @@ -1116,7 +1173,7 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event) int a; for(a=0; a<me->totvert; a++) ED_vgroup_vert_remove (ob, defGroup, a); - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); } } break; @@ -1157,16 +1214,6 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event) WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, ob); } -void removeTransformOrientation_func(bContext *C, void *target, void *unused) -{ - BIF_removeTransformOrientation(C, (TransformOrientation *) target); -} - -void selectTransformOrientation_func(bContext *C, void *target, void *unused) -{ - BIF_selectTransformOrientation(C, (TransformOrientation *) target); -} - static void view3d_panel_object(const bContext *C, Panel *pa) { uiBlock *block; @@ -1208,12 +1255,12 @@ static void view3d_panel_object(const bContext *C, Panel *pa) RNA_id_pointer_create(&ob->id, &obptr); if(ob==obedit) { - if(ob->type==OB_ARMATURE) v3d_editarmature_buts(col, v3d, ob, lim); - if(ob->type==OB_MBALL) v3d_editmetaball_buts(col, ob, lim); - else v3d_editvertex_buts(C, col, v3d, ob, lim); + if(ob->type==OB_ARMATURE) v3d_editarmature_buts(col, ob); + if(ob->type==OB_MBALL) v3d_editmetaball_buts(col, ob); + else v3d_editvertex_buts(col, v3d, ob, lim); } else if(ob->mode & OB_MODE_POSE) { - v3d_posearmature_buts(col, v3d, ob, lim); + v3d_posearmature_buts(col, ob); } else { @@ -1381,53 +1428,6 @@ static void view3d_panel_bonesketch_spaces(const bContext *C, Panel *pa) uiBlockEndAlign(block); } -/* op->invoke */ -static void redo_cb(bContext *C, void *arg_op, void *arg2) -{ - wmOperator *lastop= arg_op; - - if(lastop) { - int retval; - - if (G.f & G_DEBUG) - printf("operator redo %s\n", lastop->type->name); - ED_undo_pop(C); - retval= WM_operator_repeat(C, lastop); - if((retval & OPERATOR_FINISHED)==0) { - if (G.f & G_DEBUG) - printf("operator redo failed %s\n", lastop->type->name); - ED_undo_redo(C); - } - } -} - -static void view3d_panel_operator_redo(const bContext *C, Panel *pa) -{ - wmWindowManager *wm= CTX_wm_manager(C); - wmOperator *op; - PointerRNA ptr; - uiBlock *block; - - block= uiLayoutGetBlock(pa->layout); - - /* only for operators that are registered and did an undo push */ - for(op= wm->operators.last; op; op= op->prev) - if((op->type->flag & OPTYPE_REGISTER) && (op->type->flag & OPTYPE_UNDO)) - break; - - if(op==NULL) - return; - - uiBlockSetFunc(block, redo_cb, op, NULL); - - if(!op->properties) { - IDPropertyTemplate val = {0}; - op->properties= IDP_New(IDP_GROUP, val, "wmOperatorProperties"); - } - - RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); - uiDefAutoButsRNA(C, pa->layout, &ptr, 2); -} #endif // XXX not used void view3d_buttons_register(ARegionType *art) @@ -1456,7 +1456,7 @@ void view3d_buttons_register(ARegionType *art) // XXX view3d_panel_preview(C, ar, 0); } -static int view3d_properties(bContext *C, wmOperator *op) +static int view3d_properties(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa= CTX_wm_area(C); ARegion *ar= view3d_has_buttons_region(sa); diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 0dc505e0146..4d591645679 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -45,6 +45,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_rand.h" +#include "BLI_utildefines.h" #include "BKE_anim.h" #include "BKE_context.h" @@ -55,10 +56,7 @@ #include "BKE_global.h" #include "BKE_paint.h" #include "BKE_scene.h" -#include "BKE_screen.h" -#include "BKE_tessmesh.h" #include "BKE_unit.h" -#include "BKE_utildefines.h" #include "RE_pipeline.h" // make_stars @@ -246,15 +244,13 @@ static void drawgrid_draw(ARegion *ar, float wx, float wy, float x, float y, flo #define GRID_MIN_PX 6.0f -static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, char **grid_unit) +static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit) { /* extern short bgpicmode; */ RegionView3D *rv3d= ar->regiondata; float wx, wy, x, y, fw, fx, fy, dx; float vec4[4]; - char col[3], col2[3]; - - *grid_unit= NULL; + unsigned char col[3], col2[3]; vec4[0]=vec4[1]=vec4[2]=0.0; vec4[3]= 1.0; @@ -269,7 +265,7 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, char **grid_u x= (wx)*fx/fw; y= (wy)*fy/fw; - vec4[0]=vec4[1]= (unit->system) ? 1.0 : v3d->grid; + vec4[0]=vec4[1]= v3d->grid; vec4[2]= 0.0; vec4[3]= 1.0; @@ -309,7 +305,7 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, char **grid_u /* Store the smallest drawn grid size units name so users know how big each grid cell is */ if(*grid_unit==NULL) { *grid_unit= bUnit_GetNameDisplay(usys, i); - rv3d->gridview= (scalar * unit->scale_length); + rv3d->gridview= (scalar * v3d->grid) / unit->scale_length; } blend_fac= 1-((GRID_MIN_PX*2)/dx_scalar); @@ -402,17 +398,19 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, char **grid_u setlinestyle(0); /* center cross */ + /* horizontal line */ if( ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT)) - UI_make_axis_color(col, col2, 'y'); - else UI_make_axis_color(col, col2, 'x'); - glColor3ubv((GLubyte *)col2); + UI_make_axis_color(col, col2, 'Y'); + else UI_make_axis_color(col, col2, 'X'); + glColor3ubv(col2); fdrawline(0.0, y, (float)ar->winx, y); + /* vertical line */ if( ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) - UI_make_axis_color(col, col2, 'y'); - else UI_make_axis_color(col, col2, 'z'); - glColor3ubv((GLubyte *)col2); + UI_make_axis_color(col, col2, 'Y'); + else UI_make_axis_color(col, col2, 'Z'); + glColor3ubv(col2); fdrawline(x, 0.0, x, (float)ar->winy); @@ -420,22 +418,39 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, char **grid_u } #undef GRID_MIN_PX -static void drawfloor(Scene *scene, View3D *v3d) +static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit) { - float vert[3], grid; + float vert[3], grid, grid_scale; int a, gridlines, emphasise; - char col[3], col2[3]; + unsigned char col[3], col2[3]; short draw_line = 0; vert[2]= 0.0; if(v3d->gridlines<3) return; + grid_scale= v3d->grid; + /* use 'grid_scale' instead of 'v3d->grid' from now on */ + + /* apply units */ + if(scene->unit.system) { + void *usys; + int len; + + bUnit_GetSystem(&usys, &len, scene->unit.system, B_UNIT_LENGTH); + + if(usys) { + int i= bUnit_GetBaseUnit(usys); + *grid_unit= bUnit_GetNameDisplay(usys, i); + grid_scale = (grid_scale * bUnit_GetScaler(usys, i)) / scene->unit.scale_length; + } + } + if(v3d->zbuf && scene->obedit) glDepthMask(0); // for zbuffer-select gridlines= v3d->gridlines/2; - grid= gridlines*v3d->grid; - + grid= gridlines * grid_scale; + UI_GetThemeColor3ubv(TH_GRID, col); UI_GetThemeColor3ubv(TH_BACK, col2); @@ -450,8 +465,8 @@ static void drawfloor(Scene *scene, View3D *v3d) if(a==0) { /* check for the 'show Y axis' preference */ if (v3d->gridflag & V3D_SHOW_Y) { - UI_make_axis_color(col, col2, 'y'); - glColor3ubv((GLubyte *)col2); + UI_make_axis_color(col, col2, 'Y'); + glColor3ubv(col2); draw_line = 1; } else if (v3d->gridflag & V3D_SHOW_FLOOR) { @@ -475,7 +490,7 @@ static void drawfloor(Scene *scene, View3D *v3d) if (draw_line) { glBegin(GL_LINE_STRIP); - vert[0]= a*v3d->grid; + vert[0]= a * grid_scale; vert[1]= grid; glVertex3fv(vert); vert[1]= -grid; @@ -489,8 +504,8 @@ static void drawfloor(Scene *scene, View3D *v3d) if(a==0) { /* check for the 'show X axis' preference */ if (v3d->gridflag & V3D_SHOW_X) { - UI_make_axis_color(col, col2, 'x'); - glColor3ubv((GLubyte *)col2); + UI_make_axis_color(col, col2, 'X'); + glColor3ubv(col2); draw_line = 1; } else if (v3d->gridflag & V3D_SHOW_FLOOR) { @@ -514,7 +529,7 @@ static void drawfloor(Scene *scene, View3D *v3d) if (draw_line) { glBegin(GL_LINE_STRIP); - vert[1]= a*v3d->grid; + vert[1]= a * grid_scale; vert[0]= grid; glVertex3fv(vert ); vert[0]= -grid; @@ -526,8 +541,8 @@ static void drawfloor(Scene *scene, View3D *v3d) /* draw the Z axis line */ /* check for the 'show Z axis' preference */ if (v3d->gridflag & V3D_SHOW_Z) { - UI_make_axis_color(col, col2, 'z'); - glColor3ubv((GLubyte *)col2); + UI_make_axis_color(col, col2, 'Z'); + glColor3ubv(col2); glBegin(GL_LINE_STRIP); vert[0]= 0; @@ -574,94 +589,85 @@ static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d) } } -/* Draw a live substitute of the view icon, which is always shown */ +/* Draw a live substitute of the view icon, which is always shown + * colors copied from transform_manipulator.c, we should keep these matching. */ static void draw_view_axis(RegionView3D *rv3d) { const float k = U.rvisize; /* axis size */ const float toll = 0.5; /* used to see when view is quasi-orthogonal */ const float start = k + 1.0; /* axis center in screen coordinates, x=y */ float ydisp = 0.0; /* vertical displacement to allow obj info text */ - - /* rvibright ranges approx. from original axis icon color to gizmo color */ - float bright = U.rvibright / 15.0f; - - unsigned char col[3]; - unsigned char gridcol[3]; - float colf[3]; - - float vec[4]; + int bright = 25*(float)U.rvibright + 5; /* axis alpha (rvibright has range 0-10) */ + + float vec[3]; float dx, dy; - float h, s, v; /* thickness of lines is proportional to k */ - /* (log(k)-1) gives a more suitable thickness, but fps decreased by about 3 fps */ - glLineWidth(k / 10); - //glLineWidth(log(k)-1); // a bit slow - - UI_GetThemeColor3ubv(TH_GRID, (char *)gridcol); - + glLineWidth(2); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + /* X */ - vec[0] = vec[3] = 1; + vec[0] = 1; vec[1] = vec[2] = 0; mul_qt_v3(rv3d->viewquat, vec); - - UI_make_axis_color((char *)gridcol, (char *)col, 'x'); - rgb_to_hsv(col[0]/255.0f, col[1]/255.0f, col[2]/255.0f, &h, &s, &v); - s = s<0.5 ? s+0.5 : 1.0; - v = 0.3; - v = (v<1.0-(bright) ? v+bright : 1.0); - hsv_to_rgb(h, s, v, colf, colf+1, colf+2); - glColor3fv(colf); - dx = vec[0] * k; dy = vec[1] * k; - fdrawline(start, start + ydisp, start + dx, start + dy + ydisp); + + glColor4ub(220, 0, 0, bright); + glBegin(GL_LINES); + glVertex2f(start, start + ydisp); + glVertex2f(start + dx, start + dy + ydisp); + glEnd(); + if (fabs(dx) > toll || fabs(dy) > toll) { - BLF_draw_default(start + dx + 2, start + dy + ydisp + 2, 0.0f, "x"); + BLF_draw_default(start + dx + 2, start + dy + ydisp + 2, 0.0f, "x", 1); } + /* BLF_draw_default disables blending */ + glEnable(GL_BLEND); + /* Y */ - vec[1] = vec[3] = 1; + vec[1] = 1; vec[0] = vec[2] = 0; mul_qt_v3(rv3d->viewquat, vec); - - UI_make_axis_color((char *)gridcol, (char *)col, 'y'); - rgb_to_hsv(col[0]/255.0f, col[1]/255.0f, col[2]/255.0f, &h, &s, &v); - s = s<0.5 ? s+0.5 : 1.0; - v = 0.3; - v = (v<1.0-(bright) ? v+bright : 1.0); - hsv_to_rgb(h, s, v, colf, colf+1, colf+2); - glColor3fv(colf); - dx = vec[0] * k; dy = vec[1] * k; - fdrawline(start, start + ydisp, start + dx, start + dy + ydisp); + + glColor4ub(0, 220, 0, bright); + glBegin(GL_LINES); + glVertex2f(start, start + ydisp); + glVertex2f(start + dx, start + dy + ydisp); + glEnd(); + if (fabs(dx) > toll || fabs(dy) > toll) { - BLF_draw_default(start + dx + 2, start + dy + ydisp + 2, 0.0f, "y"); + BLF_draw_default(start + dx + 2, start + dy + ydisp + 2, 0.0f, "y", 1); } + + glEnable(GL_BLEND); /* Z */ - vec[2] = vec[3] = 1; + vec[2] = 1; vec[1] = vec[0] = 0; mul_qt_v3(rv3d->viewquat, vec); - - UI_make_axis_color((char *)gridcol, (char *)col, 'z'); - rgb_to_hsv(col[0]/255.0f, col[1]/255.0f, col[2]/255.0f, &h, &s, &v); - s = s<0.5 ? s+0.5 : 1.0; - v = 0.5; - v = (v<1.0-(bright) ? v+bright : 1.0); - hsv_to_rgb(h, s, v, colf, colf+1, colf+2); - glColor3fv(colf); - dx = vec[0] * k; dy = vec[1] * k; - fdrawline(start, start + ydisp, start + dx, start + dy + ydisp); + + glColor4ub(30, 30, 220, bright); + glBegin(GL_LINES); + glVertex2f(start, start + ydisp); + glVertex2f(start + dx, start + dy + ydisp); + glEnd(); + if (fabs(dx) > toll || fabs(dy) > toll) { - BLF_draw_default(start + dx + 2, start + dy + ydisp + 2, 0.0f, "z"); + BLF_draw_default(start + dx + 2, start + dy + ydisp + 2, 0.0f, "z", 1); } - + /* restore line-width */ + glLineWidth(1.0); + glDisable(GL_BLEND); } @@ -685,9 +691,9 @@ static void draw_view_icon(RegionView3D *rv3d) glDisable(GL_BLEND); } -static char *view3d_get_name(View3D *v3d, RegionView3D *rv3d) +static const char *view3d_get_name(View3D *v3d, RegionView3D *rv3d) { - char *name = NULL; + const char *name = NULL; switch (rv3d->view) { case RV3D_VIEW_FRONT: @@ -736,24 +742,17 @@ static char *view3d_get_name(View3D *v3d, RegionView3D *rv3d) static void draw_viewport_name(ARegion *ar, View3D *v3d) { RegionView3D *rv3d= ar->regiondata; - char *name = view3d_get_name(v3d, rv3d); - char *printable = NULL; + const char *name= view3d_get_name(v3d, rv3d); + char tmpstr[24]; if (v3d->localvd) { - printable = MEM_mallocN(strlen(name) + strlen(" (Local)_"), "viewport_name"); /* '_' gives space for '\0' */ - strcpy(printable, name); - strcat(printable, " (Local)"); - } else { - printable = name; + BLI_snprintf(tmpstr, sizeof(tmpstr), "%s (Local)", name); + name= tmpstr; } - if (printable) { + if (name) { UI_ThemeColor(TH_TEXT_HI); - BLF_draw_default(22, ar->winy-17, 0.0f, printable); - } - - if (v3d->localvd) { - MEM_freeN(printable); + BLF_draw_default(22, ar->winy-17, 0.0f, name, sizeof(tmpstr)); } } @@ -828,7 +827,7 @@ static void draw_selected_name(Scene *scene, Object *ob, View3D *v3d) sprintf(info, "(%d) %s", CFRA, ob->id.name+2); } - /* colour depends on whether there is a keyframe */ + /* color depends on whether there is a keyframe */ if (id_frame_has_keyframe((ID *)ob, /*BKE_curframe(scene)*/(float)(CFRA), v3d->keyflags)) UI_ThemeColor(TH_VERTEX_SELECT); else @@ -841,17 +840,17 @@ static void draw_selected_name(Scene *scene, Object *ob, View3D *v3d) else sprintf(info, "(%d)", CFRA); - /* colour is always white */ + /* color is always white */ UI_ThemeColor(TH_TEXT_HI); } if (U.uiflag & USER_SHOW_ROTVIEWICON) offset = 14 + (U.rvisize * 2); - BLF_draw_default(offset, 10, 0.0f, info); + BLF_draw_default(offset, 10, 0.0f, info, sizeof(info)-1); } -static void view3d_get_viewborder_size(Scene *scene, ARegion *ar, float size_r[2]) +void view3d_viewborder_size_get(Scene *scene, ARegion *ar, float size_r[2]) { float winmax= MAX2(ar->winx, ar->winy); float aspect= (scene->r.xsch*scene->r.xasp) / (scene->r.ysch*scene->r.yasp); @@ -865,12 +864,12 @@ static void view3d_get_viewborder_size(Scene *scene, ARegion *ar, float size_r[2 } } -void view3d_calc_camera_border(Scene *scene, ARegion *ar, RegionView3D *rv3d, View3D *v3d, rctf *viewborder_r) +void view3d_calc_camera_border(Scene *scene, ARegion *ar, RegionView3D *rv3d, View3D *v3d, rctf *viewborder_r, short do_shift) { float zoomfac, size[2]; float dx= 0.0f, dy= 0.0f; - view3d_get_viewborder_size(scene, ar, size); + view3d_viewborder_size_get(scene, ar, size); if (rv3d == NULL) rv3d = ar->regiondata; @@ -904,12 +903,13 @@ void view3d_calc_camera_border(Scene *scene, ARegion *ar, RegionView3D *rv3d, Vi viewborder_r->xmax-= dx; viewborder_r->ymax-= dy; - if(v3d->camera && v3d->camera->type==OB_CAMERA) { + if(do_shift && v3d->camera && v3d->camera->type==OB_CAMERA) { Camera *cam= v3d->camera->data; float w = viewborder_r->xmax - viewborder_r->xmin; float h = viewborder_r->ymax - viewborder_r->ymin; float side = MAX2(w, h); - + + if(do_shift == -1) side *= -1; viewborder_r->xmin+= cam->shiftx*side; viewborder_r->xmax+= cam->shiftx*side; viewborder_r->ymin+= cam->shifty*side; @@ -917,67 +917,8 @@ void view3d_calc_camera_border(Scene *scene, ARegion *ar, RegionView3D *rv3d, Vi } } -void view3d_set_1_to_1_viewborder(Scene *scene, ARegion *ar) -{ - RegionView3D *rv3d= ar->regiondata; - float size[2]; - int im_width= (scene->r.size*scene->r.xsch)/100; - - view3d_get_viewborder_size(scene, ar, size); - - rv3d->camzoom= (sqrt(4.0*im_width/size[0]) - M_SQRT2)*50.0; - rv3d->camzoom= CLAMPIS(rv3d->camzoom, -30, 300); -} - - -static void drawviewborder_flymode(ARegion *ar) -{ - /* draws 4 edge brackets that frame the safe area where the - mouse can move during fly mode without spinning the view */ - float x1, x2, y1, y2; - - x1= 0.45*(float)ar->winx; - y1= 0.45*(float)ar->winy; - x2= 0.55*(float)ar->winx; - y2= 0.55*(float)ar->winy; - cpack(0); - - - glBegin(GL_LINES); - /* bottom left */ - glVertex2f(x1,y1); - glVertex2f(x1,y1+5); - - glVertex2f(x1,y1); - glVertex2f(x1+5,y1); - - /* top right */ - glVertex2f(x2,y2); - glVertex2f(x2,y2-5); - - glVertex2f(x2,y2); - glVertex2f(x2-5,y2); - - /* top left */ - glVertex2f(x1,y2); - glVertex2f(x1,y2-5); - - glVertex2f(x1,y2); - glVertex2f(x1+5,y2); - - /* bottom right */ - glVertex2f(x2,y1); - glVertex2f(x2,y1+5); - - glVertex2f(x2,y1); - glVertex2f(x2-5,y1); - glEnd(); -} - - static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) { - extern void gl_round_box(int mode, float minx, float miny, float maxx, float maxy, float rad); // interface_panel.c float fac, a; float x1, x2, y1, y2; float x1i, x2i, y1i, y2i; @@ -991,7 +932,7 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) if(v3d->camera->type==OB_CAMERA) ca = v3d->camera->data; - view3d_calc_camera_border(scene, ar, rv3d, v3d, &viewborder); + view3d_calc_camera_border(scene, ar, rv3d, v3d, &viewborder, FALSE); /* the offsets */ x1= viewborder.xmin; y1= viewborder.ymin; @@ -1064,7 +1005,7 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) UI_ThemeColorBlendShade(TH_WIRE, TH_BACK, 0.25, 0); uiSetRoundBox(15); - gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, 12.0); + uiDrawBox(GL_LINE_LOOP, x1, y1, x2, y2, 12.0); } setlinestyle(0); @@ -1073,7 +1014,7 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) /* camera name - draw in highlighted text color */ if (ca && (ca->flag & CAM_SHOWNAME)) { UI_ThemeColor(TH_TEXT_HI); - BLF_draw_default(x1i, y1i-15, 0.0f, v3d->camera->id.name+2); + BLF_draw_default(x1i, y1i-15, 0.0f, v3d->camera->id.name+2, sizeof(v3d->camera->id.name)-2); UI_ThemeColor(TH_WIRE); } } @@ -1190,7 +1131,7 @@ ImBuf *view3d_read_backbuf(ViewContext *vc, short xmin, short ymin, short xmax, if(ymax >= vc->ar->winy) ymaxc= vc->ar->winy-1; else ymaxc= ymax; if(yminc > ymaxc) return NULL; - ibuf= IMB_allocImBuf((xmaxc-xminc+1), (ymaxc-yminc+1), 32, IB_rect,0); + ibuf= IMB_allocImBuf((xmaxc-xminc+1), (ymaxc-yminc+1), 32, IB_rect); view3d_validate_backbuf(vc); @@ -1210,7 +1151,7 @@ ImBuf *view3d_read_backbuf(ViewContext *vc, short xmin, short ymin, short xmax, if(xminc==xmin && xmaxc==xmax && yminc==ymin && ymaxc==ymax) return ibuf; - ibuf1= IMB_allocImBuf( (xmax-xmin+1),(ymax-ymin+1),32,IB_rect,0); + ibuf1= IMB_allocImBuf( (xmax-xmin+1),(ymax-ymin+1),32,IB_rect); rd= ibuf->rect; dr= ibuf1->rect; @@ -1328,7 +1269,7 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d) if(rv3d->persp==RV3D_CAMOB) { rctf vb; - view3d_calc_camera_border(scene, ar, rv3d, v3d, &vb); + view3d_calc_camera_border(scene, ar, rv3d, v3d, &vb, FALSE); x1= vb.xmin; y1= vb.ymin; @@ -1458,26 +1399,26 @@ static void view3d_draw_transp(Scene *scene, ARegion *ar, View3D *v3d) static void view3d_draw_xray(Scene *scene, ARegion *ar, View3D *v3d, int clear) { View3DAfter *v3da, *next; - + if(clear && v3d->zbuf) glClear(GL_DEPTH_BUFFER_BIT); - - v3d->xray= TRUE; + + v3d->xray= TRUE; for(v3da= v3d->afterdraw_xray.first; v3da; v3da= next) { - next= v3da->next; - draw_object(scene, ar, v3d, v3da->base, v3da->flag); + next= v3da->next; + draw_object(scene, ar, v3d, v3da->base, v3da->flag); BLI_remlink(&v3d->afterdraw_xray, v3da); - MEM_freeN(v3da); - } - v3d->xray= FALSE; + MEM_freeN(v3da); } + v3d->xray= FALSE; +} /* clears zbuffer and draws it over */ static void view3d_draw_xraytransp(Scene *scene, ARegion *ar, View3D *v3d, int clear) { View3DAfter *v3da, *next; - + if(clear && v3d->zbuf) glClear(GL_DEPTH_BUFFER_BIT); @@ -1486,14 +1427,14 @@ static void view3d_draw_xraytransp(Scene *scene, ARegion *ar, View3D *v3d, int c for(v3da= v3d->afterdraw_xraytransp.first; v3da; v3da= next) { next= v3da->next; - draw_object(scene, ar, v3d, v3da->base, v3da->flag); + draw_object(scene, ar, v3d, v3da->base, v3da->flag); BLI_remlink(&v3d->afterdraw_xraytransp, v3da); - MEM_freeN(v3da); - } + MEM_freeN(v3da); + } v3d->transp= FALSE; v3d->xray= FALSE; - + } /* *********************** */ @@ -1528,7 +1469,7 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas { RegionView3D *rv3d= ar->regiondata; ListBase *lb; - DupliObject *dob_prev= NULL, *dob, *dob_next; + DupliObject *dob_prev= NULL, *dob, *dob_next= NULL; Base tbase; BoundBox bb, *bb_tmp; /* use a copy because draw_object, calls clear_mesh_caches */ GLuint displist=0; @@ -1638,8 +1579,62 @@ static void draw_dupli_objects(Scene *scene, ARegion *ar, View3D *v3d, Base *bas draw_dupli_objects_color(scene, ar, v3d, base, color); } +void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect) +{ + int x, y, w, h; + rcti r; + /* clamp rect by area */ + + r.xmin= 0; + r.xmax= ar->winx-1; + r.ymin= 0; + r.ymax= ar->winy-1; + + /* Constrain rect to depth bounds */ + BLI_isect_rcti(&r, rect, rect); + + /* assign values to compare with the ViewDepths */ + x= rect->xmin; + y= rect->ymin; -void view3d_update_depths(ARegion *ar, View3D *v3d) + w= rect->xmax - rect->xmin; + h= rect->ymax - rect->ymin; + + if(w <= 0 || h <= 0) { + if(d->depths) + MEM_freeN(d->depths); + d->depths= NULL; + + d->damaged= FALSE; + } + else if( d->w != w || + d->h != h || + d->x != x || + d->y != y || + d->depths==NULL + ) { + d->x= x; + d->y= y; + d->w= w; + d->h= h; + + if(d->depths) + MEM_freeN(d->depths); + + d->depths= MEM_mallocN(sizeof(float)*d->w*d->h,"View depths Subset"); + + d->damaged= TRUE; + } + + if(d->damaged) { + glReadPixels(ar->winrct.xmin+d->x,ar->winrct.ymin+d->y, d->w,d->h, GL_DEPTH_COMPONENT,GL_FLOAT, d->depths); + glGetDoublev(GL_DEPTH_RANGE,d->depth_range); + d->damaged= FALSE; + } +} + +/* note, with nouveau drivers the glReadPixels() is very slow. [#24339] */ +void view3d_update_depths(ARegion *ar) { RegionView3D *rv3d= ar->regiondata; @@ -1669,6 +1664,30 @@ void view3d_update_depths(ARegion *ar, View3D *v3d) } } +/* utility function to find the closest Z value, use for autodepth */ +float view3d_depth_near(ViewDepths *d) +{ + /* convert to float for comparisons */ + const float near= (float)d->depth_range[0]; + const float far_real= (float)d->depth_range[1]; + float far= far_real; + + const float *depths= d->depths; + float depth= FLT_MAX; + int i= (int)d->w * (int)d->h; /* cast to avoid short overflow */ + + /* far is both the starting 'far' value + * and the closest value found. */ + while(i--) { + depth= *depths++; + if((depth < far) && (depth > near)) { + far= depth; + } + } + + return far == far_real ? FLT_MAX : far; +} + void draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d) { short zbuf= v3d->zbuf; @@ -1698,7 +1717,6 @@ void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (* func)(void *)) { RegionView3D *rv3d= ar->regiondata; Base *base; - Scene *sce; short zbuf= v3d->zbuf; short flag= v3d->flag; float glalphaclip= U.glalphaclip; @@ -1731,7 +1749,8 @@ void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (* func)(void *)) /* draw set first */ if(scene->set) { - for(SETLOOPER(scene->set, base)) { + Scene *sce_iter; + for(SETLOOPER(scene->set, sce_iter, base)) { if(v3d->lay & base->lay) { if (func == NULL || func(base)) { draw_object(scene, ar, v3d, base, 0); @@ -1770,9 +1789,9 @@ void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (* func)(void *)) if(v3d->afterdraw_xray.first || v3d->afterdraw_xraytransp.first) { - glDepthFunc(GL_ALWAYS); /* always write into the depth bufer, overwriting front z values */ + glDepthFunc(GL_ALWAYS); /* always write into the depth bufer, overwriting front z values */ for(v3da= v3d->afterdraw_xray.first; v3da; v3da= next) { - next= v3da->next; + next= v3da->next; draw_object(scene, ar, v3d, v3da->base, 0); } glDepthFunc(GL_LEQUAL); /* Now write the depth buffer normally */ @@ -1787,7 +1806,7 @@ void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (* func)(void *)) BLI_remlink(&v3d->afterdraw_transp, v3da); MEM_freeN(v3da); } - + v3d->xray= TRUE; v3d->transp= FALSE; for(v3da= v3d->afterdraw_xray.first; v3da; v3da= next) { @@ -1795,8 +1814,8 @@ void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (* func)(void *)) draw_object(scene, ar, v3d, v3da->base, 0); BLI_remlink(&v3d->afterdraw_xray, v3da); MEM_freeN(v3da); - } - + } + v3d->xray= TRUE; v3d->transp= TRUE; for(v3da= v3d->afterdraw_xraytransp.first; v3da; v3da= next) { @@ -1853,16 +1872,14 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d) { ListBase shadows; View3DShadow *shadow; - Scene *sce; + Scene *sce_iter; Base *base; Object *ob; - ARegion ar; - RegionView3D rv3d; shadows.first= shadows.last= NULL; /* update lamp transform and gather shadow lamps */ - for(SETLOOPER(scene, base)) { + for(SETLOOPER(scene, sce_iter, base)) { ob= base->object; if(ob->type == OB_LAMP) @@ -1886,6 +1903,8 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d) /* this needs to be done better .. */ float viewmat[4][4], winmat[4][4]; int drawtype, lay, winsize, flag2=v3d->flag2; + ARegion ar= {0}; + RegionView3D rv3d= {{{0}}}; drawtype= v3d->drawtype; lay= v3d->lay; @@ -1897,9 +1916,6 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d) GPU_lamp_shadow_buffer_bind(shadow->lamp, viewmat, &winsize, winmat); - memset(&ar, 0, sizeof(ar)); - memset(&rv3d, 0, sizeof(rv3d)); - ar.regiondata= &rv3d; ar.regiontype= RGN_TYPE_WINDOW; rv3d.persp= RV3D_CAMOB; @@ -1923,8 +1939,10 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d) /* *********************** customdata **************** */ /* goes over all modes and view3d settings */ -static CustomDataMask get_viewedit_datamask(bScreen *screen, Scene *scene, Object *ob) +CustomDataMask ED_viewedit_datamask(bScreen *screen) { + Scene *scene= screen->scene; + Object *ob= scene->basact ? scene->basact->object : NULL; CustomDataMask mask = CD_MASK_BAREMESH; ScrArea *sa; @@ -1974,29 +1992,34 @@ static void view3d_main_area_setup_view(Scene *scene, View3D *v3d, ARegion *ar, if(viewmat) copy_m4_m4(rv3d->viewmat, viewmat); else - setviewmatrixview3d(scene, v3d, rv3d); /* note: calls where_is_object for camera... */ + setviewmatrixview3d(scene, v3d, rv3d); /* note: calls where_is_object for camera... */ /* update utilitity matrices */ mul_m4_m4m4(rv3d->persmat, rv3d->viewmat, rv3d->winmat); invert_m4_m4(rv3d->persinv, rv3d->persmat); invert_m4_m4(rv3d->viewinv, rv3d->viewmat); - + /* calculate pixelsize factor once, is used for lamps and obcenters */ { - float len1, len2, vec[3]; - - copy_v3_v3(vec, rv3d->persinv[0]); - len1= normalize_v3(vec); - copy_v3_v3(vec, rv3d->persinv[1]); - len2= normalize_v3(vec); - - rv3d->pixsize= 2.0f*(len1>len2?len1:len2); + /* note: '1.0f / len_v3(v1)' replaced 'len_v3(rv3d->viewmat[0])' + * because of float point precision problems at large values [#23908] */ + float v1[3], v2[3]; + float len1, len2; + + v1[0]= rv3d->persmat[0][0]; + v1[1]= rv3d->persmat[1][0]; + v1[2]= rv3d->persmat[2][0]; + + v2[0]= rv3d->persmat[0][1]; + v2[1]= rv3d->persmat[1][1]; + v2[2]= rv3d->persmat[2][1]; - /* correct for window size */ - if(ar->winx > ar->winy) rv3d->pixsize/= (float)ar->winx; - else rv3d->pixsize/= (float)ar->winy; + len1= 1.0f / len_v3(v1); + len2= 1.0f / len_v3(v2); + + rv3d->pixsize = (2.0f * MAX2(len1, len2)) / (float)MAX2(ar->winx, ar->winy); } - + /* set for opengl */ glMatrixMode(GL_PROJECTION); glLoadMatrixf(rv3d->winmat); @@ -2006,7 +2029,6 @@ static void view3d_main_area_setup_view(Scene *scene, View3D *v3d, ARegion *ar, void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, int winy, float viewmat[][4], float winmat[][4]) { - Scene *sce; Base *base; float backcol[3]; int bwinx, bwiny; @@ -2020,7 +2042,7 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, brect= ar->winrct; ar->winx= winx; - ar->winy= winy; + ar->winy= winy; ar->winrct.xmin= 0; ar->winrct.ymin= 0; ar->winrct.xmax= winx; @@ -2033,6 +2055,10 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, /* free images which can have changed on frame-change * warning! can be slow so only free animated images - campbell */ GPU_free_images_anim(); + + /* shadow buffers, before we setup matrices */ + if(draw_glsl_material(scene, NULL, v3d, v3d->drawtype)) + gpu_update_lamps_shadows(scene, v3d); /* set background color, fallback on the view background color */ if(scene->world) { @@ -2061,14 +2087,15 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, /* draw set first */ if(scene->set) { - for(SETLOOPER(scene->set, base)) { + Scene *sce_iter; + for(SETLOOPER(scene->set, sce_iter, base)) { if(v3d->lay & base->lay) { UI_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f); draw_object(scene, ar, v3d, base, DRAW_CONSTCOLOR|DRAW_SCENESET); - + if(base->object->transflag & OB_DUPLI) draw_dupli_objects_color(scene, ar, v3d, base, TH_WIRE); - } + } } } @@ -2123,9 +2150,12 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in RegionView3D *rv3d= ar->regiondata; ImBuf *ibuf; GPUOffScreen *ofs; + + /* state changes make normal drawing go weird otherwise */ + glPushAttrib(GL_LIGHTING_BIT); /* bind */ - ofs= GPU_offscreen_create(sizex, sizey); + ofs= GPU_offscreen_create(&sizex, &sizey); if(ofs == NULL) return NULL; @@ -2146,13 +2176,13 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in } /* read in pixels & stamp */ - ibuf= IMB_allocImBuf(sizex, sizey, 32, flag, 0); + ibuf= IMB_allocImBuf(sizex, sizey, 32, flag); if(ibuf->rect_float) glReadPixels(0, 0, sizex, sizey, GL_RGBA, GL_FLOAT, ibuf->rect_float); else if(ibuf->rect) - glReadPixels(0, 0, sizex, sizey, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); - + glReadPixels(0, 0, sizex, sizey, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); + //if((scene->r.stamp & R_STAMP_ALL) && (scene->r.stamp & R_STAMP_DRAW)) // BKE_stamp_buf(scene, NULL, rr->rectf, rr->rectx, rr->recty, 4); @@ -2160,6 +2190,8 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in GPU_offscreen_unbind(ofs); GPU_offscreen_free(ofs); + glPopAttrib(); + if(ibuf->rect_float && ibuf->rect) IMB_rect_from_float(ibuf); @@ -2169,13 +2201,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in /* creates own 3d views, used by the sequencer */ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, int width, int height, unsigned int flag, int drawtype) { - View3D v3d; - ARegion ar; - RegionView3D rv3d; - - memset(&v3d, 0, sizeof(v3d)); - memset(&ar, 0, sizeof(ar)); - memset(&rv3d, 0, sizeof(rv3d)); + View3D v3d= {0}; + ARegion ar= {0}; + RegionView3D rv3d= {{{0}}}; /* connect data */ v3d.regionbase.first= v3d.regionbase.last= &ar; @@ -2256,24 +2284,20 @@ static void draw_viewport_fps(Scene *scene, ARegion *ar) BLI_snprintf(printable, sizeof(printable), "fps: %i", (int)(fps+0.5)); } - BLF_draw_default(22, ar->winy-17, 0.0f, printable); + BLF_draw_default(22, ar->winy-17, 0.0f, printable, sizeof(printable)-1); } +/* warning: this function has duplicate drawing in ED_view3d_draw_offscreen() */ void view3d_main_area_draw(const bContext *C, ARegion *ar) { Scene *scene= CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d= CTX_wm_region_view3d(C); - Scene *sce; Base *base; Object *ob; float backcol[3]; - int retopo= 0, sculptparticle= 0; - Object *obact = OBACT; - char *grid_unit= NULL; - - /* from now on all object derived meshes check this */ - v3d->customdata_mask= get_viewedit_datamask(CTX_wm_screen(C), scene, obact); + unsigned int lay_used; + const char *grid_unit= NULL; /* shadow buffers, before we setup matrices */ if(draw_glsl_material(scene, NULL, v3d, v3d->drawtype)) @@ -2320,22 +2344,25 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) // needs to be done always, gridview is adjusted in drawgrid() now rv3d->gridview= v3d->grid; - - if ((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) { - if(rv3d->view==0 || rv3d->persp != RV3D_ORTHO) { - drawfloor(scene, v3d); - if(rv3d->persp==RV3D_CAMOB) { - if(scene->world) { - if(scene->world->mode & WO_STARS) { - RE_make_stars(NULL, scene, star_stuff_init_func, star_stuff_vertex_func, - star_stuff_term_func); - } + if(rv3d->view==0 || rv3d->persp != RV3D_ORTHO) { + if ((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) { + drawfloor(scene, v3d, &grid_unit); + } + if(rv3d->persp==RV3D_CAMOB) { + if(scene->world) { + if(scene->world->mode & WO_STARS) { + RE_make_stars(NULL, scene, star_stuff_init_func, star_stuff_vertex_func, + star_stuff_term_func); } + } + if ((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) { if(v3d->flag & V3D_DISPBGPICS) draw_bgpic(scene, ar, v3d); } } - else { + } + else { + if ((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) { ED_region_pixelspace(ar); drawgrid(&scene->unit, ar, v3d, &grid_unit); /* XXX make function? replaces persp(1) */ @@ -2355,7 +2382,8 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) /* draw set first */ if(scene->set) { - for(SETLOOPER(scene->set, base)) { + Scene *sce_iter; + for(SETLOOPER(scene->set, sce_iter, base)) { if(v3d->lay & base->lay) { @@ -2370,9 +2398,13 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) /* Transp and X-ray afterdraw stuff for sets is done later */ } - + + lay_used= 0; + /* then draw not selected and the duplis, but skip editmode object */ for(base= scene->base.first; base; base= base->next) { + lay_used |= base->lay & ((1<<20)-1); + if(v3d->lay & base->lay) { /* dupli drawing */ @@ -2386,11 +2418,20 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) } } -// retopo= retopo_mesh_check() || retopo_curve_check(); - sculptparticle= (obact && obact->mode & (OB_MODE_PARTICLE_EDIT)) && !scene->obedit; - if(retopo) - view3d_update_depths(ar, v3d); - + if(v3d->lay_used != lay_used) { /* happens when loading old files or loading with UI load */ + ARegion *ar_iter; + ScrArea *sa= CTX_wm_area(C); + + /* find header and force tag redraw */ + for(ar_iter= sa->regionbase.first; ar_iter; ar_iter= ar_iter->next) + if(ar_iter->regiontype==RGN_TYPE_HEADER) { + ED_region_tag_redraw(ar_iter); + break; + } + + v3d->lay_used= lay_used; + } + /* draw selected and editmode */ for(base= scene->base.first; base; base= base->next) { if(v3d->lay & base->lay) { @@ -2398,11 +2439,7 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) draw_object(scene, ar, v3d, base, 0); } } - - if(!retopo && sculptparticle && !(obact && (obact->dtx & OB_DRAWXRAY))) { - view3d_update_depths(ar, v3d); - } - + // REEB_draw(); /* Transp and X-ray afterdraw stuff */ @@ -2411,11 +2448,7 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) if(v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(scene, ar, v3d, 1); ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); - - if(!retopo && sculptparticle && (obact && (OBACT->dtx & OB_DRAWXRAY))) { - view3d_update_depths(ar, v3d); - } - + if(rv3d->rflag & RV3D_CLIPPING) view3d_clr_clipping(); @@ -2446,8 +2479,8 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) /* Draw particle edit brush XXX (removed) */ - if(rv3d->persp==RV3D_CAMOB) drawviewborder(scene, ar, v3d); - if(rv3d->rflag & RV3D_FLYMODE) drawviewborder_flymode(ar); + if(rv3d->persp==RV3D_CAMOB) + drawviewborder(scene, ar, v3d); if ((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) { /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ @@ -2469,8 +2502,14 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) draw_viewport_name(ar, v3d); } if (grid_unit) { /* draw below the viewport name */ + char tstr[32]= ""; + UI_ThemeColor(TH_TEXT_HI); - BLF_draw_default(22, ar->winy-(USER_SHOW_VIEWPORTNAME?40:20), 0.0f, grid_unit); + if(v3d->grid != 1.0f) { + BLI_snprintf(tstr, sizeof(tstr), "%s x %.4g", grid_unit, v3d->grid); + } + + BLF_draw_default(22, ar->winy-(USER_SHOW_VIEWPORTNAME?40:20), 0.0f, tstr[0]?tstr : grid_unit, sizeof(tstr)); /* XXX, use real length */ } ob= OBACT; diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 6d09da2dbcf..86957ecb86c 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -34,12 +34,14 @@ #include "DNA_armature_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_camera_types.h" #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_rand.h" +#include "BLI_utildefines.h" #include "BKE_context.h" #include "BKE_image.h" @@ -52,6 +54,7 @@ #include "BIF_gl.h" +#include "BIF_glutil.h" #include "WM_api.h" #include "WM_types.h" @@ -60,10 +63,10 @@ #include "RNA_define.h" #include "ED_particle.h" -#include "ED_retopo.h" #include "ED_screen.h" #include "ED_transform.h" #include "ED_mesh.h" +#include "ED_view3d.h" #include "PIL_time.h" /* smoothview */ @@ -158,6 +161,7 @@ static void view3d_boxview_sync(ScrArea *sa, ARegion *ar) { ARegion *artest; RegionView3D *rv3d= ar->regiondata; + short clip= 0; for(artest= sa->regionbase.first; artest; artest= artest->next) { if(artest!=ar && artest->regiontype==RGN_TYPE_WINDOW) { @@ -185,11 +189,16 @@ static void view3d_boxview_sync(ScrArea *sa, ARegion *ar) rv3dtest->ofs[2]= rv3d->ofs[2]; } + clip |= rv3dtest->viewlock & RV3D_BOXCLIP; + ED_region_tag_redraw(artest); } } } - view3d_boxview_clip(sa); + + if(clip) { + view3d_boxview_clip(sa); + } } /* for home, center etc */ @@ -197,6 +206,7 @@ void view3d_boxview_copy(ScrArea *sa, ARegion *ar) { ARegion *artest; RegionView3D *rv3d= ar->regiondata; + short clip= 0; for(artest= sa->regionbase.first; artest; artest= artest->next) { if(artest!=ar && artest->regiontype==RGN_TYPE_WINDOW) { @@ -206,17 +216,23 @@ void view3d_boxview_copy(ScrArea *sa, ARegion *ar) rv3dtest->dist= rv3d->dist; copy_v3_v3(rv3dtest->ofs, rv3d->ofs); ED_region_tag_redraw(artest); + + clip |= rv3dtest->viewlock & RV3D_BOXCLIP; } } } - view3d_boxview_clip(sa); + + if(clip) { + view3d_boxview_clip(sa); + } } -void ED_view3d_quadview_update(ScrArea *sa, ARegion *ar) +/* 'clip' is used to know if our clip setting has changed */ +void ED_view3d_quadview_update(ScrArea *sa, ARegion *ar, short do_clip) { + ARegion *arsync= NULL; RegionView3D *rv3d= ar->regiondata; short viewlock; - /* this function copies flags from the first of the 3 other quadview regions to the 2 other, so it assumes this is the region whose properties are always being edited, weak */ @@ -224,18 +240,30 @@ void ED_view3d_quadview_update(ScrArea *sa, ARegion *ar) if((viewlock & RV3D_LOCKED)==0) viewlock= 0; - else if((viewlock & RV3D_BOXVIEW)==0) + else if((viewlock & RV3D_BOXVIEW)==0) { viewlock &= ~RV3D_BOXCLIP; + do_clip= TRUE; + } for(; ar; ar= ar->prev) { if(ar->alignment==RGN_ALIGN_QSPLIT) { rv3d= ar->regiondata; rv3d->viewlock= viewlock; + + if(do_clip && (viewlock & RV3D_BOXCLIP)==0) { + rv3d->rflag &= ~RV3D_BOXCLIP; + } + + /* use arsync so we sync with one of the aligned views below + * else the view jumps on changing view settings like 'clip' + * since it copies from the perspective view */ + arsync= ar; } } - if(rv3d->viewlock & RV3D_BOXVIEW) - view3d_boxview_copy(sa, sa->regionbase.last); + if(rv3d->viewlock & RV3D_BOXVIEW) { + view3d_boxview_copy(sa, arsync ? arsync : sa->regionbase.last); + } ED_area_tag_redraw(sa); } @@ -298,7 +326,7 @@ static void calctrackballvec(rcti *rect, int mx, int my, float *vec) static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event) { static float lastofs[3] = {0,0,0}; - View3D *v3d = CTX_wm_view3d(C); + View3D *v3d; RegionView3D *rv3d; ViewOpsData *vod= MEM_callocN(sizeof(ViewOpsData), "viewops data"); @@ -306,6 +334,7 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event) op->customdata= vod; vod->sa= CTX_wm_area(C); vod->ar= CTX_wm_region(C); + v3d= vod->sa->spacedata.first; vod->rv3d= rv3d= vod->ar->regiondata; vod->dist0= rv3d->dist; copy_qt_qt(vod->oldquat, rv3d->viewquat); @@ -378,19 +407,26 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event) static void viewops_data_free(bContext *C, wmOperator *op) { + ARegion *ar; Paint *p = paint_get_active(CTX_data_scene(C)); - ViewOpsData *vod= op->customdata; - vod->rv3d->rflag &= ~RV3D_NAVIGATING; + if(op->customdata) { + ViewOpsData *vod= op->customdata; + ar= vod->ar; + vod->rv3d->rflag &= ~RV3D_NAVIGATING; - if(p && (p->flags & PAINT_FAST_NAVIGATE)) - ED_region_tag_redraw(vod->ar); + if(vod->timer) + WM_event_remove_timer(CTX_wm_manager(C), vod->timer->win, vod->timer); - if(vod->timer) - WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), vod->timer); + MEM_freeN(vod); + op->customdata= NULL; + } + else { + ar= CTX_wm_region(C); + } - MEM_freeN(vod); - op->customdata= NULL; + if(p && (p->flags & PAINT_FAST_NAVIGATE)) + ED_region_tag_redraw(ar); } /* ************************** viewrotate **********************************/ @@ -664,6 +700,9 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y) vod->oldx= x; vod->oldy= y; + /* avoid precision loss over time */ + normalize_qt(rv3d->viewquat); + ED_region_tag_redraw(vod->ar); } @@ -707,7 +746,7 @@ static int viewrotate_modal(bContext *C, wmOperator *op, wmEvent *event) viewrotate_apply(vod, event->x, event->y); } else if (event_code==VIEW_CONFIRM) { - request_depth_update(CTX_wm_region_view3d(C)); + request_depth_update(vod->rv3d); viewops_data_free(C, op); return OPERATOR_FINISHED; @@ -718,36 +757,44 @@ static int viewrotate_modal(bContext *C, wmOperator *op, wmEvent *event) static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event) { - RegionView3D *rv3d= CTX_wm_region_view3d(C); ViewOpsData *vod; - - if(rv3d->viewlock) - return OPERATOR_CANCELLED; + RegionView3D *rv3d; /* makes op->customdata */ viewops_data_create(C, op, event); vod= op->customdata; + rv3d= vod->rv3d; + + if(rv3d->viewlock) { /* poll should check but in some cases fails, see poll func for details */ + viewops_data_free(C, op); + return OPERATOR_PASS_THROUGH; + } /* switch from camera view when: */ - if(vod->rv3d->persp != RV3D_PERSP) { + if(rv3d->persp != RV3D_PERSP) { - if (U.uiflag & USER_AUTOPERSP) - vod->rv3d->persp= RV3D_PERSP; - else if(vod->rv3d->persp==RV3D_CAMOB) { + if (U.uiflag & USER_AUTOPERSP) { + rv3d->persp= RV3D_PERSP; + } + else if(rv3d->persp==RV3D_CAMOB) { /* changed since 2.4x, use the camera view */ - View3D *v3d = CTX_wm_view3d(C); - if(v3d->camera) + View3D *v3d = vod->sa->spacedata.first; + + if(v3d->camera) { view3d_settings_from_ob(v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL); + } - vod->rv3d->persp= RV3D_PERSP; + if(rv3d->persp==RV3D_CAMOB) { + rv3d->persp= rv3d->lpersp; + } } ED_region_tag_redraw(vod->ar); } if (event->type == MOUSEPAN) { viewrotate_apply(vod, event->prevx, event->prevy); - request_depth_update(CTX_wm_region_view3d(C)); + request_depth_update(rv3d); viewops_data_free(C, op); @@ -756,7 +803,7 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event) else if (event->type == MOUSEROTATE) { /* MOUSEROTATE performs orbital rotation, so y axis delta is set to 0 */ viewrotate_apply(vod, event->prevx, event->y); - request_depth_update(CTX_wm_region_view3d(C)); + request_depth_update(rv3d); viewops_data_free(C, op); @@ -782,21 +829,6 @@ static int view3d_camera_active_poll(bContext *C) return 0; } -static int view3d_rotate_poll(bContext *C) -{ - if (!ED_operator_view3d_active(C)) { - return 0; - } else { - RegionView3D *rv3d= CTX_wm_region_view3d(C); - /* rv3d is null in menus, but it's ok when the menu is clicked on */ - /* XXX of course, this doesn't work with quadview - * Maybe having exec return PASSTHROUGH would be better than polling here - * Poll functions are full of problems anyway. - * */ - return rv3d == NULL || rv3d->viewlock == 0; - } -} - void VIEW3D_OT_rotate(wmOperatorType *ot) { @@ -808,7 +840,7 @@ void VIEW3D_OT_rotate(wmOperatorType *ot) /* api callbacks */ ot->invoke= viewrotate_invoke; ot->modal= viewrotate_modal; - ot->poll= view3d_rotate_poll; + ot->poll= ED_operator_region_view3d_active; /* flags */ ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER; @@ -855,10 +887,11 @@ void viewmove_modal_keymap(wmKeyConfig *keyconf) static void viewmove_apply(ViewOpsData *vod, int x, int y) { if(vod->rv3d->persp==RV3D_CAMOB) { - float max= (float)MAX2(vod->ar->winx, vod->ar->winy); + float zoomfac= (M_SQRT2 + vod->rv3d->camzoom/50.0); + zoomfac= (zoomfac*zoomfac)*0.5; - vod->rv3d->camdx += (vod->oldx - x)/(max); - vod->rv3d->camdy += (vod->oldy - y)/(max); + vod->rv3d->camdx += (vod->oldx - x)/(vod->ar->winx * zoomfac); + vod->rv3d->camdy += (vod->oldy - y)/(vod->ar->winy * zoomfac); CLAMP(vod->rv3d->camdx, -1.0f, 1.0f); CLAMP(vod->rv3d->camdy, -1.0f, 1.0f); // XXX preview3d_event= 0; @@ -913,7 +946,7 @@ static int viewmove_modal(bContext *C, wmOperator *op, wmEvent *event) viewmove_apply(vod, event->x, event->y); } else if (event_code==VIEW_CONFIRM) { - request_depth_update(CTX_wm_region_view3d(C)); + request_depth_update(vod->rv3d); viewops_data_free(C, op); @@ -931,7 +964,7 @@ static int viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event) if (event->type == MOUSEPAN) { ViewOpsData *vod= op->customdata; viewmove_apply(vod, event->prevx, event->prevy); - request_depth_update(CTX_wm_region_view3d(C)); + request_depth_update(vod->rv3d); viewops_data_free(C, op); @@ -1145,7 +1178,7 @@ static int viewzoom_modal(bContext *C, wmOperator *op, wmEvent *event) viewzoom_apply(vod, event->x, event->y, U.viewzoom); } else if (event_code==VIEW_CONFIRM) { - request_depth_update(CTX_wm_region_view3d(C)); + request_depth_update(vod->rv3d); viewops_data_free(C, op); return OPERATOR_FINISHED; @@ -1156,38 +1189,57 @@ static int viewzoom_modal(bContext *C, wmOperator *op, wmEvent *event) static int viewzoom_exec(bContext *C, wmOperator *op) { - View3D *v3d = CTX_wm_view3d(C); - RegionView3D *rv3d= CTX_wm_region_view3d(C); + View3D *v3d; + RegionView3D *rv3d; + ScrArea *sa; + ARegion *ar; + int delta= RNA_int_get(op->ptr, "delta"); - int mx = RNA_int_get(op->ptr, "mx"); - int my = RNA_int_get(op->ptr, "my"); + int mx, my; + + if(op->customdata) { + ViewOpsData *vod= op->customdata; + + sa= vod->sa; + ar= vod->ar; + } + else { + sa= CTX_wm_area(C); + ar= CTX_wm_region(C); + } + + v3d= sa->spacedata.first; + rv3d= ar->regiondata; + + mx= RNA_property_is_set(op->ptr, "mx") ? RNA_int_get(op->ptr, "mx") : ar->winx / 2; + my= RNA_property_is_set(op->ptr, "my") ? RNA_int_get(op->ptr, "my") : ar->winy / 2; if(delta < 0) { /* this min and max is also in viewmove() */ if(rv3d->persp==RV3D_CAMOB) { rv3d->camzoom-= 10; - if(rv3d->camzoom<-30) rv3d->camzoom= -30; + if(rv3d->camzoom < RV3D_CAMZOOM_MIN) rv3d->camzoom= RV3D_CAMZOOM_MIN; } else if(rv3d->dist<10.0*v3d->far) { - view_zoom_mouseloc(CTX_wm_region(C), 1.2f, mx, my); + view_zoom_mouseloc(ar, 1.2f, mx, my); } } else { if(rv3d->persp==RV3D_CAMOB) { rv3d->camzoom+= 10; - if(rv3d->camzoom>600) rv3d->camzoom= 600; + if(rv3d->camzoom > RV3D_CAMZOOM_MAX) rv3d->camzoom= RV3D_CAMZOOM_MAX; } else if(rv3d->dist> 0.001*v3d->grid) { - view_zoom_mouseloc(CTX_wm_region(C), .83333f, mx, my); + view_zoom_mouseloc(ar, .83333f, mx, my); } } if(rv3d->viewlock & RV3D_BOXVIEW) - view3d_boxview_sync(CTX_wm_area(C), CTX_wm_region(C)); + view3d_boxview_sync(sa, ar); + + request_depth_update(rv3d); + ED_region_tag_redraw(ar); - request_depth_update(CTX_wm_region_view3d(C)); - ED_region_tag_redraw(CTX_wm_region(C)); - viewops_data_free(C, op); return OPERATOR_FINISHED; @@ -1195,8 +1247,6 @@ static int viewzoom_exec(bContext *C, wmOperator *op) static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event) { - int delta= RNA_int_get(op->ptr, "delta"); - /* if one or the other zoom position aren't set, set from event */ if (!RNA_property_is_set(op->ptr, "mx") || !RNA_property_is_set(op->ptr, "my")) { @@ -1204,7 +1254,7 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event) RNA_int_set(op->ptr, "my", event->y); } - if(delta) { + if(RNA_property_is_set(op->ptr, "delta")) { /* makes op->customdata */ viewops_data_create(C, op, event); viewzoom_exec(C, op); @@ -1231,7 +1281,7 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event) vod->origy = vod->oldy = vod->origy + event->x - event->prevx; viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY); } - request_depth_update(CTX_wm_region_view3d(C)); + request_depth_update(vod->rv3d); viewops_data_free(C, op); return OPERATOR_FINISHED; @@ -1264,7 +1314,7 @@ void VIEW3D_OT_zoom(wmOperatorType *ot) ot->invoke= viewzoom_invoke; ot->exec= viewzoom_exec; ot->modal= viewzoom_modal; - ot->poll= ED_operator_view3d_active; + ot->poll= ED_operator_region_view3d_active; /* flags */ ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER; @@ -1274,7 +1324,7 @@ void VIEW3D_OT_zoom(wmOperatorType *ot) RNA_def_int(ot->srna, "my", 0, 0, INT_MAX, "Zoom Position Y", "", 0, INT_MAX); } -static int viewhome_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2.4x */ +static int view3d_all_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2.4x */ { ARegion *ar= CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); @@ -1289,19 +1339,18 @@ static int viewhome_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2. int ok= 1, onedone=0; if(center) { - min[0]= min[1]= min[2]= 0.0f; - max[0]= max[1]= max[2]= 0.0f; - /* in 2.4x this also move the cursor to (0, 0, 0) (with shift+c). */ curs= give_cursor(scene, v3d); - curs[0]= curs[1]= curs[2]= 0.0; + zero_v3(min); + zero_v3(max); + zero_v3(curs); } else { INIT_MINMAX(min, max); } for(base= scene->base.first; base; base= base->next) { - if(base->lay & v3d->lay) { + if(BASE_VISIBLE(v3d, base)) { onedone= 1; minmax_object(base->object, min, max); } @@ -1318,9 +1367,7 @@ static int viewhome_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2. return OPERATOR_FINISHED; } - afm[0]= (max[0]-min[0]); - afm[1]= (max[1]-min[1]); - afm[2]= (max[2]-min[2]); + sub_v3_v3v3(afm, max, min); size= 0.7f*MAX3(afm[0], afm[1], afm[2]); if(size==0.0) ok= 0; @@ -1342,7 +1389,7 @@ static int viewhome_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2. if (rv3d->persp==RV3D_CAMOB) { rv3d->persp= RV3D_PERSP; - smooth_view(C, NULL, v3d->camera, new_ofs, NULL, &new_dist, NULL); + smooth_view(C, v3d->camera, NULL, new_ofs, NULL, &new_dist, NULL); } else { smooth_view(C, NULL, NULL, new_ofs, NULL, &new_dist, NULL); @@ -1350,25 +1397,11 @@ static int viewhome_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2. } // XXX BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT); - if(rv3d->viewlock & RV3D_BOXVIEW) - view3d_boxview_copy(CTX_wm_area(C), ar); - WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, v3d); return OPERATOR_FINISHED; } -static int viewhome_poll(bContext *C) -{ - if(ED_operator_view3d_active(C)) { - RegionView3D *rv3d= CTX_wm_region_view3d(C); //XXX, when accessed from a header menu this doesnt work! - if(rv3d && rv3d->persp!=RV3D_CAMOB) { - return 1; - } - } - - return 0; -} void VIEW3D_OT_view_all(wmOperatorType *ot) { @@ -1378,8 +1411,8 @@ void VIEW3D_OT_view_all(wmOperatorType *ot) ot->idname= "VIEW3D_OT_view_all"; /* api callbacks */ - ot->exec= viewhome_exec; - ot->poll= viewhome_poll; + ot->exec= view3d_all_exec; + ot->poll= ED_operator_region_view3d_active; /* flags */ ot->flag= 0; @@ -1388,7 +1421,7 @@ void VIEW3D_OT_view_all(wmOperatorType *ot) } -static int viewselected_exec(bContext *C, wmOperator *op) /* like a localview without local!, was centerview() in 2.4x */ +static int viewselected_exec(bContext *C, wmOperator *UNUSED(op)) /* like a localview without local!, was centerview() in 2.4x */ { ARegion *ar= CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); @@ -1445,7 +1478,7 @@ static int viewselected_exec(bContext *C, wmOperator *op) /* like a localview wi } } else if (paint_facesel_test(ob)) { - ok= minmax_tface(scene, min, max); + ok= paintface_minmax(ob, min, max); } else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) { ok= PE_minmax(scene, min, max); @@ -1505,9 +1538,9 @@ static int viewselected_exec(bContext *C, wmOperator *op) /* like a localview wi smooth_view(C, NULL, NULL, new_ofs, NULL, ok_dist ? &new_dist : NULL, NULL); } + /* smooth view does viewlock RV3D_BOXVIEW copy */ + // XXX BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT); - if(rv3d->viewlock & RV3D_BOXVIEW) - view3d_boxview_copy(CTX_wm_area(C), ar); return OPERATOR_FINISHED; } @@ -1522,13 +1555,13 @@ void VIEW3D_OT_view_selected(wmOperatorType *ot) /* api callbacks */ ot->exec= viewselected_exec; - ot->poll= ED_operator_view3d_active; + ot->poll= ED_operator_region_view3d_active; /* flags */ ot->flag= 0; } -static int viewcenter_cursor_exec(bContext *C, wmOperator *op) +static int viewcenter_cursor_exec(bContext *C, wmOperator *UNUSED(op)) { View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d= CTX_wm_region_view3d(C); @@ -1540,8 +1573,7 @@ static int viewcenter_cursor_exec(bContext *C, wmOperator *op) negate_v3_v3(new_ofs, give_cursor(scene, v3d)); smooth_view(C, NULL, NULL, new_ofs, NULL, NULL, NULL); - if (rv3d->viewlock & RV3D_BOXVIEW) - view3d_boxview_copy(CTX_wm_area(C), CTX_wm_region(C)); + /* smooth view does viewlock RV3D_BOXVIEW copy */ } return OPERATOR_FINISHED; @@ -1562,7 +1594,7 @@ void VIEW3D_OT_view_center_cursor(wmOperatorType *ot) ot->flag= 0; } -static int view3d_center_camera_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2.4x */ +static int view3d_center_camera_exec(bContext *C, wmOperator *UNUSED(op)) /* was view3d_home() in 2.4x */ { RegionView3D *rv3d= CTX_wm_region_view3d(C); @@ -1607,7 +1639,7 @@ static int render_border_exec(bContext *C, wmOperator *op) rect.ymax= RNA_int_get(op->ptr, "ymax"); /* calculate range */ - view3d_calc_camera_border(scene, ar, rv3d, v3d, &vb); + view3d_calc_camera_border(scene, ar, rv3d, v3d, &vb, FALSE); scene->r.border.xmin= ((float)rect.xmin-vb.xmin)/(vb.xmax-vb.xmin); scene->r.border.ymin= ((float)rect.ymin-vb.ymin)/(vb.ymax-vb.ymin); @@ -1681,10 +1713,8 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op) /* ZBuffer depth vars */ bglMats mats; - float depth, depth_close= FLT_MAX; - int had_depth = 0; + float depth_close= FLT_MAX; double cent[2], p[3]; - int xs, ys; /* note; otherwise opengl won't work */ view3d_operator_needs_opengl(C); @@ -1698,38 +1728,19 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op) /* Get Z Depths, needed for perspective, nice for ortho */ bgl_get_mats(&mats); draw_depth(scene, ar, v3d, NULL); + + { + /* avoid allocating the whole depth buffer */ + ViewDepths depth_temp= {0}; - /* force updating */ - if (rv3d->depths) { - had_depth = 1; - rv3d->depths->damaged = 1; - } - - view3d_update_depths(ar, v3d); - - /* Constrain rect to depth bounds */ - if (rect.xmin < 0) rect.xmin = 0; - if (rect.ymin < 0) rect.ymin = 0; - if (rect.xmax >= rv3d->depths->w) rect.xmax = rv3d->depths->w-1; - if (rect.ymax >= rv3d->depths->h) rect.ymax = rv3d->depths->h-1; - - /* Find the closest Z pixel */ - for (xs=rect.xmin; xs < rect.xmax; xs++) { - for (ys=rect.ymin; ys < rect.ymax; ys++) { - depth= rv3d->depths->depths[ys*rv3d->depths->w+xs]; - if(depth < rv3d->depths->depth_range[1] && depth > rv3d->depths->depth_range[0]) { - if (depth_close > depth) { - depth_close = depth; - } - } - } - } - - if (had_depth==0) { - MEM_freeN(rv3d->depths->depths); - rv3d->depths->depths = NULL; + /* avoid view3d_update_depths() for speed. */ + view3d_update_depths_rect(ar, &depth_temp, &rect); + + /* find the closest Z pixel */ + depth_close= view3d_depth_near(&depth_temp); + + MEM_freeN(depth_temp.depths); } - rv3d->depths->damaged = 1; cent[0] = (((double)rect.xmin)+((double)rect.xmax)) / 2; cent[1] = (((double)rect.ymin)+((double)rect.ymax)) / 2; @@ -1811,7 +1822,6 @@ static int view3d_zoom_border_invoke(bContext *C, wmOperator *op, wmEvent *event void VIEW3D_OT_zoom_border(wmOperatorType *ot) { - /* identifiers */ ot->name= "Border Zoom"; ot->description = "Zoom in the view to the nearest object contained in the border"; @@ -1822,7 +1832,7 @@ void VIEW3D_OT_zoom_border(wmOperatorType *ot) ot->exec= view3d_zoom_border_exec; ot->modal= WM_border_select_modal; - ot->poll= ED_operator_view3d_active; + ot->poll= ED_operator_region_view3d_active; /* flags */ ot->flag= 0; @@ -1834,6 +1844,47 @@ void VIEW3D_OT_zoom_border(wmOperatorType *ot) RNA_def_int(ot->srna, "ymax", 0, INT_MIN, INT_MAX, "Y Max", "", INT_MIN, INT_MAX); } + +/* sets the view to 1:1 camera/render-pixel */ +static void view3d_set_1_to_1_viewborder(Scene *scene, ARegion *ar) +{ + RegionView3D *rv3d= ar->regiondata; + float size[2]; + int im_width= (scene->r.size*scene->r.xsch)/100; + + view3d_viewborder_size_get(scene, ar, size); + + rv3d->camzoom= (sqrt(4.0*im_width/size[0]) - M_SQRT2)*50.0; + rv3d->camzoom= CLAMPIS(rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX); +} + +static int view3d_zoom_1_to_1_camera_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene= CTX_data_scene(C); + ARegion *ar= CTX_wm_region(C); + + view3d_set_1_to_1_viewborder(scene, ar); + + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C)); + + return OPERATOR_FINISHED; +} + +void VIEW3D_OT_zoom_camera_1_to_1(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Zoom Camera 1:1"; + ot->description = "Match the camera to 1:1 to the render output"; + ot->idname= "VIEW3D_OT_zoom_camera_1_to_1"; + + /* api callbacks */ + ot->exec= view3d_zoom_1_to_1_camera_exec; + ot->poll= view3d_camera_active_poll; + + /* flags */ + ot->flag= 0; +} + /* ********************* Changing view operator ****************** */ static EnumPropertyItem prop_view_items[] = { @@ -1870,7 +1921,7 @@ static void axis_set_view(bContext *C, float q1, float q2, float q3, float q4, s float twmat[3][3]; /* same as transform manipulator when normal is set */ - ED_getTransformOrientationMatrix(C, twmat, TRUE); + ED_getTransformOrientationMatrix(C, twmat, FALSE); mat3_to_quat( obact_quat,twmat); invert_qt(obact_quat); @@ -1903,14 +1954,14 @@ static void axis_set_view(bContext *C, float q1, float q2, float q3, float q4, s if (rv3d->persp==RV3D_CAMOB && v3d->camera) { - if (U.uiflag & USER_AUTOPERSP) rv3d->persp= RV3D_ORTHO; + if (U.uiflag & USER_AUTOPERSP) rv3d->persp= view ? RV3D_ORTHO : RV3D_PERSP; else if(rv3d->persp==RV3D_CAMOB) rv3d->persp= perspo; smooth_view(C, v3d->camera, NULL, rv3d->ofs, new_quat, NULL, NULL); } else { - if (U.uiflag & USER_AUTOPERSP) rv3d->persp= RV3D_ORTHO; + if (U.uiflag & USER_AUTOPERSP) rv3d->persp= view ? RV3D_ORTHO : RV3D_PERSP; else if(rv3d->persp==RV3D_CAMOB) rv3d->persp= perspo; smooth_view(C, NULL, NULL, NULL, new_quat, NULL, NULL); @@ -1929,6 +1980,9 @@ static int viewnumpad_exec(bContext *C, wmOperator *op) viewnum = RNA_enum_get(op->ptr, "type"); align_active = RNA_boolean_get(op->ptr, "align_active"); + /* set this to zero, gets handled in axis_set_view */ + if(rv3d->viewlock) + align_active= 0; /* Use this to test if we started out with a camera */ @@ -2035,6 +2089,8 @@ static int viewnumpad_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } + + void VIEW3D_OT_viewnumpad(wmOperatorType *ot) { /* identifiers */ @@ -2044,7 +2100,7 @@ void VIEW3D_OT_viewnumpad(wmOperatorType *ot) /* api callbacks */ ot->exec= viewnumpad_exec; - ot->poll= ED_operator_view3d_active; + ot->poll= ED_operator_region_view3d_active; /* flags */ ot->flag= 0; @@ -2112,7 +2168,7 @@ void VIEW3D_OT_view_orbit(wmOperatorType *ot) /* api callbacks */ ot->exec= vieworbit_exec; - ot->poll= view3d_rotate_poll; + ot->poll= ED_operator_region_view3d_active; /* flags */ ot->flag= 0; @@ -2136,14 +2192,11 @@ static int viewpan_exec(bContext *C, wmOperator *op) pandir = RNA_enum_get(op->ptr, "type"); initgrabz(rv3d, 0.0, 0.0, 0.0); - if(pandir == V3D_VIEW_PANRIGHT) window_to_3d_delta(ar, vec, -32, 0); else if(pandir == V3D_VIEW_PANLEFT) window_to_3d_delta(ar, vec, 32, 0); else if(pandir == V3D_VIEW_PANUP) window_to_3d_delta(ar, vec, 0, -25); else if(pandir == V3D_VIEW_PANDOWN) window_to_3d_delta(ar, vec, 0, 25); - rv3d->ofs[0]+= vec[0]; - rv3d->ofs[1]+= vec[1]; - rv3d->ofs[2]+= vec[2]; + add_v3_v3(rv3d->ofs, vec); if(rv3d->viewlock & RV3D_BOXVIEW) view3d_boxview_sync(CTX_wm_area(C), ar); @@ -2162,14 +2215,14 @@ void VIEW3D_OT_view_pan(wmOperatorType *ot) /* api callbacks */ ot->exec= viewpan_exec; - ot->poll= ED_operator_view3d_active; + ot->poll= ED_operator_region_view3d_active; /* flags */ ot->flag= 0; RNA_def_enum(ot->srna, "type", prop_view_pan_items, 0, "Pan", "Direction of View Pan"); } -static int viewpersportho_exec(bContext *C, wmOperator *op) +static int viewpersportho_exec(bContext *C, wmOperator *UNUSED(op)) { ARegion *ar= CTX_wm_region(C); RegionView3D *rv3d= CTX_wm_region_view3d(C); @@ -2194,7 +2247,7 @@ void VIEW3D_OT_view_persportho(wmOperatorType *ot) /* api callbacks */ ot->exec= viewpersportho_exec; - ot->poll= ED_operator_view3d_active; + ot->poll= ED_operator_region_view3d_active; /* flags */ ot->flag= 0; @@ -2202,32 +2255,31 @@ void VIEW3D_OT_view_persportho(wmOperatorType *ot) /* ******************** add background image operator **************** */ -static BGpic *add_background_image(bContext *C) +static BGpic *background_image_add(bContext *C) { View3D *v3d= CTX_wm_view3d(C); - + BGpic *bgpic= MEM_callocN(sizeof(BGpic), "Background Image"); bgpic->size= 5.0; bgpic->blend= 0.5; bgpic->iuser.fie_ima= 2; bgpic->iuser.ok= 1; bgpic->view= 0; /* 0 for all */ - + BLI_addtail(&v3d->bgpicbase, bgpic); - + return bgpic; } -static int add_background_image_exec(bContext *C, wmOperator *op) +static int background_image_add_exec(bContext *C, wmOperator *UNUSED(op)) { - add_background_image(C); + background_image_add(C); return OPERATOR_FINISHED; } -static int add_background_image_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int background_image_add_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { - Scene *scene= CTX_data_scene(C); View3D *v3d= CTX_wm_view3d(C); Image *ima= NULL; BGpic *bgpic; @@ -2238,14 +2290,14 @@ static int add_background_image_invoke(bContext *C, wmOperator *op, wmEvent *eve char path[FILE_MAX]; RNA_string_get(op->ptr, "filepath", path); - ima= BKE_add_image_file(path, scene ? scene->r.cfra : 1); -} + ima= BKE_add_image_file(path); + } else if(RNA_property_is_set(op->ptr, "name")) { RNA_string_get(op->ptr, "name", name); ima= (Image *)find_id("IM", name); } - - bgpic = add_background_image(C); + + bgpic = background_image_add(C); if (ima) { bgpic->ima = ima; @@ -2262,16 +2314,16 @@ static int add_background_image_invoke(bContext *C, wmOperator *op, wmEvent *eve return OPERATOR_FINISHED; } -void VIEW3D_OT_add_background_image(wmOperatorType *ot) +void VIEW3D_OT_background_image_add(wmOperatorType *ot) { /* identifiers */ ot->name = "Add Background Image"; ot->description= "Add a new background image"; - ot->idname = "VIEW3D_OT_add_background_image"; + ot->idname = "VIEW3D_OT_background_image_add"; /* api callbacks */ - ot->invoke = add_background_image_invoke; - ot->exec = add_background_image_exec; + ot->invoke = background_image_add_invoke; + ot->exec = background_image_add_exec; ot->poll = ED_operator_view3d_active; /* flags */ @@ -2284,33 +2336,34 @@ void VIEW3D_OT_add_background_image(wmOperatorType *ot) /* ***** remove image operator ******* */ -static int remove_background_image_exec(bContext *C, wmOperator *op) +static int background_image_remove_exec(bContext *C, wmOperator *op) { - BGpic *bgpic_rem = CTX_data_pointer_get_type(C, "bgpic", &RNA_BackgroundImage).data; View3D *vd = CTX_wm_view3d(C); int index = RNA_int_get(op->ptr, "index"); + BGpic *bgpic_rem= BLI_findlink(&vd->bgpicbase, index); - bgpic_rem = BLI_findlink(&vd->bgpicbase, index); if(bgpic_rem) { BLI_remlink(&vd->bgpicbase, bgpic_rem); if(bgpic_rem->ima) bgpic_rem->ima->id.us--; MEM_freeN(bgpic_rem); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, vd); + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; } - WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, vd); - - return OPERATOR_FINISHED; } -void VIEW3D_OT_remove_background_image(wmOperatorType *ot) +void VIEW3D_OT_background_image_remove(wmOperatorType *ot) { /* identifiers */ ot->name = "Remove Background Image"; ot->description= "Remove a background image from the 3D view"; - ot->idname = "VIEW3D_OT_remove_background_image"; + ot->idname = "VIEW3D_OT_background_image_remove"; /* api callbacks */ - ot->exec = remove_background_image_exec; + ot->exec = background_image_remove_exec; ot->poll = ED_operator_view3d_active; /* flags */ @@ -2413,7 +2466,7 @@ void VIEW3D_OT_clip_border(wmOperatorType *ot) ot->exec= view3d_clipping_exec; ot->modal= WM_border_select_modal; - ot->poll= ED_operator_view3d_active; + ot->poll= ED_operator_region_view3d_active; /* flags */ ot->flag= 0; @@ -2428,7 +2481,7 @@ void VIEW3D_OT_clip_border(wmOperatorType *ot) /* ***************** 3d cursor cursor op ******************* */ /* mx my in region coords */ -static int set_3dcursor_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int set_3dcursor_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) { Scene *scene= CTX_data_scene(C); ARegion *ar= CTX_wm_region(C); @@ -2462,7 +2515,9 @@ static int set_3dcursor_invoke(bContext *C, wmOperator *op, wmEvent *event) short depth_used = 0; if (U.uiflag & USER_ORBIT_ZBUF) { /* maybe this should be accessed some other way */ - short mval_depth[2] = {mx, my}; + short mval_depth[2]; + mval_depth[0]= mx; + mval_depth[1]= my; view3d_operator_needs_opengl(C); if (view_autodist(scene, ar, v3d, mval_depth, fp)) depth_used= 1; @@ -2553,7 +2608,7 @@ void VIEW3D_OT_manipulator(wmOperatorType *ot) Transform_Properties(ot, P_CONSTRAINT); } -static int enable_manipulator_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int enable_manipulator_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { View3D *v3d = CTX_wm_view3d(C); @@ -2591,90 +2646,49 @@ void VIEW3D_OT_enable_manipulator(wmOperatorType *ot) /* ************************* below the line! *********************** */ -static float view_autodist_depth_margin(ARegion *ar, short *mval, int margin) +static float view_autodist_depth_margin(ARegion *ar, short mval[2], int margin) { - RegionView3D *rv3d= ar->regiondata; - float depth= FLT_MAX; + ViewDepths depth_temp= {0}; + rcti rect; + float depth_close; if(margin==0) { - if (mval[0] < 0) return 0; - if (mval[1] < 0) return 0; - if (mval[0] >= rv3d->depths->w) return 0; - if (mval[1] >= rv3d->depths->h) return 0; - /* Get Z Depths, needed for perspective, nice for ortho */ - depth= rv3d->depths->depths[mval[1]*rv3d->depths->w+mval[0]]; - if(depth >= rv3d->depths->depth_range[1] || depth <= rv3d->depths->depth_range[0]) { - depth= FLT_MAX; - } + rect.xmin= mval[0]; + rect.ymin= mval[1]; + rect.xmax= mval[0] + 1; + rect.ymax= mval[1] + 1; } else { - rcti rect; - float depth_close= FLT_MAX; - int xs, ys; - rect.xmax = mval[0] + margin; rect.ymax = mval[1] + margin; rect.xmin = mval[0] - margin; rect.ymin = mval[1] - margin; - - /* Constrain rect to depth bounds */ - if (rect.xmin < 0) rect.xmin = 0; - if (rect.ymin < 0) rect.ymin = 0; - if (rect.xmax >= rv3d->depths->w) rect.xmax = rv3d->depths->w-1; - if (rect.ymax >= rv3d->depths->h) rect.ymax = rv3d->depths->h-1; - - /* Find the closest Z pixel */ - for (xs=rect.xmin; xs < rect.xmax; xs++) { - for (ys=rect.ymin; ys < rect.ymax; ys++) { - depth= rv3d->depths->depths[ys*rv3d->depths->w+xs]; - if(depth < rv3d->depths->depth_range[1] && depth > rv3d->depths->depth_range[0]) { - if (depth_close > depth) { - depth_close = depth; - } - } - } - } - - depth= depth_close; } - return depth; + view3d_update_depths_rect(ar, &depth_temp, &rect); + depth_close= view3d_depth_near(&depth_temp); + if(depth_temp.depths) MEM_freeN(depth_temp.depths); + return depth_close; } /* XXX todo Zooms in on a border drawn by the user */ int view_autodist(Scene *scene, ARegion *ar, View3D *v3d, short *mval, float mouse_worldloc[3] ) //, float *autodist ) { - RegionView3D *rv3d= ar->regiondata; bglMats mats; /* ZBuffer depth vars */ float depth_close= FLT_MAX; - int had_depth = 0; double cent[2], p[3]; /* Get Z Depths, needed for perspective, nice for ortho */ bgl_get_mats(&mats); draw_depth(scene, ar, v3d, NULL); - /* force updating */ - if (rv3d->depths) { - had_depth = 1; - rv3d->depths->damaged = 1; - } - - view3d_update_depths(ar, v3d); - depth_close= view_autodist_depth_margin(ar, mval, 4); if (depth_close==FLT_MAX) return 0; - if (had_depth==0) { - MEM_freeN(rv3d->depths->depths); - rv3d->depths->depths = NULL; - } - rv3d->depths->damaged = 1; - cent[0] = (double)mval[0]; cent[1] = (double)mval[1]; @@ -2689,8 +2703,6 @@ int view_autodist(Scene *scene, ARegion *ar, View3D *v3d, short *mval, float mou int view_autodist_init(Scene *scene, ARegion *ar, View3D *v3d, int mode) //, float *autodist ) { - RegionView3D *rv3d= ar->regiondata; - /* Get Z Depths, needed for perspective, nice for ortho */ switch(mode) { case 0: @@ -2701,12 +2713,6 @@ int view_autodist_init(Scene *scene, ARegion *ar, View3D *v3d, int mode) //, flo break; } - /* force updating */ - if (rv3d->depths) { - rv3d->depths->damaged = 1; - } - - view3d_update_depths(ar, v3d); return 1; } @@ -2739,12 +2745,51 @@ int view_autodist_simple(ARegion *ar, short *mval, float mouse_worldloc[3], int return 1; } -int view_autodist_depth(struct ARegion *ar, short *mval, int margin, float *depth) +int view_autodist_depth(struct ARegion *ar, short mval[2], int margin, float *depth) { *depth= view_autodist_depth_margin(ar, mval, margin); return (*depth==FLT_MAX) ? 0:1; +} + +static int depth_segment_cb(int x, int y, void *userData) +{ + struct { struct ARegion *ar; int margin; float depth; } *data = userData; + short mval[2]; + float depth; + + mval[0]= (short)x; + mval[1]= (short)y; + + depth= view_autodist_depth_margin(data->ar, mval, data->margin); + + if(depth != FLT_MAX) { + data->depth= depth; return 0; + } + else { + return 1; + } +} + +int view_autodist_depth_segment(struct ARegion *ar, short mval_sta[2], short mval_end[2], int margin, float *depth) +{ + struct { struct ARegion *ar; int margin; float depth; } data = {0}; + int p1[2]; + int p2[2]; + + data.ar= ar; + data.margin= margin; + data.depth= FLT_MAX; + + VECCOPY2D(p1, mval_sta); + VECCOPY2D(p2, mval_end); + + plot_line_v2v2i(p1, p2, depth_segment_cb, &data); + + *depth= data.depth; + + return (*depth==FLT_MAX) ? 0:1; } /* ********************* NDOF ************************ */ @@ -2773,8 +2818,8 @@ int view_autodist_depth(struct ARegion *ar, short *mval, int margin, float *dept // speed and os, i changed the scaling values, but // those are still not ok - -float ndof_axis_scale[6] = { +#if 0 +static float ndof_axis_scale[6] = { +0.01, // Tx +0.01, // Tz +0.01, // Ty @@ -2783,7 +2828,7 @@ float ndof_axis_scale[6] = { +0.0015 // Ry }; -void filterNDOFvalues(float *sbval) +static void filterNDOFvalues(float *sbval) { int i=0; float max = 0.0; @@ -2803,7 +2848,7 @@ void filterNDOFvalues(float *sbval) int dz_flag = 0; float m_dist; -void viewmoveNDOFfly(ARegion *ar, View3D *v3d, int mode) +void viewmoveNDOFfly(ARegion *ar, View3D *v3d, int UNUSED(mode)) { RegionView3D *rv3d= ar->regiondata; int i; @@ -2932,7 +2977,7 @@ void viewmoveNDOFfly(ARegion *ar, View3D *v3d, int mode) // XXX BIF_view3d_previewrender_signal(ar, PR_DBASE|PR_DISPRECT); } -void viewmoveNDOF(Scene *scene, ARegion *ar, View3D *v3d, int mode) +void viewmoveNDOF(Scene *scene, ARegion *ar, View3D *v3d, int UNUSED(mode)) { RegionView3D *rv3d= ar->regiondata; float fval[7]; @@ -3136,7 +3181,23 @@ void viewmoveNDOF(Scene *scene, ARegion *ar, View3D *v3d, int mode) */ // XXX scrarea_do_windraw(curarea); } - - - - +#endif // if 0, unused NDof code + +/* give a 4x4 matrix from a perspective view, only needs viewquat, ofs and dist + * basically the same as... + * rv3d->persp= RV3D_PERSP + * setviewmatrixview3d(scene, v3d, rv3d); + * setcameratoview3d(v3d, rv3d, v3d->camera); + * ...but less of a hassle + * */ +void view3d_persp_mat4(RegionView3D *rv3d, float mat[][4]) +{ + float qt[4], dvec[3]; + copy_qt_qt(qt, rv3d->viewquat); + qt[0]= -qt[0]; + quat_to_mat4(mat, qt); + mat[3][2] -= rv3d->dist; + translate_m4(mat, rv3d->ofs[0], rv3d->ofs[1], rv3d->ofs[2]); + mul_v3_v3fl(dvec, mat[2], -rv3d->dist); + sub_v3_v3v3(mat[3], dvec, rv3d->ofs); +} diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c new file mode 100644 index 00000000000..7a4fb86a4dd --- /dev/null +++ b/source/blender/editors/space_view3d/view3d_fly.c @@ -0,0 +1,942 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/* defines VIEW3D_OT_fly modal operator */ + +#include "DNA_anim_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_math.h" +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" + +#include "BKE_context.h" +#include "BKE_object.h" +#include "BKE_report.h" + +#include "BKE_depsgraph.h" /* for fly mode updating */ + +#include "BIF_gl.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_keyframing.h" +#include "ED_screen.h" +#include "ED_space_api.h" + +#include "PIL_time.h" /* smoothview */ + +#include "view3d_intern.h" // own include + +/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */ +#define FLY_MODAL_CANCEL 1 +#define FLY_MODAL_CONFIRM 2 +#define FLY_MODAL_ACCELERATE 3 +#define FLY_MODAL_DECELERATE 4 +#define FLY_MODAL_PAN_ENABLE 5 +#define FLY_MODAL_PAN_DISABLE 6 +#define FLY_MODAL_DIR_FORWARD 7 +#define FLY_MODAL_DIR_BACKWARD 8 +#define FLY_MODAL_DIR_LEFT 9 +#define FLY_MODAL_DIR_RIGHT 10 +#define FLY_MODAL_DIR_UP 11 +#define FLY_MODAL_DIR_DOWN 12 +#define FLY_MODAL_AXIS_LOCK_X 13 +#define FLY_MODAL_AXIS_LOCK_Z 14 +#define FLY_MODAL_PRECISION_ENABLE 15 +#define FLY_MODAL_PRECISION_DISABLE 16 + +/* called in transform_ops.c, on each regeneration of keymaps */ +void fly_modal_keymap(wmKeyConfig *keyconf) +{ + static EnumPropertyItem modal_items[] = { + {FLY_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""}, + {FLY_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""}, + {FLY_MODAL_ACCELERATE, "ACCELERATE", 0, "Accelerate", ""}, + {FLY_MODAL_DECELERATE, "DECELERATE", 0, "Decelerate", ""}, + + {FLY_MODAL_PAN_ENABLE, "PAN_ENABLE", 0, "Pan Enable", ""}, + {FLY_MODAL_PAN_DISABLE, "PAN_DISABLE", 0, "Pan Disable", ""}, + + {FLY_MODAL_DIR_FORWARD, "FORWARD", 0, "Fly Forward", ""}, + {FLY_MODAL_DIR_BACKWARD,"BACKWARD", 0, "Fly Backward", ""}, + {FLY_MODAL_DIR_LEFT, "LEFT", 0, "Fly Left", ""}, + {FLY_MODAL_DIR_RIGHT, "RIGHT", 0, "Fly Right", ""}, + {FLY_MODAL_DIR_UP, "UP", 0, "Fly Up", ""}, + {FLY_MODAL_DIR_DOWN, "DOWN", 0, "Fly Down", ""}, + + {FLY_MODAL_AXIS_LOCK_X, "AXIS_LOCK_X", 0, "X Axis Correction", "X axis correction (toggle)"}, + {FLY_MODAL_AXIS_LOCK_Z, "AXIS_LOCK_Z", 0, "X Axis Correction", "Z axis correction (toggle)"}, + + {FLY_MODAL_PRECISION_ENABLE, "PRECISION_ENABLE", 0, "Precision Enable", ""}, + {FLY_MODAL_PRECISION_DISABLE, "PRECISION_DISABLE", 0, "Precision Disable", ""}, + + {0, NULL, 0, NULL, NULL}}; + + wmKeyMap *keymap= WM_modalkeymap_get(keyconf, "View3D Fly Modal"); + + /* this function is called for each spacetype, only needs to add map once */ + if(keymap) return; + + keymap= WM_modalkeymap_add(keyconf, "View3D Fly Modal", modal_items); + + /* items for modal map */ + WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_CANCEL); + WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_ANY, KM_ANY, 0, FLY_MODAL_CANCEL); + + WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_ANY, KM_ANY, 0, FLY_MODAL_CONFIRM); + WM_modalkeymap_add_item(keymap, RETKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_CONFIRM); + WM_modalkeymap_add_item(keymap, SPACEKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_CONFIRM); + WM_modalkeymap_add_item(keymap, PADENTER, KM_PRESS, KM_ANY, 0, FLY_MODAL_CONFIRM); + + WM_modalkeymap_add_item(keymap, PADPLUSKEY, KM_PRESS, 0, 0, FLY_MODAL_ACCELERATE); + WM_modalkeymap_add_item(keymap, PADMINUS, KM_PRESS, 0, 0, FLY_MODAL_DECELERATE); + WM_modalkeymap_add_item(keymap, WHEELUPMOUSE, KM_PRESS, 0, 0, FLY_MODAL_ACCELERATE); + WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, 0, 0, FLY_MODAL_DECELERATE); + + WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_PAN_ENABLE); + WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, FLY_MODAL_PAN_DISABLE); /* XXX - Bug in the event system, middle mouse release doesnt work */ + + /* WASD */ + WM_modalkeymap_add_item(keymap, WKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_FORWARD); + WM_modalkeymap_add_item(keymap, SKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_BACKWARD); + WM_modalkeymap_add_item(keymap, AKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_LEFT); + WM_modalkeymap_add_item(keymap, DKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_RIGHT); + WM_modalkeymap_add_item(keymap, RKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_UP); + WM_modalkeymap_add_item(keymap, FKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_DOWN); + + WM_modalkeymap_add_item(keymap, XKEY, KM_PRESS, 0, 0, FLY_MODAL_AXIS_LOCK_X); + WM_modalkeymap_add_item(keymap, ZKEY, KM_PRESS, 0, 0, FLY_MODAL_AXIS_LOCK_Z); + + WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_PRECISION_ENABLE); + WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_RELEASE, KM_ANY, 0, FLY_MODAL_PRECISION_DISABLE); + + /* assign map to operators */ + WM_modalkeymap_assign(keymap, "VIEW3D_OT_fly"); + +} + +typedef struct FlyInfo { + /* context stuff */ + RegionView3D *rv3d; + View3D *v3d; + ARegion *ar; + Scene *scene; + + wmTimer *timer; /* needed for redraws */ + + short state; + short use_precision; + short redraw; + short mval[2]; + + /* fly state state */ + float speed; /* the speed the view is moving per redraw */ + short axis; /* Axis index to move allong by default Z to move allong the view */ + short pan_view; /* when true, pan the view instead of rotating */ + + /* relative view axis locking - xlock, zlock + 0; disabled + 1; enabled but not checking because mouse hasnt moved outside the margin since locking was checked an not needed + when the mouse moves, locking is set to 2 so checks are done. + 2; mouse moved and checking needed, if no view altering is donem its changed back to 1 */ + short xlock, zlock; + float xlock_momentum, zlock_momentum; /* nicer dynamics */ + float grid; /* world scale 1.0 default */ + + /* root most parent */ + Object *root_parent; + + /* backup values */ + float dist_backup; /* backup the views distance since we use a zero dist for fly mode */ + float ofs_backup[3]; /* backup the views offset incase the user cancels flying in non camera mode */ + float rot_backup[4]; /* backup the views quat incase the user cancels flying in non camera mode. (quat for view, eul for camera) */ + short persp_backup; /* remember if were ortho or not, only used for restoring the view if it was a ortho view */ + + void *obtfm; /* backup the objects transform */ + + /* compare between last state */ + double time_lastwheel; /* used to accelerate when using the mousewheel a lot */ + double time_lastdraw; /* time between draws */ + + void *draw_handle_pixel; + + /* use for some lag */ + float dvec_prev[3]; /* old for some lag */ + +} FlyInfo; + +static void drawFlyPixel(const struct bContext *UNUSED(C), struct ARegion *UNUSED(ar), void *arg) +{ + FlyInfo *fly = arg; + + /* draws 4 edge brackets that frame the safe area where the + mouse can move during fly mode without spinning the view */ + float x1, x2, y1, y2; + + x1= 0.45*(float)fly->ar->winx; + y1= 0.45*(float)fly->ar->winy; + x2= 0.55*(float)fly->ar->winx; + y2= 0.55*(float)fly->ar->winy; + cpack(0); + + + glBegin(GL_LINES); + /* bottom left */ + glVertex2f(x1,y1); + glVertex2f(x1,y1+5); + + glVertex2f(x1,y1); + glVertex2f(x1+5,y1); + + /* top right */ + glVertex2f(x2,y2); + glVertex2f(x2,y2-5); + + glVertex2f(x2,y2); + glVertex2f(x2-5,y2); + + /* top left */ + glVertex2f(x1,y2); + glVertex2f(x1,y2-5); + + glVertex2f(x1,y2); + glVertex2f(x1+5,y2); + + /* bottom right */ + glVertex2f(x2,y1); + glVertex2f(x2,y1+5); + + glVertex2f(x2,y1); + glVertex2f(x2-5,y1); + glEnd(); +} + +/* FlyInfo->state */ +#define FLY_RUNNING 0 +#define FLY_CANCEL 1 +#define FLY_CONFIRM 2 + +static int initFlyInfo (bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *event) +{ + float upvec[3]; // tmp + float mat[3][3]; + + fly->rv3d= CTX_wm_region_view3d(C); + fly->v3d = CTX_wm_view3d(C); + fly->ar = CTX_wm_region(C); + fly->scene= CTX_data_scene(C); + + if(fly->rv3d->persp==RV3D_CAMOB && fly->v3d->camera->id.lib) { + BKE_report(op->reports, RPT_ERROR, "Cannot fly a camera from an external library"); + return FALSE; + } + + if(fly->v3d->ob_centre) { + BKE_report(op->reports, RPT_ERROR, "Cannot fly when the view is locked to an object"); + return FALSE; + } + + if(fly->rv3d->persp==RV3D_CAMOB && fly->v3d->camera->constraints.first) { + BKE_report(op->reports, RPT_ERROR, "Cannot fly an object with constraints"); + return FALSE; + } + + fly->state= FLY_RUNNING; + fly->speed= 0.0f; + fly->axis= 2; + fly->pan_view= FALSE; + fly->xlock= FALSE; + fly->zlock= FALSE; + fly->xlock_momentum=0.0f; + fly->zlock_momentum=0.0f; + fly->grid= 1.0f; + fly->use_precision= 0; + + fly->dvec_prev[0]= fly->dvec_prev[1]= fly->dvec_prev[2]= 0.0f; + + fly->timer= WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f); + + fly->mval[0] = event->x - fly->ar->winrct.xmin; + fly->mval[1] = event->y - fly->ar->winrct.ymin; + + + fly->time_lastdraw= fly->time_lastwheel= PIL_check_seconds_timer(); + + fly->draw_handle_pixel = ED_region_draw_cb_activate(fly->ar->type, drawFlyPixel, fly, REGION_DRAW_POST_PIXEL); + + fly->rv3d->rflag |= RV3D_NAVIGATING; /* so we draw the corner margins */ + + /* detect weather to start with Z locking */ + upvec[0]=1.0f; upvec[1]=0.0f; upvec[2]=0.0f; + copy_m3_m4(mat, fly->rv3d->viewinv); + mul_m3_v3(mat, upvec); + if (fabs(upvec[2]) < 0.1) + fly->zlock = 1; + upvec[0]=0; upvec[1]=0; upvec[2]=0; + + fly->persp_backup= fly->rv3d->persp; + fly->dist_backup= fly->rv3d->dist; + if (fly->rv3d->persp==RV3D_CAMOB) { + Object *ob_back; + if((fly->root_parent=fly->v3d->camera->parent)) { + while(fly->root_parent->parent) + fly->root_parent= fly->root_parent->parent; + ob_back= fly->root_parent; + } + else { + ob_back= fly->v3d->camera; + } + + /* store the original camera loc and rot */ + /* TODO. axis angle etc */ + + fly->obtfm= object_tfm_backup(ob_back); + + where_is_object(fly->scene, fly->v3d->camera); + negate_v3_v3(fly->rv3d->ofs, fly->v3d->camera->obmat[3]); + + fly->rv3d->dist=0.0; + } else { + /* perspective or ortho */ + if (fly->rv3d->persp==RV3D_ORTHO) + fly->rv3d->persp= RV3D_PERSP; /*if ortho projection, make perspective */ + copy_qt_qt(fly->rot_backup, fly->rv3d->viewquat); + copy_v3_v3(fly->ofs_backup, fly->rv3d->ofs); + fly->rv3d->dist= 0.0f; + + upvec[2]= fly->dist_backup; /*x and y are 0*/ + mul_m3_v3(mat, upvec); + sub_v3_v3(fly->rv3d->ofs, upvec); + /*Done with correcting for the dist*/ + } + + + /* center the mouse, probably the UI mafia are against this but without its quite annoying */ + WM_cursor_warp(CTX_wm_window(C), fly->ar->winrct.xmin + fly->ar->winx/2, fly->ar->winrct.ymin + fly->ar->winy/2); + + return 1; +} + +static int flyEnd(bContext *C, FlyInfo *fly) +{ + RegionView3D *rv3d= fly->rv3d; + View3D *v3d = fly->v3d; + + float upvec[3]; + + if(fly->state == FLY_RUNNING) + return OPERATOR_RUNNING_MODAL; + + WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), fly->timer); + + ED_region_draw_cb_exit(fly->ar->type, fly->draw_handle_pixel); + + rv3d->dist= fly->dist_backup; + + if (fly->state == FLY_CANCEL) { + /* Revert to original view? */ + if (fly->persp_backup==RV3D_CAMOB) { /* a camera view */ + Object *ob_back; + if(fly->root_parent)ob_back= fly->root_parent; + else ob_back= fly->v3d->camera; + + /* store the original camera loc and rot */ + object_tfm_restore(ob_back, fly->obtfm); + + DAG_id_tag_update(&ob_back->id, OB_RECALC_OB); + } else { + /* Non Camera we need to reset the view back to the original location bacause the user canceled*/ + copy_qt_qt(rv3d->viewquat, fly->rot_backup); + copy_v3_v3(rv3d->ofs, fly->ofs_backup); + rv3d->persp= fly->persp_backup; + } + } + else if (fly->persp_backup==RV3D_CAMOB) { /* camera */ + DAG_id_tag_update(fly->root_parent ? &fly->root_parent->id : &v3d->camera->id, OB_RECALC_OB); + } + else { /* not camera */ + /* Apply the fly mode view */ + /*restore the dist*/ + float mat[3][3]; + upvec[0]= upvec[1]= 0; + upvec[2]= fly->dist_backup; /*x and y are 0*/ + copy_m3_m4(mat, rv3d->viewinv); + mul_m3_v3(mat, upvec); + add_v3_v3(rv3d->ofs, upvec); + /*Done with correcting for the dist */ + } + + rv3d->rflag &= ~RV3D_NAVIGATING; +//XXX2.5 BIF_view3d_previewrender_signal(fly->sa, PR_DBASE|PR_DISPRECT); /* not working at the moment not sure why */ + + if(fly->obtfm) + MEM_freeN(fly->obtfm); + + if(fly->state == FLY_CONFIRM) { + MEM_freeN(fly); + return OPERATOR_FINISHED; + } + + MEM_freeN(fly); + return OPERATOR_CANCELLED; +} + +static void flyEvent(FlyInfo *fly, wmEvent *event) +{ + if (event->type == TIMER && event->customdata == fly->timer) { + fly->redraw = 1; + } + else if (event->type == MOUSEMOVE) { + fly->mval[0] = event->x - fly->ar->winrct.xmin; + fly->mval[1] = event->y - fly->ar->winrct.ymin; + } /* handle modal keymap first */ + else if (event->type == EVT_MODAL_MAP) { + switch (event->val) { + case FLY_MODAL_CANCEL: + fly->state = FLY_CANCEL; + break; + case FLY_MODAL_CONFIRM: + fly->state = FLY_CONFIRM; + break; + + case FLY_MODAL_ACCELERATE: + { + double time_currwheel; + float time_wheel; + + time_currwheel= PIL_check_seconds_timer(); + time_wheel = (float)(time_currwheel - fly->time_lastwheel); + fly->time_lastwheel = time_currwheel; + /*printf("Wheel %f\n", time_wheel);*/ + /*Mouse wheel delays range from 0.5==slow to 0.01==fast*/ + time_wheel = 1+ (10 - (20*MIN2(time_wheel, 0.5))); /* 0-0.5 -> 0-5.0 */ + + if (fly->speed<0.0f) fly->speed= 0.0f; + else { + if (event->shift) + fly->speed+= fly->grid*time_wheel*0.1; + else + fly->speed+= fly->grid*time_wheel; + } + break; + } + case FLY_MODAL_DECELERATE: + { + double time_currwheel; + float time_wheel; + + time_currwheel= PIL_check_seconds_timer(); + time_wheel = (float)(time_currwheel - fly->time_lastwheel); + fly->time_lastwheel = time_currwheel; + time_wheel = 1+ (10 - (20*MIN2(time_wheel, 0.5))); /* 0-0.5 -> 0-5.0 */ + + if (fly->speed>0) fly->speed=0; + else { + if (event->shift) + fly->speed-= fly->grid*time_wheel*0.1; + else + fly->speed-= fly->grid*time_wheel; + } + break; + } + case FLY_MODAL_PAN_ENABLE: + fly->pan_view= TRUE; + break; + case FLY_MODAL_PAN_DISABLE: +//XXX2.5 warp_pointer(cent_orig[0], cent_orig[1]); + fly->pan_view= FALSE; + break; + + /* impliment WASD keys */ + case FLY_MODAL_DIR_FORWARD: + if (fly->speed < 0.0f) fly->speed= -fly->speed; /* flip speed rather then stopping, game like motion */ + else if (fly->axis==2) fly->speed += fly->grid; /* increse like mousewheel if were already moving in that difection*/ + fly->axis= 2; + break; + case FLY_MODAL_DIR_BACKWARD: + if (fly->speed > 0.0f) fly->speed= -fly->speed; + else if (fly->axis==2) fly->speed -= fly->grid; + fly->axis= 2; + break; + case FLY_MODAL_DIR_LEFT: + if (fly->speed < 0.0f) fly->speed= -fly->speed; + else if (fly->axis==0) fly->speed += fly->grid; + fly->axis= 0; + break; + case FLY_MODAL_DIR_RIGHT: + if (fly->speed > 0.0f) fly->speed= -fly->speed; + else if (fly->axis==0) fly->speed -= fly->grid; + fly->axis= 0; + break; + case FLY_MODAL_DIR_DOWN: + if (fly->speed < 0.0f) fly->speed= -fly->speed; + else if (fly->axis==1) fly->speed += fly->grid; + fly->axis= 1; + break; + case FLY_MODAL_DIR_UP: + if (fly->speed > 0.0f) fly->speed= -fly->speed; + else if (fly->axis==1) fly->speed -= fly->grid; + fly->axis= 1; + break; + + case FLY_MODAL_AXIS_LOCK_X: + if (fly->xlock) fly->xlock=0; + else { + fly->xlock = 2; + fly->xlock_momentum = 0.0; + } + break; + case FLY_MODAL_AXIS_LOCK_Z: + if (fly->zlock) fly->zlock=0; + else { + fly->zlock = 2; + fly->zlock_momentum = 0.0; + } + break; + + case FLY_MODAL_PRECISION_ENABLE: + fly->use_precision= TRUE; + break; + case FLY_MODAL_PRECISION_DISABLE: + fly->use_precision= FALSE; + break; + + } + } +} + +static int flyApply(bContext *C, FlyInfo *fly) +{ + +#define FLY_ROTATE_FAC 2.5f /* more is faster */ +#define FLY_ZUP_CORRECT_FAC 0.1f /* ammount to correct per step */ +#define FLY_ZUP_CORRECT_ACCEL 0.05f /* increase upright momentum each step */ + + /* + fly mode - Shift+F + a fly loop where the user can move move the view as if they are flying + */ + RegionView3D *rv3d= fly->rv3d; + View3D *v3d = fly->v3d; + ARegion *ar = fly->ar; + Scene *scene= fly->scene; + + float prev_view_mat[4][4]; + + float mat[3][3], /* 3x3 copy of the view matrix so we can move allong the view axis */ + dvec[3]={0,0,0}, /* this is the direction thast added to the view offset per redraw */ + + /* Camera Uprighting variables */ + upvec[3]={0,0,0}, /* stores the view's up vector */ + + moffset[2], /* mouse offset from the views center */ + tmp_quat[4]; /* used for rotating the view */ + + int cent_orig[2], /* view center */ +//XXX- can avoid using // cent[2], /* view center modified */ + xmargin, ymargin; /* x and y margin are define the safe area where the mouses movement wont rotate the view */ + unsigned char + apply_rotation= 1; /* if the user presses shift they can look about without movinf the direction there looking*/ + + if(fly->root_parent) + view3d_persp_mat4(rv3d, prev_view_mat); + + /* the dist defines a vector that is infront of the offset + to rotate the view about. + this is no good for fly mode because we + want to rotate about the viewers center. + but to correct the dist removal we must + alter offset so the view doesn't jump. */ + + xmargin= ar->winx/20.0f; + ymargin= ar->winy/20.0f; + + cent_orig[0]= ar->winrct.xmin + ar->winx/2; + cent_orig[1]= ar->winrct.ymin + ar->winy/2; + + { + + /* mouse offset from the center */ + moffset[0]= fly->mval[0]- ar->winx/2; + moffset[1]= fly->mval[1]- ar->winy/2; + + /* enforce a view margin */ + if (moffset[0]>xmargin) moffset[0]-=xmargin; + else if (moffset[0] < -xmargin) moffset[0]+=xmargin; + else moffset[0]=0; + + if (moffset[1]>ymargin) moffset[1]-=ymargin; + else if (moffset[1] < -ymargin) moffset[1]+=ymargin; + else moffset[1]=0; + + + /* scale the mouse movement by this value - scales mouse movement to the view size + * moffset[0]/(ar->winx-xmargin*2) - window size minus margin (same for y) + * + * the mouse moves isnt linear */ + + if(moffset[0]) { + moffset[0] /= ar->winx - (xmargin*2); + moffset[0] *= fabs(moffset[0]); + } + + if(moffset[1]) { + moffset[1] /= ar->winy - (ymargin*2); + moffset[1] *= fabs(moffset[1]); + } + + /* Should we redraw? */ + if(fly->speed != 0.0f || moffset[0] || moffset[1] || fly->zlock || fly->xlock || dvec[0] || dvec[1] || dvec[2] ) { + float dvec_tmp[3]; + double time_current, time_redraw; /*time how fast it takes for us to redraw, this is so simple scenes dont fly too fast */ + float time_redraw_clamped; + + time_current= PIL_check_seconds_timer(); + time_redraw= (float)(time_current - fly->time_lastdraw); + time_redraw_clamped= MIN2(0.05f, time_redraw); /* clamt the redraw time to avoid jitter in roll correction */ + fly->time_lastdraw= time_current; + /*fprintf(stderr, "%f\n", time_redraw);*/ /* 0.002 is a small redraw 0.02 is larger */ + + /* Scale the time to use shift to scale the speed down- just like + shift slows many other areas of blender down */ + if (fly->use_precision) + fly->speed= fly->speed * (1.0f-time_redraw_clamped); + + copy_m3_m4(mat, rv3d->viewinv); + + if (fly->pan_view==TRUE) { + /* pan only */ + dvec_tmp[0]= -moffset[0]; + dvec_tmp[1]= -moffset[1]; + dvec_tmp[2]= 0; + + if (fly->use_precision) { + dvec_tmp[0] *= 0.1; + dvec_tmp[1] *= 0.1; + } + + mul_m3_v3(mat, dvec_tmp); + mul_v3_fl(dvec_tmp, time_redraw*200.0 * fly->grid); + + } else { + float roll; /* similar to the angle between the camera's up and the Z-up, but its very rough so just roll*/ + + /* rotate about the X axis- look up/down */ + if (moffset[1]) { + upvec[0]=1; + upvec[1]=0; + upvec[2]=0; + mul_m3_v3(mat, upvec); + axis_angle_to_quat( tmp_quat, upvec, (float)moffset[1] * time_redraw * -FLY_ROTATE_FAC); /* Rotate about the relative up vec */ + mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat); + + if (fly->xlock) fly->xlock = 2; /*check for rotation*/ + if (fly->zlock) fly->zlock = 2; + fly->xlock_momentum= 0.0f; + } + + /* rotate about the Y axis- look left/right */ + if (moffset[0]) { + + /* if we're upside down invert the moffset */ + upvec[0]=0; + upvec[1]=1; + upvec[2]=0; + mul_m3_v3(mat, upvec); + + if(upvec[2] < 0.0f) + moffset[0]= -moffset[0]; + + /* make the lock vectors */ + if (fly->zlock) { + upvec[0]=0; + upvec[1]=0; + upvec[2]=1; + } else { + upvec[0]=0; + upvec[1]=1; + upvec[2]=0; + mul_m3_v3(mat, upvec); + } + + axis_angle_to_quat( tmp_quat, upvec, (float)moffset[0] * time_redraw * FLY_ROTATE_FAC); /* Rotate about the relative up vec */ + mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat); + + if (fly->xlock) fly->xlock = 2;/*check for rotation*/ + if (fly->zlock) fly->zlock = 2; + } + + if (fly->zlock==2) { + upvec[0]=1; + upvec[1]=0; + upvec[2]=0; + mul_m3_v3(mat, upvec); + + /*make sure we have some z rolling*/ + if (fabs(upvec[2]) > 0.00001f) { + roll= upvec[2]*5; + upvec[0]=0; /*rotate the view about this axis*/ + upvec[1]=0; + upvec[2]=1; + + mul_m3_v3(mat, upvec); + axis_angle_to_quat( tmp_quat, upvec, roll*time_redraw_clamped*fly->zlock_momentum * FLY_ZUP_CORRECT_FAC); /* Rotate about the relative up vec */ + mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat); + + fly->zlock_momentum += FLY_ZUP_CORRECT_ACCEL; + } else { + fly->zlock=1; /* dont check until the view rotates again */ + fly->zlock_momentum= 0.0f; + } + } + + if (fly->xlock==2 && moffset[1]==0) { /*only apply xcorrect when mouse isnt applying x rot*/ + upvec[0]=0; + upvec[1]=0; + upvec[2]=1; + mul_m3_v3(mat, upvec); + /*make sure we have some z rolling*/ + if (fabs(upvec[2]) > 0.00001) { + roll= upvec[2] * -5; + + upvec[0]= 1.0f; /*rotate the view about this axis*/ + upvec[1]= 0.0f; + upvec[2]= 0.0f; + + mul_m3_v3(mat, upvec); + + axis_angle_to_quat( tmp_quat, upvec, roll*time_redraw_clamped*fly->xlock_momentum*0.1f); /* Rotate about the relative up vec */ + mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat); + + fly->xlock_momentum += 0.05f; + } else { + fly->xlock=1; /* see above */ + fly->xlock_momentum= 0.0f; + } + } + + + if (apply_rotation) { + /* Normal operation */ + /* define dvec, view direction vector */ + dvec_tmp[0]= dvec_tmp[1]= dvec_tmp[2]= 0.0f; + /* move along the current axis */ + dvec_tmp[fly->axis]= 1.0f; + + mul_m3_v3(mat, dvec_tmp); + + mul_v3_fl(dvec_tmp, fly->speed * time_redraw * 0.25f); + } + } + + /* impose a directional lag */ + interp_v3_v3v3(dvec, dvec_tmp, fly->dvec_prev, (1.0f/(1.0f+(time_redraw*5.0f)))); + + if (rv3d->persp==RV3D_CAMOB) { + Object *lock_ob= fly->root_parent ? fly->root_parent : fly->v3d->camera; + if (lock_ob->protectflag & OB_LOCK_LOCX) dvec[0] = 0.0; + if (lock_ob->protectflag & OB_LOCK_LOCY) dvec[1] = 0.0; + if (lock_ob->protectflag & OB_LOCK_LOCZ) dvec[2] = 0.0; + } + + add_v3_v3(rv3d->ofs, dvec); + + /* todo, dynamic keys */ +#if 0 + if (fly->zlock && fly->xlock) + ED_area_headerprint(fly->ar, "FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB"); + else if (fly->zlock) + ED_area_headerprint(fly->ar, "FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB"); + else if (fly->xlock) + ED_area_headerprint(fly->ar, "FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB"); + else + ED_area_headerprint(fly->ar, "FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB"); +#endif + + /* we are in camera view so apply the view ofs and quat to the view matrix and set the camera to the view */ + if (rv3d->persp==RV3D_CAMOB) { + ID *id_key; + /* transform the parent or the camera? */ + if(fly->root_parent) { + Object *ob_update; + + float view_mat[4][4]; + float prev_view_imat[4][4]; + float diff_mat[4][4]; + float parent_mat[4][4]; + + invert_m4_m4(prev_view_imat, prev_view_mat); + view3d_persp_mat4(rv3d, view_mat); + mul_m4_m4m4(diff_mat, prev_view_imat, view_mat); + mul_m4_m4m4(parent_mat, fly->root_parent->obmat, diff_mat); + object_apply_mat4(fly->root_parent, parent_mat, TRUE, FALSE); + + // where_is_object(scene, fly->root_parent); + + ob_update= v3d->camera->parent; + while(ob_update) { + DAG_id_tag_update(&ob_update->id, OB_RECALC_OB); + ob_update= ob_update->parent; + } + + copy_m4_m4(prev_view_mat, view_mat); + + id_key= &fly->root_parent->id; + + } + else { + float view_mat[4][4]; + view3d_persp_mat4(rv3d, view_mat); + object_apply_mat4(v3d->camera, view_mat, TRUE, FALSE); + id_key= &v3d->camera->id; + } + + /* record the motion */ + if (autokeyframe_cfra_can_key(scene, id_key)) { + ListBase dsources = {NULL, NULL}; + + /* add datasource override for the camera object */ + ANIM_relative_keyingset_add_source(&dsources, id_key, NULL, NULL); + + /* insert keyframes + * 1) on the first frame + * 2) on each subsequent frame + * TODO: need to check in future that frame changed before doing this + */ + if (fly->xlock || fly->zlock || moffset[0] || moffset[1]) { + KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Rotation"); + ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA); + } + if (fly->speed) { + KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Location"); + ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA); + } + + /* free temp data */ + BLI_freelistN(&dsources); + } + } + } else + /*were not redrawing but we need to update the time else the view will jump */ + fly->time_lastdraw= PIL_check_seconds_timer(); + /* end drawing */ + copy_v3_v3(fly->dvec_prev, dvec); + } + +/* moved to flyEnd() */ + + return OPERATOR_FINISHED; +} + + + +static int fly_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + RegionView3D *rv3d= CTX_wm_region_view3d(C); + FlyInfo *fly; + + if(rv3d->viewlock) + return OPERATOR_CANCELLED; + + fly= MEM_callocN(sizeof(FlyInfo), "FlyOperation"); + + op->customdata= fly; + + if(initFlyInfo(C, fly, op, event)==FALSE) { + MEM_freeN(op->customdata); + return OPERATOR_CANCELLED; + } + + flyEvent(fly, event); + + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +static int fly_cancel(bContext *C, wmOperator *op) +{ + FlyInfo *fly = op->customdata; + + fly->state = FLY_CANCEL; + flyEnd(C, fly); + op->customdata= NULL; + + return OPERATOR_CANCELLED; +} + +static int fly_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + int exit_code; + short do_draw= FALSE; + FlyInfo *fly= op->customdata; + RegionView3D *rv3d= fly->rv3d; + Object *fly_object= fly->root_parent ? fly->root_parent : fly->v3d->camera; + + fly->redraw= 0; + + flyEvent(fly, event); + + if(event->type==TIMER && event->customdata == fly->timer) + flyApply(C, fly); + + do_draw |= fly->redraw; + + exit_code = flyEnd(C, fly); + + if(exit_code!=OPERATOR_RUNNING_MODAL) + do_draw= TRUE; + + if(do_draw) { + if(rv3d->persp==RV3D_CAMOB) { + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, fly_object); + } + + ED_region_tag_redraw(CTX_wm_region(C)); + } + + return exit_code; +} + +void VIEW3D_OT_fly(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Fly Navigation"; + ot->description= "Interactively fly around the scene"; + ot->idname= "VIEW3D_OT_fly"; + + /* api callbacks */ + ot->invoke= fly_invoke; + ot->cancel= fly_cancel; + ot->modal= fly_modal; + ot->poll= ED_operator_view3d_active; + + /* flags */ + ot->flag= OPTYPE_BLOCKING; +} diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index d7c7652e348..05735d810d3 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -37,6 +37,11 @@ #include "MEM_guardedalloc.h" +#include "BLI_math.h" +#include "BLI_blenlib.h" +#include "BLI_editVert.h" +#include "BLI_utildefines.h" + #include "BKE_context.h" #include "BKE_depsgraph.h" #include "BKE_effect.h" @@ -59,11 +64,6 @@ #include "RNA_define.h" #include "RNA_enum_types.h" - -#include "BLI_math.h" -#include "BLI_blenlib.h" -#include "BLI_editVert.h" - #include "UI_interface.h" #include "UI_resources.h" @@ -82,9 +82,6 @@ #define TEST_EDITMESH if(obedit==0) return; \ if( (v3d->lay & obedit->lay)==0 ) return; -/* XXX port over */ -extern void borderselect(); - /* view3d handler codes */ #define VIEW3D_HANDLER_BACKGROUND 1 #define VIEW3D_HANDLER_PROPERTIES 2 @@ -141,12 +138,13 @@ static void handle_view3d_lock(bContext *C) } } -static int layers_exec(bContext *C, wmOperator *op) +static int view3d_layers_exec(bContext *C, wmOperator *op) { - Main *bmain= CTX_data_main(C); Scene *scene= CTX_data_scene(C); ScrArea *sa= CTX_wm_area(C); View3D *v3d= sa->spacedata.first; + Base *base; + int oldlay= v3d->lay; int nr= RNA_int_get(op->ptr, "nr"); int toggle= RNA_boolean_get(op->ptr, "toggle"); @@ -204,8 +202,12 @@ static int layers_exec(bContext *C, wmOperator *op) if(v3d->scenelock) handle_view3d_lock(C); - /* new layers might need unflushed events events */ - DAG_scene_update_flags(bmain, scene, v3d->lay); /* tags all that moves and flushes */ + /* XXX new layers might need updates, there is no provision yet to detect if that's needed */ + oldlay= ~oldlay & v3d->lay; + for (base= scene->base.first; base; base= base->next) { + if(base->lay & oldlay) + base->object->recalc= OB_RECALC_OB|OB_RECALC_DATA; + } ED_area_tag_redraw(sa); @@ -214,7 +216,7 @@ static int layers_exec(bContext *C, wmOperator *op) /* applies shift and alt, lazy coding or ok? :) */ /* the local per-keymap-entry keymap will solve it */ -static int layers_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int view3d_layers_invoke(bContext *C, wmOperator *op, wmEvent *event) { if(event->ctrl || event->oskey) return OPERATOR_PASS_THROUGH; @@ -226,12 +228,12 @@ static int layers_invoke(bContext *C, wmOperator *op, wmEvent *event) int nr= RNA_int_get(op->ptr, "nr") + 10; RNA_int_set(op->ptr, "nr", nr); } - layers_exec(C, op); + view3d_layers_exec(C, op); return OPERATOR_FINISHED; } -int layers_poll(bContext *C) +static int view3d_layers_poll(bContext *C) { return (ED_operator_view3d_active(C) && CTX_wm_view3d(C)->localvd==NULL); } @@ -244,9 +246,9 @@ void VIEW3D_OT_layers(wmOperatorType *ot) ot->idname= "VIEW3D_OT_layers"; /* api callbacks */ - ot->invoke= layers_invoke; - ot->exec= layers_exec; - ot->poll= layers_poll; + ot->invoke= view3d_layers_invoke; + ot->exec= view3d_layers_exec; + ot->poll= view3d_layers_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -305,7 +307,7 @@ static char *view3d_modeselect_pup(Scene *scene) } -static void do_view3d_header_buttons(bContext *C, void *arg, int event) +static void do_view3d_header_buttons(bContext *C, void *UNUSED(arg), int event) { wmWindow *win= CTX_wm_window(C); ToolSettings *ts= CTX_data_tool_settings(C); @@ -449,24 +451,14 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) } else { v3d->modeselect = OB_MODE_OBJECT; } - - v3d->flag &= ~V3D_MODE; - /* not sure what the v3d->flag is useful for now... modeselect is confusing */ - if(obedit) v3d->flag |= V3D_EDITMODE; - if(ob && (ob->mode & OB_MODE_POSE)) v3d->flag |= V3D_POSEMODE; - if(ob && (ob->mode & OB_MODE_VERTEX_PAINT)) v3d->flag |= V3D_VERTEXPAINT; - if(ob && (ob->mode & OB_MODE_WEIGHT_PAINT)) v3d->flag |= V3D_WEIGHTPAINT; - if(ob && (ob->mode & OB_MODE_TEXTURE_PAINT)) v3d->flag |= V3D_TEXTUREPAINT; - if(paint_facesel_test(ob)) v3d->flag |= V3D_FACESELECT; - uiBlockBeginAlign(block); uiDefIconTextButS(block, MENU, B_MODESELECT, object_mode_icon(v3d->modeselect), view3d_modeselect_pup(scene) , 0,0,126,20, &(v3d->modeselect), 0, 0, 0, 0, "Mode"); uiBlockEndAlign(block); /* Draw type */ - uiItemR(layout, &v3dptr, "viewport_shade", UI_ITEM_R_ICON_ONLY, "", 0); + uiItemR(layout, &v3dptr, "viewport_shade", UI_ITEM_R_ICON_ONLY, "", ICON_NULL); if (obedit==NULL && ((ob && ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT)))) { /* Manipulators aren't used in weight paint mode */ @@ -474,13 +466,13 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) PointerRNA meshptr; RNA_pointer_create(&ob->id, &RNA_Mesh, ob->data, &meshptr); - uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", 0); + uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NULL); } else { - char *str_menu; + const char *str_menu; row= uiLayoutRow(layout, 1); - uiItemR(row, &v3dptr, "pivot_point", UI_ITEM_R_ICON_ONLY, "", 0); - uiItemR(row, &v3dptr, "use_pivot_point_align", UI_ITEM_R_ICON_ONLY, "", 0); + uiItemR(row, &v3dptr, "pivot_point", UI_ITEM_R_ICON_ONLY, "", ICON_NULL); + uiItemR(row, &v3dptr, "use_pivot_point_align", UI_ITEM_R_ICON_ONLY, "", ICON_NULL); /* NDOF */ /* Not implemented yet @@ -495,7 +487,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) /* Transform widget / manipulators */ row= uiLayoutRow(layout, 1); - uiItemR(row, &v3dptr, "show_manipulator", UI_ITEM_R_ICON_ONLY, "", 0); + uiItemR(row, &v3dptr, "show_manipulator", UI_ITEM_R_ICON_ONLY, "", ICON_NULL); block= uiLayoutGetBlock(row); if(v3d->twflag & V3D_USE_MANIPULATOR) { @@ -510,11 +502,11 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) str_menu = BIF_menustringTransformOrientation(C, "Orientation"); uiDefButS(block, MENU, B_MAN_MODE, str_menu,0,0,70,YIC, &v3d->twmode, 0, 0, 0, 0, "Transform Orientation"); - MEM_freeN(str_menu); + MEM_freeN((void *)str_menu); } if(obedit==NULL && v3d->localvd==NULL) { - int ob_lay = ob ? ob->lay : 0; + unsigned int ob_lay = ob ? ob->lay : 0; /* Layers */ if (v3d->scenelock) @@ -523,7 +515,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) uiTemplateLayers(layout, &v3dptr, "layers", &v3dptr, "layers_used", ob_lay); /* Scene lock */ - uiItemR(layout, &v3dptr, "lock_camera_and_layers", UI_ITEM_R_ICON_ONLY, "", 0); + uiItemR(layout, &v3dptr, "lock_camera_and_layers", UI_ITEM_R_ICON_ONLY, "", ICON_NULL); } /* selection modus, dont use python for this since it cant do the toggle buttons with shift+click as well as clicking to set one. */ @@ -534,8 +526,8 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) row= uiLayoutRow(layout, 1); block= uiLayoutGetBlock(row); - uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL, 0,0,XIC,YIC, &em->selectmode, 1.0, 0.0, 0, 0, "Vertex select mode"); - uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL, 0,0,XIC,YIC, &em->selectmode, 1.0, 0.0, 0, 0, "Edge select mode"); - uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL, 0,0,XIC,YIC, &em->selectmode, 1.0, 0.0, 0, 0, "Face select mode"); + uiDefIconButBitI(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL, 0,0,XIC,YIC, &em->selectmode, 1.0, 0.0, 0, 0, "Vertex select mode"); + uiDefIconButBitI(block, TOG, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL, 0,0,XIC,YIC, &em->selectmode, 1.0, 0.0, 0, 0, "Edge select mode"); + uiDefIconButBitI(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL, 0,0,XIC,YIC, &em->selectmode, 1.0, 0.0, 0, 0, "Face select mode"); } } diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index cdb569c8f75..8cd07916b7b 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -54,22 +54,16 @@ struct bMotionPath; #define DRAW_CONSTCOLOR 2 #define DRAW_SCENESET 4 -#define V3D_XRAY 1 -#define V3D_TRANSP 2 -#define V3D_XRAYTRANSP 4 - -#define V3D_SELECT_MOUSE 1 - /* view3d_header.c */ void view3d_header_buttons(const struct bContext *C, struct ARegion *ar); void VIEW3D_OT_layers(struct wmOperatorType *ot); /* view3d_ops.c */ void view3d_operatortypes(void); -void view3d_keymap(struct wmKeyConfig *keyconf); /* view3d_edit.c */ void VIEW3D_OT_zoom(struct wmOperatorType *ot); +void VIEW3D_OT_zoom_camera_1_to_1(struct wmOperatorType *ot); void VIEW3D_OT_move(struct wmOperatorType *ot); void VIEW3D_OT_rotate(struct wmOperatorType *ot); void VIEW3D_OT_view_all(struct wmOperatorType *ot); @@ -79,8 +73,8 @@ void VIEW3D_OT_view_center_cursor(struct wmOperatorType *ot); void VIEW3D_OT_view_center_camera(struct wmOperatorType *ot); void VIEW3D_OT_view_pan(struct wmOperatorType *ot); void VIEW3D_OT_view_persportho(struct wmOperatorType *ot); -void VIEW3D_OT_add_background_image(struct wmOperatorType *ot); -void VIEW3D_OT_remove_background_image(struct wmOperatorType *ot); +void VIEW3D_OT_background_image_add(struct wmOperatorType *ot); +void VIEW3D_OT_background_image_remove(struct wmOperatorType *ot); void VIEW3D_OT_view_orbit(struct wmOperatorType *ot); void VIEW3D_OT_clip_border(struct wmOperatorType *ot); void VIEW3D_OT_cursor3d(struct wmOperatorType *ot); @@ -91,13 +85,18 @@ void VIEW3D_OT_zoom_border(struct wmOperatorType *ot); void VIEW3D_OT_drawtype(struct wmOperatorType *ot); void view3d_boxview_copy(ScrArea *sa, ARegion *ar); +void view3d_persp_mat4(struct RegionView3D *rv3d, float mat[][4]); + +/* view3d_fly.c */ +void view3d_keymap(struct wmKeyConfig *keyconf); +void VIEW3D_OT_fly(struct wmOperatorType *ot); /* drawanim.c */ -void draw_motion_paths_init(Scene *scene, View3D *v3d, struct ARegion *ar); -void draw_motion_path_instance(Scene *scene, View3D *v3d, struct ARegion *ar, +void draw_motion_paths_init(View3D *v3d, struct ARegion *ar); +void draw_motion_path_instance(Scene *scene, struct Object *ob, struct bPoseChannel *pchan, struct bAnimVizSettings *avs, struct bMotionPath *mpath); -void draw_motion_paths_cleanup(Scene *scene, View3D *v3d, struct ARegion *ar); +void draw_motion_paths_cleanup(View3D *v3d); @@ -106,13 +105,14 @@ void draw_object(Scene *scene, struct ARegion *ar, View3D *v3d, Base *base, int int draw_glsl_material(Scene *scene, struct Object *ob, View3D *v3d, int dt); void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob, int dt, int outline); void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob); -void drawaxes(float size, int flag, char drawtype); +void drawaxes(float size, char drawtype); void view3d_cached_text_draw_begin(void); -void view3d_cached_text_draw_add(float x, float y, float z, char *str, short xoffs, short flag); +void view3d_cached_text_draw_add(const float co[3], const char *str, short xoffs, short flag, const unsigned char col[4]); void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[][4]); -#define V3D_CACHE_TEXT_ZBUF 1 -#define V3D_CACHE_TEXT_WORLDSPACE 2 +#define V3D_CACHE_TEXT_ZBUF (1<<0) +#define V3D_CACHE_TEXT_WORLDSPACE (1<<1) +#define V3D_CACHE_TEXT_ASCII (1<<2) /* drawarmature.c */ int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, int flag); @@ -127,10 +127,12 @@ void draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d); void view3d_clr_clipping(void); void view3d_set_clipping(RegionView3D *rv3d); void add_view3d_after(ListBase *lb, Base *base, int flag); +void view3d_viewborder_size_get(struct Scene *scene, struct ARegion *ar, float size_r[2]); void circf(float x, float y, float rad); void circ(float x, float y, float rad); -void view3d_update_depths(struct ARegion *ar, View3D *v3d); +void view3d_update_depths_rect(struct ARegion *ar, struct ViewDepths *d, struct rcti *rect); +float view3d_depth_near(struct ViewDepths *d); /* view3d_select.c */ void VIEW3D_OT_select(struct wmOperatorType *ot); @@ -141,13 +143,13 @@ void VIEW3D_OT_select_lasso(struct wmOperatorType *ot); /* view3d_view.c */ void view3d_settings_from_ob(struct Object *ob, float *ofs, float *quat, float *dist, float *lens); +int view3d_is_ortho(View3D *v3d, RegionView3D *rv3d); void VIEW3D_OT_smoothview(struct wmOperatorType *ot); void VIEW3D_OT_setcameratoview(struct wmOperatorType *ot); void VIEW3D_OT_object_as_camera(struct wmOperatorType *ot); void VIEW3D_OT_localview(struct wmOperatorType *ot); void VIEW3D_OT_game_start(struct wmOperatorType *ot); -void VIEW3D_OT_fly(struct wmOperatorType *ot); int boundbox_clip(RegionView3D *rv3d, float obmat[][4], struct BoundBox *bb); @@ -190,8 +192,10 @@ void VIEW3D_OT_evtrec(struct wmOperatorType *ot); ARegion *view3d_has_buttons_region(ScrArea *sa); ARegion *view3d_has_tools_region(ScrArea *sa); +extern const char *view3d_context_dir[]; /* doc access */ + /* draw_volume.c */ -void draw_volume(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct Base *base, struct GPUTexture *tex, float *min, float *max, int res[3], float dx, struct GPUTexture *tex_shadow); +void draw_volume(struct ARegion *ar, struct GPUTexture *tex, float *min, float *max, int res[3], float dx, struct GPUTexture *tex_shadow); #endif /* ED_VIEW3D_INTERN_H */ diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index c436c179f8f..dc1d2e26de0 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -38,7 +38,7 @@ #include "BLI_math.h" #include "BLI_blenlib.h" - +#include "BLI_utildefines.h" #include "RNA_access.h" @@ -60,13 +60,14 @@ void view3d_operatortypes(void) WM_operatortype_append(VIEW3D_OT_rotate); WM_operatortype_append(VIEW3D_OT_move); WM_operatortype_append(VIEW3D_OT_zoom); + WM_operatortype_append(VIEW3D_OT_zoom_camera_1_to_1); WM_operatortype_append(VIEW3D_OT_view_all); WM_operatortype_append(VIEW3D_OT_viewnumpad); WM_operatortype_append(VIEW3D_OT_view_orbit); WM_operatortype_append(VIEW3D_OT_view_pan); WM_operatortype_append(VIEW3D_OT_view_persportho); - WM_operatortype_append(VIEW3D_OT_add_background_image); - WM_operatortype_append(VIEW3D_OT_remove_background_image); + WM_operatortype_append(VIEW3D_OT_background_image_add); + WM_operatortype_append(VIEW3D_OT_background_image_remove); WM_operatortype_append(VIEW3D_OT_view_selected); WM_operatortype_append(VIEW3D_OT_view_center_cursor); WM_operatortype_append(VIEW3D_OT_view_center_camera); @@ -150,6 +151,8 @@ void view3d_keymap(wmKeyConfig *keyconf) RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", WHEELINMOUSE, KM_PRESS, 0, 0)->ptr, "delta", 1); RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", WHEELOUTMOUSE, KM_PRESS, 0, 0)->ptr, "delta", -1); + WM_keymap_add_item(keymap, "VIEW3D_OT_zoom_camera_1_to_1", PADENTER, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "VIEW3D_OT_view_center_camera", HOMEKEY, KM_PRESS, 0, 0); /* only with camera view */ RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", HOMEKEY, KM_PRESS, 0, 0)->ptr, "center", 0); /* only without camera view */ RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", CKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "center", 1); @@ -184,6 +187,26 @@ void view3d_keymap(wmKeyConfig *keyconf) RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_orbit", WHEELDOWNMOUSE, KM_PRESS, KM_SHIFT|KM_ALT, 0)->ptr, "type", V3D_VIEW_STEPDOWN); /* active aligned, replaces '*' key in 2.4x */ +#ifdef WIN32 + kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD1, KM_PRESS, KM_ALT, 0); + RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_FRONT); + RNA_boolean_set(kmi->ptr, "align_active", TRUE); + kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD3, KM_PRESS, KM_ALT, 0); + RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_RIGHT); + RNA_boolean_set(kmi->ptr, "align_active", TRUE); + kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD7, KM_PRESS, KM_ALT, 0); + RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_TOP); + RNA_boolean_set(kmi->ptr, "align_active", TRUE); + kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD1, KM_PRESS, KM_ALT|KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_BACK); + RNA_boolean_set(kmi->ptr, "align_active", TRUE); + kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD3, KM_PRESS, KM_ALT|KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_LEFT); + RNA_boolean_set(kmi->ptr, "align_active", TRUE); + kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD7, KM_PRESS, KM_ALT|KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_BOTTOM); + RNA_boolean_set(kmi->ptr, "align_active", TRUE); +#else kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD1, KM_PRESS, KM_SHIFT, 0); RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_FRONT); RNA_boolean_set(kmi->ptr, "align_active", TRUE); @@ -202,6 +225,7 @@ void view3d_keymap(wmKeyConfig *keyconf) kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD7, KM_PRESS, KM_SHIFT|KM_CTRL, 0); RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_BOTTOM); RNA_boolean_set(kmi->ptr, "align_active", TRUE); +#endif WM_keymap_add_item(keymap, "VIEW3D_OT_localview", PADSLASHKEY, KM_PRESS, 0, 0); @@ -275,7 +299,7 @@ void view3d_keymap(wmKeyConfig *keyconf) RNA_string_set(kmi->ptr, "value", "MEDIAN_POINT"); kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", COMMAKEY, KM_PRESS, KM_ALT, 0); /* new in 2.5 */ - RNA_string_set(kmi->ptr, "data_path", "space_data.pivot_point_align"); + RNA_string_set(kmi->ptr, "data_path", "space_data.use_pivot_point_align"); kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", SPACEKEY, KM_PRESS, KM_CTRL, 0); /* new in 2.5 */ RNA_string_set(kmi->ptr, "data_path", "space_data.show_manipulator"); diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 776048c8f74..c557952a454 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -1,5 +1,5 @@ -/** - * $Id: +/* + * $Id: view3d_select.c 35106 2011-02-23 10:52:22Z jesterking $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -30,22 +30,15 @@ #include <stdio.h> #include <math.h> #include <float.h> +#include <assert.h> #include "DNA_action_types.h" #include "DNA_armature_types.h" #include "DNA_curve_types.h" -#include "DNA_camera_types.h" -#include "DNA_lamp_types.h" #include "DNA_meta_types.h" -#include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" -#include "DNA_space_types.h" #include "DNA_scene_types.h" -#include "DNA_screen_types.h" -#include "DNA_userdef_types.h" -#include "DNA_view3d_types.h" -#include "DNA_world_types.h" #include "MEM_guardedalloc.h" @@ -54,14 +47,15 @@ #include "BLI_editVert.h" #include "BLI_rand.h" #include "BLI_linklist.h" +#include "BLI_utildefines.h" #include "BKE_context.h" #include "BKE_paint.h" +#include "BKE_armature.h" #include "BKE_tessmesh.h" -#include "RE_pipeline.h" // make_stars - #include "BIF_gl.h" +#include "BIF_glutil.h" #include "WM_api.h" #include "WM_types.h" @@ -75,16 +69,10 @@ #include "ED_mesh.h" #include "ED_object.h" #include "ED_screen.h" -#include "ED_types.h" -#include "ED_util.h" -#include "ED_retopo.h" #include "ED_mball.h" #include "UI_interface.h" -#include "UI_resources.h" -#include "UI_view2d.h" -#include "PIL_time.h" /* smoothview */ #include "view3d_intern.h" // own include @@ -114,7 +102,7 @@ void view3d_get_view_aligned_coordinate(ViewContext *vc, float *fp, short mval[2 if(mval[0]!=IS_CLIPPED) { window_to_3d_delta(vc->ar, dvec, mval[0]-mx, mval[1]-my); - sub_v3_v3v3(fp, fp, dvec); + sub_v3_v3(fp, dvec); } } @@ -199,21 +187,21 @@ void EDBM_backbuf_checkAndSelectFaces(BMEditMesh *em, int select) void EDBM_backbuf_checkAndSelectTFaces(Mesh *me, int select) { - MFace *mface = me->mface; + MPoly *mpoly = me->mpoly; int a; - if (mface) { - for(a=1; a<=me->totface; a++, mface++) { + if (mpoly) { + for(a=1; a<=me->totpoly; a++, mpoly++) { if(EDBM_check_backbuf(a)) { - mface->flag = select?(mface->flag|ME_FACE_SEL):(mface->flag&~ME_FACE_SEL); + mpoly->flag = select?(mpoly->flag|ME_FACE_SEL):(mpoly->flag&~ME_FACE_SEL); } } } } +#if 0 void arrows_move_cursor(unsigned short event) { -#if 0 short mval[2]; getmouseco_sc(mval); @@ -227,12 +215,39 @@ void arrows_move_cursor(unsigned short event) } else if(event==RIGHTARROWKEY) { warp_pointer(mval[0]+1, mval[1]); } -#endif } +#endif /* *********************** GESTURE AND LASSO ******************* */ +static int view3d_selectable_data(bContext *C) +{ + Object *ob = CTX_data_active_object(C); + + if (!ED_operator_region_view3d_active(C)) + return 0; + + if(ob) { + if (ob->mode & OB_MODE_EDIT) { + if(ob->type == OB_FONT) { + return 0; + } + } + else { + if (ob->mode & OB_MODE_SCULPT) { + return 0; + } + if (ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT) && !paint_facesel_test(ob)) { + return 0; + } + } + } + + return 1; +} + + /* helper also for borderselect */ static int edge_fully_inside_rect(rcti *rect, short x1, short y1, short x2, short y2) { @@ -350,34 +365,43 @@ static void do_lasso_select_pose(ViewContext *vc, Object *ob, short mcords[][2], bPoseChannel *pchan; float vec[3]; short sco1[2], sco2[2]; + bArmature *arm= ob->data; if(ob->type!=OB_ARMATURE || ob->pose==NULL) return; - + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - mul_v3_m4v3(vec, ob->obmat, pchan->pose_head); - project_short(vc->ar, vec, sco1); - mul_v3_m4v3(vec, ob->obmat, pchan->pose_tail); - project_short(vc->ar, vec, sco2); - - if(lasso_inside_edge(mcords, moves, sco1[0], sco1[1], sco2[0], sco2[1])) { - if(select) pchan->bone->flag |= BONE_SELECTED; - else pchan->bone->flag &= ~BONE_SELECTED; + if (PBONE_VISIBLE(arm, pchan->bone) && (pchan->bone->flag & BONE_UNSELECTABLE)==0) { + mul_v3_m4v3(vec, ob->obmat, pchan->pose_head); + project_short(vc->ar, vec, sco1); + mul_v3_m4v3(vec, ob->obmat, pchan->pose_tail); + project_short(vc->ar, vec, sco2); + + if(lasso_inside_edge(mcords, moves, sco1[0], sco1[1], sco2[0], sco2[1])) { + if(select) pchan->bone->flag |= BONE_SELECTED; + else pchan->bone->flag &= ~BONE_SELECTED; + } } } - - { - bArmature *arm= ob->data; - if(arm->act_bone && (arm->act_bone->flag & BONE_SELECTED)==0) { - arm->act_bone= NULL; +} + +static void object_deselect_all_visible(Scene *scene, View3D *v3d) +{ + Base *base; + + for(base= scene->base.first; base; base= base->next) { + if(BASE_SELECTABLE(v3d, base)) { + ED_base_object_select(base, BA_DESELECT); } } } - -static void do_lasso_select_objects(ViewContext *vc, short mcords[][2], short moves, short select) +static void do_lasso_select_objects(ViewContext *vc, short mcords[][2], short moves, short extend, short select) { Base *base; + if (extend == 0 && select) + object_deselect_all_visible(vc->scene, vc->v3d); + for(base= vc->scene->base.first; base; base= base->next) { if(BASE_SELECTABLE(vc->v3d, base)) { /* use this to avoid un-needed lasso lookups */ project_short(vc->ar, base->object->obmat[3], &base->sx); @@ -394,7 +418,7 @@ static void do_lasso_select_objects(ViewContext *vc, short mcords[][2], short mo } } -void lasso_select_boundbox(rcti *rect, short mcords[][2], short moves) +static void lasso_select_boundbox(rcti *rect, short mcords[][2], short moves) { short a; @@ -409,12 +433,12 @@ void lasso_select_boundbox(rcti *rect, short mcords[][2], short moves) } } -static void do_lasso_select_mesh__doSelectVert(void *userData, BMVert *eve, int x, int y, int index) +static void do_lasso_select_mesh__doSelectVert(void *userData, BMVert *eve, int x, int y, int UNUSED(index)) { struct { ViewContext vc; rcti *rect; short (*mcords)[2], moves, select, pass, done; } *data = userData; if (BLI_in_rcti(data->rect, x, y) && lasso_inside(data->mcords, data->moves, x, y)) { - BM_Select_Vert(data->vc.em->bm, eve, data->select); + BM_Select(data->vc.em->bm, eve, data->select); } } static void do_lasso_select_mesh__doSelectEdge(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index) @@ -426,28 +450,29 @@ static void do_lasso_select_mesh__doSelectEdge(void *userData, BMEdge *eed, int if ( edge_fully_inside_rect(data->rect, x0, y0, x1, y1) && lasso_inside(data->mcords, data->moves, x0, y0) && lasso_inside(data->mcords, data->moves, x1, y1)) { - BM_Select_Edge(data->vc.em->bm, eed, data->select); + BM_Select(data->vc.em->bm, eed, data->select); data->done = 1; } } else { if (lasso_inside_edge(data->mcords, data->moves, x0, y0, x1, y1)) { - BM_Select_Edge(data->vc.em->bm, eed, data->select); + BM_Select(data->vc.em->bm, eed, data->select); } } } } -static void do_lasso_select_mesh__doSelectFace(void *userData, BMFace *efa, int x, int y, int index) +static void do_lasso_select_mesh__doSelectFace(void *userData, BMFace *efa, int x, int y, int UNUSED(index)) { struct { ViewContext vc; rcti *rect; short (*mcords)[2], moves, select, pass, done; } *data = userData; if (BLI_in_rcti(data->rect, x, y) && lasso_inside(data->mcords, data->moves, x, y)) { - BM_Select_Face(data->vc.em->bm, efa, data->select); + BM_Select(data->vc.em->bm, efa, data->select); } } -static void do_lasso_select_mesh(ViewContext *vc, short mcords[][2], short moves, short select) +static void do_lasso_select_mesh(ViewContext *vc, short mcords[][2], short moves, short extend, short select) { struct { ViewContext vc; rcti *rect; short (*mcords)[2], moves, select, pass, done; } data; + ToolSettings *ts= vc->scene->toolsettings; rcti rect; int bbsel; @@ -464,8 +489,11 @@ static void do_lasso_select_mesh(ViewContext *vc, short mcords[][2], short moves data.done = 0; data.pass = 0; - /* workaround: init mats first, EDBM_mask_init_backbuf_border can change - view matrix to pixel space, breaking edge select with backbuf. fixes bug #20936 */ + if (extend == 0 && select) + EDBM_clear_flag_all(vc->em, BM_SELECT); + + /* workaround: init mats first, EM_mask_init_backbuf_border can change + view matrix to pixel space, breaking edge select with backbuf. fixes bug [#20936] */ /* [#21018] breaks zbuf select. run below. only if bbsel fails */ /* ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d) */ @@ -473,7 +501,7 @@ static void do_lasso_select_mesh(ViewContext *vc, short mcords[][2], short moves glLoadMatrixf(vc->rv3d->viewmat); bbsel= EDBM_mask_init_backbuf_border(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax); - if(vc->scene->toolsettings->selectmode & SCE_SELECT_VERTEX) { + if(ts->selectmode & SCE_SELECT_VERTEX) { if (bbsel) { EDBM_backbuf_checkAndSelectVerts(vc->em, select); } else { @@ -481,7 +509,7 @@ static void do_lasso_select_mesh(ViewContext *vc, short mcords[][2], short moves mesh_foreachScreenVert(vc, do_lasso_select_mesh__doSelectVert, &data, 1); } } - if(vc->scene->toolsettings->selectmode & SCE_SELECT_EDGE) { + if(ts->selectmode & SCE_SELECT_EDGE) { /* Does both bbsel and non-bbsel versions (need screen cos for both) */ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ @@ -494,7 +522,7 @@ static void do_lasso_select_mesh(ViewContext *vc, short mcords[][2], short moves } } - if(vc->scene->toolsettings->selectmode & SCE_SELECT_FACE) { + if(ts->selectmode & SCE_SELECT_FACE) { if (bbsel) { EDBM_backbuf_checkAndSelectFaces(vc->em, select); } else { @@ -540,7 +568,7 @@ static void do_lasso_select_mesh_uv(short mcords[][2], short moves, short select } else { /* Vert Sel*/ for (efa= em->faces.first; efa; efa= efa->next) { tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if (simaFaceDraw_Check(efa, tf)) { + if (uvedit_face_visible(scene, ima, efa, tf)) { nverts= efa->v4? 4: 3; for(i=0; i<nverts; i++) { if ((select) != (simaUVSel_Check(efa, tf, i))) { @@ -564,16 +592,17 @@ static void do_lasso_select_mesh_uv(short mcords[][2], short moves, short select } #endif -static void do_lasso_select_curve__doSelect(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y) +static void do_lasso_select_curve__doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y) { - struct { ViewContext vc; short (*mcords)[2]; short moves; short select; } *data = userData; - + struct { ViewContext *vc; short (*mcords)[2]; short moves; short select; } *data = userData; + Object *obedit= data->vc->obedit; + Curve *cu= (Curve*)obedit->data; + if (lasso_inside(data->mcords, data->moves, x, y)) { if (bp) { bp->f1 = data->select?(bp->f1|SELECT):(bp->f1&~SELECT); + if (bp == cu->lastsel && !(bp->f1 & 1)) cu->lastsel = NULL; } else { - Curve *cu= data->vc.obedit->data; - if (cu->drawflag & CU_HIDE_HANDLES) { /* can only be beztindex==0 here since handles are hidden */ bezt->f1 = bezt->f2 = bezt->f3 = data->select?(bezt->f2|SELECT):(bezt->f2&~SELECT); @@ -586,20 +615,25 @@ static void do_lasso_select_curve__doSelect(void *userData, Nurb *nu, BPoint *bp bezt->f3 = data->select?(bezt->f3|SELECT):(bezt->f3&~SELECT); } } + + if (bezt == cu->lastsel && !(bezt->f2 & 1)) cu->lastsel = NULL; } } } -static void do_lasso_select_curve(ViewContext *vc, short mcords[][2], short moves, short select) +static void do_lasso_select_curve(ViewContext *vc, short mcords[][2], short moves, short extend, short select) { - struct { ViewContext vc; short (*mcords)[2]; short moves; short select; } data; + struct { ViewContext *vc; short (*mcords)[2]; short moves; short select; } data; /* set vc->editnurb */ - data.vc = *vc; + data.vc = vc; data.mcords = mcords; data.moves = moves; data.select = select; + if (extend == 0 && select) + CU_deselect_all(vc->obedit); + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ nurbs_foreachScreenVert(vc, do_lasso_select_curve__doSelect, &data); } @@ -612,7 +646,7 @@ static void do_lasso_select_lattice__doSelect(void *userData, BPoint *bp, int x, bp->f1 = data->select?(bp->f1|SELECT):(bp->f1&~SELECT); } } -static void do_lasso_select_lattice(ViewContext *vc, short mcords[][2], short moves, short select) +static void do_lasso_select_lattice(ViewContext *vc, short mcords[][2], short moves, short extend, short select) { struct { short (*mcords)[2]; short moves; short select; } data; @@ -621,66 +655,112 @@ static void do_lasso_select_lattice(ViewContext *vc, short mcords[][2], short mo data.moves = moves; data.select = select; + if (extend == 0 && select) + ED_setflagsLatt(vc->obedit, 0); + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ lattice_foreachScreenVert(vc, do_lasso_select_lattice__doSelect, &data); } -static void do_lasso_select_armature(ViewContext *vc, short mcords[][2], short moves, short select) +static void do_lasso_select_armature(ViewContext *vc, short mcords[][2], short moves, short extend, short select) { bArmature *arm= vc->obedit->data; EditBone *ebone; float vec[3]; short sco1[2], sco2[2], didpoint; - + int change= FALSE; + + if (extend==0 && select) + ED_armature_deselect_all_visible(vc->obedit); + /* set editdata in vc */ for (ebone= arm->edbo->first; ebone; ebone=ebone->next) { - - mul_v3_m4v3(vec, vc->obedit->obmat, ebone->head); - project_short(vc->ar, vec, sco1); - mul_v3_m4v3(vec, vc->obedit->obmat, ebone->tail); - project_short(vc->ar, vec, sco2); - - didpoint= 0; - if(lasso_inside(mcords, moves, sco1[0], sco1[1])) { - if(select) ebone->flag |= BONE_ROOTSEL; - else ebone->flag &= ~BONE_ROOTSEL; - didpoint= 1; + if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_UNSELECTABLE)==0) { + mul_v3_m4v3(vec, vc->obedit->obmat, ebone->head); + project_short(vc->ar, vec, sco1); + mul_v3_m4v3(vec, vc->obedit->obmat, ebone->tail); + project_short(vc->ar, vec, sco2); + + didpoint= 0; + if(lasso_inside(mcords, moves, sco1[0], sco1[1])) { + if(select) ebone->flag |= BONE_ROOTSEL; + else ebone->flag &= ~BONE_ROOTSEL; + didpoint= 1; + change= TRUE; + } + if(lasso_inside(mcords, moves, sco2[0], sco2[1])) { + if(select) ebone->flag |= BONE_TIPSEL; + else ebone->flag &= ~BONE_TIPSEL; + didpoint= 1; + change= TRUE; + } + /* if one of points selected, we skip the bone itself */ + if(didpoint==0 && lasso_inside_edge(mcords, moves, sco1[0], sco1[1], sco2[0], sco2[1])) { + if(select) ebone->flag |= BONE_TIPSEL|BONE_ROOTSEL|BONE_SELECTED; + else ebone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); + change= TRUE; + } } - if(lasso_inside(mcords, moves, sco2[0], sco2[1])) { - if(select) ebone->flag |= BONE_TIPSEL; - else ebone->flag &= ~BONE_TIPSEL; - didpoint= 1; + } + + if(change) { + ED_armature_sync_selection(arm->edbo); + ED_armature_validate_active(arm); + WM_main_add_notifier(NC_OBJECT|ND_BONE_SELECT, vc->obedit); + } +} + + + + +static void do_lasso_select_meta(ViewContext *vc, short mcords[][2], short moves, short extend, short select) +{ + MetaBall *mb = (MetaBall*)vc->obedit->data; + MetaElem *ml; + float vec[3]; + short sco[2]; + + if (extend == 0 && select) { + for(ml= mb->editelems->first; ml; ml= ml->next) { + ml->flag &= ~SELECT; } - /* if one of points selected, we skip the bone itself */ - if(didpoint==0 && lasso_inside_edge(mcords, moves, sco1[0], sco1[1], sco2[0], sco2[1])) { - if(select) ebone->flag |= BONE_TIPSEL|BONE_ROOTSEL|BONE_SELECTED; - else ebone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); + } + + for(ml= mb->editelems->first; ml; ml= ml->next) { + + mul_v3_m4v3(vec, vc->obedit->obmat, &ml->x); + project_short(vc->ar, vec, sco); + + if(lasso_inside(mcords, moves, sco[0], sco[1])) { + if(select) ml->flag |= SELECT; + else ml->flag &= ~SELECT; } } - ED_armature_sync_selection(arm->edbo); - ED_armature_validate_active(arm); } -static void do_lasso_select_facemode(ViewContext *vc, short mcords[][2], short moves, short select) +static void do_lasso_select_paintface(ViewContext *vc, short mcords[][2], short moves, short extend, short select) { Object *ob= vc->obact; Mesh *me= ob?ob->data:NULL; rcti rect; - - if(me==NULL || me->mtface==NULL) return; - if(me->totface==0) return; - - bm_vertoffs= me->totface+1; /* max index array */ - + + if(me==NULL || me->totface==0) + return; + + if(extend==0 && select) + paintface_deselect_all_visible(ob, SEL_DESELECT, FALSE); /* flush selection at the end */ + + bm_vertoffs= me->totpoly+1; /* max index array */ + lasso_select_boundbox(&rect, mcords, moves); EDBM_mask_init_backbuf_border(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax); EDBM_backbuf_checkAndSelectTFaces(me, select); - + EDBM_free_backbuf(); - -// XXX object_tface_flags_changed(ob, 0); + + paintface_flush_flags(ob); } #if 0 @@ -714,47 +794,55 @@ static void do_lasso_select_node(short mcords[][2], short moves, short select) } #endif -void view3d_lasso_select(bContext *C, ViewContext *vc, short mcords[][2], short moves, short select) +static void view3d_lasso_select(bContext *C, ViewContext *vc, short mcords[][2], short moves, short extend, short select) { Object *ob = CTX_data_active_object(C); if(vc->obedit==NULL) { /* Object Mode */ if(paint_facesel_test(ob)) - do_lasso_select_facemode(vc, mcords, moves, select); + do_lasso_select_paintface(vc, mcords, moves, extend, select); else if(ob && ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT)) ; else if(ob && ob->mode & OB_MODE_PARTICLE_EDIT) - PE_lasso_select(C, mcords, moves, select); - else - do_lasso_select_objects(vc, mcords, moves, select); + PE_lasso_select(C, mcords, moves, extend, select); + else { + do_lasso_select_objects(vc, mcords, moves, extend, select); + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, vc->scene); + } } else { /* Edit Mode */ - if(vc->obedit->type==OB_MESH) - do_lasso_select_mesh(vc, mcords, moves, select); - else if(vc->obedit->type==OB_CURVE || vc->obedit->type==OB_SURF) - do_lasso_select_curve(vc, mcords, moves, select); - else if(vc->obedit->type==OB_LATTICE) - do_lasso_select_lattice(vc, mcords, moves, select); - else if(vc->obedit->type==OB_ARMATURE) - do_lasso_select_armature(vc, mcords, moves, select); - + switch(vc->obedit->type) { + case OB_MESH: + do_lasso_select_mesh(vc, mcords, moves, extend, select); + break; + case OB_CURVE: + case OB_SURF: + do_lasso_select_curve(vc, mcords, moves, extend, select); + break; + case OB_LATTICE: + do_lasso_select_lattice(vc, mcords, moves, extend, select); + break; + case OB_ARMATURE: + do_lasso_select_armature(vc, mcords, moves, extend, select); + break; + case OB_MBALL: + do_lasso_select_meta(vc, mcords, moves, extend, select); + break; + default: + assert(!"lasso select on incorrect object type"); + } + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, vc->obedit->data); } } -static EnumPropertyItem lasso_select_types[] = { - {0, "SELECT", 0, "Select", ""}, - {1, "DESELECT", 0, "Deselect", ""}, - {0, NULL, 0, NULL, NULL} -}; - /* lasso operator gives properties, but since old code works with short array we convert */ static int view3d_lasso_select_exec(bContext *C, wmOperator *op) { ViewContext vc; - int select, i= 0; + int i= 0; short mcords[1024][2]; RNA_BEGIN(op->ptr, itemptr, "path") { @@ -769,13 +857,15 @@ static int view3d_lasso_select_exec(bContext *C, wmOperator *op) RNA_END; if(i>1) { + short extend, select; view3d_operator_needs_opengl(C); /* setup view context for argument to callbacks */ view3d_set_viewcontext(C, &vc); - select= RNA_enum_is_equal(C, op->ptr, "type", "SELECT"); - view3d_lasso_select(C, &vc, mcords, i, select); + extend= RNA_boolean_get(op->ptr, "extend"); + select= !RNA_boolean_get(op->ptr, "deselect"); + view3d_lasso_select(C, &vc, mcords, i, extend, select); return OPERATOR_FINISHED; } @@ -791,13 +881,14 @@ void VIEW3D_OT_select_lasso(wmOperatorType *ot) ot->invoke= WM_gesture_lasso_invoke; ot->modal= WM_gesture_lasso_modal; ot->exec= view3d_lasso_select_exec; - ot->poll= WM_operator_winactive; + ot->poll= view3d_selectable_data; /* flags */ ot->flag= OPTYPE_UNDO; RNA_def_collection_runtime(ot->srna, "path", &RNA_OperatorMousePath, "Path", ""); - RNA_def_enum(ot->srna, "type", lasso_select_types, 0, "Type", ""); + RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Deselect rather than select items."); + RNA_def_boolean(ot->srna, "extend", 1, "Extend", "Extend selection instead of deselecting everything first."); } @@ -922,7 +1013,7 @@ static Base *mouse_select_menu(bContext *C, ViewContext *vc, unsigned int *buffe } else { /* UI */ - uiPopupMenu *pup= uiPupMenuBegin(C, "Select Object", 0); + uiPopupMenu *pup= uiPupMenuBegin(C, "Select Object", ICON_NULL); uiLayout *layout= uiPupMenuLayout(pup); uiLayout *split= uiLayoutSplit(layout, 0, 0); uiLayout *column= uiLayoutColumn(split, 0); @@ -942,7 +1033,7 @@ static Base *mouse_select_menu(bContext *C, ViewContext *vc, unsigned int *buffe WM_operator_properties_create(&ptr, "OBJECT_OT_select_name"); RNA_string_set(&ptr, "name", name); RNA_boolean_set(&ptr, "extend", extend); - uiItemFullO(column, name, uiIconFromID((ID *)ob), "OBJECT_OT_select_name", ptr.data, WM_OP_EXEC_DEFAULT, 0); + uiItemFullO(column, "OBJECT_OT_select_name", name, uiIconFromID((ID *)ob), ptr.data, WM_OP_EXEC_DEFAULT, 0); } node= node->next; @@ -1060,7 +1151,7 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int base= FIRSTBASE; while(base) { - if(base->lay & v3d->lay) { + if(BASE_SELECTABLE(v3d, base)) { if(base->selcol==selcol) break; } base= base->next; @@ -1079,7 +1170,7 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int if(base==startbase) break; } - if(base->lay & v3d->lay) { + if(BASE_SELECTABLE(v3d, base)) { for(a=0; a<hits; a++) { if(has_bones) { /* skip non-bone objects */ @@ -1288,16 +1379,17 @@ int edge_inside_circle(short centx, short centy, short rad, short x1, short y1, return 0; } -static void do_nurbs_box_select__doSelect(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y) +static void do_nurbs_box_select__doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y) { - struct { ViewContext vc; rcti *rect; int select; } *data = userData; + struct { ViewContext *vc; rcti *rect; int select; } *data = userData; + Object *obedit= data->vc->obedit; + Curve *cu= (Curve*)obedit->data; if (BLI_in_rcti(data->rect, x, y)) { if (bp) { bp->f1 = data->select?(bp->f1|SELECT):(bp->f1&~SELECT); + if (bp == cu->lastsel && !(bp->f1 & 1)) cu->lastsel = NULL; } else { - Curve *cu= data->vc.obedit->data; - if (cu->drawflag & CU_HIDE_HANDLES) { /* can only be beztindex==0 here since handles are hidden */ bezt->f1 = bezt->f2 = bezt->f3 = data->select?(bezt->f2|SELECT):(bezt->f2&~SELECT); @@ -1310,23 +1402,26 @@ static void do_nurbs_box_select__doSelect(void *userData, Nurb *nu, BPoint *bp, bezt->f3 = data->select?(bezt->f3|SELECT):(bezt->f3&~SELECT); } } + + if (bezt == cu->lastsel && !(bezt->f2 & 1)) cu->lastsel = NULL; } } } -static void do_nurbs_box_select(ViewContext *vc, rcti *rect, int select, int extend) +static int do_nurbs_box_select(ViewContext *vc, rcti *rect, int select, int extend) { - struct { ViewContext vc; rcti *rect; int select; } data; + struct { ViewContext *vc; rcti *rect; int select; } data; - data.vc = *vc; + data.vc = vc; data.rect = rect; data.select = select; - if (extend == 0 && select) { + if (extend == 0 && select) CU_deselect_all(vc->obedit); - } ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ nurbs_foreachScreenVert(vc, do_nurbs_box_select__doSelect, &data); + + return OPERATOR_FINISHED; } static void do_lattice_box_select__doSelect(void *userData, BPoint *bp, int x, int y) @@ -1337,7 +1432,7 @@ static void do_lattice_box_select__doSelect(void *userData, BPoint *bp, int x, i bp->f1 = data->select?(bp->f1|SELECT):(bp->f1&~SELECT); } } -static void do_lattice_box_select(ViewContext *vc, rcti *rect, int select, int extend) +static int do_lattice_box_select(ViewContext *vc, rcti *rect, int select, int extend) { struct { ViewContext vc; rcti *rect; int select, pass, done; } data; @@ -1345,20 +1440,21 @@ static void do_lattice_box_select(ViewContext *vc, rcti *rect, int select, int e data.rect = rect; data.select = select; - if (extend == 0 && select) { + if (extend == 0 && select) ED_setflagsLatt(vc->obedit, 0); - } ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ lattice_foreachScreenVert(vc, do_lattice_box_select__doSelect, &data); + + return OPERATOR_FINISHED; } -static void do_mesh_box_select__doSelectVert(void *userData, BMVert *eve, int x, int y, int index) +static void do_mesh_box_select__doSelectVert(void *userData, BMVert *eve, int x, int y, int UNUSED(index)) { struct { ViewContext vc; rcti *rect; short select, pass, done; } *data = userData; if (BLI_in_rcti(data->rect, x, y)) { - BM_Select_Vert(data->vc.em->bm, eve, data->select); + BM_Select(data->vc.em->bm, eve, data->select); } } static void do_mesh_box_select__doSelectEdge(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index) @@ -1368,32 +1464,28 @@ static void do_mesh_box_select__doSelectEdge(void *userData, BMEdge *eed, int x0 if(EDBM_check_backbuf(bm_solidoffs+index)) { if (data->pass==0) { if (edge_fully_inside_rect(data->rect, x0, y0, x1, y1)) { - BM_Select_Edge(data->vc.em->bm, eed, data->select); + BM_Select(data->vc.em->bm, eed, data->select); data->done = 1; } } else { if (edge_inside_rect(data->rect, x0, y0, x1, y1)) { - BM_Select_Edge(data->vc.em->bm, eed, data->select); + BM_Select(data->vc.em->bm, eed, data->select); } } } } - -static void -do_mesh_box_select__doSelectFace(void *userData, BMFace - *efa, int x, int y, - int index) - +static void do_mesh_box_select__doSelectFace(void *userData, BMFace *efa, int x, int y, int UNUSED(index)) { struct { ViewContext vc; rcti *rect; short select, pass, done; } *data = userData; if (BLI_in_rcti(data->rect, x, y)) { - BM_Select_Face(data->vc.em->bm, efa, data->select); + BM_Select(data->vc.em->bm, efa, data->select); } } -static void do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int extend) +static int do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int extend) { struct { ViewContext vc; rcti *rect; short select, pass, done; } data; + ToolSettings *ts= vc->scene->toolsettings; int bbsel; data.vc= *vc; @@ -1403,9 +1495,7 @@ static void do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int exte data.done = 0; if (extend == 0 && select) - { EDBM_clear_flag_all(vc->em, BM_SELECT); - } /* workaround: init mats first, EM_mask_init_backbuf_border can change view matrix to pixel space, breaking edge select with backbuf. fixes bug #20936 */ @@ -1417,7 +1507,7 @@ static void do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int exte glLoadMatrixf(vc->rv3d->viewmat); bbsel= EDBM_init_backbuf_border(vc, rect->xmin, rect->ymin, rect->xmax, rect->ymax); - if(vc->scene->toolsettings->selectmode & SCE_SELECT_VERTEX) { + if(ts->selectmode & SCE_SELECT_VERTEX) { if (bbsel) { EDBM_backbuf_checkAndSelectVerts(vc->em, select); } else { @@ -1425,7 +1515,7 @@ static void do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int exte mesh_foreachScreenVert(vc, do_mesh_box_select__doSelectVert, &data, 1); } } - if(vc->scene->toolsettings->selectmode & SCE_SELECT_EDGE) { + if(ts->selectmode & SCE_SELECT_EDGE) { /* Does both bbsel and non-bbsel versions (need screen cos for both) */ data.pass = 0; @@ -1437,7 +1527,7 @@ static void do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int exte } } - if(vc->scene->toolsettings->selectmode & SCE_SELECT_FACE) { + if(ts->selectmode & SCE_SELECT_FACE) { if(bbsel) { EDBM_backbuf_checkAndSelectFaces(vc->em, select); } else { @@ -1449,264 +1539,289 @@ static void do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int exte EDBM_free_backbuf(); EDBM_selectmode_flush(vc->em); + + return OPERATOR_FINISHED; } -static int view3d_borderselect_exec(bContext *C, wmOperator *op) +static int do_meta_box_select(ViewContext *vc, rcti *rect, int select, int extend) { - ViewContext vc; - Scene *scene= CTX_data_scene(C); - ScrArea *sa= CTX_wm_area(C); - View3D *v3d= sa->spacedata.first; - Object *obedit= CTX_data_edit_object(C); - Object *obact= CTX_data_active_object(C); - rcti rect; - Base *base; + MetaBall *mb = (MetaBall*)vc->obedit->data; MetaElem *ml; + int a; + unsigned int buffer[4*MAXPICKBUF]; - int a, index; - int extend; - short hits, selecting; + short hits; - view3d_operator_needs_opengl(C); - - /* setup view context for argument to callbacks */ - view3d_set_viewcontext(C, &vc); - - selecting= (RNA_int_get(op->ptr, "gesture_mode")==GESTURE_MODAL_SELECT); - rect.xmin= RNA_int_get(op->ptr, "xmin"); - rect.ymin= RNA_int_get(op->ptr, "ymin"); - rect.xmax= RNA_int_get(op->ptr, "xmax"); - rect.ymax= RNA_int_get(op->ptr, "ymax"); - extend = RNA_boolean_get(op->ptr, "extend"); + hits= view3d_opengl_select(vc, buffer, MAXPICKBUF, rect); - if(obedit==NULL && (paint_facesel_test(OBACT))) { - face_borderselect(C, obact, &rect, selecting, extend); - return OPERATOR_FINISHED; - } - else if(obedit==NULL && (obact && obact->mode & OB_MODE_PARTICLE_EDIT)) { - return PE_border_select(C, &rect, selecting, extend); + if (extend == 0 && select) { + for(ml= mb->editelems->first; ml; ml= ml->next) { + ml->flag &= ~SELECT; + } } - else if(obedit==NULL && (obact && obact->mode & OB_MODE_SCULPT)) - return OPERATOR_CANCELLED; - if(obedit) { - if(obedit->type==OB_MESH) { - Mesh *me= obedit->data; - vc.em= me->edit_btmesh; - do_mesh_box_select(&vc, &rect, selecting, extend); -// if (EDBM_texFaceCheck()) - WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); - - } - else if(ELEM(obedit->type, OB_CURVE, OB_SURF)) { - do_nurbs_box_select(&vc, &rect, selecting, extend); - } - else if(obedit->type==OB_MBALL) { - MetaBall *mb = (MetaBall*)obedit->data; - hits= view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect); - - if (extend == 0 && selecting) { - ml= mb->editelems->first; - - while(ml) { - ml->flag &= ~SELECT; - ml= ml->next; - } + for(ml= mb->editelems->first; ml; ml= ml->next) { + for(a=0; a<hits; a++) { + if(ml->selcol1==buffer[ (4 * a) + 3 ]) { + ml->flag |= MB_SCALE_RAD; + if(select) ml->flag |= SELECT; + else ml->flag &= ~SELECT; + break; } - - ml= mb->editelems->first; - - while(ml) { - for(a=0; a<hits; a++) { - if(ml->selcol1==buffer[ (4 * a) + 3 ]) { - ml->flag |= MB_SCALE_RAD; - if(selecting) ml->flag |= SELECT; - else ml->flag &= ~SELECT; - break; - } - if(ml->selcol2==buffer[ (4 * a) + 3 ]) { - ml->flag &= ~MB_SCALE_RAD; - if(selecting) ml->flag |= SELECT; - else ml->flag &= ~SELECT; - break; - } - } - ml= ml->next; + if(ml->selcol2==buffer[ (4 * a) + 3 ]) { + ml->flag &= ~MB_SCALE_RAD; + if(select) ml->flag |= SELECT; + else ml->flag &= ~SELECT; + break; } } - else if(obedit->type==OB_ARMATURE) { - bArmature *arm= obedit->data; - EditBone *ebone; - - /* clear flag we use to detect point was affected */ - for(ebone= arm->edbo->first; ebone; ebone= ebone->next) - ebone->flag &= ~BONE_DONE; - - if (extend==0 && selecting) { - /* Set the flags */ - CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones) { - /* ignore bone if selection can't change */ - if ((ebone->flag & BONE_UNSELECTABLE) == 0) { - ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - } - } - CTX_DATA_END; - } + } - hits= view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect); - - /* first we only check points inside the border */ - for (a=0; a<hits; a++){ - index = buffer[(4*a)+3]; - if (index!=-1) { - ebone = BLI_findlink(arm->edbo, index & ~(BONESEL_ANY)); - if (index & BONESEL_TIP) { - ebone->flag |= BONE_DONE; - if (selecting) ebone->flag |= BONE_TIPSEL; - else ebone->flag &= ~BONE_TIPSEL; - } - - if (index & BONESEL_ROOT) { - ebone->flag |= BONE_DONE; - if (selecting) ebone->flag |= BONE_ROOTSEL; - else ebone->flag &= ~BONE_ROOTSEL; - } + return OPERATOR_FINISHED; +} + +static int do_armature_box_select(ViewContext *vc, rcti *rect, short select, short extend) +{ + bArmature *arm= vc->obedit->data; + EditBone *ebone; + int a; + + unsigned int buffer[4*MAXPICKBUF]; + short hits; + + hits= view3d_opengl_select(vc, buffer, MAXPICKBUF, rect); + + /* clear flag we use to detect point was affected */ + for(ebone= arm->edbo->first; ebone; ebone= ebone->next) + ebone->flag &= ~BONE_DONE; + + if (extend==0 && select) + ED_armature_deselect_all_visible(vc->obedit); + + /* first we only check points inside the border */ + for (a=0; a<hits; a++){ + int index = buffer[(4*a)+3]; + if (index!=-1) { + ebone = BLI_findlink(arm->edbo, index & ~(BONESEL_ANY)); + if ((ebone->flag & BONE_UNSELECTABLE)==0) { + if (index & BONESEL_TIP) { + ebone->flag |= BONE_DONE; + if (select) ebone->flag |= BONE_TIPSEL; + else ebone->flag &= ~BONE_TIPSEL; } - } - - /* now we have to flush tag from parents... */ - for(ebone= arm->edbo->first; ebone; ebone= ebone->next) { - if(ebone->parent && (ebone->flag & BONE_CONNECTED)) { - if(ebone->parent->flag & BONE_DONE) - ebone->flag |= BONE_DONE; + + if (index & BONESEL_ROOT) { + ebone->flag |= BONE_DONE; + if (select) ebone->flag |= BONE_ROOTSEL; + else ebone->flag &= ~BONE_ROOTSEL; } } - - /* only select/deselect entire bones when no points where in the rect */ - for (a=0; a<hits; a++){ - index = buffer[(4*a)+3]; - if (index!=-1) { - ebone = BLI_findlink(arm->edbo, index & ~(BONESEL_ANY)); - if (index & BONESEL_BONE) { - if(!(ebone->flag & BONE_DONE)) { - if (selecting) - ebone->flag |= (BONE_ROOTSEL|BONE_TIPSEL|BONE_SELECTED); - else - ebone->flag &= ~(BONE_ROOTSEL|BONE_TIPSEL|BONE_SELECTED); - } + } + } + + /* now we have to flush tag from parents... */ + for(ebone= arm->edbo->first; ebone; ebone= ebone->next) { + if(ebone->parent && (ebone->flag & BONE_CONNECTED)) { + if(ebone->parent->flag & BONE_DONE) + ebone->flag |= BONE_DONE; + } + } + + /* only select/deselect entire bones when no points where in the rect */ + for (a=0; a<hits; a++){ + int index = buffer[(4*a)+3]; + if (index!=-1) { + ebone = BLI_findlink(arm->edbo, index & ~(BONESEL_ANY)); + if (index & BONESEL_BONE) { + if ((ebone->flag & BONE_UNSELECTABLE)==0) { + if(!(ebone->flag & BONE_DONE)) { + if (select) + ebone->flag |= (BONE_ROOTSEL|BONE_TIPSEL|BONE_SELECTED); + else + ebone->flag &= ~(BONE_ROOTSEL|BONE_TIPSEL|BONE_SELECTED); } } } - - } - else if(obedit->type==OB_LATTICE) { - do_lattice_box_select(&vc, &rect, selecting, extend); } } - else { /* no editmode, unified for bones and objects */ - Bone *bone; - Object *ob= OBACT; - unsigned int *vbuffer=NULL; /* selection buffer */ - unsigned int *col; /* color in buffer */ - int bone_only; - int totobj= MAXPICKBUF; // XXX solve later - - if((ob) && (ob->mode & OB_MODE_POSE)) - bone_only= 1; - else - bone_only= 0; - - if (extend == 0 && selecting) { - base= FIRSTBASE; + + ED_armature_sync_selection(arm->edbo); + + return OPERATOR_CANCELLED; +} - if (bone_only) { - CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pose_bones) { +static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, int select, int extend) +{ + Bone *bone; + Object *ob= vc->obact; + unsigned int *vbuffer=NULL; /* selection buffer */ + unsigned int *col; /* color in buffer */ + int bone_only; + int bone_selected=0; + int totobj= MAXPICKBUF; // XXX solve later + short hits; + + if((ob) && (ob->mode & OB_MODE_POSE)) + bone_only= 1; + else + bone_only= 0; + + if (extend == 0 && select) { + if (bone_only) { + CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pose_bones) { + if ((pchan->bone->flag & BONE_UNSELECTABLE)==0) { pchan->bone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); } - CTX_DATA_END; - } else { - while(base) { - Base *next = base->next; - if(base->lay & v3d->lay) { - ED_base_object_select(base, BA_DESELECT); - } - base= next; - } } + CTX_DATA_END; + } else { + object_deselect_all_visible(vc->scene, vc->v3d); } + } - /* selection buffer now has bones potentially too, so we add MAXPICKBUF */ - vbuffer = MEM_mallocN(4 * (totobj+MAXPICKBUF) * sizeof(unsigned int), "selection buffer"); - hits= view3d_opengl_select(&vc, vbuffer, 4*(totobj+MAXPICKBUF), &rect); - /* - LOGIC NOTES (theeth): - The buffer and ListBase have the same relative order, which makes the selection - very simple. Loop through both data sets at the same time, if the color - is the same as the object, we have a hit and can move to the next color - and object pair, if not, just move to the next object, - keeping the same color until we have a hit. - - The buffer order is defined by OGL standard, hopefully no stupid GFX card - does it incorrectly. - */ - - if (hits>0) { /* no need to loop if there's no hit */ - base= FIRSTBASE; - col = vbuffer + 3; - - while(base && hits) { - Base *next = base->next; - if(base->lay & v3d->lay) { - while (base->selcol == (*col & 0xFFFF)) { /* we got an object */ - - if(*col & 0xFFFF0000) { /* we got a bone */ - bone = get_indexed_bone(base->object, *col & ~(BONESEL_ANY)); - if(bone) { - if(selecting) { + /* selection buffer now has bones potentially too, so we add MAXPICKBUF */ + vbuffer = MEM_mallocN(4 * (totobj+MAXPICKBUF) * sizeof(unsigned int), "selection buffer"); + hits= view3d_opengl_select(vc, vbuffer, 4*(totobj+MAXPICKBUF), rect); + /* + LOGIC NOTES (theeth): + The buffer and ListBase have the same relative order, which makes the selection + very simple. Loop through both data sets at the same time, if the color + is the same as the object, we have a hit and can move to the next color + and object pair, if not, just move to the next object, + keeping the same color until we have a hit. + + The buffer order is defined by OGL standard, hopefully no stupid GFX card + does it incorrectly. + */ + + if (hits>0) { /* no need to loop if there's no hit */ + Base *base; + col = vbuffer + 3; + + for(base= vc->scene->base.first; base && hits; base= base->next) { + if(BASE_SELECTABLE(vc->v3d, base)) { + while (base->selcol == (*col & 0xFFFF)) { /* we got an object */ + + if(*col & 0xFFFF0000) { /* we got a bone */ + bone = get_indexed_bone(base->object, *col & ~(BONESEL_ANY)); + if(bone) { + if(select) { + if ((bone->flag & BONE_UNSELECTABLE)==0) { bone->flag |= BONE_SELECTED; + bone_selected=1; // XXX select_actionchannel_by_name(base->object->action, bone->name, 1); } - else { - bArmature *arm= base->object->data; - bone->flag &= ~BONE_SELECTED; + } + else { + bArmature *arm= base->object->data; + bone->flag &= ~BONE_SELECTED; // XXX select_actionchannel_by_name(base->object->action, bone->name, 0); - if(arm->act_bone==bone) - arm->act_bone= NULL; - - } + if(arm->act_bone==bone) + arm->act_bone= NULL; + } } - else if(!bone_only) { - if (selecting) - ED_base_object_select(base, BA_SELECT); - else - ED_base_object_select(base, BA_DESELECT); - } - - col+=4; /* next color */ - hits--; - if(hits==0) break; } + else if(!bone_only) { + if (select) + ED_base_object_select(base, BA_SELECT); + else + ED_base_object_select(base, BA_DESELECT); + } + + col+=4; /* next color */ + hits--; + if(hits==0) break; } - - base= next; } + + if (bone_selected) { + WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, base->object); + } + } - WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, vc->scene); + } + MEM_freeN(vbuffer); + + return hits > 0 ? OPERATOR_FINISHED : OPERATOR_CANCELLED; +} + +static int view3d_borderselect_exec(bContext *C, wmOperator *op) +{ + ViewContext vc; + rcti rect; + short extend; + short select; + + int ret= OPERATOR_CANCELLED; + + view3d_operator_needs_opengl(C); + + /* setup view context for argument to callbacks */ + view3d_set_viewcontext(C, &vc); + + select= (RNA_int_get(op->ptr, "gesture_mode")==GESTURE_MODAL_SELECT); + rect.xmin= RNA_int_get(op->ptr, "xmin"); + rect.ymin= RNA_int_get(op->ptr, "ymin"); + rect.xmax= RNA_int_get(op->ptr, "xmax"); + rect.ymax= RNA_int_get(op->ptr, "ymax"); + extend = RNA_boolean_get(op->ptr, "extend"); + + if(vc.obedit) { + switch(vc.obedit->type) { + case OB_MESH: + vc.em= ((Mesh *)vc.obedit->data)->edit_btmesh; + ret= do_mesh_box_select(&vc, &rect, select, extend); +// if (EM_texFaceCheck()) + if(ret & OPERATOR_FINISHED) { + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, vc.obedit->data); + } + break; + case OB_CURVE: + case OB_SURF: + ret= do_nurbs_box_select(&vc, &rect, select, extend); + break; + case OB_MBALL: + ret= do_meta_box_select(&vc, &rect, select, extend); + break; + case OB_ARMATURE: + ret= do_armature_box_select(&vc, &rect, select, extend); + if(ret & OPERATOR_FINISHED) { + WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, vc.obedit); + } + break; + case OB_LATTICE: + ret= do_lattice_box_select(&vc, &rect, select, extend); + if(ret & OPERATOR_FINISHED) { + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, vc.obedit->data); + } + break; + default: + assert(!"border select on incorrect object type"); } - MEM_freeN(vbuffer); } - return OPERATOR_FINISHED; + else { /* no editmode, unified for bones and objects */ + if(vc.obact && vc.obact->mode & OB_MODE_SCULPT) { + /* pass */ + } + else if(vc.obact && paint_facesel_test(vc.obact)) { + ret= do_paintface_box_select(&vc, &rect, select, extend); + } + else if(vc.obact && vc.obact->mode & OB_MODE_PARTICLE_EDIT) { + ret= PE_border_select(C, &rect, select, extend); + } + else { /* object mode with none active */ + ret= do_object_pose_box_select(C, &vc, &rect, select, extend); + } + } + + return ret; } /* *****************Selection Operators******************* */ -static EnumPropertyItem prop_select_types[] = { - {0, "EXCLUSIVE", 0, "Exclusive", ""}, - {1, "EXTEND", 0, "Extend", ""}, - {0, NULL, 0, NULL, NULL} -}; /* ****** Border Select ****** */ void VIEW3D_OT_select_border(wmOperatorType *ot) @@ -1720,8 +1835,7 @@ void VIEW3D_OT_select_border(wmOperatorType *ot) ot->invoke= WM_border_select_invoke; ot->exec= view3d_borderselect_exec; ot->modal= WM_border_select_modal; - - ot->poll= ED_operator_view3d_active; + ot->poll= view3d_selectable_data; /* flags */ ot->flag= OPTYPE_UNDO; @@ -1736,8 +1850,8 @@ void VIEW3D_OT_select_border(wmOperatorType *ot) static int view3d_select_invoke(bContext *C, wmOperator *op, wmEvent *event) { Object *obedit= CTX_data_edit_object(C); - short extend= RNA_boolean_get(op->ptr, "extend"); Object *obact= CTX_data_active_object(C); + short extend= RNA_boolean_get(op->ptr, "extend"); short center= RNA_boolean_get(op->ptr, "center"); short enumerate= RNA_boolean_get(op->ptr, "enumerate"); int retval = 0; @@ -1762,7 +1876,7 @@ static int view3d_select_invoke(bContext *C, wmOperator *op, wmEvent *event) else if(obact && obact->mode & OB_MODE_PARTICLE_EDIT) return PE_mouse_particles(C, event->mval, extend); else if(obact && paint_facesel_test(obact)) - retval = face_select(C, obact, event->mval, extend); + retval = paintface_mouse_select(C, obact, event->mval, extend); else retval = mouse_select(C, event->mval, extend, center, enumerate); @@ -1798,127 +1912,138 @@ void VIEW3D_OT_select(wmOperatorType *ot) /* -------------------- circle select --------------------------------------------- */ -static void mesh_circle_doSelectVert(void *userData, BMVert *eve, int x, int y, int index) +static void mesh_circle_doSelectVert(void *userData, BMVert *eve, int x, int y, int UNUSED(index)) { struct {ViewContext *vc; short select, mval[2]; float radius; } *data = userData; int mx = x - data->mval[0], my = y - data->mval[1]; float r = sqrt(mx*mx + my*my); if (r<=data->radius) { - BM_Select_Vert(data->vc->em->bm, eve, data->select); + BM_Select(data->vc->em->bm, eve, data->select); } } -static void mesh_circle_doSelectEdge(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index) +static void mesh_circle_doSelectEdge(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int UNUSED(index)) { struct {ViewContext *vc; short select, mval[2]; float radius; } *data = userData; if (edge_inside_circle(data->mval[0], data->mval[1], (short) data->radius, x0, y0, x1, y1)) { - BM_Select_Edge(data->vc->em->bm, eed, data->select); + BM_Select(data->vc->em->bm, eed, data->select); } } -static void mesh_circle_doSelectFace(void *userData, BMFace *efa, int x, int y, int index) +static void mesh_circle_doSelectFace(void *userData, BMFace *efa, int x, int y, int UNUSED(index)) { struct {ViewContext *vc; short select, mval[2]; float radius; } *data = userData; int mx = x - data->mval[0], my = y - data->mval[1]; float r = sqrt(mx*mx + my*my); if (r<=data->radius) { - BM_Select_Face(data->vc->em->bm, efa, data->select); + BM_Select(data->vc->em->bm, efa, data->select); } } -static void mesh_circle_select(ViewContext *vc, int selecting, short *mval, float rad) +static void mesh_circle_select(ViewContext *vc, int select, short *mval, float rad) { + ToolSettings *ts= vc->scene->toolsettings; int bbsel; - Object *ob= vc->obact; + struct {ViewContext *vc; short select, mval[2]; float radius; } data; - if(vc->obedit==NULL && paint_facesel_test(ob)) { - Mesh *me = ob?ob->data:NULL; + bbsel= EDBM_init_backbuf_circle(vc, mval[0], mval[1], (short)(rad+1.0)); + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ - if (me) { - bm_vertoffs= me->totface+1; /* max index array */ + vc->em= ((Mesh *)vc->obedit->data)->edit_btmesh; - //bbsel= EDBM_init_backbuf_circle(vc, mval[0], mval[1], (short)(rad+1.0)); - //BMESH_TODO EM_backbuf_checkAndSelectTFaces(me, selecting==LEFTMOUSE); - //EDBM_free_backbuf(); + data.vc = vc; + data.select = select; + data.mval[0] = mval[0]; + data.mval[1] = mval[1]; + data.radius = rad; -// XXX object_tface_flags_changed(OBACT, 0); + if(ts->selectmode & SCE_SELECT_VERTEX) { + if(bbsel) { + EDBM_backbuf_checkAndSelectVerts(vc->em, select==LEFTMOUSE); + } else { + mesh_foreachScreenVert(vc, mesh_circle_doSelectVert, &data, 1); } } - else { - struct {ViewContext *vc; short select, mval[2]; float radius; } data; - - bbsel= EDBM_init_backbuf_circle(vc, mval[0], mval[1], (short)(rad+1.0)); - vc->em= ((Mesh *)vc->obedit->data)->edit_btmesh; - ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ - - data.vc = vc; - data.select = selecting; - data.mval[0] = mval[0]; - data.mval[1] = mval[1]; - data.radius = rad; - data.vc = vc; - - if(vc->scene->toolsettings->selectmode & SCE_SELECT_VERTEX) { - if(bbsel) { - EDBM_backbuf_checkAndSelectVerts(vc->em, selecting==LEFTMOUSE); - } else { - mesh_foreachScreenVert(vc, mesh_circle_doSelectVert, &data, 1); - } - } - if(vc->scene->toolsettings->selectmode & SCE_SELECT_EDGE) { - if (bbsel) { - EDBM_backbuf_checkAndSelectEdges(vc->em, selecting==LEFTMOUSE); - } else { - mesh_foreachScreenEdge(vc, mesh_circle_doSelectEdge, &data, 0); - } + if(ts->selectmode & SCE_SELECT_EDGE) { + if (bbsel) { + EDBM_backbuf_checkAndSelectEdges(vc->em, select==LEFTMOUSE); + } else { + mesh_foreachScreenEdge(vc, mesh_circle_doSelectEdge, &data, 0); } - - if(vc->scene->toolsettings->selectmode & SCE_SELECT_FACE) { - if(bbsel) { - EDBM_backbuf_checkAndSelectFaces(vc->em, selecting==LEFTMOUSE); - } else { - mesh_foreachScreenFace(vc, mesh_circle_doSelectFace, &data); - } + } + + if(ts->selectmode & SCE_SELECT_FACE) { + if(bbsel) { + EDBM_backbuf_checkAndSelectFaces(vc->em, select==LEFTMOUSE); + } else { + mesh_foreachScreenFace(vc, mesh_circle_doSelectFace, &data); } + } + + EDBM_free_backbuf(); + EDBM_selectmode_flush(vc->em); +} +static void paint_facesel_circle_select(ViewContext *vc, int select, short *mval, float rad) +{ + Object *ob= vc->obact; + Mesh *me = ob?ob->data:NULL; + int bbsel; + + if (me) { + bm_vertoffs= me->totface+1; /* max index array */ + + bbsel= EDBM_init_backbuf_circle(vc, mval[0], mval[1], (short)(rad+1.0)); + EDBM_backbuf_checkAndSelectTFaces(me, select==LEFTMOUSE); EDBM_free_backbuf(); - EDBM_selectmode_flush(vc->em); } } -static void nurbscurve_circle_doSelect(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y) +static void nurbscurve_circle_doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y) { struct {ViewContext *vc; short select, mval[2]; float radius; } *data = userData; int mx = x - data->mval[0], my = y - data->mval[1]; float r = sqrt(mx*mx + my*my); + Object *obedit= data->vc->obedit; + Curve *cu= (Curve*)obedit->data; if (r<=data->radius) { if (bp) { bp->f1 = data->select?(bp->f1|SELECT):(bp->f1&~SELECT); + + if (bp == cu->lastsel && !(bp->f1 & 1)) cu->lastsel = NULL; } else { - if (beztindex==0) { - bezt->f1 = data->select?(bezt->f1|SELECT):(bezt->f1&~SELECT); - } else if (beztindex==1) { - bezt->f2 = data->select?(bezt->f2|SELECT):(bezt->f2&~SELECT); + if (cu->drawflag & CU_HIDE_HANDLES) { + /* can only be beztindex==0 here since handles are hidden */ + bezt->f1 = bezt->f2 = bezt->f3 = data->select?(bezt->f2|SELECT):(bezt->f2&~SELECT); } else { - bezt->f3 = data->select?(bezt->f3|SELECT):(bezt->f3&~SELECT); + if (beztindex==0) { + bezt->f1 = data->select?(bezt->f1|SELECT):(bezt->f1&~SELECT); + } else if (beztindex==1) { + bezt->f2 = data->select?(bezt->f2|SELECT):(bezt->f2&~SELECT); + } else { + bezt->f3 = data->select?(bezt->f3|SELECT):(bezt->f3&~SELECT); + } } + + if (bezt == cu->lastsel && !(bezt->f2 & 1)) cu->lastsel = NULL; } } } -static void nurbscurve_circle_select(ViewContext *vc, int selecting, short *mval, float rad) +static void nurbscurve_circle_select(ViewContext *vc, int select, short *mval, float rad) { struct {ViewContext *vc; short select, mval[2]; float radius; } data; /* set vc-> edit data */ - data.select = selecting; + data.select = select; data.mval[0] = mval[0]; data.mval[1] = mval[1]; data.radius = rad; + data.vc = vc; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ nurbs_foreachScreenVert(vc, nurbscurve_circle_doSelect, &data); @@ -1935,13 +2060,13 @@ static void latticecurve_circle_doSelect(void *userData, BPoint *bp, int x, int bp->f1 = data->select?(bp->f1|SELECT):(bp->f1&~SELECT); } } -static void lattice_circle_select(ViewContext *vc, int selecting, short *mval, float rad) +static void lattice_circle_select(ViewContext *vc, int select, short *mval, float rad) { struct {ViewContext *vc; short select, mval[2]; float radius; } data; /* set vc-> edit data */ - data.select = selecting; + data.select = select; data.mval[0] = mval[0]; data.mval[1] = mval[1]; data.radius = rad; @@ -1951,6 +2076,67 @@ static void lattice_circle_select(ViewContext *vc, int selecting, short *mval, f } +// NOTE: pose-bone case is copied from editbone case... +static short pchan_circle_doSelectJoint(void *userData, bPoseChannel *pchan, int x, int y) +{ + struct {ViewContext *vc; short select, mval[2]; float radius; } *data = userData; + int mx = x - data->mval[0], my = y - data->mval[1]; + float r = sqrt(mx*mx + my*my); + + if (r <= data->radius) { + if (data->select) + pchan->bone->flag |= BONE_SELECTED; + else + pchan->bone->flag &= ~BONE_SELECTED; + return 1; + } + return 0; +} +static void pose_circle_select(ViewContext *vc, int select, short *mval, float rad) +{ + struct {ViewContext *vc; short select, mval[2]; float radius; } data; + bPose *pose = vc->obact->pose; + bPoseChannel *pchan; + int change= FALSE; + + /* set vc->edit data */ + data.select = select; + data.mval[0] = mval[0]; + data.mval[1] = mval[1]; + data.radius = rad; + + ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); /* for foreach's screen/vert projection */ + + /* check each PoseChannel... */ + // TODO: could be optimised at some point + for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { + short sco1[2], sco2[2], didpoint=0; + float vec[3]; + + /* project head location to screenspace */ + mul_v3_m4v3(vec, vc->obact->obmat, pchan->pose_head); + project_short(vc->ar, vec, sco1); + + /* project tail location to screenspace */ + mul_v3_m4v3(vec, vc->obact->obmat, pchan->pose_tail); + project_short(vc->ar, vec, sco2); + + /* check if the head and/or tail is in the circle + * - the call to check also does the selection already + */ + if (pchan_circle_doSelectJoint(&data, pchan, sco1[0], sco1[1])) + didpoint= 1; + if (pchan_circle_doSelectJoint(&data, pchan, sco2[0], sco2[1])) + didpoint= 1; + + change |= didpoint; + } + + if (change) { + WM_main_add_notifier(NC_OBJECT|ND_BONE_SELECT, vc->obact); + } +} + static short armature_circle_doSelectJoint(void *userData, EditBone *ebone, int x, int y, short head) { struct {ViewContext *vc; short select, mval[2]; float radius; } *data = userData; @@ -1974,14 +2160,15 @@ static short armature_circle_doSelectJoint(void *userData, EditBone *ebone, int } return 0; } -static void armature_circle_select(ViewContext *vc, int selecting, short *mval, float rad) +static void armature_circle_select(ViewContext *vc, int select, short *mval, float rad) { struct {ViewContext *vc; short select, mval[2]; float radius; } data; bArmature *arm= vc->obedit->data; EditBone *ebone; + int change= FALSE; /* set vc->edit data */ - data.select = selecting; + data.select = select; data.mval[0] = mval[0]; data.mval[1] = mval[1]; data.radius = rad; @@ -2013,33 +2200,40 @@ static void armature_circle_select(ViewContext *vc, int selecting, short *mval, /* only if the endpoints didn't get selected, deal with the middle of the bone too */ // XXX should we just do this always? if ( (didpoint==0) && edge_inside_circle(mval[0], mval[1], rad, sco1[0], sco1[1], sco2[0], sco2[1]) ) { - if (selecting) + if (select) ebone->flag |= BONE_TIPSEL|BONE_ROOTSEL|BONE_SELECTED; else ebone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); + change= TRUE; } + + change |= didpoint; } - ED_armature_validate_active(arm); + if(change) { + ED_armature_sync_selection(arm->edbo); + ED_armature_validate_active(arm); + WM_main_add_notifier(NC_OBJECT|ND_BONE_SELECT, vc->obedit); + } } /** Callbacks for circle selection in Editmode */ -static void obedit_circle_select(ViewContext *vc, short selecting, short *mval, float rad) +static void obedit_circle_select(ViewContext *vc, short select, short *mval, float rad) { switch(vc->obedit->type) { case OB_MESH: - mesh_circle_select(vc, selecting, mval, rad); + mesh_circle_select(vc, select, mval, rad); break; case OB_CURVE: case OB_SURF: - nurbscurve_circle_select(vc, selecting, mval, rad); + nurbscurve_circle_select(vc, select, mval, rad); break; case OB_LATTICE: - lattice_circle_select(vc, selecting, mval, rad); + lattice_circle_select(vc, select, mval, rad); break; case OB_ARMATURE: - armature_circle_select(vc, selecting, mval, rad); + armature_circle_select(vc, select, mval, rad); break; default: return; @@ -2057,12 +2251,14 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op) int x= RNA_int_get(op->ptr, "x"); int y= RNA_int_get(op->ptr, "y"); int radius= RNA_int_get(op->ptr, "radius"); - int gesture_mode= RNA_int_get(op->ptr, "gesture_mode"); - int selecting; + int gesture_mode= RNA_int_get(op->ptr, "gesture_mode"); + int select; - selecting= (gesture_mode==GESTURE_MODAL_SELECT); + select= (gesture_mode==GESTURE_MODAL_SELECT); - if(CTX_data_edit_object(C) || (obact && obact->mode & OB_MODE_PARTICLE_EDIT)) { + if( CTX_data_edit_object(C) || paint_facesel_test(obact) || + (obact && (obact->mode & (OB_MODE_PARTICLE_EDIT|OB_MODE_POSE))) ) + { ViewContext vc; short mval[2]; @@ -2073,26 +2269,32 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op) mval[1]= y; if(CTX_data_edit_object(C)) { - obedit_circle_select(&vc, selecting, mval, (float)radius); + obedit_circle_select(&vc, select, mval, (float)radius); WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obact->data); } + else if(paint_facesel_test(obact)) { + paint_facesel_circle_select(&vc, select, mval, (float)radius); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obact->data); + } + else if(obact->mode & OB_MODE_POSE) + pose_circle_select(&vc, select, mval, (float)radius); else - return PE_circle_select(C, selecting, mval, (float)radius); + return PE_circle_select(C, select, mval, (float)radius); } else if(obact && obact->mode & OB_MODE_SCULPT) { return OPERATOR_CANCELLED; } else { Base *base; - selecting= selecting?BA_SELECT:BA_DESELECT; + select= select?BA_SELECT:BA_DESELECT; for(base= FIRSTBASE; base; base= base->next) { - if(base->lay & v3d->lay) { + if(BASE_SELECTABLE(v3d, base)) { project_short(ar, base->object->obmat[3], &base->sx); if(base->sx!=IS_CLIPPED) { int dx= base->sx-x; int dy= base->sy-y; if( dx*dx + dy*dy < radius*radius) - ED_base_object_select(base, selecting); + ED_base_object_select(base, select); } } } @@ -2112,7 +2314,7 @@ void VIEW3D_OT_select_circle(wmOperatorType *ot) ot->invoke= WM_gesture_circle_invoke; ot->modal= WM_gesture_circle_modal; ot->exec= view3d_circle_select_exec; - ot->poll= ED_operator_view3d_active; + ot->poll= view3d_selectable_data; /* flags */ ot->flag= OPTYPE_UNDO; diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 48e38c6c419..04b097ba097 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -1,5 +1,5 @@ -/** - * $Id: view3d_snap.c 18967 2009-02-14 13:07:09Z ton $ +/* + * $Id: view3d_snap.c 35106 2011-02-23 10:52:22Z jesterking $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -32,26 +32,18 @@ #include "MEM_guardedalloc.h" -#include "DNA_action_types.h" #include "DNA_armature_types.h" #include "DNA_curve_types.h" -#include "DNA_group_types.h" -#include "DNA_ipo_types.h" #include "DNA_lattice_types.h" #include "DNA_meta_types.h" -#include "DNA_mesh_types.h" -#include "DNA_modifier_types.h" -#include "DNA_object_types.h" -#include "DNA_screen_types.h" #include "DNA_scene_types.h" -#include "DNA_space_types.h" -#include "DNA_view3d_types.h" #include "DNA_object_types.h" #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_editVert.h" #include "BLI_linklist.h" +#include "BLI_utildefines.h" #include "BKE_armature.h" #include "BKE_context.h" @@ -65,16 +57,11 @@ #include "WM_api.h" #include "WM_types.h" -#include "RNA_access.h" -#include "RNA_define.h" -#include "UI_interface.h" -#include "ED_anim_api.h" #include "ED_armature.h" #include "ED_mesh.h" #include "ED_screen.h" -#include "ED_view3d.h" #include "ED_curve.h" /* for ED_curve_editnurbs */ #include "view3d_intern.h" @@ -97,13 +84,13 @@ static TransVert *transvmain=NULL; static int tottrans= 0; /* copied from editobject.c, now uses (almost) proper depgraph */ -static void special_transvert_update(Scene *scene, Object *obedit) +static void special_transvert_update(Object *obedit) { if(obedit) { - DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - + DAG_id_tag_update(obedit->data, 0); + if(obedit->type==OB_MESH) { Mesh *me= obedit->data; BM_Compute_Normals(me->edit_btmesh->bm); // does face centers too @@ -114,6 +101,37 @@ static void special_transvert_update(Scene *scene, Object *obedit) Nurb *nu= nurbs->first; while(nu) { + /* keep handles' vectors unchanged */ + if(nu->bezt) { + int a= nu->pntsu; + TransVert *tv= transvmain; + BezTriple *bezt= nu->bezt; + + while(a--) { + if(bezt->f1 & SELECT) tv++; + + if(bezt->f2 & SELECT) { + float v[3]; + + if(bezt->f1 & SELECT) { + sub_v3_v3v3(v, (tv-1)->oldloc, tv->oldloc); + add_v3_v3v3(bezt->vec[0], bezt->vec[1], v); + } + + if(bezt->f3 & SELECT) { + sub_v3_v3v3(v, (tv+1)->oldloc, tv->oldloc); + add_v3_v3v3(bezt->vec[2], bezt->vec[1], v); + } + + tv++; + } + + if(bezt->f3 & SELECT) tv++; + + bezt++; + } + } + test2DNurb(nu); testhandlesNurb(nu); /* test for bezier too */ nu= nu->next; @@ -133,7 +151,7 @@ static void special_transvert_update(Scene *scene, Object *obedit) float diffvec[3]; sub_v3_v3v3(diffvec, tv->loc, tv->oldloc); - add_v3_v3v3(ebo->tail, ebo->tail, diffvec); + add_v3_v3(ebo->tail, diffvec); a++; if (a<tottrans) tv++; @@ -167,7 +185,9 @@ static void special_transvert_update(Scene *scene, Object *obedit) } /* copied from editobject.c, needs to be replaced with new transform code still */ -/* mode: 1 = proportional, 2 = all joints (for bones only) */ +/* mode flags: */ +#define TM_ALL_JOINTS 1 /* all joints (for bones only) */ +#define TM_SKIP_HANDLES 2 /* skip handles when control point is selected (for curves only) */ static void make_trans_verts(Object *obedit, float *min, float *max, int mode) { Nurb *nu; @@ -176,7 +196,6 @@ static void make_trans_verts(Object *obedit, float *min, float *max, int mode) TransVert *tv=NULL; MetaElem *ml; BMVert *eve; - BMIter iter; EditBone *ebo; float total, center[3], centroid[3]; int a; @@ -190,6 +209,7 @@ static void make_trans_verts(Object *obedit, float *min, float *max, int mode) Mesh *me= obedit->data; BMEditMesh *em= me->edit_btmesh; BMesh *bm = em->bm; + BMIter iter; int proptrans= 0; // transform now requires awareness for select mode, so we tag the f1 flags in verts @@ -281,7 +301,7 @@ static void make_trans_verts(Object *obedit, float *min, float *max, int mode) short rootok= (!(ebo->parent && (ebo->flag & BONE_CONNECTED) && ebo->parent->flag & BONE_TIPSEL)); if ((tipsel && rootsel) || (rootsel)) { - /* Don't add the tip (unless mode & 2, for getting all joints), + /* Don't add the tip (unless mode & TM_ALL_JOINTS, for getting all joints), * otherwise we get zero-length bones as tips will snap to the same * location as heads. */ @@ -294,7 +314,7 @@ static void make_trans_verts(Object *obedit, float *min, float *max, int mode) tottrans++; } - if ((mode & 2) && (tipsel)) { + if ((mode & TM_ALL_JOINTS) && (tipsel)) { VECCOPY (tv->oldloc, ebo->tail); tv->loc= ebo->tail; tv->nor= NULL; @@ -320,7 +340,7 @@ static void make_trans_verts(Object *obedit, float *min, float *max, int mode) ListBase *nurbs= ED_curve_editnurbs(cu); for(nu= nurbs->first; nu; nu= nu->next) { - if((nu->type & 7)==CU_BEZIER) + if(nu->type == CU_BEZIER) totmalloc += 3*nu->pntsu; else totmalloc += nu->pntsu*nu->pntsv; @@ -329,19 +349,23 @@ static void make_trans_verts(Object *obedit, float *min, float *max, int mode) nu= nurbs->first; while(nu) { - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { a= nu->pntsu; bezt= nu->bezt; while(a--) { if(bezt->hide==0) { - if((mode & 1) || (bezt->f1 & SELECT)) { + int skip_handle= 0; + if(bezt->f2 & SELECT) + skip_handle= mode & TM_SKIP_HANDLES; + + if((bezt->f1 & SELECT) && !skip_handle) { VECCOPY(tv->oldloc, bezt->vec[0]); tv->loc= bezt->vec[0]; tv->flag= bezt->f1 & SELECT; tv++; tottrans++; } - if((mode & 1) || (bezt->f2 & SELECT)) { + if(bezt->f2 & SELECT) { VECCOPY(tv->oldloc, bezt->vec[1]); tv->loc= bezt->vec[1]; tv->val= &(bezt->alfa); @@ -350,7 +374,7 @@ static void make_trans_verts(Object *obedit, float *min, float *max, int mode) tv++; tottrans++; } - if((mode & 1) || (bezt->f3 & SELECT)) { + if((bezt->f3 & SELECT) && !skip_handle) { VECCOPY(tv->oldloc, bezt->vec[2]); tv->loc= bezt->vec[2]; tv->flag= bezt->f3 & SELECT; @@ -366,7 +390,7 @@ static void make_trans_verts(Object *obedit, float *min, float *max, int mode) bp= nu->bp; while(a--) { if(bp->hide==0) { - if((mode & 1) || (bp->f1 & SELECT)) { + if(bp->f1 & SELECT) { VECCOPY(tv->oldloc, bp->vec); tv->loc= bp->vec; tv->val= &(bp->alfa); @@ -409,10 +433,10 @@ static void make_trans_verts(Object *obedit, float *min, float *max, int mode) a= lt->editlatt->latt->pntsu*lt->editlatt->latt->pntsv*lt->editlatt->latt->pntsw; - tv=transvmain= MEM_callocN(a*sizeof(TransVert), "maketransverts curve"); + tv=transvmain= MEM_callocN(a*sizeof(TransVert), "maketransverts latt"); while(a--) { - if((mode & 1) || (bp->f1 & SELECT)) { + if(bp->f1 & SELECT) { if(bp->hide==0) { copy_v3_v3(tv->oldloc, bp->vec); tv->loc= bp->vec; @@ -425,6 +449,13 @@ static void make_trans_verts(Object *obedit, float *min, float *max, int mode) } } + if(!tottrans && transvmain) { + /* prevent memory leak. happens for curves/latticies due to */ + /* difficult condition of adding points to trans data */ + MEM_freeN(transvmain); + transvmain= NULL; + } + /* cent etc */ tv= transvmain; total= 0.0; @@ -444,7 +475,7 @@ static void make_trans_verts(Object *obedit, float *min, float *max, int mode) /* *********************** operators ******************** */ -static int snap_sel_to_grid(bContext *C, wmOperator *op) +static int snap_sel_to_grid(bContext *C, wmOperator *UNUSED(op)) { extern float originmat[3][3]; /* XXX object.c */ Main *bmain= CTX_data_main(C); @@ -472,17 +503,17 @@ static int snap_sel_to_grid(bContext *C, wmOperator *op) VECCOPY(vec, tv->loc); mul_m3_v3(bmat, vec); - add_v3_v3v3(vec, vec, obedit->obmat[3]); + add_v3_v3(vec, obedit->obmat[3]); vec[0]= gridf*floor(.5+ vec[0]/gridf); vec[1]= gridf*floor(.5+ vec[1]/gridf); vec[2]= gridf*floor(.5+ vec[2]/gridf); - sub_v3_v3v3(vec, vec, obedit->obmat[3]); + sub_v3_v3(vec, obedit->obmat[3]); mul_m3_v3(imat, vec); VECCOPY(tv->loc, vec); } - special_transvert_update(scene, obedit); + special_transvert_update(obedit); MEM_freeN(transvmain); transvmain= NULL; @@ -511,7 +542,12 @@ static int snap_sel_to_grid(bContext *C, wmOperator *op) armature_loc_pose_to_bone(pchan, vec, vecN); /* adjust location */ - VECCOPY(pchan->loc, vecN); + if ((pchan->protectflag & OB_LOCK_LOCX)==0) + pchan->loc[0]= vecN[0]; + if ((pchan->protectflag & OB_LOCK_LOCY)==0) + pchan->loc[0]= vecN[1]; + if ((pchan->protectflag & OB_LOCK_LOCZ)==0) + pchan->loc[0]= vecN[2]; } /* if the bone has a parent and is connected to the parent, * don't do anything - will break chain unless we do auto-ik. @@ -523,7 +559,7 @@ static int snap_sel_to_grid(bContext *C, wmOperator *op) /* auto-keyframing */ // XXX autokeyframe_pose_cb_func(ob, TFM_TRANSLATION, 0); - DAG_id_flush_update(ob->data, OB_RECALC_DATA); + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); } else { ob->recalc |= OB_RECALC_OB; @@ -537,16 +573,14 @@ static int snap_sel_to_grid(bContext *C, wmOperator *op) invert_m3_m3(imat, originmat); mul_m3_v3(imat, vec); - ob->loc[0]+= vec[0]; - ob->loc[1]+= vec[1]; - ob->loc[2]+= vec[2]; } - else { + if ((ob->protectflag & OB_LOCK_LOCX)==0) ob->loc[0]+= vec[0]; + if ((ob->protectflag & OB_LOCK_LOCY)==0) ob->loc[1]+= vec[1]; + if ((ob->protectflag & OB_LOCK_LOCZ)==0) ob->loc[2]+= vec[2]; - } - + /* auto-keyframing */ // XXX autokeyframe_ob_cb_func(ob, TFM_TRANSLATION); } @@ -565,11 +599,12 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot) /* identifiers */ ot->name= "Snap Selection to Grid"; + ot->description= "Snap selected item(s) to nearest grid node"; ot->idname= "VIEW3D_OT_snap_selected_to_grid"; /* api callbacks */ ot->exec= snap_sel_to_grid; - ot->poll= ED_operator_view3d_active; + ot->poll= ED_operator_region_view3d_active; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -577,7 +612,7 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot) /* *************************************************** */ -static int snap_sel_to_curs(bContext *C, wmOperator *op) +static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op)) { extern float originmat[3][3]; /* XXX object.c */ Main *bmain= CTX_data_main(C); @@ -602,15 +637,12 @@ static int snap_sel_to_curs(bContext *C, wmOperator *op) tv= transvmain; for(a=0; a<tottrans; a++, tv++) { - vec[0]= curs[0]-obedit->obmat[3][0]; - vec[1]= curs[1]-obedit->obmat[3][1]; - vec[2]= curs[2]-obedit->obmat[3][2]; - + sub_v3_v3v3(vec, curs, obedit->obmat[3]); mul_m3_v3(imat, vec); - VECCOPY(tv->loc, vec); + copy_v3_v3(tv->loc, vec); } - special_transvert_update(scene, obedit); + special_transvert_update(obedit); MEM_freeN(transvmain); transvmain= NULL; @@ -636,8 +668,13 @@ static int snap_sel_to_curs(bContext *C, wmOperator *op) /* get location of cursor in bone-space */ armature_loc_pose_to_bone(pchan, cursp, curspn); - /* calculate new position */ - VECCOPY(pchan->loc, curspn); + /* copy new position */ + if ((pchan->protectflag & OB_LOCK_LOCX)==0) + pchan->loc[0]= curspn[0]; + if ((pchan->protectflag & OB_LOCK_LOCY)==0) + pchan->loc[1]= curspn[1]; + if ((pchan->protectflag & OB_LOCK_LOCZ)==0) + pchan->loc[2]= curspn[2]; } /* if the bone has a parent and is connected to the parent, * don't do anything - will break chain unless we do auto-ik. @@ -649,7 +686,7 @@ static int snap_sel_to_curs(bContext *C, wmOperator *op) /* auto-keyframing */ // XXX autokeyframe_pose_cb_func(ob, TFM_TRANSLATION, 0); - DAG_id_flush_update(ob->data, OB_RECALC_DATA); + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); } else { ob->recalc |= OB_RECALC_OB; @@ -663,15 +700,14 @@ static int snap_sel_to_curs(bContext *C, wmOperator *op) invert_m3_m3(imat, originmat); mul_m3_v3(imat, vec); - ob->loc[0]+= vec[0]; - ob->loc[1]+= vec[1]; - ob->loc[2]+= vec[2]; } - else { + if ((ob->protectflag & OB_LOCK_LOCX)==0) ob->loc[0]+= vec[0]; + if ((ob->protectflag & OB_LOCK_LOCY)==0) ob->loc[1]+= vec[1]; + if ((ob->protectflag & OB_LOCK_LOCZ)==0) ob->loc[2]+= vec[2]; - } + /* auto-keyframing */ // XXX autokeyframe_ob_cb_func(ob, TFM_TRANSLATION); } @@ -690,6 +726,7 @@ void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot) /* identifiers */ ot->name= "Snap Selection to Cursor"; + ot->description= "Snap selected item(s) to cursor"; ot->idname= "VIEW3D_OT_snap_selected_to_cursor"; /* api callbacks */ @@ -702,7 +739,7 @@ void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot) /* *************************************************** */ -static int snap_curs_to_grid(bContext *C, wmOperator *op) +static int snap_curs_to_grid(bContext *C, wmOperator *UNUSED(op)) { Scene *scene= CTX_data_scene(C); RegionView3D *rv3d= CTX_wm_region_data(C); @@ -726,11 +763,12 @@ void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot) /* identifiers */ ot->name= "Snap Cursor to Grid"; + ot->description= "Snap cursor to nearest grid node"; ot->idname= "VIEW3D_OT_snap_cursor_to_grid"; /* api callbacks */ ot->exec= snap_curs_to_grid; - ot->poll= ED_operator_view3d_active; + ot->poll= ED_operator_region_view3d_active; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -738,7 +776,7 @@ void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot) /* **************************************************** */ -static int snap_curs_to_sel(bContext *C, wmOperator *op) +static int snap_curs_to_sel(bContext *C, wmOperator *UNUSED(op)) { Object *obedit= CTX_data_edit_object(C); Scene *scene= CTX_data_scene(C); @@ -757,7 +795,7 @@ static int snap_curs_to_sel(bContext *C, wmOperator *op) tottrans=0; if ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) - make_trans_verts(obedit, bmat[0], bmat[1], 2); + make_trans_verts(obedit, bmat[0], bmat[1], TM_ALL_JOINTS|TM_SKIP_HANDLES); if(tottrans==0) return OPERATOR_CANCELLED; copy_m3_m4(bmat, obedit->obmat); @@ -766,8 +804,8 @@ static int snap_curs_to_sel(bContext *C, wmOperator *op) for(a=0; a<tottrans; a++, tv++) { VECCOPY(vec, tv->loc); mul_m3_v3(bmat, vec); - add_v3_v3v3(vec, vec, obedit->obmat[3]); - add_v3_v3v3(centroid, centroid, vec); + add_v3_v3(vec, obedit->obmat[3]); + add_v3_v3(centroid, vec); DO_MINMAX(vec, min, max); } @@ -784,17 +822,17 @@ static int snap_curs_to_sel(bContext *C, wmOperator *op) transvmain= NULL; } else { - Object *ob= CTX_data_active_object(C); + Object *obact= CTX_data_active_object(C); - if(ob && (ob->mode & OB_MODE_POSE)) { - bArmature *arm= ob->data; + if(obact && (obact->mode & OB_MODE_POSE)) { + bArmature *arm= obact->data; bPoseChannel *pchan; - for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next) { + for (pchan = obact->pose->chanbase.first; pchan; pchan=pchan->next) { if(arm->layer & pchan->bone->layer) { if(pchan->bone->flag & BONE_SELECTED) { VECCOPY(vec, pchan->pose_head); - mul_m4_v3(ob->obmat, vec); - add_v3_v3v3(centroid, centroid, vec); + mul_m4_v3(obact->obmat, vec); + add_v3_v3(centroid, vec); DO_MINMAX(vec, min, max); count++; } @@ -802,9 +840,9 @@ static int snap_curs_to_sel(bContext *C, wmOperator *op) } } else { - CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { + CTX_DATA_BEGIN(C, Object*, ob, selected_objects) { VECCOPY(vec, ob->obmat[3]); - add_v3_v3v3(centroid, centroid, vec); + add_v3_v3(centroid, vec); DO_MINMAX(vec, min, max); count++; } @@ -832,6 +870,7 @@ void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot) /* identifiers */ ot->name= "Snap Cursor to Selected"; + ot->description= "Snap cursor to center of selected item(s)"; ot->idname= "VIEW3D_OT_snap_cursor_to_selected"; /* api callbacks */ @@ -844,7 +883,7 @@ void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot) /* ********************************************** */ -static int snap_curs_to_active(bContext *C, wmOperator *op) +static int snap_curs_to_active(bContext *C, wmOperator *UNUSED(op)) { Object *obedit= CTX_data_edit_object(C); Object *obact= CTX_data_active_object(C); @@ -882,6 +921,7 @@ void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot) /* identifiers */ ot->name= "Snap Cursor to Active"; + ot->description= "Snap cursor to active item"; ot->idname= "VIEW3D_OT_snap_cursor_to_active"; /* api callbacks */ @@ -892,221 +932,24 @@ void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -/* ************************************** */ - -static int snap_selected_to_center(bContext *C, wmOperator *op) +/* **************************************************** */ +/*New Code - Snap Cursor to Center -*/ +static int snap_curs_to_center(bContext *C, wmOperator *UNUSED(op)) { - extern float originmat[3][3]; /* XXX object.c */ - Object *obedit= CTX_data_edit_object(C); Scene *scene= CTX_data_scene(C); View3D *v3d= CTX_wm_view3d(C); - TransVert *tv; - float snaploc[3], imat[3][3], bmat[3][3], vec[3], min[3], max[3], centroid[3]; - int count, a; - - /*calculate the snaplocation (centerpoint) */ - count= 0; - INIT_MINMAX(min, max); - centroid[0]= centroid[1]= centroid[2]= 0.0f; - snaploc[0]= snaploc[1]= snaploc[2]= 0.0f; - - if(obedit) { - tottrans= 0; - - if ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) - make_trans_verts(obedit, bmat[0], bmat[1], 0); - if(tottrans==0) return OPERATOR_CANCELLED; - - copy_m3_m4(bmat, obedit->obmat); - invert_m3_m3(imat, bmat); - - tv= transvmain; - for(a=0; a<tottrans; a++, tv++) { - VECCOPY(vec, tv->loc); - mul_m3_v3(bmat, vec); - add_v3_v3v3(vec, vec, obedit->obmat[3]); - add_v3_v3v3(centroid, centroid, vec); - DO_MINMAX(vec, min, max); - } - - if(v3d->around==V3D_CENTROID) { - mul_v3_fl(centroid, 1.0/(float)tottrans); - VECCOPY(snaploc, centroid); - } - else { - snaploc[0]= (min[0]+max[0])/2; - snaploc[1]= (min[1]+max[1])/2; - snaploc[2]= (min[2]+max[2])/2; - } - - MEM_freeN(transvmain); - transvmain= NULL; - } - else { - - CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { - if(ob->mode & OB_MODE_POSE) { - bPoseChannel *pchan; - bArmature *arm= ob->data; - - for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next) { - if(pchan->bone->flag & BONE_SELECTED) { - if(pchan->bone->layer & arm->layer) { - VECCOPY(vec, pchan->pose_mat[3]); - add_v3_v3v3(centroid, centroid, vec); - DO_MINMAX(vec, min, max); - count++; - } - } - } - } - else { - /* not armature bones (i.e. objects) */ - VECCOPY(vec, ob->obmat[3]); - add_v3_v3v3(centroid, centroid, vec); - DO_MINMAX(vec, min, max); - count++; - } - } - CTX_DATA_END; - - if(count) { - if(v3d->around==V3D_CENTROID) { - mul_v3_fl(centroid, 1.0/(float)count); - VECCOPY(snaploc, centroid); - } - else { - snaploc[0]= (min[0]+max[0])/2; - snaploc[1]= (min[1]+max[1])/2; - snaploc[2]= (min[2]+max[2])/2; - } - } - } - - /* Snap the selection to the snaplocation (duh!) */ - if(obedit) { - tottrans= 0; - - if ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) - make_trans_verts(obedit, bmat[0], bmat[1], 0); - if(tottrans==0) return OPERATOR_CANCELLED; - - copy_m3_m4(bmat, obedit->obmat); - invert_m3_m3(imat, bmat); - - tv= transvmain; - for(a=0; a<tottrans; a++, tv++) { - vec[0]= snaploc[0]-obedit->obmat[3][0]; - vec[1]= snaploc[1]-obedit->obmat[3][1]; - vec[2]= snaploc[2]-obedit->obmat[3][2]; - - mul_m3_v3(imat, vec); - VECCOPY(tv->loc, vec); - } - - special_transvert_update(scene, obedit); - - MEM_freeN(transvmain); - transvmain= NULL; - - } - else { + float *curs; + curs= give_cursor(scene, v3d); - CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { - if(ob->mode & OB_MODE_POSE) { - bPoseChannel *pchan; - bArmature *arm= ob->data; - - for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next) { - if(pchan->bone->flag & BONE_SELECTED) { - if(pchan->bone->layer & arm->layer) { - if((pchan->bone->flag & BONE_CONNECTED)==0) { - /* get location of cursor in bone-space */ - armature_loc_pose_to_bone(pchan, snaploc, vec); - - /* calculate new position */ - VECCOPY(pchan->loc, vec); - } - /* if the bone has a parent and is connected to the parent, - * don't do anything - will break chain unless we do auto-ik. - */ - } - } - } - - /* auto-keyframing */ - ob->pose->flag |= POSE_DO_UNLOCK; -// XXX autokeyframe_pose_cb_func(ob, TFM_TRANSLATION, 0); - DAG_id_flush_update(ob->data, OB_RECALC_DATA); - } - else { - ob->recalc |= OB_RECALC_OB; - - vec[0]= -ob->obmat[3][0] + snaploc[0]; - vec[1]= -ob->obmat[3][1] + snaploc[1]; - vec[2]= -ob->obmat[3][2] + snaploc[2]; - - if(ob->parent) { - where_is_object(scene, ob); - - invert_m3_m3(imat, originmat); - mul_m3_v3(imat, vec); - ob->loc[0]+= vec[0]; - ob->loc[1]+= vec[1]; - ob->loc[2]+= vec[2]; - } - else { - ob->loc[0]+= vec[0]; - ob->loc[1]+= vec[1]; - ob->loc[2]+= vec[2]; - } - /* auto-keyframing */ -// XXX autokeyframe_ob_cb_func(ob, TFM_TRANSLATION); - } - } - CTX_DATA_END; - } + curs[0]= 0.0; + curs[1]= 0.0; + curs[2]= 0.0; - DAG_ids_flush_update(CTX_data_main(C), 0); - WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, v3d); return OPERATOR_FINISHED; } -void VIEW3D_OT_snap_selected_to_center(wmOperatorType *ot) -{ - - /* identifiers */ - ot->name= "Snap Selection to Center"; - ot->idname= "VIEW3D_OT_snap_selected_to_center"; - - /* api callbacks */ - ot->exec= snap_selected_to_center; - ot->poll= ED_operator_view3d_active; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - - -/* **************************************************** */ -/*New Code - Snap Cursor to Center -*/ -static int snap_curs_to_center(bContext *C, wmOperator *op) -{ - Scene *scene= CTX_data_scene(C); - View3D *v3d= CTX_wm_view3d(C); - float *curs; - curs= give_cursor(scene, v3d); - - curs[0]= 0.0; - curs[1]= 0.0; - curs[2]= 0.0; - - WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, v3d); - - return OPERATOR_FINISHED; -} - void VIEW3D_OT_snap_cursor_to_center(wmOperatorType *ot) { @@ -1115,12 +958,12 @@ void VIEW3D_OT_snap_cursor_to_center(wmOperatorType *ot) ot->description= "Snap cursor to the Center"; ot->idname= "VIEW3D_OT_snap_cursor_to_center"; - /* api callbacks */ - ot->exec= snap_curs_to_center; - ot->poll= ED_operator_view3d_active; + /* api callbacks */ + ot->exec= snap_curs_to_center; + ot->poll= ED_operator_view3d_active; - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } /* **************************************************** */ @@ -1134,7 +977,7 @@ int minmax_verts(Object *obedit, float *min, float *max) tottrans=0; if ELEM5(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE) - make_trans_verts(obedit, bmat[0], bmat[1], 2); + make_trans_verts(obedit, bmat[0], bmat[1], TM_ALL_JOINTS); if(tottrans==0) return 0; @@ -1144,8 +987,8 @@ int minmax_verts(Object *obedit, float *min, float *max) for(a=0; a<tottrans; a++, tv++) { VECCOPY(vec, tv->loc); mul_m3_v3(bmat, vec); - add_v3_v3v3(vec, vec, obedit->obmat[3]); - add_v3_v3v3(centroid, centroid, vec); + add_v3_v3(vec, obedit->obmat[3]); + add_v3_v3(centroid, vec); DO_MINMAX(vec, min, max); } @@ -1154,3 +997,4 @@ int minmax_verts(Object *obedit, float *min, float *max) return 1; } + diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c index c07d7d88944..3292c5d396c 100644 --- a/source/blender/editors/space_view3d/view3d_toolbar.c +++ b/source/blender/editors/space_view3d/view3d_toolbar.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -40,6 +40,7 @@ #include "BLI_blenlib.h" #include "BLI_editVert.h" #include "BLI_rand.h" +#include "BLI_utildefines.h" #include "BKE_context.h" #include "BKE_idprop.h" @@ -63,27 +64,6 @@ /* ******************* view3d space & buttons ************** */ - -/* op->invoke */ -static void redo_cb(bContext *C, void *arg_op, void *arg2) -{ - wmOperator *lastop= arg_op; - - if(lastop) { - int retval; - - if (G.f & G_DEBUG) - printf("operator redo %s\n", lastop->type->name); - ED_undo_pop_op(C, lastop); - retval= WM_operator_repeat(C, lastop); - if((retval & OPERATOR_FINISHED)==0) { - if (G.f & G_DEBUG) - printf("operator redo failed %s\n", lastop->type->name); - ED_undo_redo(C); - } - } -} - static wmOperator *view3d_last_operator(const bContext *C) { wmWindowManager *wm= CTX_wm_manager(C); @@ -99,22 +79,7 @@ static wmOperator *view3d_last_operator(const bContext *C) static void view3d_panel_operator_redo_buts(const bContext *C, Panel *pa, wmOperator *op) { - wmWindowManager *wm= CTX_wm_manager(C); - PointerRNA ptr; - - if(!op->properties) { - IDPropertyTemplate val = {0}; - op->properties= IDP_New(IDP_GROUP, val, "wmOperatorProperties"); - } - - RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); - if(op->type->ui) { - op->layout= pa->layout; - op->type->ui((bContext*)C, op); - op->layout= NULL; - } - else - uiDefAutoButsRNA(C, pa->layout, &ptr, 1); + uiLayoutOperatorButs(C, pa->layout, op, NULL, 'V', 0); } static void view3d_panel_operator_redo_header(const bContext *C, Panel *pa) @@ -129,7 +94,7 @@ static void view3d_panel_operator_redo_operator(const bContext *C, Panel *pa, wm { if(op->type->flag & OPTYPE_MACRO) { for(op= op->macro.first; op; op= op->next) { - uiItemL(pa->layout, op->idname, 0); + uiItemL(pa->layout, op->type->name, ICON_NULL); view3d_panel_operator_redo_operator(C, pa, op); } } @@ -149,8 +114,12 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa) return; block= uiLayoutGetBlock(pa->layout); + + if(ED_undo_valid(C, op->type->name)==0) + uiLayoutSetEnabled(pa->layout, 0); - uiBlockSetFunc(block, redo_cb, op, NULL); + /* note, blockfunc is a default but->func, use Handle func to allow button callbacks too */ + uiBlockSetHandleFunc(block, ED_undo_operator_repeat_cb_evt, op); view3d_panel_operator_redo_operator(C, pa, op); } @@ -177,7 +146,7 @@ static void operator_call_cb(struct bContext *C, void *arg_listbase, void *arg2) } -static void operator_search_cb(const struct bContext *C, void *arg, char *str, uiSearchItems *items) +static void operator_search_cb(const struct bContext *C, void *UNUSED(arg), const char *str, uiSearchItems *items) { wmOperatorType *ot = WM_operatortype_first(); @@ -246,7 +215,7 @@ static void view3d_panel_tool_shelf(const bContext *C, Panel *pa) for(ct= st->toolshelf.first; ct; ct= ct->next) { if(0==strncmp(context, ct->context, OP_MAX_TYPENAME)) { col= uiLayoutColumn(pa->layout, 1); - uiItemFullO(col, ct->opname, NULL, 0, NULL, WM_OP_INVOKE_REGION_WIN, 0); + uiItemFullO(col, ct->opname, NULL, ICON_NULL, NULL, WM_OP_INVOKE_REGION_WIN, 0); } } } @@ -280,7 +249,7 @@ void view3d_tool_props_register(ARegionType *art) /* ********** operator to open/close toolshelf region */ -static int view3d_toolshelf(bContext *C, wmOperator *op) +static int view3d_toolshelf(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa= CTX_wm_area(C); ARegion *ar= view3d_has_tools_region(sa); diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 532c13314fd..794088de20c 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -26,12 +26,6 @@ * ***** END GPL LICENSE BLOCK ***** */ -#include <string.h> -#include <stdio.h> -#include <math.h> -#include <float.h> - -#include "DNA_anim_types.h" #include "DNA_camera_types.h" #include "DNA_lamp_types.h" #include "DNA_scene_types.h" @@ -40,9 +34,9 @@ #include "MEM_guardedalloc.h" #include "BLI_math.h" -#include "BLI_blenlib.h" -#include "BLI_editVert.h" -#include "BLI_rand.h" +#include "BLI_rect.h" +#include "BLI_listbase.h" +#include "BLI_utildefines.h" #include "BKE_anim.h" #include "BKE_action.h" @@ -52,25 +46,19 @@ #include "BKE_main.h" #include "BKE_report.h" #include "BKE_scene.h" -#include "BKE_depsgraph.h" /* for fly mode updating */ - #include "BIF_gl.h" #include "BIF_glutil.h" +#include "GPU_draw.h" + #include "WM_api.h" #include "WM_types.h" -#include "ED_keyframing.h" #include "ED_screen.h" #include "ED_armature.h" -#include "GPU_draw.h" - - -#include "PIL_time.h" /* smoothview */ - -#if GAMEBLENDER == 1 +#ifdef WITH_GAMEENGINE #include "SYS_System.h" #endif @@ -81,15 +69,21 @@ opengl drawing context */ void view3d_operator_needs_opengl(const bContext *C) { + wmWindow *win = CTX_wm_window(C); ARegion *ar= CTX_wm_region(C); + + view3d_region_operator_needs_opengl(win, ar); +} +void view3d_region_operator_needs_opengl(wmWindow *win, ARegion *ar) +{ /* for debugging purpose, context should always be OK */ - if(ar->regiontype!=RGN_TYPE_WINDOW) - printf("view3d_operator_needs_opengl error, wrong region\n"); + if ((ar == NULL) || (ar->regiontype!=RGN_TYPE_WINDOW)) + printf("view3d_region_operator_needs_opengl error, wrong region\n"); else { RegionView3D *rv3d= ar->regiondata; - wmSubWindowSet(CTX_wm_window(C), ar->swinid); + wmSubWindowSet(win, ar->swinid); glMatrixMode(GL_PROJECTION); glLoadMatrixf(rv3d->winmat); glMatrixMode(GL_MODELVIEW); @@ -153,8 +147,12 @@ void view3d_settings_from_ob(Object *ob, float *ofs, float *quat, float *dist, f } if (dist) { - float vec[3] = {0.0f, 0.0f, -(*dist)}; float tquat[4]; + float vec[3]; + + vec[0]= 0.0f; + vec[1]= 0.0f; + vec[2]= -(*dist); mat4_to_quat(tquat, ob->obmat); @@ -189,10 +187,10 @@ void smooth_view(bContext *C, Object *oldcamera, Object *camera, float *ofs, flo { View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d= CTX_wm_region_view3d(C); - struct SmoothViewStore sms; + struct SmoothViewStore sms= {0}; + short ok= FALSE; /* initialize sms */ - memset(&sms,0,sizeof(struct SmoothViewStore)); copy_v3_v3(sms.new_ofs, rv3d->ofs); copy_qt_qt(sms.new_quat, rv3d->viewquat); sms.new_dist= rv3d->dist; @@ -204,7 +202,7 @@ void smooth_view(bContext *C, Object *oldcamera, Object *camera, float *ofs, flo if(quat) copy_qt_qt(sms.new_quat, quat); if(dist) sms.new_dist= *dist; if(lens) sms.new_lens= *lens; - + if (camera) { view3d_settings_from_ob(camera, sms.new_ofs, sms.new_quat, &sms.new_dist, &sms.new_lens); sms.to_camera= 1; /* restore view3d values in end */ @@ -213,15 +211,15 @@ void smooth_view(bContext *C, Object *oldcamera, Object *camera, float *ofs, flo if (C && U.smooth_viewtx) { int changed = 0; /* zero means no difference */ - if (sms.new_dist != rv3d->dist) + if (oldcamera != camera) changed = 1; - if (sms.new_lens != v3d->lens) + else if (sms.new_dist != rv3d->dist) changed = 1; - - if (!equals_v3v3(sms.new_ofs, rv3d->ofs)) + else if (sms.new_lens != v3d->lens) changed = 1; - - if (!equals_v4v4(sms.new_quat, rv3d->viewquat)) + else if (!equals_v3v3(sms.new_ofs, rv3d->ofs)) + changed = 1; + else if (!equals_v4v4(sms.new_quat, rv3d->viewquat)) changed = 1; /* The new view is different from the old one @@ -280,22 +278,30 @@ void smooth_view(bContext *C, Object *oldcamera, Object *camera, float *ofs, flo /* TIMER1 is hardcoded in keymap */ rv3d->smooth_timer= WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER1, 1.0/100.0); /* max 30 frs/sec */ - return; + ok= TRUE; } } /* if we get here nothing happens */ - if(sms.to_camera==0) { - copy_v3_v3(rv3d->ofs, sms.new_ofs); - copy_qt_qt(rv3d->viewquat, sms.new_quat); - rv3d->dist = sms.new_dist; - v3d->lens = sms.new_lens; + if(ok == FALSE) { + ARegion *ar= CTX_wm_region(C); + + if(sms.to_camera==0) { + copy_v3_v3(rv3d->ofs, sms.new_ofs); + copy_qt_qt(rv3d->viewquat, sms.new_quat); + rv3d->dist = sms.new_dist; + v3d->lens = sms.new_lens; + } + + if(rv3d->viewlock & RV3D_BOXVIEW) + view3d_boxview_copy(CTX_wm_area(C), ar); + + ED_region_tag_redraw(ar); } - ED_region_tag_redraw(CTX_wm_region(C)); } /* only meant for timer usage */ -static int view3d_smoothview_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) { View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d= CTX_wm_region_view3d(C); @@ -358,6 +364,9 @@ static int view3d_smoothview_invoke(bContext *C, wmOperator *op, wmEvent *event) v3d->lens = sms->new_lens*step + sms->orig_lens*step_inv; } + if(rv3d->viewlock & RV3D_BOXVIEW) + view3d_boxview_copy(CTX_wm_area(C), CTX_wm_region(C)); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, v3d); return OPERATOR_FINISHED; @@ -379,7 +388,7 @@ void VIEW3D_OT_smoothview(wmOperatorType *ot) /* ****************** change view operators ****************** */ -static void setcameratoview3d(View3D *v3d, RegionView3D *rv3d, Object *ob) +static void setcameratoview3d(RegionView3D *rv3d, Object *ob) { float dvec[3]; float mat3[3][3]; @@ -398,16 +407,18 @@ static void setcameratoview3d(View3D *v3d, RegionView3D *rv3d, Object *ob) } -static int view3d_setcameratoview_exec(bContext *C, wmOperator *op) +static int view3d_setcameratoview_exec(bContext *C, wmOperator *UNUSED(op)) { View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d= CTX_wm_region_view3d(C); copy_qt_qt(rv3d->lviewquat, rv3d->viewquat); rv3d->lview= rv3d->view; - rv3d->lpersp= rv3d->persp; + if(rv3d->persp != RV3D_CAMOB) { + rv3d->lpersp= rv3d->persp; + } - setcameratoview3d(v3d, rv3d, v3d->camera); + setcameratoview3d(rv3d, v3d->camera); rv3d->persp = RV3D_CAMOB; WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, v3d->camera); @@ -416,7 +427,7 @@ static int view3d_setcameratoview_exec(bContext *C, wmOperator *op) } -int view3d_setcameratoview_poll(bContext *C) +static int view3d_setcameratoview_poll(bContext *C) { View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d= CTX_wm_region_view3d(C); @@ -443,25 +454,36 @@ void VIEW3D_OT_setcameratoview(wmOperatorType *ot) } -static int view3d_setobjectascamera_exec(bContext *C, wmOperator *op) +static int view3d_setobjectascamera_exec(bContext *C, wmOperator *UNUSED(op)) { View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d= CTX_wm_region_view3d(C); Scene *scene= CTX_data_scene(C); - - if(BASACT) { + Object *ob = CTX_data_active_object(C); + + if(ob) { + Object *camera_old= (rv3d->persp == RV3D_CAMOB && scene->camera) ? scene->camera : NULL; rv3d->persp= RV3D_CAMOB; - v3d->camera= OBACT; + v3d->camera= ob; if(v3d->scenelock) - scene->camera= OBACT; - smooth_view(C, NULL, v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, &v3d->lens); + scene->camera= ob; + + if(camera_old != ob) /* unlikely but looks like a glitch when set to the same */ + smooth_view(C, camera_old, v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, &v3d->lens); + + WM_event_add_notifier(C, NC_SCENE|ND_RENDER_OPTIONS|NC_OBJECT|ND_DRAW, CTX_data_scene(C)); } - WM_event_add_notifier(C, NC_SCENE|ND_RENDER_OPTIONS|NC_OBJECT|ND_DRAW, CTX_data_scene(C)); - return OPERATOR_FINISHED; } +static int region3d_unlocked_poll(bContext *C) +{ + RegionView3D *rv3d= CTX_wm_region_view3d(C); + return (rv3d && rv3d->viewlock==0); +} + + void VIEW3D_OT_object_as_camera(wmOperatorType *ot) { @@ -472,7 +494,7 @@ void VIEW3D_OT_object_as_camera(wmOperatorType *ot) /* api callbacks */ ot->exec= view3d_setobjectascamera_exec; - ot->poll= ED_operator_view3d_active; + ot->poll= region3d_unlocked_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -1052,6 +1074,17 @@ int get_view3d_viewplane(View3D *v3d, RegionView3D *rv3d, int winxi, int winyi, if(cam) { float dx= 0.5*fac*rv3d->camdx*(x2-x1); float dy= 0.5*fac*rv3d->camdy*(y2-y1); + + /* shift offset */ + if(cam->type==CAM_ORTHO) { + dx += cam->shiftx * cam->ortho_scale; + dy += cam->shifty * cam->ortho_scale; + } + else { + dx += cam->shiftx * (cam->clipsta / cam->lens) * 32.0; + dy += cam->shifty * (cam->clipsta / cam->lens) * 32.0; + } + x1+= dx; x2+= dx; y1+= dy; @@ -1191,25 +1224,6 @@ static void view3d_viewlock(RegionView3D *rv3d) } } -/* give a 4x4 matrix from a perspective view, only needs viewquat, ofs and dist - * basically the same as... - * rv3d->persp= RV3D_PERSP - * setviewmatrixview3d(scene, v3d, rv3d); - * setcameratoview3d(v3d, rv3d, v3d->camera); - * ...but less of a hassle - * */ -static void view3d_persp_mat4(RegionView3D *rv3d, float mat[][4]) -{ - float qt[4], dvec[3]; - copy_qt_qt(qt, rv3d->viewquat); - qt[0]= -qt[0]; - quat_to_mat4(mat, qt); - mat[3][2] -= rv3d->dist; - translate_m4(mat, rv3d->ofs[0], rv3d->ofs[1], rv3d->ofs[2]); - mul_v3_v3fl(dvec, mat[2], -rv3d->dist); - sub_v3_v3v3(mat[3], dvec, rv3d->ofs); -} - /* dont set windows active in in here, is used by renderwin too */ void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d) { @@ -1244,6 +1258,11 @@ void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d) } translate_m4( rv3d->viewmat,-vec[0], -vec[1], -vec[2]); } + else if (v3d->ob_centre_cursor) { + float vec[3]; + copy_v3_v3(vec, give_cursor(scene, v3d)); + translate_m4(rv3d->viewmat, -vec[0], -vec[1], -vec[2]); + } else translate_m4( rv3d->viewmat,rv3d->ofs[0], rv3d->ofs[1], rv3d->ofs[2]); } } @@ -1529,7 +1548,6 @@ static void initlocalview(Main *bmain, Scene *scene, ScrArea *sa) v3d->cursor[2]= -rv3d->ofs[2]; } } - if (v3d->near> 0.1) v3d->near= 0.1; v3d->lay= locallay; } @@ -1616,7 +1634,7 @@ static void endlocalview(Scene *scene, ScrArea *sa) } } -static int localview_exec(bContext *C, wmOperator *unused) +static int localview_exec(bContext *C, wmOperator *UNUSED(unused)) { View3D *v3d= CTX_wm_view3d(C); @@ -1644,12 +1662,11 @@ void VIEW3D_OT_localview(wmOperatorType *ot) ot->poll= ED_operator_view3d_active; } -#if GAMEBLENDER == 1 +#ifdef WITH_GAMEENGINE static ListBase queue_back; -static void SaveState(bContext *C) +static void SaveState(bContext *C, wmWindow *win) { - wmWindow *win= CTX_wm_window(C); Object *obact = CTX_data_active_object(C); glPushAttrib(GL_ALL_ATTRIB_BITS); @@ -1664,9 +1681,8 @@ static void SaveState(bContext *C) //XXX waitcursor(1); } -static void RestoreState(bContext *C) +static void RestoreState(bContext *C, wmWindow *win) { - wmWindow *win= CTX_wm_window(C); Object *obact = CTX_data_active_object(C); if(obact && obact->mode & OB_MODE_TEXTURE_PAINT) @@ -1680,9 +1696,11 @@ static void RestoreState(bContext *C) //XXX waitcursor(0); //XXX G.qual= 0; - win->queue= queue_back; + if(win) /* check because closing win can set to NULL */ + win->queue= queue_back; GPU_state_init(); + GPU_set_tpage(NULL, 0); glPopAttrib(); } @@ -1735,9 +1753,9 @@ void game_set_commmandline_options(GameData *gm) /* maybe we need this defined somewhere else */ extern void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *cam_frame, int always_use_expand_framing); -#endif // GAMEBLENDER == 1 +#endif // WITH_GAMEENGINE -int game_engine_poll(bContext *C) +static int game_engine_poll(bContext *C) { /* we need a context and area to launch BGE it's a temporary solution to avoid crash at load time @@ -1759,7 +1777,6 @@ int ED_view3d_context_activate(bContext *C) bScreen *sc= CTX_wm_screen(C); ScrArea *sa= CTX_wm_area(C); ARegion *ar; - RegionView3D *rv3d; /* sa can be NULL when called from python */ if(sa==NULL || sa->spacetype != SPACE_VIEW3D) @@ -1780,14 +1797,13 @@ int ED_view3d_context_activate(bContext *C) // bad context switch .. CTX_wm_area_set(C, sa); CTX_wm_region_set(C, ar); - rv3d= ar->regiondata; return 1; } static int game_engine_exec(bContext *C, wmOperator *op) { -#if GAMEBLENDER == 1 +#ifdef WITH_GAMEENGINE Scene *startscene = CTX_data_scene(C); ScrArea *sa, *prevsa= CTX_wm_area(C); ARegion *ar, *prevar= CTX_wm_region(C); @@ -1795,6 +1811,8 @@ static int game_engine_exec(bContext *C, wmOperator *op) RegionView3D *rv3d; rcti cam_frame; + (void)op; /* unused */ + // bad context switch .. if(!ED_view3d_context_activate(C)) return OPERATOR_CANCELLED; @@ -1809,7 +1827,7 @@ static int game_engine_exec(bContext *C, wmOperator *op) if(rv3d->persp==RV3D_CAMOB && startscene->gm.framing.type == SCE_GAMEFRAMING_BARS && startscene->gm.stereoflag != STEREO_DOME) { /* Letterbox */ rctf cam_framef; - view3d_calc_camera_border(startscene, ar, rv3d, CTX_wm_view3d(C), &cam_framef); + view3d_calc_camera_border(startscene, ar, rv3d, CTX_wm_view3d(C), &cam_framef, FALSE); cam_frame.xmin = cam_framef.xmin + ar->winrct.xmin; cam_frame.xmax = cam_framef.xmax + ar->winrct.xmin; cam_frame.ymin = cam_framef.ymin + ar->winrct.ymin; @@ -1824,16 +1842,25 @@ static int game_engine_exec(bContext *C, wmOperator *op) } - SaveState(C); + SaveState(C, prevwin); StartKetsjiShell(C, ar, &cam_frame, 1); + + /* window wasnt closed while the BGE was running */ + if(BLI_findindex(&CTX_wm_manager(C)->windows, prevwin) == -1) { + prevwin= NULL; + CTX_wm_window_set(C, NULL); + } - /* restore context, in case it changed in the meantime, for - example by working in another window or closing it */ - CTX_wm_region_set(C, prevar); - CTX_wm_window_set(C, prevwin); - CTX_wm_area_set(C, prevsa); - RestoreState(C); + if(prevwin) { + /* restore context, in case it changed in the meantime, for + example by working in another window or closing it */ + CTX_wm_region_set(C, prevar); + CTX_wm_window_set(C, prevwin); + CTX_wm_area_set(C, prevsa); + } + + RestoreState(C, prevwin); //XXX restore_all_scene_cfra(scene_cfra_store); set_scene_bg(CTX_data_main(C), startscene); @@ -1843,6 +1870,7 @@ static int game_engine_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; #else + (void)C; /* unused */ BKE_report(op->reports, RPT_ERROR, "Game engine is disabled in this build."); return OPERATOR_CANCELLED; #endif @@ -1862,852 +1890,6 @@ void VIEW3D_OT_game_start(wmOperatorType *ot) ot->poll= game_engine_poll; } - -/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */ -#define FLY_MODAL_CANCEL 1 -#define FLY_MODAL_CONFIRM 2 -#define FLY_MODAL_ACCELERATE 3 -#define FLY_MODAL_DECELERATE 4 -#define FLY_MODAL_PAN_ENABLE 5 -#define FLY_MODAL_PAN_DISABLE 6 -#define FLY_MODAL_DIR_FORWARD 7 -#define FLY_MODAL_DIR_BACKWARD 8 -#define FLY_MODAL_DIR_LEFT 9 -#define FLY_MODAL_DIR_RIGHT 10 -#define FLY_MODAL_DIR_UP 11 -#define FLY_MODAL_DIR_DOWN 12 -#define FLY_MODAL_AXIS_LOCK_X 13 -#define FLY_MODAL_AXIS_LOCK_Z 14 -#define FLY_MODAL_PRECISION_ENABLE 15 -#define FLY_MODAL_PRECISION_DISABLE 16 - -/* called in transform_ops.c, on each regeneration of keymaps */ -void fly_modal_keymap(wmKeyConfig *keyconf) -{ - static EnumPropertyItem modal_items[] = { - {FLY_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""}, - {FLY_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""}, - {FLY_MODAL_ACCELERATE, "ACCELERATE", 0, "Accelerate", ""}, - {FLY_MODAL_DECELERATE, "DECELERATE", 0, "Decelerate", ""}, - - {FLY_MODAL_PAN_ENABLE, "PAN_ENABLE", 0, "Pan Enable", ""}, - {FLY_MODAL_PAN_DISABLE, "PAN_DISABLE", 0, "Pan Disable", ""}, - - {FLY_MODAL_DIR_FORWARD, "FORWARD", 0, "Fly Forward", ""}, - {FLY_MODAL_DIR_BACKWARD,"BACKWARD", 0, "Fly Backward", ""}, - {FLY_MODAL_DIR_LEFT, "LEFT", 0, "Fly Left", ""}, - {FLY_MODAL_DIR_RIGHT, "RIGHT", 0, "Fly Right", ""}, - {FLY_MODAL_DIR_UP, "UP", 0, "Fly Up", ""}, - {FLY_MODAL_DIR_DOWN, "DOWN", 0, "Fly Down", ""}, - - {FLY_MODAL_AXIS_LOCK_X, "AXIS_LOCK_X", 0, "X Axis Correction", "X axis correction (toggle)"}, - {FLY_MODAL_AXIS_LOCK_Z, "AXIS_LOCK_Z", 0, "X Axis Correction", "Z axis correction (toggle)"}, - - {FLY_MODAL_PRECISION_ENABLE, "PRECISION_ENABLE", 0, "Precision Enable", ""}, - {FLY_MODAL_PRECISION_DISABLE, "PRECISION_DISABLE", 0, "Precision Disable", ""}, - - {0, NULL, 0, NULL, NULL}}; - - wmKeyMap *keymap= WM_modalkeymap_get(keyconf, "View3D Fly Modal"); - - /* this function is called for each spacetype, only needs to add map once */ - if(keymap) return; - - keymap= WM_modalkeymap_add(keyconf, "View3D Fly Modal", modal_items); - - /* items for modal map */ - WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_CANCEL); - WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_ANY, KM_ANY, 0, FLY_MODAL_CANCEL); - - WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_ANY, KM_ANY, 0, FLY_MODAL_CONFIRM); - WM_modalkeymap_add_item(keymap, RETKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_CONFIRM); - WM_modalkeymap_add_item(keymap, SPACEKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_CONFIRM); - WM_modalkeymap_add_item(keymap, PADENTER, KM_PRESS, KM_ANY, 0, FLY_MODAL_CONFIRM); - - WM_modalkeymap_add_item(keymap, PADPLUSKEY, KM_PRESS, 0, 0, FLY_MODAL_ACCELERATE); - WM_modalkeymap_add_item(keymap, PADMINUS, KM_PRESS, 0, 0, FLY_MODAL_DECELERATE); - WM_modalkeymap_add_item(keymap, WHEELUPMOUSE, KM_PRESS, 0, 0, FLY_MODAL_ACCELERATE); - WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, 0, 0, FLY_MODAL_DECELERATE); - - WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_PAN_ENABLE); - WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, FLY_MODAL_PAN_DISABLE); /* XXX - Bug in the event system, middle mouse release doesnt work */ - - /* WASD */ - WM_modalkeymap_add_item(keymap, WKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_FORWARD); - WM_modalkeymap_add_item(keymap, SKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_BACKWARD); - WM_modalkeymap_add_item(keymap, AKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_LEFT); - WM_modalkeymap_add_item(keymap, DKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_RIGHT); - WM_modalkeymap_add_item(keymap, RKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_UP); - WM_modalkeymap_add_item(keymap, FKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_DOWN); - - WM_modalkeymap_add_item(keymap, XKEY, KM_PRESS, 0, 0, FLY_MODAL_AXIS_LOCK_X); - WM_modalkeymap_add_item(keymap, ZKEY, KM_PRESS, 0, 0, FLY_MODAL_AXIS_LOCK_Z); - - WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_PRECISION_ENABLE); - WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_RELEASE, KM_ANY, 0, FLY_MODAL_PRECISION_DISABLE); - - /* assign map to operators */ - WM_modalkeymap_assign(keymap, "VIEW3D_OT_fly"); - -} - -typedef struct FlyInfo { - /* context stuff */ - RegionView3D *rv3d; - View3D *v3d; - ARegion *ar; - Scene *scene; - - wmTimer *timer; /* needed for redraws */ - - short state; - short use_precision; - short redraw; - short mval[2]; - - /* fly state state */ - float speed; /* the speed the view is moving per redraw */ - short axis; /* Axis index to move allong by default Z to move allong the view */ - short pan_view; /* when true, pan the view instead of rotating */ - - /* relative view axis locking - xlock, zlock - 0; disabled - 1; enabled but not checking because mouse hasnt moved outside the margin since locking was checked an not needed - when the mouse moves, locking is set to 2 so checks are done. - 2; mouse moved and checking needed, if no view altering is donem its changed back to 1 */ - short xlock, zlock; - float xlock_momentum, zlock_momentum; /* nicer dynamics */ - float grid; /* world scale 1.0 default */ - - /* root most parent */ - Object *root_parent; - - /* backup values */ - float dist_backup; /* backup the views distance since we use a zero dist for fly mode */ - float ofs_backup[3]; /* backup the views offset incase the user cancels flying in non camera mode */ - float rot_backup[4]; /* backup the views quat incase the user cancels flying in non camera mode. (quat for view, eul for camera) */ - short persp_backup; /* remember if were ortho or not, only used for restoring the view if it was a ortho view */ - - void *obtfm; /* backup the objects transform */ - - /* compare between last state */ - double time_lastwheel; /* used to accelerate when using the mousewheel a lot */ - double time_lastdraw; /* time between draws */ - - /* use for some lag */ - float dvec_prev[3]; /* old for some lag */ - -} FlyInfo; - -/* FlyInfo->state */ -#define FLY_RUNNING 0 -#define FLY_CANCEL 1 -#define FLY_CONFIRM 2 - -static int initFlyInfo (bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *event) -{ - float upvec[3]; // tmp - float mat[3][3]; - - fly->rv3d= CTX_wm_region_view3d(C); - fly->v3d = CTX_wm_view3d(C); - fly->ar = CTX_wm_region(C); - fly->scene= CTX_data_scene(C); - - if(fly->rv3d->persp==RV3D_CAMOB && fly->v3d->camera->id.lib) { - BKE_report(op->reports, RPT_ERROR, "Cannot fly a camera from an external library"); - return FALSE; - } - - if(fly->v3d->ob_centre) { - BKE_report(op->reports, RPT_ERROR, "Cannot fly when the view is locked to an object"); - return FALSE; - } - - if(fly->rv3d->persp==RV3D_CAMOB && fly->v3d->camera->constraints.first) { - BKE_report(op->reports, RPT_ERROR, "Cannot fly an object with constraints"); - return FALSE; - } - - fly->state= FLY_RUNNING; - fly->speed= 0.0f; - fly->axis= 2; - fly->pan_view= FALSE; - fly->xlock= FALSE; - fly->zlock= FALSE; - fly->xlock_momentum=0.0f; - fly->zlock_momentum=0.0f; - fly->grid= 1.0f; - fly->use_precision= 0; - - fly->dvec_prev[0]= fly->dvec_prev[1]= fly->dvec_prev[2]= 0.0f; - - fly->timer= WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f); - - fly->mval[0] = event->x - fly->ar->winrct.xmin; - fly->mval[1] = event->y - fly->ar->winrct.ymin; - - - fly->time_lastdraw= fly->time_lastwheel= PIL_check_seconds_timer(); - - fly->rv3d->rflag |= RV3D_FLYMODE|RV3D_NAVIGATING; /* so we draw the corner margins */ - - /* detect weather to start with Z locking */ - upvec[0]=1.0f; upvec[1]=0.0f; upvec[2]=0.0f; - copy_m3_m4(mat, fly->rv3d->viewinv); - mul_m3_v3(mat, upvec); - if (fabs(upvec[2]) < 0.1) - fly->zlock = 1; - upvec[0]=0; upvec[1]=0; upvec[2]=0; - - fly->persp_backup= fly->rv3d->persp; - fly->dist_backup= fly->rv3d->dist; - if (fly->rv3d->persp==RV3D_CAMOB) { - Object *ob_back; - if((fly->root_parent=fly->v3d->camera->parent)) { - while(fly->root_parent->parent) - fly->root_parent= fly->root_parent->parent; - ob_back= fly->root_parent; - } - else { - ob_back= fly->v3d->camera; - } - - /* store the original camera loc and rot */ - /* TODO. axis angle etc */ - - fly->obtfm= object_tfm_backup(ob_back); - - where_is_object(fly->scene, fly->v3d->camera); - negate_v3_v3(fly->rv3d->ofs, fly->v3d->camera->obmat[3]); - - fly->rv3d->dist=0.0; - } else { - /* perspective or ortho */ - if (fly->rv3d->persp==RV3D_ORTHO) - fly->rv3d->persp= RV3D_PERSP; /*if ortho projection, make perspective */ - copy_qt_qt(fly->rot_backup, fly->rv3d->viewquat); - copy_v3_v3(fly->ofs_backup, fly->rv3d->ofs); - fly->rv3d->dist= 0.0f; - - upvec[2]= fly->dist_backup; /*x and y are 0*/ - mul_m3_v3(mat, upvec); - sub_v3_v3(fly->rv3d->ofs, upvec); - /*Done with correcting for the dist*/ - } - - - /* center the mouse, probably the UI mafia are against this but without its quite annoying */ - WM_cursor_warp(CTX_wm_window(C), fly->ar->winrct.xmin + fly->ar->winx/2, fly->ar->winrct.ymin + fly->ar->winy/2); - - return 1; -} - -static int flyEnd(bContext *C, FlyInfo *fly) -{ - RegionView3D *rv3d= fly->rv3d; - View3D *v3d = fly->v3d; - - float upvec[3]; - - if(fly->state == FLY_RUNNING) - return OPERATOR_RUNNING_MODAL; - - WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), fly->timer); - - rv3d->dist= fly->dist_backup; - - if (fly->state == FLY_CANCEL) { - /* Revert to original view? */ - if (fly->persp_backup==RV3D_CAMOB) { /* a camera view */ - Object *ob_back; - if(fly->root_parent)ob_back= fly->root_parent; - else ob_back= fly->v3d->camera; - - /* store the original camera loc and rot */ - object_tfm_restore(ob_back, fly->obtfm); - - DAG_id_flush_update(&ob_back->id, OB_RECALC_OB); - } else { - /* Non Camera we need to reset the view back to the original location bacause the user canceled*/ - copy_qt_qt(rv3d->viewquat, fly->rot_backup); - copy_v3_v3(rv3d->ofs, fly->ofs_backup); - rv3d->persp= fly->persp_backup; - } - } - else if (fly->persp_backup==RV3D_CAMOB) { /* camera */ - float mat3[3][3]; - if(fly->root_parent) { - DAG_id_flush_update(&fly->root_parent->id, OB_RECALC_OB); - } - else { - copy_m3_m4(mat3, v3d->camera->obmat); - object_mat3_to_rot(v3d->camera, mat3, TRUE); - DAG_id_flush_update(&v3d->camera->id, OB_RECALC_OB); - } - -#if 0 //XXX2.5 - if (IS_AUTOKEY_MODE(NORMAL)) { - allqueue(REDRAWIPO, 0); - allspace(REMAKEIPO, 0); - allqueue(REDRAWNLA, 0); - allqueue(REDRAWTIME, 0); - } -#endif - } - else { /* not camera */ - /* Apply the fly mode view */ - /*restore the dist*/ - float mat[3][3]; - upvec[0]= upvec[1]= 0; - upvec[2]= fly->dist_backup; /*x and y are 0*/ - copy_m3_m4(mat, rv3d->viewinv); - mul_m3_v3(mat, upvec); - add_v3_v3(rv3d->ofs, upvec); - /*Done with correcting for the dist */ - } - - rv3d->rflag &= ~(RV3D_FLYMODE|RV3D_NAVIGATING); -//XXX2.5 BIF_view3d_previewrender_signal(fly->sa, PR_DBASE|PR_DISPRECT); /* not working at the moment not sure why */ - - if(fly->obtfm) - MEM_freeN(fly->obtfm); - - if(fly->state == FLY_CONFIRM) { - MEM_freeN(fly); - return OPERATOR_FINISHED; - } - - MEM_freeN(fly); - return OPERATOR_CANCELLED; -} - -static void flyEvent(FlyInfo *fly, wmEvent *event) -{ - if (event->type == TIMER && event->customdata == fly->timer) { - fly->redraw = 1; - } - else if (event->type == MOUSEMOVE) { - fly->mval[0] = event->x - fly->ar->winrct.xmin; - fly->mval[1] = event->y - fly->ar->winrct.ymin; - } /* handle modal keymap first */ - else if (event->type == EVT_MODAL_MAP) { - switch (event->val) { - case FLY_MODAL_CANCEL: - fly->state = FLY_CANCEL; - break; - case FLY_MODAL_CONFIRM: - fly->state = FLY_CONFIRM; - break; - - case FLY_MODAL_ACCELERATE: - { - double time_currwheel; - float time_wheel; - - time_currwheel= PIL_check_seconds_timer(); - time_wheel = (float)(time_currwheel - fly->time_lastwheel); - fly->time_lastwheel = time_currwheel; - /*printf("Wheel %f\n", time_wheel);*/ - /*Mouse wheel delays range from 0.5==slow to 0.01==fast*/ - time_wheel = 1+ (10 - (20*MIN2(time_wheel, 0.5))); /* 0-0.5 -> 0-5.0 */ - - if (fly->speed<0.0f) fly->speed= 0.0f; - else { - if (event->shift) - fly->speed+= fly->grid*time_wheel*0.1; - else - fly->speed+= fly->grid*time_wheel; - } - break; - } - case FLY_MODAL_DECELERATE: - { - double time_currwheel; - float time_wheel; - - time_currwheel= PIL_check_seconds_timer(); - time_wheel = (float)(time_currwheel - fly->time_lastwheel); - fly->time_lastwheel = time_currwheel; - time_wheel = 1+ (10 - (20*MIN2(time_wheel, 0.5))); /* 0-0.5 -> 0-5.0 */ - - if (fly->speed>0) fly->speed=0; - else { - if (event->shift) - fly->speed-= fly->grid*time_wheel*0.1; - else - fly->speed-= fly->grid*time_wheel; - } - break; - } - case FLY_MODAL_PAN_ENABLE: - fly->pan_view= TRUE; - break; - case FLY_MODAL_PAN_DISABLE: -//XXX2.5 warp_pointer(cent_orig[0], cent_orig[1]); - fly->pan_view= FALSE; - break; - - /* impliment WASD keys */ - case FLY_MODAL_DIR_FORWARD: - if (fly->speed < 0.0f) fly->speed= -fly->speed; /* flip speed rather then stopping, game like motion */ - else fly->speed += fly->grid; /* increse like mousewheel if were already moving in that difection*/ - fly->axis= 2; - break; - case FLY_MODAL_DIR_BACKWARD: - if (fly->speed>0) fly->speed= -fly->speed; - else fly->speed -= fly->grid; - fly->axis= 2; - break; - case FLY_MODAL_DIR_LEFT: - if (fly->speed < 0.0f) fly->speed= -fly->speed; - fly->axis= 0; - break; - case FLY_MODAL_DIR_RIGHT: - if (fly->speed > 0.0f) fly->speed= -fly->speed; - fly->axis= 0; - break; - - case FLY_MODAL_DIR_UP: - if (fly->speed > 0.0f) fly->speed= -fly->speed; - fly->axis= 1; - break; - - case FLY_MODAL_DIR_DOWN: - if (fly->speed < 0.0f) fly->speed= -fly->speed; - fly->axis= 1; - break; - - case FLY_MODAL_AXIS_LOCK_X: - if (fly->xlock) fly->xlock=0; - else { - fly->xlock = 2; - fly->xlock_momentum = 0.0; - } - break; - case FLY_MODAL_AXIS_LOCK_Z: - if (fly->zlock) fly->zlock=0; - else { - fly->zlock = 2; - fly->zlock_momentum = 0.0; - } - break; - - case FLY_MODAL_PRECISION_ENABLE: - fly->use_precision= TRUE; - break; - case FLY_MODAL_PRECISION_DISABLE: - fly->use_precision= FALSE; - break; - - } - } -} - -static int flyApply(bContext *C, FlyInfo *fly) -{ - -#define FLY_ROTATE_FAC 2.5f /* more is faster */ -#define FLY_ZUP_CORRECT_FAC 0.1f /* ammount to correct per step */ -#define FLY_ZUP_CORRECT_ACCEL 0.05f /* increase upright momentum each step */ - - /* - fly mode - Shift+F - a fly loop where the user can move move the view as if they are flying - */ - RegionView3D *rv3d= fly->rv3d; - View3D *v3d = fly->v3d; - ARegion *ar = fly->ar; - Scene *scene= fly->scene; - - float prev_view_mat[4][4]; - - float mat[3][3], /* 3x3 copy of the view matrix so we can move allong the view axis */ - dvec[3]={0,0,0}, /* this is the direction thast added to the view offset per redraw */ - - /* Camera Uprighting variables */ - upvec[3]={0,0,0}, /* stores the view's up vector */ - - moffset[2], /* mouse offset from the views center */ - tmp_quat[4]; /* used for rotating the view */ - - int cent_orig[2], /* view center */ -//XXX- can avoid using // cent[2], /* view center modified */ - xmargin, ymargin; /* x and y margin are define the safe area where the mouses movement wont rotate the view */ - unsigned char - apply_rotation= 1; /* if the user presses shift they can look about without movinf the direction there looking*/ - - if(fly->root_parent) - view3d_persp_mat4(rv3d, prev_view_mat); - - /* the dist defines a vector that is infront of the offset - to rotate the view about. - this is no good for fly mode because we - want to rotate about the viewers center. - but to correct the dist removal we must - alter offset so the view doesn't jump. */ - - xmargin= ar->winx/20.0f; - ymargin= ar->winy/20.0f; - - cent_orig[0]= ar->winrct.xmin + ar->winx/2; - cent_orig[1]= ar->winrct.ymin + ar->winy/2; - - { - - /* mouse offset from the center */ - moffset[0]= fly->mval[0]- ar->winx/2; - moffset[1]= fly->mval[1]- ar->winy/2; - - /* enforce a view margin */ - if (moffset[0]>xmargin) moffset[0]-=xmargin; - else if (moffset[0] < -xmargin) moffset[0]+=xmargin; - else moffset[0]=0; - - if (moffset[1]>ymargin) moffset[1]-=ymargin; - else if (moffset[1] < -ymargin) moffset[1]+=ymargin; - else moffset[1]=0; - - - /* scale the mouse movement by this value - scales mouse movement to the view size - * moffset[0]/(ar->winx-xmargin*2) - window size minus margin (same for y) - * - * the mouse moves isnt linear */ - - if(moffset[0]) { - moffset[0] /= ar->winx - (xmargin*2); - moffset[0] *= fabs(moffset[0]); - } - - if(moffset[1]) { - moffset[1] /= ar->winy - (ymargin*2); - moffset[1] *= fabs(moffset[1]); - } - - /* Should we redraw? */ - if(fly->speed != 0.0f || moffset[0] || moffset[1] || fly->zlock || fly->xlock || dvec[0] || dvec[1] || dvec[2] ) { - float dvec_tmp[3]; - double time_current, time_redraw; /*time how fast it takes for us to redraw, this is so simple scenes dont fly too fast */ - float time_redraw_clamped; - - time_current= PIL_check_seconds_timer(); - time_redraw= (float)(time_current - fly->time_lastdraw); - time_redraw_clamped= MIN2(0.05f, time_redraw); /* clamt the redraw time to avoid jitter in roll correction */ - fly->time_lastdraw= time_current; - /*fprintf(stderr, "%f\n", time_redraw);*/ /* 0.002 is a small redraw 0.02 is larger */ - - /* Scale the time to use shift to scale the speed down- just like - shift slows many other areas of blender down */ - if (fly->use_precision) - fly->speed= fly->speed * (1.0f-time_redraw_clamped); - - copy_m3_m4(mat, rv3d->viewinv); - - if (fly->pan_view==TRUE) { - /* pan only */ - dvec_tmp[0]= -moffset[0]; - dvec_tmp[1]= -moffset[1]; - dvec_tmp[2]= 0; - - if (fly->use_precision) { - dvec_tmp[0] *= 0.1; - dvec_tmp[1] *= 0.1; - } - - mul_m3_v3(mat, dvec_tmp); - mul_v3_fl(dvec_tmp, time_redraw*200.0 * fly->grid); - - } else { - float roll; /* similar to the angle between the camera's up and the Z-up, but its very rough so just roll*/ - - /* rotate about the X axis- look up/down */ - if (moffset[1]) { - upvec[0]=1; - upvec[1]=0; - upvec[2]=0; - mul_m3_v3(mat, upvec); - axis_angle_to_quat( tmp_quat, upvec, (float)moffset[1] * time_redraw * -FLY_ROTATE_FAC); /* Rotate about the relative up vec */ - mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat); - - if (fly->xlock) fly->xlock = 2; /*check for rotation*/ - if (fly->zlock) fly->zlock = 2; - fly->xlock_momentum= 0.0f; - } - - /* rotate about the Y axis- look left/right */ - if (moffset[0]) { - - /* if we're upside down invert the moffset */ - upvec[0]=0; - upvec[1]=1; - upvec[2]=0; - mul_m3_v3(mat, upvec); - - if(upvec[2] < 0.0f) - moffset[0]= -moffset[0]; - - /* make the lock vectors */ - if (fly->zlock) { - upvec[0]=0; - upvec[1]=0; - upvec[2]=1; - } else { - upvec[0]=0; - upvec[1]=1; - upvec[2]=0; - mul_m3_v3(mat, upvec); - } - - axis_angle_to_quat( tmp_quat, upvec, (float)moffset[0] * time_redraw * FLY_ROTATE_FAC); /* Rotate about the relative up vec */ - mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat); - - if (fly->xlock) fly->xlock = 2;/*check for rotation*/ - if (fly->zlock) fly->zlock = 2; - } - - if (fly->zlock==2) { - upvec[0]=1; - upvec[1]=0; - upvec[2]=0; - mul_m3_v3(mat, upvec); - - /*make sure we have some z rolling*/ - if (fabs(upvec[2]) > 0.00001f) { - roll= upvec[2]*5; - upvec[0]=0; /*rotate the view about this axis*/ - upvec[1]=0; - upvec[2]=1; - - mul_m3_v3(mat, upvec); - axis_angle_to_quat( tmp_quat, upvec, roll*time_redraw_clamped*fly->zlock_momentum * FLY_ZUP_CORRECT_FAC); /* Rotate about the relative up vec */ - mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat); - - fly->zlock_momentum += FLY_ZUP_CORRECT_ACCEL; - } else { - fly->zlock=1; /* dont check until the view rotates again */ - fly->zlock_momentum= 0.0f; - } - } - - if (fly->xlock==2 && moffset[1]==0) { /*only apply xcorrect when mouse isnt applying x rot*/ - upvec[0]=0; - upvec[1]=0; - upvec[2]=1; - mul_m3_v3(mat, upvec); - /*make sure we have some z rolling*/ - if (fabs(upvec[2]) > 0.00001) { - roll= upvec[2] * -5; - - upvec[0]= 1.0f; /*rotate the view about this axis*/ - upvec[1]= 0.0f; - upvec[2]= 0.0f; - - mul_m3_v3(mat, upvec); - - axis_angle_to_quat( tmp_quat, upvec, roll*time_redraw_clamped*fly->xlock_momentum*0.1f); /* Rotate about the relative up vec */ - mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat); - - fly->xlock_momentum += 0.05f; - } else { - fly->xlock=1; /* see above */ - fly->xlock_momentum= 0.0f; - } - } - - - if (apply_rotation) { - /* Normal operation */ - /* define dvec, view direction vector */ - dvec_tmp[0]= dvec_tmp[1]= dvec_tmp[2]= 0.0f; - /* move along the current axis */ - dvec_tmp[fly->axis]= 1.0f; - - mul_m3_v3(mat, dvec_tmp); - - mul_v3_fl(dvec_tmp, fly->speed * time_redraw * 0.25f); - } - } - - /* impose a directional lag */ - interp_v3_v3v3(dvec, dvec_tmp, fly->dvec_prev, (1.0f/(1.0f+(time_redraw*5.0f)))); - - if (rv3d->persp==RV3D_CAMOB) { - Object *lock_ob= fly->root_parent ? fly->root_parent : fly->v3d->camera; - if (lock_ob->protectflag & OB_LOCK_LOCX) dvec[0] = 0.0; - if (lock_ob->protectflag & OB_LOCK_LOCY) dvec[1] = 0.0; - if (lock_ob->protectflag & OB_LOCK_LOCZ) dvec[2] = 0.0; - } - - add_v3_v3(rv3d->ofs, dvec); - - /* todo, dynamic keys */ -#if 0 - if (fly->zlock && fly->xlock) - ED_area_headerprint(fly->ar, "FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB"); - else if (fly->zlock) - ED_area_headerprint(fly->ar, "FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB"); - else if (fly->xlock) - ED_area_headerprint(fly->ar, "FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB"); - else - ED_area_headerprint(fly->ar, "FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB"); -#endif - - /* we are in camera view so apply the view ofs and quat to the view matrix and set the camera to the view */ - if (rv3d->persp==RV3D_CAMOB) { - ID *id_key; - /* transform the parent or the camera? */ - if(fly->root_parent) { - Object *ob_update; - - float view_mat[4][4]; - float prev_view_imat[4][4]; - float diff_mat[4][4]; - float parent_mat[4][4]; - - invert_m4_m4(prev_view_imat, prev_view_mat); - view3d_persp_mat4(rv3d, view_mat); - mul_m4_m4m4(diff_mat, prev_view_imat, view_mat); - mul_m4_m4m4(parent_mat, fly->root_parent->obmat, diff_mat); - object_apply_mat4(fly->root_parent, parent_mat); - - // where_is_object(scene, fly->root_parent); - - ob_update= v3d->camera->parent; - while(ob_update) { - DAG_id_flush_update(&ob_update->id, OB_RECALC_OB); - ob_update= ob_update->parent; - } - - copy_m4_m4(prev_view_mat, view_mat); - - id_key= &fly->root_parent->id; - - } - else { - float view_mat[4][4]; - view3d_persp_mat4(rv3d, view_mat); - object_apply_mat4(v3d->camera, view_mat); - id_key= &v3d->camera->id; - } - - /* record the motion */ - if (autokeyframe_cfra_can_key(scene, id_key)) { - ListBase dsources = {NULL, NULL}; - - /* add datasource override for the camera object */ - ANIM_relative_keyingset_add_source(&dsources, id_key, NULL, NULL); - - /* insert keyframes - * 1) on the first frame - * 2) on each subsequent frame - * TODO: need to check in future that frame changed before doing this - */ - if (fly->xlock || fly->zlock || moffset[0] || moffset[1]) { - KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Rotation"); - ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA); - } - if (fly->speed) { - KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Location"); - ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA); - } - - /* free temp data */ - BLI_freelistN(&dsources); - } - } - } else - /*were not redrawing but we need to update the time else the view will jump */ - fly->time_lastdraw= PIL_check_seconds_timer(); - /* end drawing */ - copy_v3_v3(fly->dvec_prev, dvec); - } - -/* moved to flyEnd() */ - - return OPERATOR_FINISHED; -} - - - -static int fly_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - RegionView3D *rv3d= CTX_wm_region_view3d(C); - FlyInfo *fly; - - if(rv3d->viewlock) - return OPERATOR_CANCELLED; - - fly= MEM_callocN(sizeof(FlyInfo), "FlyOperation"); - - op->customdata= fly; - - if(initFlyInfo(C, fly, op, event)==FALSE) { - MEM_freeN(op->customdata); - return OPERATOR_CANCELLED; - } - - flyEvent(fly, event); - - WM_event_add_modal_handler(C, op); - - return OPERATOR_RUNNING_MODAL; -} - -static int fly_cancel(bContext *C, wmOperator *op) -{ - FlyInfo *fly = op->customdata; - - fly->state = FLY_CANCEL; - flyEnd(C, fly); - op->customdata= NULL; - - return OPERATOR_CANCELLED; -} - -static int fly_modal(bContext *C, wmOperator *op, wmEvent *event) -{ - int exit_code; - - FlyInfo *fly = op->customdata; - - fly->redraw= 0; - - flyEvent(fly, event); - - if(event->type==TIMER && event->customdata == fly->timer) - flyApply(C, fly); - - if(fly->redraw) { - ED_region_tag_redraw(CTX_wm_region(C)); - } - - exit_code = flyEnd(C, fly); - - if(exit_code!=OPERATOR_RUNNING_MODAL) - ED_region_tag_redraw(CTX_wm_region(C)); - - return exit_code; -} - -void VIEW3D_OT_fly(wmOperatorType *ot) -{ - - /* identifiers */ - ot->name= "Fly Navigation"; - ot->description= "Interactively fly around the scene"; - ot->idname= "VIEW3D_OT_fly"; - - /* api callbacks */ - ot->invoke= fly_invoke; - ot->cancel= fly_cancel; - ot->modal= fly_modal; - ot->poll= ED_operator_view3d_active; - - /* flags */ - ot->flag= OPTYPE_BLOCKING; - -} - /* ************************************** */ void view3d_align_axis_to_vector(View3D *v3d, RegionView3D *rv3d, int axisidx, float vec[3]) @@ -2743,3 +1925,16 @@ void view3d_align_axis_to_vector(View3D *v3d, RegionView3D *rv3d, int axisidx, f } } +int view3d_is_ortho(View3D *v3d, RegionView3D *rv3d) +{ + return (rv3d->persp == RV3D_ORTHO || (v3d->camera && ((Camera *)v3d->camera->data)->type == CAM_ORTHO)); +} + +float view3d_pixel_size(struct RegionView3D *rv3d, const float co[3]) +{ + return (rv3d->persmat[3][3] + ( + rv3d->persmat[0][3]*co[0] + + rv3d->persmat[1][3]*co[1] + + rv3d->persmat[2][3]*co[2]) + ) * rv3d->pixsize; +} |