diff options
author | Joseph Eagar <joeedh@gmail.com> | 2009-01-09 21:32:33 +0300 |
---|---|---|
committer | Joseph Eagar <joeedh@gmail.com> | 2009-01-09 21:32:33 +0300 |
commit | dbe6735ae5a33f9763e1eb58478bb562e421f65b (patch) | |
tree | 5ba1d86f8083a2858da0fe9b7b44022eed8282a9 /source/blender/editors | |
parent | 4746ada4e3618834103f392a1dc9bfcba159f80d (diff) | |
parent | e60be63d23bce8c8fe9b749a17c1f3dc3fd56711 (diff) |
merge with 2.5 at revision 18432, made bmesh compile, and also made msvc use incremental linking under scons
Diffstat (limited to 'source/blender/editors')
44 files changed, 4753 insertions, 657 deletions
diff --git a/source/blender/editors/armature/SConscript b/source/blender/editors/armature/SConscript index 95f20404c4b..e4e42a27b36 100644 --- a/source/blender/editors/armature/SConscript +++ b/source/blender/editors/armature/SConscript @@ -8,4 +8,4 @@ incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' incs += ' ../../render/extern/include #/intern/guardedalloc #intern/bmfont' incs += ' ../../gpu ../../makesrna #/intern/opennl/extern' -env.BlenderLib ( 'bf_editors_armature', sources, Split(incs), [], libtype=['core'], priority=[100] ) +env.BlenderLib ( 'bf_editors_armature', sources, Split(incs), [], libtype=['core'], priority=[44] ) diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 42d3629e3dd..06855d4446d 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -101,12 +101,8 @@ static void adduplicate() {} static void countall() {} static void vertexgroup_select_by_name() {} static void deselect_actionchannels() {} -static void *add_defgroup_name() {return NULL;} static void add_vert_to_defgroup() {} -#define WEIGHT_REPLACE 0 static void create_dverts() {} -static void remove_vert_defgroup() {} -static int mesh_get_x_mirror_vert() {return 0;} static void select_actionchannel_by_name() {} /* ************* XXX *************** */ @@ -1834,7 +1830,7 @@ void ED_armature_to_edit(Object *ob) /* adjust bone roll to align Z axis with vector * vec is in local space and is normalized */ -float rollBoneToVector(EditBone *bone, float new_up_axis[3]) +float ED_rollBoneToVector(EditBone *bone, float new_up_axis[3]) { float mat[3][3], nor[3], up_axis[3], vec[3]; float roll; diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 457e0741399..17d6b25b93b 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -92,6 +92,9 @@ int ED_do_pose_selectbuffer(struct Scene *scene, struct Base *base, unsigned int short hits, short extend); void mouse_armature(struct bContext *C, short mval[2], int extend); +float ED_rollBoneToVector(EditBone *bone, float new_up_axis[3]); + +void transform_armature_mirror_update(struct Object *obedit); /* poseobject.c */ void ED_armature_exit_posemode(struct Base *base); diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h index c62990a69d9..c0efaab3786 100644 --- a/source/blender/editors/include/ED_fileselect.h +++ b/source/blender/editors/include/ED_fileselect.h @@ -28,6 +28,8 @@ #ifndef ED_FILES_H #define ED_FILES_H +struct SpaceFile; + typedef struct FileSelectParams { int type; /* the mode of the filebrowser, FILE_BLENDER, FILE_SPECIAL, FILE_MAIN or FILE_LOADLIB */ char title[24]; /* title, also used for the text of the execute button */ @@ -53,10 +55,12 @@ typedef struct FileSelectParams { /* XXX --- end unused -- */ } FileSelectParams; -FileSelectParams* ED_fileselect_get_params(const struct bContext *C); +FileSelectParams* ED_fileselect_get_params(struct SpaceFile *sfile); -short ED_fileselect_set_params(FileSelectParams *params, int type, const char *title, const char *path, +short ED_fileselect_set_params(struct SpaceFile *sfile, int type, const char *title, const char *path, short flag, short display, short filter); +void ED_fileselect_reset_params(struct SpaceFile *sfile); + #endif /* ED_FILES_H */ diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index e89bdff5325..02419b9aca9 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -38,6 +38,9 @@ struct bContext; struct wmWindowManager; struct EditSelection; struct ViewContext; +struct bDeformGroup; +struct MDeformWeight; +struct MDeformVert; // edge and face flag both #define EM_FGON 2 @@ -64,6 +67,7 @@ struct ViewContext; intptr_t mesh_octree_table(Object *ob, struct EditMesh *em, float *co, char mode); struct EditVert *editmesh_get_x_mirror_vert(Object *ob, struct EditMesh *em, float *co); +int mesh_get_x_mirror_vert(Object *ob, int index); /* mesh_ops.c */ void ED_operatortypes_mesh(void); @@ -119,6 +123,20 @@ void EM_free_backbuf(void); int EM_init_backbuf_border(struct ViewContext *vc, short xmin, short ymin, short xmax, short ymax); int EM_init_backbuf_circle(struct ViewContext *vc, short xs, short ys, short rads); +/* editdeform.c XXX rename functions? */ + +#define WEIGHT_REPLACE 1 +#define WEIGHT_ADD 2 +#define WEIGHT_SUBTRACT 3 + +void add_defgroup (Object *ob); +void remove_vert_defgroup (Object *ob, struct bDeformGroup *dg, int vertnum); +void remove_verts_defgroup (Object *obedit, int allverts); +struct bDeformGroup *add_defgroup_name (Object *ob, char *name); +struct MDeformWeight *verify_defweight (struct MDeformVert *dv, int defgroup); +struct MDeformWeight *get_defweight (struct MDeformVert *dv, int defgroup); +bDeformGroup *add_defgroup_name (Object *ob, char *name); + #endif /* ED_MESH_H */ diff --git a/source/blender/editors/include/ED_space_api.h b/source/blender/editors/include/ED_space_api.h index b705c050aa3..20b1e2b5499 100644 --- a/source/blender/editors/include/ED_space_api.h +++ b/source/blender/editors/include/ED_space_api.h @@ -29,6 +29,9 @@ #ifndef ED_SPACE_API_H #define ED_SPACE_API_H +struct ARegionType; +struct bContext; + /* the pluginnable API for export to editors */ /* calls for registering default spaces */ @@ -54,5 +57,14 @@ void ED_spacetype_sequencer(void); void ED_file_init(void); void ED_file_exit(void); +#define REGION_DRAW_PRE 1 +#define REGION_DRAW_POST 0 + +void *ED_region_draw_cb_activate(struct ARegionType *, + void (*draw)(const struct bContext *, struct ARegion *), + int type); +void ED_region_draw_cb_draw(const struct bContext *, struct ARegion *, int); +void ED_region_draw_cb_exit(struct ARegionType *, void *); + #endif /* ED_SPACE_API_H */ diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 7b3b31cbe30..60a5ff8481e 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -40,6 +40,7 @@ struct EditEdge; struct EditFace; struct ImBuf; struct Scene; +struct bContext; /* for derivedmesh drawing callbacks, for view3d_select, .... */ typedef struct ViewContext { @@ -60,6 +61,8 @@ typedef struct VPaint { int tot, pad; /* allocation size of prev buffers */ unsigned int *vpaint_prev; /* previous mesh colors */ struct MDeformVert *wpaint_prev; /* previous vertex weights */ + + void *paintcursor; /* wm handle */ } VPaint; /* Gvp.flag and Gwp.flag */ @@ -112,6 +115,9 @@ unsigned int view3d_sample_backbuf(struct ViewContext *vc, int x, int y); #define MAXPICKBUF 10000 short view3d_opengl_select(struct ViewContext *vc, unsigned int *buffer, unsigned int bufsize, rcti *input); +/* modes */ +void ED_view3d_exit_paint_modes(struct bContext *C); + #endif /* ED_VIEW3D_H */ diff --git a/source/blender/editors/interface/keyval.c b/source/blender/editors/interface/keyval.c new file mode 100644 index 00000000000..f2172ac8cf0 --- /dev/null +++ b/source/blender/editors/interface/keyval.c @@ -0,0 +1,540 @@ +/** + * $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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "stdio.h" +#include "ctype.h" +#include "string.h" + +#include "BKE_global.h" +#include "BLI_blenlib.h" +#include "BLI_arithb.h" + +#include "WM_types.h" + +char *key_event_to_string(unsigned short event) +{ + + switch(event) { + case AKEY: + return "A"; + break; + case BKEY: + return "B"; + break; + case CKEY: + return "C"; + break; + case DKEY: + return "D"; + break; + case EKEY: + return "E"; + break; + case FKEY: + return "F"; + break; + case GKEY: + return "G"; + break; + case HKEY: + return "H"; + break; + case IKEY: + return "I"; + break; + case JKEY: + return "J"; + break; + case KKEY: + return "K"; + break; + case LKEY: + return "L"; + break; + case MKEY: + return "M"; + break; + case NKEY: + return "N"; + break; + case OKEY: + return "O"; + break; + case PKEY: + return "P"; + break; + case QKEY: + return "Q"; + break; + case RKEY: + return "R"; + break; + case SKEY: + return "S"; + break; + case TKEY: + return "T"; + break; + case UKEY: + return "U"; + break; + case VKEY: + return "V"; + break; + case WKEY: + return "W"; + break; + case XKEY: + return "X"; + break; + case YKEY: + return "Y"; + break; + case ZKEY: + return "Z"; + break; + + case ZEROKEY: + return "Zero"; + break; + case ONEKEY: + return "One"; + break; + case TWOKEY: + return "Two"; + break; + case THREEKEY: + return "Three"; + break; + case FOURKEY: + return "Four"; + break; + case FIVEKEY: + return "Five"; + break; + case SIXKEY: + return "Six"; + break; + case SEVENKEY: + return "Seven"; + break; + case EIGHTKEY: + return "Eight"; + break; + case NINEKEY: + return "Nine"; + break; + + case LEFTCTRLKEY: + return "Leftctrl"; + break; + case LEFTALTKEY: + return "Leftalt"; + break; + case RIGHTALTKEY: + return "Rightalt"; + break; + case RIGHTCTRLKEY: + return "Rightctrl"; + break; + case RIGHTSHIFTKEY: + return "Rightshift"; + break; + case LEFTSHIFTKEY: + return "Leftshift"; + break; + + case ESCKEY: + return "Esc"; + break; + case TABKEY: + return "Tab"; + break; + case RETKEY: + return "Ret"; + break; + case SPACEKEY: + return "Space"; + break; + case LINEFEEDKEY: + return "Linefeed"; + break; + case BACKSPACEKEY: + return "Backspace"; + break; + case DELKEY: + return "Del"; + break; + case SEMICOLONKEY: + return "Semicolon"; + break; + case PERIODKEY: + return "Period"; + break; + case COMMAKEY: + return "Comma"; + break; + case QUOTEKEY: + return "Quote"; + break; + case ACCENTGRAVEKEY: + return "Accentgrave"; + break; + case MINUSKEY: + return "Minus"; + break; + case SLASHKEY: + return "Slash"; + break; + case BACKSLASHKEY: + return "Backslash"; + break; + case EQUALKEY: + return "Equal"; + break; + case LEFTBRACKETKEY: + return "Leftbracket"; + break; + case RIGHTBRACKETKEY: + return "Rightbracket"; + break; + + case LEFTARROWKEY: + return "Leftarrow"; + break; + case DOWNARROWKEY: + return "Downarrow"; + break; + case RIGHTARROWKEY: + return "Rightarrow"; + break; + case UPARROWKEY: + return "Uparrow"; + break; + + case PAD2: + return "Pad2"; + break; + case PAD4: + return "Pad4"; + break; + case PAD6: + return "Pad6"; + break; + case PAD8: + return "Pad8"; + break; + case PAD1: + return "Pad1"; + break; + case PAD3: + return "Pad3"; + break; + case PAD5: + return "Pad5"; + break; + case PAD7: + return "Pad7"; + break; + case PAD9: + return "Pad9"; + break; + + case PADPERIOD: + return "Padperiod"; + break; + case PADSLASHKEY: + return "Padslash"; + break; + case PADASTERKEY: + return "Padaster"; + break; + + case PAD0: + return "Pad0"; + break; + case PADMINUS: + return "Padminus"; + break; + case PADENTER: + return "Padenter"; + break; + case PADPLUSKEY: + return "Padplus"; + break; + + case F1KEY: + return "F1"; + break; + case F2KEY: + return "F2"; + break; + case F3KEY: + return "F3"; + break; + case F4KEY: + return "F4"; + break; + case F5KEY: + return "F5"; + break; + case F6KEY: + return "F6"; + break; + case F7KEY: + return "F7"; + break; + case F8KEY: + return "F8"; + break; + case F9KEY: + return "F9"; + break; + case F10KEY: + return "F10"; + break; + case F11KEY: + return "F11"; + break; + case F12KEY: + return "F12"; + break; + + case PAUSEKEY: + return "Pause"; + break; + case INSERTKEY: + return "Insert"; + break; + case HOMEKEY: + return "Home"; + break; + case PAGEUPKEY: + return "Pageup"; + break; + case PAGEDOWNKEY: + return "Pagedown"; + break; + case ENDKEY: + return "End"; + break; + } + + return ""; +} + +/* + * Decodes key combination strings [qual1+[qual2+[...]]]keyname + * The '+'s may be replaced by '-' or ' ' characters to support different + * formats. No additional whitespace is allowed. The keyname may be an internal + * name, like "RETKEY", or a more common name, like "Return". Decoding is case- + * insensitive. + * + * Example strings: "Ctrl+L", "ALT-ESC", "Shift A" + * + * Returns 1 if successful. + */ +int decode_key_string(char *str, unsigned short *key, unsigned short *qual) +{ + int i, prev, len, invalid=0; + + len= strlen(str); + *key= *qual= 0; + + /* Convert to upper case */ + for (i=0; i<len; i++) { + str[i]= toupper(str[i]); + } + + /* Handle modifiers */ + for (prev=i=0; i<len; i++) { + if (str[i]==' ' || str[i]=='+' || str[i]=='-') { +// XXX if (!strncmp(str+prev, "CTRL", i-prev)) *qual |= LR_CTRLKEY; +// else if (!strncmp(str+prev, "ALT", i-prev)) *qual |= LR_ALTKEY; +// else if (!strncmp(str+prev, "SHIFT", i-prev)) *qual |= LR_SHIFTKEY; +// else if (!strncmp(str+prev, "COMMAND", i-prev)) *qual |= LR_COMMANDKEY; + prev=i+1; + } + } + + /* Compare last part against key names */ + if ((len-prev==1) || ((len-prev==4) && !strncmp(str+prev, "KEY", 3))) { + + if (str[prev]>='A' && str[prev]<='Z') { + *key= str[prev]-'A'+AKEY; + } else if (str[prev]>='0' && str[prev]<='9') { + *key= str[prev]-'0'+ZEROKEY; + } else { + invalid= 1; + } + + } else if (!strncmp(str+prev, "ZEROKEY", len-prev) || !strncmp(str+prev, "ZERO", len-prev)) { + *key= ZEROKEY; + } else if (!strncmp(str+prev, "ONEKEY", len-prev) || !strncmp(str+prev, "ONE", len-prev)) { + *key= ONEKEY; + } else if (!strncmp(str+prev, "TWOKEY", len-prev) || !strncmp(str+prev, "TWO", len-prev)) { + *key= TWOKEY; + } else if (!strncmp(str+prev, "THREEKEY", len-prev) || !strncmp(str+prev, "THREE", len-prev)) { + *key= THREEKEY; + } else if (!strncmp(str+prev, "FOURKEY", len-prev) || !strncmp(str+prev, "FOUR", len-prev)) { + *key= FOURKEY; + } else if (!strncmp(str+prev, "FIVEKEY", len-prev) || !strncmp(str+prev, "FIVE", len-prev)) { + *key= FIVEKEY; + } else if (!strncmp(str+prev, "SIZEKEY", len-prev) || !strncmp(str+prev, "SIX", len-prev)) { + *key= SIXKEY; + } else if (!strncmp(str+prev, "SEVENKEY", len-prev) || !strncmp(str+prev, "SEVEN", len-prev)) { + *key= SEVENKEY; + } else if (!strncmp(str+prev, "EIGHTKEY", len-prev) || !strncmp(str+prev, "EIGHT", len-prev)) { + *key= EIGHTKEY; + } else if (!strncmp(str+prev, "NINEKEY", len-prev) || !strncmp(str+prev, "NINE", len-prev)) { + *key= NINEKEY; + + } else if (!strncmp(str+prev, "ESCKEY", len-prev) || !strncmp(str+prev, "ESC", len-prev)) { + *key= ESCKEY; + } else if (!strncmp(str+prev, "TABKEY", len-prev) || !strncmp(str+prev, "TAB", len-prev)) { + *key= TABKEY; + } else if (!strncmp(str+prev, "RETKEY", len-prev) || !strncmp(str+prev, "RETURN", len-prev) || !strncmp(str+prev, "ENTER", len-prev)) { + *key= RETKEY; + } else if (!strncmp(str+prev, "SPACEKEY", len-prev) || !strncmp(str+prev, "SPACE", len-prev)) { + *key= SPACEKEY; + } else if (!strncmp(str+prev, "LINEFEEDKEY", len-prev) || !strncmp(str+prev, "LINEFEED", len-prev)) { + *key= LINEFEEDKEY; + } else if (!strncmp(str+prev, "BACKSPACEKEY", len-prev) || !strncmp(str+prev, "BACKSPACE", len-prev)) { + *key= BACKSPACEKEY; + } else if (!strncmp(str+prev, "DELKEY", len-prev) || !strncmp(str+prev, "DELETE", len-prev)) { + *key= DELKEY; + + } else if (!strncmp(str+prev, "SEMICOLONKEY", len-prev) || !strncmp(str+prev, "SEMICOLON", len-prev)) { + *key= SEMICOLONKEY; + } else if (!strncmp(str+prev, "PERIODKEY", len-prev) || !strncmp(str+prev, "PERIOD", len-prev)) { + *key= PERIODKEY; + } else if (!strncmp(str+prev, "COMMAKEY", len-prev) || !strncmp(str+prev, "COMMA", len-prev)) { + *key= COMMAKEY; + } else if (!strncmp(str+prev, "QUOTEKEY", len-prev) || !strncmp(str+prev, "QUOTE", len-prev)) { + *key= QUOTEKEY; + } else if (!strncmp(str+prev, "ACCENTGRAVEKEY", len-prev) || !strncmp(str+prev, "ACCENTGRAVE", len-prev)) { + *key= ACCENTGRAVEKEY; + } else if (!strncmp(str+prev, "MINUSKEY", len-prev) || !strncmp(str+prev, "MINUS", len-prev)) { + *key= MINUSKEY; + } else if (!strncmp(str+prev, "SLASHKEY", len-prev) || !strncmp(str+prev, "SLASH", len-prev)) { + *key= SLASHKEY; + } else if (!strncmp(str+prev, "BACKSLASHKEY", len-prev) || !strncmp(str+prev, "BACKSLASH", len-prev)) { + *key= BACKSLASHKEY; + } else if (!strncmp(str+prev, "EQUALKEY", len-prev) || !strncmp(str+prev, "EQUAL", len-prev)) { + *key= EQUALKEY; + } else if (!strncmp(str+prev, "LEFTBRACKETKEY", len-prev) || !strncmp(str+prev, "LEFTBRACKET", len-prev)) { + *key= LEFTBRACKETKEY; + } else if (!strncmp(str+prev, "RIGHTBRACKETKEY", len-prev) || !strncmp(str+prev, "RIGHTBRACKET", len-prev)) { + *key= RIGHTBRACKETKEY; + } else if (!strncmp(str+prev, "DELKEY", len-prev) || !strncmp(str+prev, "DELETE", len-prev)) { + *key= DELKEY; + + } else if (!strncmp(str+prev, "LEFTARROWKEY", len-prev) || !strncmp(str+prev, "LEFTARROW", len-prev)) { + *key= LEFTARROWKEY; + } else if (!strncmp(str+prev, "DOWNARROWKEY", len-prev) || !strncmp(str+prev, "DOWNARROW", len-prev)) { + *key= DOWNARROWKEY; + } else if (!strncmp(str+prev, "RIGHTARROWKEY", len-prev) || !strncmp(str+prev, "RIGHTARROW", len-prev)) { + *key= RIGHTARROWKEY; + } else if (!strncmp(str+prev, "UPARROWKEY", len-prev) || !strncmp(str+prev, "UPARROW", len-prev)) { + *key= UPARROWKEY; + + } else if (!strncmp(str+prev, "PAD", 3)) { + + if (len-prev<=4) { + + if (str[prev]>='0' && str[prev]<='9') { + *key= str[prev]-'0'+ZEROKEY; + } else { + invalid= 1; + } + + } else if (!strncmp(str+prev+3, "PERIODKEY", len-prev-3) || !strncmp(str+prev+3, "PERIOD", len-prev-3)) { + *key= PADPERIOD; + } else if (!strncmp(str+prev+3, "SLASHKEY", len-prev-3) || !strncmp(str+prev+3, "SLASH", len-prev-3)) { + *key= PADSLASHKEY; + } else if (!strncmp(str+prev+3, "ASTERKEY", len-prev-3) || !strncmp(str+prev+3, "ASTERISK", len-prev-3)) { + *key= PADASTERKEY; + } else if (!strncmp(str+prev+3, "MINUSKEY", len-prev-3) || !strncmp(str+prev+3, "MINUS", len-prev-3)) { + *key= PADMINUS; + } else if (!strncmp(str+prev+3, "ENTERKEY", len-prev-3) || !strncmp(str+prev+3, "ENTER", len-prev-3)) { + *key= PADENTER; + } else if (!strncmp(str+prev+3, "PLUSKEY", len-prev-3) || !strncmp(str+prev+3, "PLUS", len-prev-3)) { + *key= PADPLUSKEY; + } else { + invalid= 1; + } + + } else if (!strncmp(str+prev, "F1KEY", len-prev) || !strncmp(str+prev, "F1", len-prev)) { + *key= F1KEY; + } else if (!strncmp(str+prev, "F2KEY", len-prev) || !strncmp(str+prev, "F2", len-prev)) { + *key= F2KEY; + } else if (!strncmp(str+prev, "F3KEY", len-prev) || !strncmp(str+prev, "F3", len-prev)) { + *key= F3KEY; + } else if (!strncmp(str+prev, "F4KEY", len-prev) || !strncmp(str+prev, "F4", len-prev)) { + *key= F4KEY; + } else if (!strncmp(str+prev, "F5KEY", len-prev) || !strncmp(str+prev, "F5", len-prev)) { + *key= F5KEY; + } else if (!strncmp(str+prev, "F6KEY", len-prev) || !strncmp(str+prev, "F6", len-prev)) { + *key= F6KEY; + } else if (!strncmp(str+prev, "F7KEY", len-prev) || !strncmp(str+prev, "F7", len-prev)) { + *key= F7KEY; + } else if (!strncmp(str+prev, "F8KEY", len-prev) || !strncmp(str+prev, "F8", len-prev)) { + *key= F8KEY; + } else if (!strncmp(str+prev, "F9KEY", len-prev) || !strncmp(str+prev, "F9", len-prev)) { + *key= F9KEY; + } else if (!strncmp(str+prev, "F10KEY", len-prev) || !strncmp(str+prev, "F10", len-prev)) { + *key= F10KEY; + } else if (!strncmp(str+prev, "F11KEY", len-prev) || !strncmp(str+prev, "F11", len-prev)) { + *key= F11KEY; + } else if (!strncmp(str+prev, "F12KEY", len-prev) || !strncmp(str+prev, "F12", len-prev)) { + *key= F12KEY; + + } else if (!strncmp(str+prev, "PAUSEKEY", len-prev) || !strncmp(str+prev, "PAUSE", len-prev)) { + *key= PAUSEKEY; + } else if (!strncmp(str+prev, "INSERTKEY", len-prev) || !strncmp(str+prev, "INSERT", len-prev)) { + *key= INSERTKEY; + } else if (!strncmp(str+prev, "HOMEKEY", len-prev) || !strncmp(str+prev, "HOME", len-prev)) { + *key= HOMEKEY; + } else if (!strncmp(str+prev, "PAGEUPKEY", len-prev) || !strncmp(str+prev, "PAGEUP", len-prev)) { + *key= PAGEUPKEY; + } else if (!strncmp(str+prev, "PAGEDOWNKEY", len-prev) || !strncmp(str+prev, "PAGEDOWN", len-prev)) { + *key= PAGEDOWNKEY; + } else if (!strncmp(str+prev, "ENDKEY", len-prev) || !strncmp(str+prev, "END", len-prev)) { + *key= ENDKEY; + + } else { + invalid= 1; + } + + if (!invalid && *key) { + return 1; + } + + return 0; +} diff --git a/source/blender/editors/mesh/SConscript b/source/blender/editors/mesh/SConscript index e99351e1a70..bd6d355d84c 100644 --- a/source/blender/editors/mesh/SConscript +++ b/source/blender/editors/mesh/SConscript @@ -7,5 +7,6 @@ incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf' incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' incs += ' #/intern/guardedalloc #intern/bmfont ../../gpu' incs += ' ../../makesrna ../../render/extern/include #/intern/elbeem/extern' +incs += ' ../../bmesh ' env.BlenderLib ( 'bf_editors_mesh', sources, Split(incs), [], libtype=['core'], priority=[45] ) diff --git a/source/blender/editors/mesh/editdeform.c b/source/blender/editors/mesh/editdeform.c new file mode 100644 index 00000000000..703ae2b9fc8 --- /dev/null +++ b/source/blender/editors/mesh/editdeform.c @@ -0,0 +1,1063 @@ +/** + * $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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + * Creator-specific support for vertex deformation groups + * Added: apply deform function (ton) + */ + +#include <string.h> + +#include "MEM_guardedalloc.h" + +#include "DNA_cloth_types.h" +#include "DNA_curve_types.h" +#include "DNA_lattice_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_modifier_types.h" +#include "DNA_object_types.h" +#include "DNA_object_force.h" +#include "DNA_scene_types.h" +#include "DNA_particle_types.h" + +#include "BLI_blenlib.h" +#include "BLI_editVert.h" + +#include "BKE_customdata.h" +#include "BKE_DerivedMesh.h" +#include "BKE_depsgraph.h" +#include "BKE_deform.h" +#include "BKE_displist.h" +#include "BKE_global.h" +#include "BKE_lattice.h" +#include "BKE_mesh.h" +#include "BKE_utildefines.h" + +#include "ED_mesh.h" +#include "ED_view3d.h" +#include "mesh_intern.h" + +/* XXX */ +static void BIF_undo_push() {} +static void error() {} + +/* only in editmode */ +void sel_verts_defgroup (Object *obedit, int select) +{ + EditVert *eve; + Object *ob; + int i; + MDeformVert *dvert; + + ob= obedit; + + if (!ob) + return; + + switch (ob->type){ + case OB_MESH: + { + Mesh *me= ob->data; + + for (eve=me->edit_mesh->verts.first; eve; eve=eve->next){ + dvert= CustomData_em_get(&me->edit_mesh->vdata, eve->data, CD_MDEFORMVERT); + + if (dvert && dvert->totweight){ + for (i=0; i<dvert->totweight; i++){ + if (dvert->dw[i].def_nr == (ob->actdef-1)){ + if (select) eve->f |= SELECT; + else eve->f &= ~SELECT; + + break; + } + } + } + } + /* this has to be called, because this function operates on vertices only */ + if(select) EM_select_flush(me->edit_mesh); // vertices to edges/faces + else EM_deselect_flush(me->edit_mesh); + } + break; + case OB_LATTICE: + if(editLatt->dvert) { + BPoint *bp; + int a, tot; + + dvert= editLatt->dvert; + + tot= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw; + for(a=0, bp= editLatt->def; a<tot; a++, bp++, dvert++) { + for (i=0; i<dvert->totweight; i++){ + if (dvert->dw[i].def_nr == (ob->actdef-1)) { + if(select) bp->f1 |= SELECT; + else bp->f1 &= ~SELECT; + + break; + } + } + } + } + break; + + default: + break; + } +} + +/* check if deform vertex has defgroup index */ +MDeformWeight *get_defweight (MDeformVert *dv, int defgroup) +{ + int i; + + if (!dv || defgroup<0) + return NULL; + + for (i=0; i<dv->totweight; i++){ + if (dv->dw[i].def_nr == defgroup) + return dv->dw+i; + } + return NULL; +} + +/* Ensures that mv has a deform weight entry for + the specified defweight group */ +/* Note this function is mirrored in editmesh_tools.c, for use for editvertices */ +MDeformWeight *verify_defweight (MDeformVert *dv, int defgroup) +{ + MDeformWeight *newdw; + + /* do this check always, this function is used to check for it */ + if (!dv || defgroup<0) + return NULL; + + newdw = get_defweight (dv, defgroup); + if (newdw) + return newdw; + + newdw = MEM_callocN (sizeof(MDeformWeight)*(dv->totweight+1), "deformWeight"); + if (dv->dw){ + memcpy (newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight); + MEM_freeN (dv->dw); + } + dv->dw=newdw; + + dv->dw[dv->totweight].weight=0.0f; + dv->dw[dv->totweight].def_nr=defgroup; + /* Group index */ + + dv->totweight++; + + return dv->dw+(dv->totweight-1); +} + +bDeformGroup *add_defgroup_name (Object *ob, char *name) +{ + bDeformGroup *defgroup; + + if (!ob) + return NULL; + + defgroup = MEM_callocN (sizeof(bDeformGroup), "add deformGroup"); + + BLI_strncpy (defgroup->name, name, 32); + + BLI_addtail(&ob->defbase, defgroup); + unique_vertexgroup_name(defgroup, ob); + + ob->actdef = BLI_countlist(&ob->defbase); + + return defgroup; +} + +void add_defgroup (Object *ob) +{ + add_defgroup_name (ob, "Group"); +} + + +void duplicate_defgroup ( Object *ob ) +{ + bDeformGroup *dg, *cdg; + char name[32], s[32]; + MDeformWeight *org, *cpy; + MDeformVert *dvert; + Mesh *me; + int i, idg, icdg; + + if (ob->type != OB_MESH) + return; + + dg = BLI_findlink (&ob->defbase, (ob->actdef-1)); + if (!dg) + return; + + if (strstr(dg->name, "_copy")) { + BLI_strncpy (name, dg->name, 32); /* will be renamed _copy.001... etc */ + } else { + BLI_snprintf (name, 32, "%s_copy", dg->name); + while (get_named_vertexgroup (ob, name)) { + if ((strlen (name) + 6) > 32) { + error ("Error: the name for the new group is > 32 characters"); + return; + } + strcpy (s, name); + BLI_snprintf (name, 32, "%s_copy", s); + } + } + + cdg = copy_defgroup (dg); + strcpy (cdg->name, name); + unique_vertexgroup_name(cdg, ob); + + BLI_addtail (&ob->defbase, cdg); + + idg = (ob->actdef-1); + ob->actdef = BLI_countlist (&ob->defbase); + icdg = (ob->actdef-1); + + me = get_mesh (ob); + if (!me->dvert) + return; + + for (i = 0; i < me->totvert; i++) { + dvert = me->dvert+i; + org = get_defweight (dvert, idg); + if (org) { + cpy = verify_defweight (dvert, icdg); + cpy->weight = org->weight; + } + } +} + +static void del_defgroup_update_users(Object *ob, int id) +{ + ExplodeModifierData *emd; + ModifierData *md; + ParticleSystem *psys; + ClothModifierData *clmd; + ClothSimSettings *clsim; + int a; + + /* these cases don't use names to refer to vertex groups, so when + * they get deleted the numbers get out of sync, this corrects that */ + + if(ob->soft) { + if(ob->soft->vertgroup == id) + ob->soft->vertgroup= 0; + else if(ob->soft->vertgroup > id) + ob->soft->vertgroup--; + } + + for(md=ob->modifiers.first; md; md=md->next) { + if(md->type == eModifierType_Explode) { + emd= (ExplodeModifierData*)md; + + if(emd->vgroup == id) + emd->vgroup= 0; + else if(emd->vgroup > id) + emd->vgroup--; + } + else if(md->type == eModifierType_Cloth) { + clmd= (ClothModifierData*)md; + clsim= clmd->sim_parms; + + if(clsim) { + if(clsim->vgroup_mass == id) + clsim->vgroup_mass= 0; + else if(clsim->vgroup_mass > id) + clsim->vgroup_mass--; + + if(clsim->vgroup_bend == id) + clsim->vgroup_bend= 0; + else if(clsim->vgroup_bend > id) + clsim->vgroup_bend--; + + if(clsim->vgroup_struct == id) + clsim->vgroup_struct= 0; + else if(clsim->vgroup_struct > id) + clsim->vgroup_struct--; + } + } + } + + for(psys=ob->particlesystem.first; psys; psys=psys->next) { + for(a=0; a<PSYS_TOT_VG; a++) + if(psys->vgroup[a] == id) + psys->vgroup[a]= 0; + else if(psys->vgroup[a] > id) + psys->vgroup[a]--; + } +} + +void del_defgroup_in_object_mode ( Object *ob ) +{ + bDeformGroup *dg; + MDeformVert *dvert; + Mesh *me; + int i, e; + + if ((!ob) || (ob->type != OB_MESH)) + return; + + dg = BLI_findlink (&ob->defbase, (ob->actdef-1)); + if (!dg) + return; + + me = get_mesh (ob); + if (me->dvert) { + for (i = 0; i < me->totvert; i++) { + dvert = me->dvert + i; + if (dvert) { + if (get_defweight (dvert, (ob->actdef-1))) + remove_vert_defgroup (ob, dg, i); + } + } + + for (i = 0; i < me->totvert; i++) { + dvert = me->dvert+i; + if (dvert) { + for (e = 0; e < dvert->totweight; e++) { + if (dvert->dw[e].def_nr > (ob->actdef-1)) + dvert->dw[e].def_nr--; + } + } + } + } + + del_defgroup_update_users(ob, ob->actdef); + + /* Update the active deform index if necessary */ + if (ob->actdef == BLI_countlist(&ob->defbase)) + ob->actdef--; + + /* Remove the group */ + BLI_freelinkN (&ob->defbase, dg); +} + +void del_defgroup (Object *ob) +{ + bDeformGroup *defgroup; + int i; + + if (!ob) + return; + + if (!ob->actdef) + return; + + defgroup = BLI_findlink(&ob->defbase, ob->actdef-1); + if (!defgroup) + return; + + /* Make sure that no verts are using this group */ + remove_verts_defgroup(ob, 1); + + /* Make sure that any verts with higher indices are adjusted accordingly */ + if(ob->type==OB_MESH) { + Mesh *me= ob->data; + EditMesh *em = me->edit_mesh; + EditVert *eve; + MDeformVert *dvert; + + for (eve=em->verts.first; eve; eve=eve->next){ + dvert= CustomData_em_get(&me->edit_mesh->vdata, eve->data, CD_MDEFORMVERT); + + if (dvert) + for (i=0; i<dvert->totweight; i++) + if (dvert->dw[i].def_nr > (ob->actdef-1)) + dvert->dw[i].def_nr--; + } + } + else { + BPoint *bp; + MDeformVert *dvert= editLatt->dvert; + int a, tot; + + if (dvert) { + tot= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw; + for(a=0, bp= editLatt->def; a<tot; a++, bp++, dvert++) { + for (i=0; i<dvert->totweight; i++){ + if (dvert->dw[i].def_nr > (ob->actdef-1)) + dvert->dw[i].def_nr--; + } + } + } + } + + del_defgroup_update_users(ob, ob->actdef); + + /* Update the active deform index if necessary */ + if (ob->actdef==BLI_countlist(&ob->defbase)) + ob->actdef--; + + /* Remove the group */ + BLI_freelinkN (&ob->defbase, defgroup); + + /* remove all dverts */ + if(ob->actdef==0) { + if(ob->type==OB_MESH) { + Mesh *me= ob->data; + CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert); + me->dvert= NULL; + } + else { + if (editLatt->dvert) { + MEM_freeN(editLatt->dvert); + editLatt->dvert= NULL; + } + } + } +} + +void del_all_defgroups (Object *ob) +{ + /* Sanity check */ + if (ob == NULL) + return; + + /* Remove all DVerts */ + if (ob->type==OB_MESH) { + Mesh *me= ob->data; + CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert); + me->dvert= NULL; + } + else { + if (editLatt->dvert) { + MEM_freeN(editLatt->dvert); + editLatt->dvert= NULL; + } + } + + /* Remove all DefGroups */ + BLI_freelistN(&ob->defbase); + + /* Fix counters/indices */ + ob->actdef= 0; +} + +void create_dverts(ID *id) +{ + /* create deform verts + */ + + if( GS(id->name)==ID_ME) { + Mesh *me= (Mesh *)id; + me->dvert= CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, me->totvert); + } + else if( GS(id->name)==ID_LT) { + Lattice *lt= (Lattice *)id; + lt->dvert= MEM_callocN(sizeof(MDeformVert)*lt->pntsu*lt->pntsv*lt->pntsw, "lattice deformVert"); + } +} + +/* for mesh in object mode + lattice can be in editmode */ +void remove_vert_def_nr (Object *ob, int def_nr, int vertnum) +{ + /* This routine removes the vertex from the deform + * group with number def_nr. + * + * This routine is meant to be fast, so it is the + * responsibility of the calling routine to: + * a) test whether ob is non-NULL + * b) test whether ob is a mesh + * c) calculate def_nr + */ + + MDeformWeight *newdw; + MDeformVert *dvert= NULL; + int i; + + /* get the deform vertices corresponding to the + * vertnum + */ + if(ob->type==OB_MESH) { + if( ((Mesh*)ob->data)->dvert ) + dvert = ((Mesh*)ob->data)->dvert + vertnum; + } + else if(ob->type==OB_LATTICE) { + Lattice *lt= ob->data; + + if(lt->editlatt) lt= lt->editlatt; + if(lt->dvert) + dvert = lt->dvert + vertnum; + } + + if(dvert==NULL) + return; + + /* for all of the deform weights in the + * deform vert + */ + for (i=dvert->totweight - 1 ; i>=0 ; i--){ + + /* if the def_nr is the same as the one + * for our weight group then remove it + * from this deform vert. + */ + if (dvert->dw[i].def_nr == def_nr) { + dvert->totweight--; + + /* if there are still other deform weights + * attached to this vert then remove this + * deform weight, and reshuffle the others + */ + if (dvert->totweight) { + newdw = MEM_mallocN (sizeof(MDeformWeight)*(dvert->totweight), + "deformWeight"); + if (dvert->dw){ + memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*i); + memcpy (newdw+i, dvert->dw+i+1, + sizeof(MDeformWeight)*(dvert->totweight-i)); + MEM_freeN (dvert->dw); + } + dvert->dw=newdw; + } + /* if there are no other deform weights + * left then just remove the deform weight + */ + else { + MEM_freeN (dvert->dw); + dvert->dw = NULL; + break; + } + } + } + +} + +/* for Mesh in Object mode */ +/* allows editmode for Lattice */ +void add_vert_defnr (Object *ob, int def_nr, int vertnum, + float weight, int assignmode) +{ + /* add the vert to the deform group with the + * specified number + */ + MDeformVert *dv= NULL; + MDeformWeight *newdw; + int i; + + /* get the vert */ + if(ob->type==OB_MESH) { + if(((Mesh*)ob->data)->dvert) + dv = ((Mesh*)ob->data)->dvert + vertnum; + } + else if(ob->type==OB_LATTICE) { + Lattice *lt= ob->data; + + if(lt->editlatt) lt= lt->editlatt; + + if(lt->dvert) + dv = lt->dvert + vertnum; + } + + if(dv==NULL) + return; + + /* Lets first check to see if this vert is + * already in the weight group -- if so + * lets update it + */ + for (i=0; i<dv->totweight; i++){ + + /* if this weight cooresponds to the + * deform group, then add it using + * the assign mode provided + */ + if (dv->dw[i].def_nr == def_nr){ + + switch (assignmode) { + case WEIGHT_REPLACE: + dv->dw[i].weight=weight; + break; + case WEIGHT_ADD: + dv->dw[i].weight+=weight; + if (dv->dw[i].weight >= 1.0) + dv->dw[i].weight = 1.0; + break; + case WEIGHT_SUBTRACT: + dv->dw[i].weight-=weight; + /* if the weight is zero or less then + * remove the vert from the deform group + */ + if (dv->dw[i].weight <= 0.0) + remove_vert_def_nr(ob, def_nr, vertnum); + break; + } + return; + } + } + + /* if the vert wasn't in the deform group then + * we must take a different form of action ... + */ + + switch (assignmode) { + case WEIGHT_SUBTRACT: + /* if we are subtracting then we don't + * need to do anything + */ + return; + + case WEIGHT_REPLACE: + case WEIGHT_ADD: + /* if we are doing an additive assignment, then + * we need to create the deform weight + */ + newdw = MEM_callocN (sizeof(MDeformWeight)*(dv->totweight+1), + "deformWeight"); + if (dv->dw){ + memcpy (newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight); + MEM_freeN (dv->dw); + } + dv->dw=newdw; + + dv->dw[dv->totweight].weight=weight; + dv->dw[dv->totweight].def_nr=def_nr; + + dv->totweight++; + break; + } +} + +/* called while not in editmode */ +void add_vert_to_defgroup (Object *ob, bDeformGroup *dg, int vertnum, + float weight, int assignmode) +{ + /* add the vert to the deform group with the + * specified assign mode + */ + int def_nr; + + /* get the deform group number, exit if + * it can't be found + */ + def_nr = get_defgroup_num(ob, dg); + if (def_nr < 0) return; + + /* if there's no deform verts then + * create some + */ + if(ob->type==OB_MESH) { + if (!((Mesh*)ob->data)->dvert) + create_dverts(ob->data); + } + else if(ob->type==OB_LATTICE) { + if (!((Lattice*)ob->data)->dvert) + create_dverts(ob->data); + } + + /* call another function to do the work + */ + add_vert_defnr (ob, def_nr, vertnum, weight, assignmode); +} + +/* Only available in editmode */ +void assign_verts_defgroup (Object *obedit) +{ + float editbutvweight; /* XXX */ + Object *ob; + EditVert *eve; + bDeformGroup *dg, *eg; + MDeformWeight *newdw; + MDeformVert *dvert; + int i, done; + +// XXX if(multires_level1_test()) return; + + ob= obedit; + + if (!ob) + return; + + dg=BLI_findlink(&ob->defbase, ob->actdef-1); + if (!dg){ + error ("No vertex group is active"); + return; + } + + switch (ob->type){ + case OB_MESH: + { + Mesh *me= ob->data; + + if (!CustomData_has_layer(&me->edit_mesh->vdata, CD_MDEFORMVERT)) + EM_add_data_layer(me->edit_mesh, &me->edit_mesh->vdata, CD_MDEFORMVERT); + + /* Go through the list of editverts and assign them */ + for (eve=me->edit_mesh->verts.first; eve; eve=eve->next){ + dvert= CustomData_em_get(&me->edit_mesh->vdata, eve->data, CD_MDEFORMVERT); + + if (dvert && (eve->f & 1)){ + done=0; + /* See if this vert already has a reference to this group */ + /* If so: Change its weight */ + done=0; + for (i=0; i<dvert->totweight; i++){ + eg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr); + /* Find the actual group */ + if (eg==dg){ + dvert->dw[i].weight=editbutvweight; + done=1; + break; + } + } + /* If not: Add the group and set its weight */ + if (!done){ + newdw = MEM_callocN (sizeof(MDeformWeight)*(dvert->totweight+1), "deformWeight"); + if (dvert->dw){ + memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*dvert->totweight); + MEM_freeN (dvert->dw); + } + dvert->dw=newdw; + + dvert->dw[dvert->totweight].weight= editbutvweight; + dvert->dw[dvert->totweight].def_nr= ob->actdef-1; + + dvert->totweight++; + + } + } + } + } + break; + case OB_LATTICE: + { + BPoint *bp; + int a, tot; + + if(editLatt->dvert==NULL) + create_dverts(&editLatt->id); + + tot= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw; + for(a=0, bp= editLatt->def; a<tot; a++, bp++) { + if(bp->f1 & SELECT) + add_vert_defnr (ob, ob->actdef-1, a, editbutvweight, WEIGHT_REPLACE); + } + } + break; + default: + printf ("Assigning deformation groups to unknown object type\n"); + break; + } + +} + +/* mesh object mode, lattice can be in editmode */ +void remove_vert_defgroup (Object *ob, bDeformGroup *dg, int vertnum) +{ + /* This routine removes the vertex from the specified + * deform group. + */ + + int def_nr; + + /* if the object is NULL abort + */ + if (!ob) + return; + + /* get the deform number that cooresponds + * to this deform group, and abort if it + * can not be found. + */ + def_nr = get_defgroup_num(ob, dg); + if (def_nr < 0) return; + + /* call another routine to do the work + */ + remove_vert_def_nr (ob, def_nr, vertnum); +} + +/* for mesh in object mode lattice can be in editmode */ +static float get_vert_def_nr (Object *ob, int def_nr, int vertnum) +{ + MDeformVert *dvert= NULL; + int i; + + /* get the deform vertices corresponding to the + * vertnum + */ + if(ob->type==OB_MESH) { + if( ((Mesh*)ob->data)->dvert ) + dvert = ((Mesh*)ob->data)->dvert + vertnum; + } + else if(ob->type==OB_LATTICE) { + Lattice *lt= ob->data; + + if(lt->editlatt) lt= lt->editlatt; + + if(lt->dvert) + dvert = lt->dvert + vertnum; + } + + if(dvert==NULL) + return 0.0f; + + for(i=dvert->totweight-1 ; i>=0 ; i--) + if(dvert->dw[i].def_nr == def_nr) + return dvert->dw[i].weight; + + return 0.0f; +} + +/* mesh object mode, lattice can be in editmode */ +float get_vert_defgroup (Object *ob, bDeformGroup *dg, int vertnum) +{ + int def_nr; + + if(!ob) + return 0.0f; + + def_nr = get_defgroup_num(ob, dg); + if(def_nr < 0) return 0.0f; + + return get_vert_def_nr (ob, def_nr, vertnum); +} + +/* Only available in editmode */ +/* removes from active defgroup, if allverts==0 only selected vertices */ +void remove_verts_defgroup (Object *obedit, int allverts) +{ + Object *ob; + EditVert *eve; + MDeformVert *dvert; + MDeformWeight *newdw; + bDeformGroup *dg, *eg; + int i; + +// XXX if(multires_level1_test()) return; + + ob= obedit; + + if (!ob) + return; + + dg=BLI_findlink(&ob->defbase, ob->actdef-1); + if (!dg){ + error ("No vertex group is active"); + return; + } + + switch (ob->type){ + case OB_MESH: + { + Mesh *me= ob->data; + + for (eve=me->edit_mesh->verts.first; eve; eve=eve->next){ + dvert= CustomData_em_get(&me->edit_mesh->vdata, eve->data, CD_MDEFORMVERT); + + if (dvert && dvert->dw && ((eve->f & 1) || allverts)){ + for (i=0; i<dvert->totweight; i++){ + /* Find group */ + eg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr); + if (eg == dg){ + dvert->totweight--; + if (dvert->totweight){ + newdw = MEM_mallocN (sizeof(MDeformWeight)*(dvert->totweight), "deformWeight"); + + if (dvert->dw){ + memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*i); + memcpy (newdw+i, dvert->dw+i+1, sizeof(MDeformWeight)*(dvert->totweight-i)); + MEM_freeN (dvert->dw); + } + dvert->dw=newdw; + } + else{ + MEM_freeN (dvert->dw); + dvert->dw=NULL; + break; + } + } + } + } + } + } + break; + case OB_LATTICE: + + if(editLatt->dvert) { + BPoint *bp; + int a, tot= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw; + + for(a=0, bp= editLatt->def; a<tot; a++, bp++) { + if(allverts || (bp->f1 & SELECT)) + remove_vert_defgroup (ob, dg, a); + } + } + break; + + default: + printf ("Removing deformation groups from unknown object type\n"); + break; + } +} + +/* Only available in editmode */ +/* removes from all defgroup, if allverts==0 only selected vertices */ +void remove_verts_defgroups(Object *obedit, int allverts) +{ + Object *ob; + int actdef, defCount; + +// XXX if (multires_level1_test()) return; + + ob= obedit; + if (ob == NULL) return; + + actdef= ob->actdef; + defCount= BLI_countlist(&ob->defbase); + + if (defCount == 0) { + error("Object has no vertex groups"); + return; + } + + /* To prevent code redundancy, we just use remove_verts_defgroup, but that + * only operates on the active vgroup. So we iterate through all groups, by changing + * active group index + */ + for (ob->actdef= 1; ob->actdef <= defCount; ob->actdef++) + remove_verts_defgroup(ob, allverts); + + ob->actdef= actdef; +} + +void vertexgroup_select_by_name(Object *ob, char *name) +{ + bDeformGroup *curdef; + int actdef= 1; + + if(ob==NULL) return; + + for (curdef = ob->defbase.first; curdef; curdef=curdef->next, actdef++){ + if (!strcmp(curdef->name, name)) { + ob->actdef= actdef; + return; + } + } + ob->actdef=0; // this signals on painting to create a new one, if a bone in posemode is selected */ +} + +/* This function provides a shortcut for adding/removing verts from + * vertex groups. It is called by the Ctrl-G hotkey in EditMode for Meshes + * and Lattices. (currently only restricted to those two) + * It is only responsible for + */ +void vgroup_assign_with_menu(Object *ob) +{ + int defCount; + int mode; + + /* prevent crashes */ + if (ob==NULL) return; + + defCount= BLI_countlist(&ob->defbase); + + /* give user choices of adding to current/new or removing from current */ +// XXX if (defCount && ob->actdef) +// mode = pupmenu("Vertex Groups %t|Add Selected to New Group %x1|Add Selected to Active Group %x2|Remove Selected from Active Group %x3|Remove Selected from All Groups %x4"); +// else +// mode= pupmenu("Vertex Groups %t|Add Selected to New Group %x1"); + + /* handle choices */ + switch (mode) { + case 1: /* add to new group */ + add_defgroup(ob); + assign_verts_defgroup(ob); + BIF_undo_push("Assign to vertex group"); + break; + case 2: /* add to current group */ + assign_verts_defgroup(ob); + BIF_undo_push("Assign to vertex group"); + break; + case 3: /* remove from current group */ + remove_verts_defgroup(ob, 0); + BIF_undo_push("Remove from vertex group"); + break; + case 4: /* remove from all groups */ + remove_verts_defgroups(ob, 0); + BIF_undo_push("Remove from all vertex groups"); + break; + } +} + +/* This function provides a shortcut for commonly used vertex group + * functions - change weight (not implemented), change active group, delete active group, + * when Ctrl-Shift-G is used in EditMode, for Meshes and Lattices (only for now). + */ +void vgroup_operation_with_menu(Object *ob) +{ + int defCount; + int mode; + + /* prevent crashes and useless cases */ + if (ob==NULL) return; + + defCount= BLI_countlist(&ob->defbase); + if (defCount == 0) return; + + /* give user choices of adding to current/new or removing from current */ +// XXX if (ob->actdef) +// mode = pupmenu("Vertex Groups %t|Change Active Group%x1|Delete Active Group%x2|Delete All Groups%x3"); +// else +// mode= pupmenu("Vertex Groups %t|Change Active Group%x1|Delete All Groups%x3"); + + /* handle choices */ + switch (mode) { + case 1: /* change active group*/ + { + char *menustr= NULL; // XXX get_vertexgroup_menustr(ob); + short nr; + + if (menustr) { +// XXX nr= pupmenu(menustr); + + if ((nr >= 1) && (nr <= defCount)) + ob->actdef= nr; + + MEM_freeN(menustr); + } + } + break; + case 2: /* delete active group */ + { + del_defgroup(ob); + BIF_undo_push("Delete vertex group"); + } + break; + case 3: /* delete all groups */ + { + del_all_defgroups(ob); + BIF_undo_push("Delete all vertex groups"); + } + break; + } +} + + diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 90a328bb49a..bd49c2e8cf6 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -34,6 +34,7 @@ struct bContext; struct wmOperatorType; +struct ViewContext; #define UVCOPY(t, s) memcpy(t, s, 2 * sizeof(float)); @@ -45,7 +46,6 @@ int edgetag_shortest_path(Scene *scene, EditMesh *em, EditEdge *source, EditEdge /* ******************* meshtools.c */ -int mesh_get_x_mirror_vert(Object *ob, int index); /* XXX move to uv editor? */ enum { @@ -92,7 +92,7 @@ int editedge_containsVert(struct EditEdge *eed, struct EditVert *eve); int editface_containsVert(struct EditFace *efa, struct EditVert *eve); int editface_containsEdge(struct EditFace *efa, struct EditEdge *eed); -void em_setup_viewcontext(struct bContext *C, ViewContext *vc); +void em_setup_viewcontext(struct bContext *C, struct ViewContext *vc); /* ******************* editmesh_add.c */ @@ -162,7 +162,7 @@ extern struct EditFace *EM_face_from_faces(EditMesh *em, struct EditFace *efa1, void MESH_OT_de_select_all(struct wmOperatorType *ot); -extern EditEdge *findnearestedge(ViewContext *vc, int *dist); +extern EditEdge *findnearestedge(struct ViewContext *vc, int *dist); extern void EM_automerge(int update); void editmesh_select_by_material(EditMesh *em, int index); void righthandfaces(EditMesh *em, int select); /* makes faces righthand turning */ @@ -177,7 +177,7 @@ void EM_select_more(EditMesh *em); * if 0, unselected vertice are given the bias * strict: if 1, the vertice corresponding to the sel parameter are ignored and not just biased */ -extern EditVert *findnearestvert(ViewContext *vc, int *dist, short sel, short strict); +extern EditVert *findnearestvert(struct ViewContext *vc, int *dist, short sel, short strict); /* ******************* editmesh_tools.c */ diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 8b749b3e829..e3fa8b22463 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -180,8 +180,8 @@ void ED_base_object_activate(bContext *C, Base *base) Base *tbase; /* activating a non-mesh, should end a couple of modes... */ - // if(base && base->object->type!=OB_MESH) - // XXX exit_paint_modes(); + if(base && base->object->type!=OB_MESH) + ED_view3d_exit_paint_modes(C); /* sets scene->basact */ BASACT= base; @@ -235,19 +235,6 @@ int object_data_is_libdata(Object *ob) -void exit_paint_modes(void) -{ -#if 0 - if(G.f & G_VERTEXPAINT) set_vpaint(); - if(G.f & G_TEXTUREPAINT) set_texturepaint(); - if(G.f & G_WEIGHTPAINT) set_wpaint(); - if(G.f & G_SCULPTMODE) set_sculptmode(); - if(G.f & G_PARTICLEEDIT) PE_set_particle_edit(); - - G.f &= ~(G_VERTEXPAINT+G_TEXTUREPAINT+G_WEIGHTPAINT+G_SCULPTMODE+G_PARTICLEEDIT); -#endif -} - /* exported */ void ED_object_base_init_from_view(Scene *scene, View3D *v3d, Base *base) { @@ -284,7 +271,7 @@ void add_object_draw(Scene *scene, View3D *v3d, int type) /* for toolbox or menu { Object *ob; - exit_paint_modes(); +// ED_view3d_exit_paint_modes(C); // XXX if (obedit) ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* freedata, and undo */ ob= add_object(scene, type); @@ -362,7 +349,7 @@ void delete_obj(Scene *scene, View3D *v3d, int ok) } } - exit_paint_modes(); +// ED_view3d_exit_paint_modes(C); if(base->object->type==OB_LAMP) islamp= 1; @@ -1639,36 +1626,78 @@ void OBJECT_OT_set_restrictview(wmOperatorType *ot) RNA_def_property_enum_items(prop, prop_set_restrictview_types); } -/* ******************** **************** */ +/* ************* Slow Parent ******************* */ +static int object_set_slowparent_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); -void reset_slowparents(Scene *scene, View3D *v3d) + CTX_DATA_BEGIN(C, Base*, base, visible_bases) { + + if(base->object->parent) base->object->partype |= PARSLOW; + base->object->recalc |= OB_RECALC_OB; + + } + CTX_DATA_END; + + ED_anim_dag_flush_update(C); + ED_undo_push(C,"Set Slow Parent"); + + WM_event_add_notifier(C, NC_SCENE, CTX_data_scene(C)); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_set_slowparent(wmOperatorType *ot) { - /* back to original locations */ - Base *base; + + /* identifiers */ + ot->name= "Set Slow Parent"; + ot->idname= "OBJECT_OT_set_slow_parent"; + + /* api callbacks */ + ot->invoke= WM_operator_confirm; + ot->exec= object_set_slowparent_exec; + ot->poll= ED_operator_view3d_active; +} - for(base= FIRSTBASE; base; base= base->next) { +static int object_clear_slowparent_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + + CTX_DATA_BEGIN(C, Base*, base, visible_bases) { if(base->object->parent) { if(base->object->partype & PARSLOW) { base->object->partype -= PARSLOW; where_is_object(scene, base->object); base->object->partype |= PARSLOW; + base->object->recalc |= OB_RECALC_OB; } } + } -} -void set_slowparent(Scene *scene, View3D *v3d) -{ - Base *base; + CTX_DATA_END; - if( okee("Set slow parent")==0 ) return; + ED_anim_dag_flush_update(C); + ED_undo_push(C,"Clear Slow Parent"); + + WM_event_add_notifier(C, NC_SCENE, CTX_data_scene(C)); + + return OPERATOR_FINISHED; +} - for(base= FIRSTBASE; base; base= base->next) { - if(TESTBASELIB(v3d, base)) { - if(base->object->parent) base->object->partype |= PARSLOW; - } - } - BIF_undo_push("Slow parent"); +void OBJECT_OT_clear_slowparent(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name= "Clear Slow Parent"; + ot->idname= "OBJECT_OT_clear_slow_parent"; + + /* api callbacks */ + ot->invoke= WM_operator_confirm; + ot->exec= object_clear_slowparent_exec; + ot->poll= ED_operator_view3d_active; } +/* ******************** **************** */ // XXX #define BEZSELECTED_HIDDENHANDLES(bezt) ((G.f & G_HIDDENHANDLES) ? (bezt)->f2 & SELECT : BEZSELECTED(bezt)) @@ -6308,55 +6337,3 @@ void hookmenu(Scene *scene, View3D *v3d) allqueue(REDRAWBUTSEDIT, 0); } } - -void hide_objects(Scene *scene, View3D *v3d, int select) -{ - Base *base; - short changed = 0, changed_act = 0; - for(base = FIRSTBASE; base; base=base->next){ - if ((base->lay & v3d->lay) && TESTBASELIB(v3d, base)==select) { - base->flag &= ~SELECT; - base->object->flag = base->flag; - base->object->restrictflag |= OB_RESTRICT_VIEW; - changed = 1; - if (base==BASACT) { - BASACT= NULL; - changed_act = 1; - } - } - } - if (changed) { - if(select) BIF_undo_push("Hide Selected Objects"); - else if(select) BIF_undo_push("Hide Unselected Objects"); - DAG_scene_sort(scene); - allqueue(REDRAWVIEW3D,0); - allqueue(REDRAWOOPS,0); - allqueue(REDRAWDATASELECT,0); - if (changed_act) { /* these spaces depend on the active object */ - allqueue(REDRAWBUTSALL,0); - allqueue(REDRAWIPO,0); - allqueue(REDRAWACTION,0); - } - } -} - -void show_objects(Scene *scene, View3D *v3d) -{ - Base *base; - int changed = 0; - - for(base = FIRSTBASE; base; base=base->next){ - if((base->lay & v3d->lay) && base->object->restrictflag & OB_RESTRICT_VIEW) { - base->flag |= SELECT; - base->object->flag = base->flag; - base->object->restrictflag &= ~OB_RESTRICT_VIEW; - changed = 1; - } - } - if (changed) { - BIF_undo_push("Unhide Objects"); - DAG_scene_sort(scene); - allqueue(REDRAWVIEW3D,0); - allqueue(REDRAWOOPS,0); - } -} diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 21dace8e0d6..f9143ce26da 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -51,6 +51,8 @@ void OBJECT_OT_clear_scale(wmOperatorType *ot); void OBJECT_OT_clear_origin(wmOperatorType *ot); void OBJECT_OT_clear_restrictview(wmOperatorType *ot); void OBJECT_OT_set_restrictview(wmOperatorType *ot); +void OBJECT_OT_set_slowparent(wmOperatorType *ot); +void OBJECT_OT_clear_slowparent(wmOperatorType *ot); #endif /* ED_OBJECT_INTERN_H */ diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index a15e606c12e..9c287302c10 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -79,6 +79,8 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_clear_origin); WM_operatortype_append(OBJECT_OT_clear_restrictview); WM_operatortype_append(OBJECT_OT_set_restrictview); + WM_operatortype_append(OBJECT_OT_set_slowparent); + WM_operatortype_append(OBJECT_OT_clear_slowparent); } void ED_keymap_object(wmWindowManager *wm) diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index e2cafeceb9e..5aa8a5b466b 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -206,33 +206,31 @@ void ED_region_do_draw(bContext *C, ARegion *ar) /* note; this sets state, so we can use wmOrtho and friends */ wmSubWindowSet(win, ar->swinid); - if(ar->swinid) { - /* optional header info instead? */ - if(ar->headerstr) { - float col[3]; - UI_SetTheme(sa); - UI_GetThemeColor3fv(TH_HEADER, col); - glClearColor(col[0], col[1], col[2], 0.0); - glClear(GL_COLOR_BUFFER_BIT); - - UI_ThemeColor(TH_MENU_TEXT); - glRasterPos2i(20, 6); - BMF_DrawString(G.font, ar->headerstr); - } - else if(at->draw) { - UI_SetTheme(sa); - at->draw(C, ar); - UI_SetTheme(NULL); - } - - if(sa) - region_draw_emboss(ar); - - uiFreeInactiveBlocks(C, &ar->uiblocks); + /* optional header info instead? */ + if(ar->headerstr) { + float col[3]; + UI_SetTheme(sa); + UI_GetThemeColor3fv(TH_HEADER, col); + glClearColor(col[0], col[1], col[2], 0.0); + glClear(GL_COLOR_BUFFER_BIT); - /* XXX test: add convention to end regions always in pixel space, for drawing of borders/gestures etc */ - ED_region_pixelspace(ar); + UI_ThemeColor(TH_MENU_TEXT); + glRasterPos2i(20, 6); + BMF_DrawString(G.font, ar->headerstr); } + else if(at->draw) { + UI_SetTheme(sa); + at->draw(C, ar); + UI_SetTheme(NULL); + } + + if(sa) + region_draw_emboss(ar); + + uiFreeInactiveBlocks(C, &ar->uiblocks); + + /* XXX test: add convention to end regions always in pixel space, for drawing of borders/gestures etc */ + ED_region_pixelspace(ar); ar->do_draw= 0; } diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 536ce9cee74..d78fdbbae6e 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1119,7 +1119,8 @@ static void screen_cursor_set(wmWindow *win, wmEvent *event) } -/* called in wm_event_system.c. sets state var in screen */ +/* called in wm_event_system.c. sets state vars in screen, cursors */ +/* event type is mouse move */ void ED_screen_set_subwinactive(wmWindow *win, wmEvent *event) { if(win->screen) { diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c new file mode 100644 index 00000000000..34094c99120 --- /dev/null +++ b/source/blender/editors/screen/screendump.c @@ -0,0 +1,131 @@ +/** + * $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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + * Making screendumps. + */ + +#include <string.h> + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" + +#include "BKE_context.h" +#include "BKE_global.h" +#include "BKE_image.h" +#include "BKE_utildefines.h" + +#include "BIF_gl.h" + +#include "WM_types.h" +#include "WM_api.h" + +static unsigned int *dumprect= NULL; +static int dumpsx, dumpsy; + +/* XXX */ +static int saveover() {return 0;} + +/* Callback */ +void write_screendump(bContext *C, char *name) +{ + Scene *scene= CTX_data_scene(C); + ImBuf *ibuf; + + if(dumprect) { + + strcpy(G.ima, name); + BLI_convertstringcode(name, G.sce); + BLI_convertstringframe(name, scene->r.cfra); /* TODO - is this ever used? */ + + /* BKE_add_image_extension() checks for if extension was already set */ + if(scene->r.scemode & R_EXTENSION) + if(strlen(name)<FILE_MAXDIR+FILE_MAXFILE-5) + BKE_add_image_extension(scene, name, scene->r.imtype); + + if(saveover(name)) { +// waitcursor(1); + + ibuf= IMB_allocImBuf(dumpsx, dumpsy, 24, 0, 0); + ibuf->rect= dumprect; + + if(scene->r.planes == 8) IMB_cspace(ibuf, rgb_to_bw); + + BKE_write_ibuf(scene, ibuf, name, scene->r.imtype, scene->r.subimtype, scene->r.quality); + + IMB_freeImBuf(ibuf); + +// waitcursor(0); + } + MEM_freeN(dumprect); + dumprect= NULL; + } +} + +/* get dump from frontbuffer */ +void ED_screendump(bContext *C, int fscreen) +{ + wmWindow *win= CTX_wm_window(C); + ScrArea *curarea= CTX_wm_area(C); + int x=0, y=0; +// char imstr[64]; + + if(dumprect) MEM_freeN(dumprect); + dumprect= NULL; + + if(fscreen) { /* full screen */ + x= 0; + y= 0; + dumpsx= win->sizex; + dumpsy= win->sizey; + + } + else { + x= curarea->totrct.xmin; + y= curarea->totrct.ymin; + dumpsx= curarea->totrct.xmax-x; + dumpsy= curarea->totrct.ymax-y; + } + + if (dumpsx && dumpsy) { + + dumprect= MEM_mallocN(sizeof(int)*dumpsx*dumpsy, "dumprect"); + glReadBuffer(GL_FRONT); + glReadPixels(x, y, dumpsx, dumpsy, GL_RGBA, GL_UNSIGNED_BYTE, dumprect); + glFinish(); + glReadBuffer(GL_BACK); + + // save_image_filesel_str(imstr); + // activate_fileselect(FILE_SPECIAL, imstr, G.ima, write_screendump); + } + +} diff --git a/source/blender/editors/sculpt/sculpt.c b/source/blender/editors/sculpt/sculpt.c index 4a81744a79a..cf670434e50 100644 --- a/source/blender/editors/sculpt/sculpt.c +++ b/source/blender/editors/sculpt/sculpt.c @@ -32,8 +32,6 @@ * */ -// XXX #include "GHOST_Types.h" - #include "MEM_guardedalloc.h" #include "BLI_arithb.h" @@ -164,39 +162,25 @@ typedef struct ProjVert { static Object *active_ob= NULL; -SculptData *sculpt_data(void) -{ - return NULL; /*XXX: return &G.scene->sculptdata; */ -} - -static void sculpt_init_session(void); -static void init_brushaction(BrushAction *a, short *, short *); -static void sculpt_undo_push(const short); +static void init_brushaction(SculptData *sd, BrushAction *a, short *, short *); -SculptSession *sculpt_session(void) -{ - if(!sculpt_data()->session) - sculpt_init_session(); - return sculpt_data()->session; -} /* ===== MEMORY ===== * * Allocate/initialize/free data */ -static void sculpt_init_session(void) +static void sculpt_init_session(SculptData *sd) { - if(sculpt_data()->session) + if(sd->session) ;/*XXX: sculptsession_free(G.scene); */ - sculpt_data()->session= MEM_callocN(sizeof(SculptSession), "SculptSession"); + sd->session= MEM_callocN(sizeof(SculptSession), "SculptSession"); } /* vertex_users is an array of Lists that store all the faces that use a particular vertex. vertex_users is in the same order as mesh.mvert */ -static void calc_vertex_users() +static void calc_vertex_users(SculptSession *ss) { - SculptSession *ss= sculpt_session(); int i,j; IndexNode *node= NULL; @@ -236,7 +220,7 @@ void sculptmode_rem_tex(void *junk0,void *junk1) MEM_freeN(ss->texcache); ss->texcache= NULL; } - BIF_undo_push("Unlink brush texture"); + // XXX BIF_undo_push("Unlink brush texture"); allqueue(REDRAWBUTSEDIT, 0); allqueue(REDRAWOOPS, 0); } @@ -292,9 +276,8 @@ float get_depth(short x, short y) /* Uses window coordinates (x,y) and depth component z to find a point in modelspace */ -void unproject(float out[3], const short x, const short y, const float z) +void unproject(SculptSession *ss, float out[3], const short x, const short y, const float z) { - SculptSession *ss= sculpt_session(); double ux, uy, uz; gluUnProject(x,y,z, ss->mats->modelview, ss->mats->projection, @@ -305,9 +288,8 @@ void unproject(float out[3], const short x, const short y, const float z) } /* Convert a point in model coordinates to 2D screen coordinates. */ -static void projectf(const float v[3], float p[2]) +static void projectf(SculptSession *ss, const float v[3], float p[2]) { - SculptSession *ss= sculpt_session(); double ux, uy, uz; gluProject(v[0],v[1],v[2], ss->mats->modelview, ss->mats->projection, @@ -316,10 +298,10 @@ static void projectf(const float v[3], float p[2]) p[1]= uy; } -static void project(const float v[3], short p[2]) +static void project(SculptSession *ss, const float v[3], short p[2]) { float f[2]; - projectf(v, f); + projectf(ss, v, f); p[0]= f[0]; p[1]= f[1]; @@ -333,12 +315,11 @@ static void project(const float v[3], short p[2]) shrink the brush. Skipped for grab brush because only the first mouse down size is used, which is small if the user has just touched the pen to the tablet */ -char brush_size(Brush *b) +char brush_size(SculptData *sd, Brush *b) { - SculptData *sd = NULL; /* XXX */ float size= b->size; float pressure= 0; /* XXX: get_pressure(); */ - short activedevice= get_activedevice(); + short activedevice= 0; /* XXX: get_activedevice(); */ if(b->sculpt_tool!=SCULPT_TOOL_GRAB) { const float size_factor= sd->tablet_size / 10.0f; @@ -355,12 +336,11 @@ char brush_size(Brush *b) /* Return modified brush strength. Includes the direction of the brush, positive values pull vertices, negative values push. Uses tablet pressure and a special multiplier found experimentally to scale the strength factor. */ -float brush_strength(Brush *b, BrushAction *a) +float brush_strength(SculptData *sd, Brush *b, BrushAction *a) { - SculptData *sd = NULL; /* XXX */ float dir= b->flag & BRUSH_DIR_IN ? -1 : 1; float pressure= 1; - short activedevice= get_activedevice(); + short activedevice= 0;/*XXX: get_activedevice(); */ float flip= a->flip ? -1:1; float anchored = b->flag & BRUSH_ANCHORED ? 25 : 1; @@ -408,9 +388,8 @@ void sculpt_clip(const BrushAction *a, float *co, const float val[3]) } } -void sculpt_axislock(float *co) +void sculpt_axislock(SculptData *sd, float *co) { - SculptData *sd = sculpt_data(); if (sd->flags & (SCULPT_LOCK_X|SCULPT_LOCK_Y|SCULPT_LOCK_Z)) return; /* XXX: if(G.vd->twmode == V3D_MANIP_LOCAL) { */ if(0) { @@ -444,16 +423,15 @@ static void add_norm_if(float view_vec[3], float out[3], float out_flip[3], cons /* Currently only for the draw brush; finds average normal for all active vertices */ -void calc_area_normal(float out[3], const BrushAction *a, const float *outdir, const ListBase* active_verts) +void calc_area_normal(SculptData *sd, float out[3], const BrushAction *a, const float *outdir, const ListBase* active_verts) { ActiveData *node = active_verts->first; - SculptData *sd = sculpt_data(); const int view = 0; /* XXX: should probably be a flag, not number: sd->brush_type==SCULPT_TOOL_DRAW ? sculptmode_brush()->view : 0; */ float out_flip[3]; out[0]=out[1]=out[2] = out_flip[0]=out_flip[1]=out_flip[2] = 0; - if(sculptmode_brush()->flag & BRUSH_ANCHORED) { + if(sd->brush->flag & BRUSH_ANCHORED) { for(; node; node = node->next) add_norm_if(((BrushAction*)a)->symm.out, out, out_flip, a->orig_norms[node->Index]); } @@ -477,14 +455,14 @@ void calc_area_normal(float out[3], const BrushAction *a, const float *outdir, c Normalize(out); } -void do_draw_brush(SculptSession *ss, const BrushAction *a, const ListBase* active_verts) +void do_draw_brush(SculptData *sd, SculptSession *ss, const BrushAction *a, const ListBase* active_verts) { float area_normal[3]; ActiveData *node= active_verts->first; - calc_area_normal(area_normal, a, a->symm.out, active_verts); + calc_area_normal(sd, area_normal, a, a->symm.out, active_verts); - sculpt_axislock(area_normal); + sculpt_axislock(sd, area_normal); while(node){ float *co= ss->mvert[node->Index].co; @@ -576,14 +554,14 @@ void do_pinch_brush(SculptSession *ss, const BrushAction *a, const ListBase* act } } -void do_grab_brush(SculptSession *ss, BrushAction *a) +void do_grab_brush(SculptData *sd, SculptSession *ss, BrushAction *a) { ActiveData *node= a->grab_active_verts[a->symm.index].first; float add[3]; float grab_delta[3]; VecCopyf(grab_delta, a->symm.grab_delta); - sculpt_axislock(grab_delta); + sculpt_axislock(sd, grab_delta); while(node) { float *co= ss->mvert[node->Index].co; @@ -598,13 +576,13 @@ void do_grab_brush(SculptSession *ss, BrushAction *a) } -void do_layer_brush(SculptSession *ss, BrushAction *a, const ListBase *active_verts) +void do_layer_brush(SculptData *sd, SculptSession *ss, BrushAction *a, const ListBase *active_verts) { float area_normal[3]; ActiveData *node= active_verts->first; - const float bstr= brush_strength(sculptmode_brush(), a); + const float bstr= brush_strength(sd, sd->brush, a); - calc_area_normal(area_normal, a, NULL, active_verts); + calc_area_normal(sd, area_normal, a, NULL, active_verts); while(node){ float *disp= &a->layer_disps[node->Index]; @@ -682,14 +660,14 @@ void calc_flatten_center(SculptSession *ss, ActiveData *node, float co[3]) VecMulf(co, 1.0f / FLATTEN_SAMPLE_SIZE); } -void do_flatten_brush(SculptSession *ss, const BrushAction *a, const ListBase *active_verts) +void do_flatten_brush(SculptData *sd, SculptSession *ss, const BrushAction *a, const ListBase *active_verts) { ActiveData *node= active_verts->first; /* area_normal and cntr define the plane towards which vertices are squashed */ float area_normal[3]; float cntr[3]; - calc_area_normal(area_normal, a, a->symm.out, active_verts); + calc_area_normal(sd, area_normal, a, a->symm.out, active_verts); calc_flatten_center(ss, node, cntr); while(node){ @@ -733,17 +711,15 @@ void flip_coord(float co[3], const char symm) } /* Use the warpfac field in MTex to store a rotation value for sculpt textures. Value is in degrees */ -float sculpt_tex_angle(void) +float sculpt_tex_angle(SculptData *sd) { - SculptData *sd= sculpt_data(); if(sd->texact!=-1 && sd->mtex[sd->texact]) return sd->mtex[sd->texact]->warpfac; return 0; } -void set_tex_angle(const float f) +void set_tex_angle(SculptData *sd, const float f) { - SculptData *sd = sculpt_data(); if(sd->texact != -1 && sd->mtex[sd->texact]) sd->mtex[sd->texact]->warpfac = f; } @@ -796,10 +772,9 @@ static float get_texcache_pixel_bilinear(const SculptSession *ss, float u, float } /* Return a multiplier for brush strength on a particular vertex. */ -float tex_strength(BrushAction *a, float *point, const float len,const unsigned vindex) +float tex_strength(SculptData *sd, BrushAction *a, float *point, const float len,const unsigned vindex) { - SculptData *sd= sculpt_data(); - SculptSession *ss= sculpt_session(); + SculptSession *ss= sd->session; float avg= 1; if(sd->texact==-1 || !sd->mtex[sd->texact]) @@ -824,7 +799,7 @@ float tex_strength(BrushAction *a, float *point, const float len,const unsigned } else if(ss->texcache) { const float bsize= a->radius * 2; - const float rot= to_rad(sculpt_tex_angle()) + a->anchored_rot; + const float rot= to_rad(sculpt_tex_angle(sd)) + a->anchored_rot; int px, py; float flip[3], point_2d[2]; @@ -833,7 +808,7 @@ float tex_strength(BrushAction *a, float *point, const float len,const unsigned that the brush texture will be oriented correctly. */ VecCopyf(flip, point); flip_coord(flip, a->symm.index); - projectf(flip, point_2d); + projectf(ss, flip, point_2d); /* For Tile and Drag modes, get the 2D screen coordinates of the and scale them up or down to the texture size. */ @@ -881,22 +856,21 @@ float tex_strength(BrushAction *a, float *point, const float len,const unsigned /* Mark area around the brush as damaged. projverts are marked if they are inside the area and the damaged rectangle in 2D screen coordinates is added to damaged_rects. */ -void sculpt_add_damaged_rect(BrushAction *a) +void sculpt_add_damaged_rect(SculptSession *ss, BrushAction *a) { short p[2]; RectNode *rn= MEM_mallocN(sizeof(RectNode),"RectNode"); - SculptSession *ss = sculpt_session(); const float radius = a->radius > a->prev_radius ? a->radius : a->prev_radius; unsigned i; /* Find center */ - project(a->symm.center_3d, p); + project(ss, a->symm.center_3d, p); rn->r.xmin= p[0] - radius; rn->r.ymin= p[1] - radius; rn->r.xmax= p[0] + radius; rn->r.ymax= p[1] + radius; - BLI_addtail(&sculpt_session()->damaged_rects, rn); + BLI_addtail(&ss->damaged_rects, rn); /* Update insides */ for(i=0; i<ss->totvert; ++i) { @@ -939,7 +913,7 @@ void sculpt_clear_damaged_areas(SculptSession *ss) } } -void do_brush_action(Brush *b, BrushAction *a) +void do_brush_action(SculptData *sd, BrushAction *a) { int i; float av_dist; @@ -947,12 +921,12 @@ void do_brush_action(Brush *b, BrushAction *a) ActiveData *adata= 0; float *vert; Mesh *me= NULL; /*XXX: get_mesh(OBACT); */ - const float bstrength= brush_strength(sculptmode_brush(), a); + const float bstrength= brush_strength(sd, sd->brush, a); KeyBlock *keyblock= NULL; /*XXX: ob_get_keyblock(OBACT); */ - SculptData *sd = sculpt_data(); - SculptSession *ss = sculpt_session(); + SculptSession *ss = sd->session; + Brush *b = sd->brush; - sculpt_add_damaged_rect(a); + sculpt_add_damaged_rect(ss, a); /* Build a list of all vertices that are potentially within the brush's area of influence. Only do this once for the grab brush. */ @@ -969,7 +943,7 @@ void do_brush_action(Brush *b, BrushAction *a) adata->Index = i; /* Fade is used to store the final strength at which the brush should modify a particular vertex. */ - adata->Fade= tex_strength(a, vert, av_dist, i) * bstrength; + adata->Fade= tex_strength(sd, a, vert, av_dist, i) * bstrength; adata->dist = av_dist; if(b->sculpt_tool == SCULPT_TOOL_GRAB && a->firsttime) @@ -986,7 +960,7 @@ void do_brush_action(Brush *b, BrushAction *a) /* Apply one type of brush action */ switch(b->sculpt_tool){ case SCULPT_TOOL_DRAW: - do_draw_brush(ss, a, &active_verts); + do_draw_brush(sd, ss, a, &active_verts); break; case SCULPT_TOOL_SMOOTH: do_smooth_brush(ss, a, &active_verts); @@ -998,13 +972,13 @@ void do_brush_action(Brush *b, BrushAction *a) do_inflate_brush(ss, a, &active_verts); break; case SCULPT_TOOL_GRAB: - do_grab_brush(ss, a); + do_grab_brush(sd, ss, a); break; case SCULPT_TOOL_LAYER: - do_layer_brush(ss, a, &active_verts); + do_layer_brush(sd, ss, a, &active_verts); break; case SCULPT_TOOL_FLATTEN: - do_flatten_brush(ss, a, &active_verts); + do_flatten_brush(sd, ss, a, &active_verts); break; } @@ -1046,16 +1020,15 @@ void calc_brushdata_symm(BrushAction *a, const char symm) flip_coord(a->symm.grab_delta, symm); } -void do_symmetrical_brush_actions(BrushAction *a, short co[2], short pr_co[2]) +void do_symmetrical_brush_actions(SculptData *sd, BrushAction *a, short co[2], short pr_co[2]) { - SculptData *sd = NULL; // XXX const char symm = sd->flags & 7; BrushActionSymm orig; int i; - init_brushaction(a, co, pr_co); + init_brushaction(sd, a, co, pr_co); orig = a->symm; - do_brush_action(sd->brush, a); + do_brush_action(sd, a); for(i = 1; i <= symm; ++i) { if(symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5))) { @@ -1063,7 +1036,7 @@ void do_symmetrical_brush_actions(BrushAction *a, short co[2], short pr_co[2]) a->symm = orig; calc_brushdata_symm(a, i); - do_brush_action(sd->brush, a); + do_brush_action(sd, a); } } @@ -1093,14 +1066,13 @@ void add_face_normal(vec3f *norm, MVert *mvert, const MFace* face, float *fn) norm->z+= final[2]; } -void update_damaged_vert(ListBase *lb, BrushAction *a) +void update_damaged_vert(SculptSession *ss, ListBase *lb, BrushAction *a) { ActiveData *vert; - SculptSession *ss = sculpt_session(); for(vert= lb->first; vert; vert= vert->next) { vec3f norm= {0,0,0}; - IndexNode *face= sculpt_session()->vertex_users[vert->Index].first; + IndexNode *face= ss->vertex_users[vert->Index].first; while(face){ float *fn = NULL; @@ -1117,16 +1089,16 @@ void update_damaged_vert(ListBase *lb, BrushAction *a) } } -void calc_damaged_verts(ListBase *damaged_verts, BrushAction *a) +void calc_damaged_verts(SculptSession *ss, BrushAction *a) { int i; for(i=0; i<8; ++i) - update_damaged_vert(&a->grab_active_verts[i], a); + update_damaged_vert(ss, &a->grab_active_verts[i], a); - update_damaged_vert(damaged_verts, a); - BLI_freelistN(damaged_verts); - damaged_verts->first = damaged_verts->last = NULL; + update_damaged_vert(ss, &ss->damaged_verts, a); + BLI_freelistN(&ss->damaged_verts); + ss->damaged_verts.first = ss->damaged_verts.last = NULL; } void projverts_clear_inside(SculptSession *ss) @@ -1136,10 +1108,9 @@ void projverts_clear_inside(SculptSession *ss) ss->projverts[i].inside = 0; } -void sculptmode_update_tex() +void sculptmode_update_tex(SculptData *sd) { - SculptData *sd= sculpt_data(); - SculptSession *ss= sculpt_session(); + SculptSession *ss= sd->session; MTex *mtex = sd->mtex[sd->texact]; TexResult texres = {0}; float x, y, step=2.0/TC_SIZE, co[3]; @@ -1188,10 +1159,9 @@ void sculptmode_update_tex() } /* pr_mouse is only used for the grab brush, can be NULL otherwise */ -static void init_brushaction(BrushAction *a, short *mouse, short *pr_mouse) +static void init_brushaction(SculptData *sd, BrushAction *a, short *mouse, short *pr_mouse) { - SculptData *sd = sculpt_data(); - SculptSession *ss = sculpt_session(); + SculptSession *ss = sd->session; Brush *b = sd->brush; Object *ob = NULL; /* XXX */ const float mouse_depth = get_depth(mouse[0], mouse[1]); @@ -1199,9 +1169,9 @@ static void init_brushaction(BrushAction *a, short *mouse, short *pr_mouse) ModifierData *md; int i; const char flip = 0; /*XXX: (get_qual() == LR_SHIFTKEY); */ - const char anchored = sculptmode_brush()->flag & BRUSH_ANCHORED; + const int anchored = sd->brush->flag & BRUSH_ANCHORED; short orig_mouse[2], dx=0, dy=0; - float size = brush_size(b); + float size = brush_size(sd, b); a->flip = flip; a->symm.index = 0; @@ -1212,23 +1182,23 @@ static void init_brushaction(BrushAction *a, short *mouse, short *pr_mouse) /* Convert the location and size of the brush to modelspace coords */ if(a->firsttime || !anchored) { - unproject(a->symm.center_3d, mouse[0], mouse[1], mouse_depth); + unproject(ss, a->symm.center_3d, mouse[0], mouse[1], mouse_depth); a->mouse[0] = mouse[0]; a->mouse[1] = mouse[1]; } if(anchored) { - project(a->symm.center_3d, orig_mouse); + project(ss, a->symm.center_3d, orig_mouse); dx = mouse[0] - orig_mouse[0]; dy = mouse[1] - orig_mouse[1]; } if(anchored) { - unproject(brush_edge_loc, mouse[0], mouse[1], a->depth); + unproject(ss, brush_edge_loc, mouse[0], mouse[1], a->depth); a->anchored_rot = atan2(dy, dx); } else - unproject(brush_edge_loc, mouse[0] + size, mouse[1], mouse_depth); + unproject(ss, brush_edge_loc, mouse[0] + size, mouse[1], mouse_depth); a->size_3d = VecLenf(a->symm.center_3d, brush_edge_loc); @@ -1244,10 +1214,10 @@ static void init_brushaction(BrushAction *a, short *mouse, short *pr_mouse) VecCopyf(sd->pivot, a->symm.center_3d); /* Now project the Up, Right, and Out normals from view to model coords */ - unproject(zero_loc, 0, 0, 0); - unproject(a->symm.up, 0, -1, 0); - unproject(a->symm.right, 1, 0, 0); - unproject(a->symm.out, 0, 0, -1); + unproject(ss, zero_loc, 0, 0, 0); + unproject(ss, a->symm.up, 0, -1, 0); + unproject(ss, a->symm.right, 1, 0, 0); + unproject(ss, a->symm.out, 0, 0, -1); VecSubf(a->symm.up, a->symm.up, zero_loc); VecSubf(a->symm.right, a->symm.right, zero_loc); VecSubf(a->symm.out, a->symm.out, zero_loc); @@ -1276,8 +1246,8 @@ static void init_brushaction(BrushAction *a, short *mouse, short *pr_mouse) float gcenter[3]; /* Find the delta */ - unproject(gcenter, mouse[0], mouse[1], a->depth); - unproject(oldloc, pr_mouse[0], pr_mouse[1], a->depth); + unproject(ss, gcenter, mouse[0], mouse[1], a->depth); + unproject(ss, oldloc, pr_mouse[0], pr_mouse[1], a->depth); VecSubf(a->symm.grab_delta, gcenter, oldloc); } else if(b->sculpt_tool == SCULPT_TOOL_LAYER) { @@ -1444,16 +1414,15 @@ void sculptmode_selectbrush_menu(void) }*/ } -void sculptmode_update_all_projverts(float *vertcosnos) +void sculptmode_update_all_projverts(SculptSession *ss) { - SculptSession *ss = sculpt_session(); unsigned i; if(!ss->projverts) ss->projverts = MEM_mallocN(sizeof(ProjVert)*ss->totvert,"ProjVerts"); for(i=0; i<ss->totvert; ++i) { - project(vertcosnos ? &vertcosnos[i * 6] : ss->mvert[i].co, ss->projverts[i].co); + project(ss, ss->vertexcosnos ? &ss->vertexcosnos[i * 6] : ss->mvert[i].co, ss->projverts[i].co); ss->projverts[i].inside= 0; } } @@ -1593,21 +1562,43 @@ void sculptmode_draw_mesh(int only_damaged) } #endif -void sculptmode_correct_state(void) + +static void sculpt_undo_push(SculptData *sd) { - if(!sculpt_session()) - sculpt_init_session(); + /*XXX: switch(sd->brush->sculpt_tool) { + case SCULPT_TOOL_DRAW: + BIF_undo_push("Draw Brush"); break; + case SCULPT_TOOL_SMOOTH: + BIF_undo_push("Smooth Brush"); break; + case SCULPT_TOOL_PINCH: + BIF_undo_push("Pinch Brush"); break; + case SCULPT_TOOL_INFLATE: + BIF_undo_push("Inflate Brush"); break; + case SCULPT_TOOL_GRAB: + BIF_undo_push("Grab Brush"); break; + case SCULPT_TOOL_LAYER: + BIF_undo_push("Layer Brush"); break; + case SCULPT_TOOL_FLATTEN: + BIF_undo_push("Flatten Brush"); break; + default: + BIF_undo_push("Sculpting"); break; + }*/ +} + +void sculptmode_correct_state(SculptData *sd) +{ + if(!sd->session) + sculpt_init_session(sd); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); - if(!sculpt_session()->vertex_users) calc_vertex_users(); + if(!sd->session->vertex_users) calc_vertex_users(sd->session); } -void sculpt(void) +void sculpt(SculptData *sd) { - SculptData *sd= sculpt_data(); - SculptSession *ss= sculpt_session(); + SculptSession *ss= sd->session; Object *ob= NULL; /*XXX */ Mesh *me; MultiresModifierData *mmd = NULL; @@ -1634,11 +1625,11 @@ void sculpt(void) }*/ if(!ss) { - sculpt_init_session(); + sculpt_init_session(sd); ss= sd->session; } - anchored = sculptmode_brush()->flag & BRUSH_ANCHORED; + anchored = sd->brush->flag & BRUSH_ANCHORED; smooth_stroke = (sd->flags & SCULPT_INPUT_SMOOTH) && (sd->brush->sculpt_tool != SCULPT_TOOL_GRAB) && !anchored; if(smooth_stroke) @@ -1654,7 +1645,7 @@ void sculpt(void) /* Check that vertex users are up-to-date */ if(ob != active_ob || !ss->vertex_users || ss->vertex_users_size != ss->totvert) { sculpt_vertexusers_free(ss); - calc_vertex_users(); + calc_vertex_users(ss); if(ss->projverts) MEM_freeN(ss->projverts); ss->projverts = NULL; @@ -1671,9 +1662,9 @@ void sculpt(void) /* Init texture FIXME: Shouldn't be doing this every time! */ if(sd->texrept!=SCULPTREPT_3D) - sculptmode_update_tex(); + sculptmode_update_tex(sd); - getmouseco_areawin(mouse); + /*XXX: getmouseco_areawin(mouse); */ mvalo[0]= mouse[0]; mvalo[1]= mouse[1]; lastSigMouse[0]=mouse[0]; @@ -1689,7 +1680,7 @@ void sculpt(void) if(modifier_calculations) ss->vertexcosnos= mesh_get_mapped_verts_nors(NULL, ob); /* XXX: scene = ? */ - sculptmode_update_all_projverts(ss->vertexcosnos); + sculptmode_update_all_projverts(ss); /* Set scaling adjustment */ a->scale[0]= 1.0f / ob->size[0]; @@ -1704,27 +1695,27 @@ void sculpt(void) glGetIntegerv(GL_SCISSOR_BOX, scissor_box); /* For raking, get the original angle*/ - offsetRot=sculpt_tex_angle(); + offsetRot=sculpt_tex_angle(sd); me = get_mesh(ob); - while (get_mbut() & mousebut) { - getmouseco_areawin(mouse); + while (/*XXX:get_mbut() & mousebut*/0) { + /* XXX: getmouseco_areawin(mouse); */ /* If rake, and the mouse has moved over 10 pixels (euclidean) (prevents jitter) then get the new angle */ if (rake && (pow(lastSigMouse[0]-mouse[0],2)+pow(lastSigMouse[1]-mouse[1],2))>100){ /*Nasty looking, but just orig + new angle really*/ - set_tex_angle(offsetRot+180.+to_deg(atan2((float)(mouse[1]-lastSigMouse[1]),(float)(mouse[0]-lastSigMouse[0])))); + set_tex_angle(sd, offsetRot+180.+to_deg(atan2((float)(mouse[1]-lastSigMouse[1]),(float)(mouse[0]-lastSigMouse[0])))); lastSigMouse[0]=mouse[0]; lastSigMouse[1]=mouse[1]; } if(firsttime || mouse[0]!=mvalo[0] || mouse[1]!=mvalo[1] || - sculptmode_brush()->flag & BRUSH_AIRBRUSH) { + sd->brush->flag & BRUSH_AIRBRUSH) { a->firsttime = firsttime; firsttime= 0; if(smooth_stroke) - sculpt_stroke_add_point(mouse[0], mouse[1]); + sculpt_stroke_add_point(ss->stroke, mouse[0], mouse[1]); spacing+= sqrt(pow(mvalo[0]-mouse[0],2)+pow(mvalo[1]-mouse[1],2)); @@ -1743,32 +1734,32 @@ void sculpt(void) } } - do_symmetrical_brush_actions(a, mouse, NULL); + do_symmetrical_brush_actions(sd, a, mouse, NULL); } else { if(smooth_stroke) { - sculpt_stroke_apply(a); + sculpt_stroke_apply(sd, ss->stroke, a); } else if(sd->spacing==0 || spacing>sd->spacing) { - do_symmetrical_brush_actions(a, mouse, NULL); + do_symmetrical_brush_actions(sd, a, mouse, NULL); spacing= 0; } } } else { - do_symmetrical_brush_actions(a, mouse, mvalo); - unproject(sd->pivot, mouse[0], mouse[1], a->depth); + do_symmetrical_brush_actions(sd, a, mouse, mvalo); + unproject(ss, sd->pivot, mouse[0], mouse[1], a->depth); } if((!ss->multires && modifier_calculations) || ob_get_keyblock(ob)) ;/* XXX: DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); */ if(modifier_calculations || sd->brush->sculpt_tool == SCULPT_TOOL_GRAB || !(sd->flags & SCULPT_DRAW_FAST)) { - calc_damaged_verts(&ss->damaged_verts, a); - /*XXX: scrarea_do_windraw(curarea); */ - screen_swapbuffers(); + calc_damaged_verts(ss, a); + /*XXX: scrarea_do_windraw(curarea); + screen_swapbuffers(); */ } else { /* Optimized drawing */ - calc_damaged_verts(&ss->damaged_verts, a); + calc_damaged_verts(ss, a); /* Draw the stored image to the screen */ glAccum(GL_RETURN, 1); @@ -1777,7 +1768,7 @@ void sculpt(void) /* Draw all the polygons that are inside the modified area(s) */ glScissor(scissor_box[0], scissor_box[1], scissor_box[2], scissor_box[3]); - sculptmode_draw_mesh(1); + /* XXX: sculptmode_draw_mesh(1); */ glAccum(GL_LOAD, 1); projverts_clear_inside(ss); @@ -1786,12 +1777,12 @@ void sculpt(void) glDisable(GL_DEPTH_TEST); /* Draw cursor */ - if(sculpt_data()->flags & SCULPT_TOOL_DRAW) - fdrawXORcirc((float)mouse[0],(float)mouse[1],sculptmode_brush()->size); - if(smooth_stroke) - sculpt_stroke_draw(); + if(sd->flags & SCULPT_TOOL_DRAW) + fdrawXORcirc((float)mouse[0],(float)mouse[1],sd->brush->size); + /* XXX: if(smooth_stroke) + sculpt_stroke_draw(); - myswapbuffers(); + myswapbuffers(); */ } BLI_freelistN(&ss->damaged_rects); @@ -1806,15 +1797,15 @@ void sculpt(void) } } - else BIF_wait_for_statechange(); + else ;/*XXX:BIF_wait_for_statechange();*/ } /* Set the rotation of the brush back to what it was before any rake */ - set_tex_angle(offsetRot); + set_tex_angle(sd, offsetRot); if(smooth_stroke) { - sculpt_stroke_apply_all(a); - calc_damaged_verts(&ss->damaged_verts, a); + sculpt_stroke_apply_all(sd, ss->stroke, a); + calc_damaged_verts(ss, a); BLI_freelistN(&ss->damaged_rects); } @@ -1824,7 +1815,8 @@ void sculpt(void) for(i=0; i<8; ++i) BLI_freelistN(&a->grab_active_verts[i]); MEM_freeN(a); - sculpt_stroke_free(); + sculpt_stroke_free(ss->stroke); + ss->stroke = NULL; if(mmd) { if(mmd->undo_verts && mmd->undo_verts != ss->mvert) @@ -1834,65 +1826,44 @@ void sculpt(void) mmd->undo_verts_tot = ss->totvert; } - /* XXX: sculpt_undo_push(G.scene->sculptdata.brush_type); */ + sculpt_undo_push(sd); /* XXX: if(G.vd->depths) G.vd->depths->damaged= 1; allqueue(REDRAWVIEW3D, 0); */ } -static void sculpt_undo_push(const short brush_type) +void ED_sculpt_enter_sculptmode() { - switch(brush_type) { - case SCULPT_TOOL_DRAW: - BIF_undo_push("Draw Brush"); break; - case SCULPT_TOOL_SMOOTH: - BIF_undo_push("Smooth Brush"); break; - case SCULPT_TOOL_PINCH: - BIF_undo_push("Pinch Brush"); break; - case SCULPT_TOOL_INFLATE: - BIF_undo_push("Inflate Brush"); break; - case SCULPT_TOOL_GRAB: - BIF_undo_push("Grab Brush"); break; - case SCULPT_TOOL_LAYER: - BIF_undo_push("Layer Brush"); break; - case SCULPT_TOOL_FLATTEN: - BIF_undo_push("Flatten Brush"); break; - default: - BIF_undo_push("Sculpting"); break; - } + G.f |= G_SCULPTMODE; + + sculpt_init_session(NULL /*XXX*/); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + + active_ob = NULL; } -void set_sculptmode(void) +void ED_sculpt_exit_sculptmode() { - if(G.f & G_SCULPTMODE) { - Object *ob = NULL; /*XXX: OBACT; */ - Mesh *me= get_mesh(ob); + Object *ob = NULL; /*XXX: OBACT; */ + Mesh *me= get_mesh(ob); - multires_force_update(ob); + multires_force_update(ob); - G.f &= ~G_SCULPTMODE; + G.f &= ~G_SCULPTMODE; - /* XXX: sculptsession_free(G.scene); */ - if(me && me->pv) - mesh_pmv_off(ob, me); - } - else { - G.f |= G_SCULPTMODE; + /* XXX: sculptsession_free(G.scene); */ + if(me && me->pv) + mesh_pmv_off(ob, me); - /* Called here to sanity-check the brush */ - sculptmode_brush(); - - sculpt_init_session(); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - } - - active_ob= NULL; + active_ob = NULL; } /* Partial Mesh Visibility */ +/* XXX: Partial vis. always was a mess, have to figure something out */ +#if 0 /* mode: 0=hide outside selection, 1=hide inside selection */ static void sculptmode_do_pmv(Object *ob, rcti *hb_2d, int mode) { @@ -2115,3 +2086,4 @@ void sculptmode_pmv(int mode) waitcursor(0); } +#endif diff --git a/source/blender/editors/sculpt/sculpt_intern.h b/source/blender/editors/sculpt/sculpt_intern.h index 35a9861eceb..b25182cfb36 100644 --- a/source/blender/editors/sculpt/sculpt_intern.h +++ b/source/blender/editors/sculpt/sculpt_intern.h @@ -47,17 +47,7 @@ struct ScrArea; struct SculptData; struct SculptStroke; -struct SculptSession *sculpt_session(void); -struct SculptData *sculpt_data(void); - -/* Memory */ -void sculptmode_correct_state(void); - /* Interface */ -void sculptmode_draw_interface_tools(struct uiBlock *block,unsigned short cx, unsigned short cy); -void sculptmode_draw_interface_brush(struct uiBlock *block,unsigned short cx, unsigned short cy); -void sculptmode_draw_interface_textures(struct uiBlock *block,unsigned short cx, unsigned short cy); -void sculptmode_rem_tex(void*,void*); void sculptmode_selectbrush_menu(void); void sculptmode_draw_mesh(int); void sculpt_paint_brush(char clear); @@ -65,21 +55,17 @@ void sculpt_stroke_draw(); void sculpt_radialcontrol_start(int mode); struct Brush *sculptmode_brush(void); -void do_symmetrical_brush_actions(struct BrushAction *a, short *, short *); +void do_symmetrical_brush_actions(struct SculptData *sd, struct BrushAction *a, short *, short *); -void sculptmode_update_tex(void); char sculpt_modifiers_active(struct Object *ob); -void sculpt(void); -void set_sculptmode(void); +void sculpt(SculptData *sd); /* Stroke */ -void sculpt_stroke_new(const int max); -void sculpt_stroke_free(); -void sculpt_stroke_add_point(const short x, const short y); -void sculpt_stroke_apply(struct BrushAction *); -void sculpt_stroke_apply_all(struct BrushAction *); -void sculpt_stroke_draw(); - +struct SculptStroke *sculpt_stroke_new(const int max); +void sculpt_stroke_free(struct SculptStroke *); +void sculpt_stroke_add_point(struct SculptStroke *, const short x, const short y); +void sculpt_stroke_apply(struct SculptData *sd, struct SculptStroke *, struct BrushAction *); +void sculpt_stroke_apply_all(struct SculptData *sd, struct SculptStroke *, struct BrushAction *); /* Partial Mesh Visibility */ void sculptmode_pmv(int mode); diff --git a/source/blender/editors/sculpt/stroke.c b/source/blender/editors/sculpt/stroke.c index 482b2fcefe0..76523f1ff35 100644 --- a/source/blender/editors/sculpt/stroke.c +++ b/source/blender/editors/sculpt/stroke.c @@ -58,31 +58,27 @@ typedef struct SculptStroke { float offset; } SculptStroke; -void sculpt_stroke_new(const int max) +SculptStroke *sculpt_stroke_new(const int max) { - SculptSession *ss = sculpt_session(); - - ss->stroke = MEM_callocN(sizeof(SculptStroke), "SculptStroke"); - ss->stroke->loc = MEM_callocN(sizeof(short) * 4 * max, "SculptStroke.loc"); - ss->stroke->max = max; - ss->stroke->index = -1; + SculptStroke *stroke = MEM_callocN(sizeof(SculptStroke), "SculptStroke"); + stroke->loc = MEM_callocN(sizeof(short) * 4 * max, "SculptStroke.loc"); + stroke->max = max; + stroke->index = -1; + return stroke; } -void sculpt_stroke_free() +void sculpt_stroke_free(SculptStroke *stroke) { - SculptSession *ss = sculpt_session(); - if(ss && ss->stroke) { - if(ss->stroke->loc) MEM_freeN(ss->stroke->loc); - if(ss->stroke->final_mem) MEM_freeN(ss->stroke->final_mem); + if(stroke) { + if(stroke->loc) MEM_freeN(stroke->loc); + if(stroke->final_mem) MEM_freeN(stroke->final_mem); - MEM_freeN(ss->stroke); - ss->stroke = NULL; + MEM_freeN(stroke); } } -void sculpt_stroke_add_point(const short x, const short y) +void sculpt_stroke_add_point(SculptStroke *stroke, const short x, const short y) { - SculptStroke *stroke = sculpt_session()->stroke; const int next = stroke->index + 1; if(stroke->index == -1) { @@ -112,10 +108,8 @@ void sculpt_stroke_smooth(SculptStroke *stroke) } } -static void sculpt_stroke_create_final() +static void sculpt_stroke_create_final(SculptStroke *stroke) { - SculptStroke *stroke = sculpt_session()->stroke; - if(stroke) { StrokePoint *p, *pnext; int i; @@ -178,9 +172,9 @@ float sculpt_stroke_final_length(SculptStroke *stroke) } /* If partial is nonzero, cuts off apply after that length has been processed */ -static StrokePoint *sculpt_stroke_apply_generic(SculptStroke *stroke, struct BrushAction *a, const int partial) +static StrokePoint *sculpt_stroke_apply_generic(SculptData *sd, SculptStroke *stroke, struct BrushAction *a, const int partial) { - const int sdspace = sculpt_data()->spacing; + const int sdspace = sd->spacing; const short spacing = sdspace > 0 ? sdspace : 2; const int dots = sculpt_stroke_final_length(stroke) / spacing; int i; @@ -215,24 +209,23 @@ static StrokePoint *sculpt_stroke_apply_generic(SculptStroke *stroke, struct Bru co[0] = p->x*v + p->next->x*u; co[1] = p->y*v + p->next->y*u; - do_symmetrical_brush_actions(a, co, NULL); + do_symmetrical_brush_actions(sd, a, co, NULL); } return p ? p->next : NULL; } -void sculpt_stroke_apply(struct BrushAction *a) +void sculpt_stroke_apply(SculptData *sd, SculptStroke *stroke, struct BrushAction *a) { - SculptStroke *stroke = sculpt_session()->stroke; /* TODO: make these values user-modifiable? */ const int partial_len = 100; const int min_len = 200; if(stroke) { - sculpt_stroke_create_final(); + sculpt_stroke_create_final(stroke); if(sculpt_stroke_final_length(stroke) > min_len) { - StrokePoint *p = sculpt_stroke_apply_generic(stroke, a, partial_len); + StrokePoint *p = sculpt_stroke_apply_generic(sd, stroke, a, partial_len); /* Replace remaining values in stroke->loc with remaining stroke->final values */ stroke->index = -1; @@ -249,21 +242,18 @@ void sculpt_stroke_apply(struct BrushAction *a) } } -void sculpt_stroke_apply_all(struct BrushAction *a) +void sculpt_stroke_apply_all(SculptData *sd, SculptStroke *stroke, struct BrushAction *a) { - SculptStroke *stroke = sculpt_session()->stroke; - - sculpt_stroke_create_final(); + sculpt_stroke_create_final(stroke); if(stroke) { - sculpt_stroke_apply_generic(stroke, a, 0); + sculpt_stroke_apply_generic(sd, stroke, a, 0); } } -void sculpt_stroke_draw() +/* XXX: drawing goes elsewhere */ +void sculpt_stroke_draw(SculptStroke *stroke) { - SculptStroke *stroke = sculpt_session()->stroke; - if(stroke) { StrokePoint *p; diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index 325227a2fc5..8ed9bb10fd5 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -123,7 +123,60 @@ void ED_spacetypes_keymap(wmWindowManager *wm) } } -/* ****************************** space template *********************** */ +/* ********************** custom drawcall api ***************** */ + +/* type */ +#define REGION_DRAW_PRE 1 +#define REGION_DRAW_POST 0 + +typedef struct RegionDrawCB { + struct RegionDrawCB *next, *prev; + + void (*draw)(const struct bContext *, struct ARegion *); + + int type; + +} RegionDrawCB; + +void *ED_region_draw_cb_activate(ARegionType *art, + void (*draw)(const struct bContext *, struct ARegion *), + int type) +{ + RegionDrawCB *rdc= MEM_callocN(sizeof(RegionDrawCB), "RegionDrawCB"); + + BLI_addtail(&art->drawcalls, rdc); + rdc->draw= draw; + rdc->type= type; + + return rdc; +} + +void ED_region_draw_cb_exit(ARegionType *art, void *handle) +{ + RegionDrawCB *rdc; + + for(rdc= art->drawcalls.first; rdc; rdc= rdc->next) { + if(rdc==(RegionDrawCB *)handle) { + BLI_remlink(&art->drawcalls, rdc); + MEM_freeN(rdc); + return; + } + } +} + +void ED_region_draw_cb_draw(const bContext *C, ARegion *ar, int type) +{ + RegionDrawCB *rdc; + + for(rdc= ar->type->drawcalls.first; rdc; rdc= rdc->next) { + if(rdc->type==type) + rdc->draw(C, ar); + } +} + + + +/* ********************* space template *********************** */ /* allocate and init some vars */ static SpaceLink *xxx_new(const bContext *C) diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index 78e4116faef..c45993d71cb 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -128,7 +128,7 @@ static void do_file_buttons(bContext *C, void *arg, int event) void file_draw_buttons(const bContext *C, ARegion *ar) { SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); - FileSelectParams* params = sfile->params; + FileSelectParams* params = ED_fileselect_get_params(sfile); uiBlock *block; int loadbutton; char name[20]; @@ -277,7 +277,7 @@ static int file_view_columns(SpaceFile* sfile, View2D *v2d) void file_calc_previews(const bContext *C, ARegion *ar) { SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); - FileSelectParams* params = sfile->params; + FileSelectParams* params = ED_fileselect_get_params(sfile); View2D *v2d= &ar->v2d; int width=0, height=0; int rows, columns; @@ -316,7 +316,7 @@ void file_calc_previews(const bContext *C, ARegion *ar) void file_draw_previews(const bContext *C, ARegion *ar) { SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); - FileSelectParams* params=sfile->params; + FileSelectParams* params= ED_fileselect_get_params(sfile); View2D *v2d= &ar->v2d; static double lasttime= 0; struct FileList* files = sfile->files; @@ -471,7 +471,7 @@ void file_draw_previews(const bContext *C, ARegion *ar) void file_draw_list(const bContext *C, ARegion *ar) { SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); - FileSelectParams* params = sfile->params; + FileSelectParams* params = ED_fileselect_get_params(sfile); struct FileList* files = sfile->files; struct direntry *file; int numfiles; @@ -558,7 +558,7 @@ void file_draw_list(const bContext *C, ARegion *ar) void file_draw_fsmenu(const bContext *C, ARegion *ar) { SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); - FileSelectParams* params = sfile->params; + FileSelectParams* params = ED_fileselect_get_params(sfile); char bookmark[FILE_MAX]; int nentries = fsmenu_get_nentries(); int linestep = U.fontsize*3/2; diff --git a/source/blender/editors/space_file/file_header.c b/source/blender/editors/space_file/file_header.c index 2aeb8ed0684..cbe36f28c9d 100644 --- a/source/blender/editors/space_file/file_header.c +++ b/source/blender/editors/space_file/file_header.c @@ -117,7 +117,7 @@ void file_header_buttons(const bContext *C, ARegion *ar) { ScrArea *sa= CTX_wm_area(C); SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); - FileSelectParams* params = sfile->params; + FileSelectParams* params = ED_fileselect_get_params(sfile); uiBlock *block; int xco, yco= 3; diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index d9e831c84da..49014a69b68 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -116,7 +116,7 @@ static void set_active_file(SpaceFile *sfile, FileSelectParams* params, struct A } -static void set_active_bookmark(SpaceFile *sfile, FileSelectParams* params, struct ARegion* ar, short y) +static void set_active_bookmark(FileSelectParams* params, struct ARegion* ar, short y) { int nentries = fsmenu_get_nentries(); short posy = ar->v2d.mask.ymax - TILE_BORDER_Y - y; @@ -187,7 +187,7 @@ static void mouse_select_bookmark(SpaceFile* sfile, ARegion* ar, short *mval) if(mval[0]>ar->v2d.mask.xmin && mval[0]<ar->v2d.mask.xmax && mval[1]>ar->v2d.mask.ymin && mval[1]<ar->v2d.mask.ymax) { char *selected; - set_active_bookmark(sfile, sfile->params, ar, mval[1]); + set_active_bookmark(sfile->params, ar, mval[1]); selected= fsmenu_get_entry(sfile->params->active_bookmark); /* which string */ if (selected) { diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index d1cfdb07c39..f2eb7ad58ea 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -76,15 +76,26 @@ #include "filelist.h" -short ED_fileselect_set_params(FileSelectParams *params, int type, const char *title, const char *path, +FileSelectParams* ED_fileselect_get_params(struct SpaceFile *sfile) +{ + if (!sfile->params) { + ED_fileselect_set_params(sfile, FILE_UNIX, "", "/", 0, 0, 0); + } + return sfile->params; +} + +short ED_fileselect_set_params(SpaceFile *sfile, int type, const char *title, const char *path, short flag, short display, short filter) { char name[FILE_MAX], dir[FILE_MAX], file[FILE_MAX]; + FileSelectParams *params; - if (!params) { - return 0; + if (!sfile->params) { + sfile->params= MEM_callocN(sizeof(FileSelectParams), "fileselparams"); } + params = sfile->params; + params->type = type; params->flag = flag; params->display = display; @@ -115,3 +126,9 @@ short ED_fileselect_set_params(FileSelectParams *params, int type, const char *t return 1; } +void ED_fileselect_reset_params(SpaceFile *sfile) +{ + sfile->params->type = FILE_UNIX; + sfile->params->flag = 0; + sfile->params->title[0] = '\0'; +} diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 703d351af2b..aa364bfb093 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -74,13 +74,7 @@ static SpaceLink *file_new(const bContext *C) SpaceFile *sfile; sfile= MEM_callocN(sizeof(SpaceFile), "initfile"); - sfile->spacetype= SPACE_FILE; - sfile->params= MEM_callocN(sizeof(FileSelectParams), "fileselparams"); - sfile->files = filelist_new(); - - ED_fileselect_set_params(sfile->params, FILE_UNIX, "", "/", 0, 0, 0); - filelist_setdir(sfile->files, sfile->params->dir); - filelist_settype(sfile->files, sfile->params->type); + sfile->spacetype= SPACE_FILE; /* header */ ar= MEM_callocN(sizeof(ARegion), "header for file"); @@ -122,14 +116,14 @@ static void file_free(SpaceLink *sl) filelist_free(sfile->files); filelist_freelib(sfile->files); MEM_freeN(sfile->files); - sfile->files = 0; + sfile->files= NULL; } if (sfile->params) { if(sfile->params->pupmenu) MEM_freeN(sfile->params->pupmenu); MEM_freeN(sfile->params); - sfile->params = 0; + sfile->params= NULL; } if (sfile->op) { @@ -142,16 +136,15 @@ static void file_free(SpaceLink *sl) static void file_init(struct wmWindowManager *wm, ScrArea *sa) { SpaceFile *sfile= sa->spacedata.first; /* XXX get through context? */ - if (!sfile->params) { - sfile->params= MEM_callocN(sizeof(FileSelectParams), "fileselparams"); - ED_fileselect_set_params(sfile->params, FILE_UNIX, "", "/", 0, 0, 0); + if (sfile->params) { + ED_fileselect_reset_params(sfile); } - if (!sfile->files) { - sfile->files = filelist_new(); + if (sfile->files) { + filelist_free(sfile->files); + filelist_freelib(sfile->files); + MEM_freeN(sfile->files); + sfile->files= NULL; } - - filelist_setdir(sfile->files, sfile->params->dir); - filelist_settype(sfile->files, sfile->params->type); } static SpaceLink *file_duplicate(SpaceLink *sl) @@ -165,9 +158,10 @@ static SpaceLink *file_duplicate(SpaceLink *sl) sfilen->params= MEM_dupallocN(sfileo->params); if (!sfilen->params) { sfilen->params= MEM_callocN(sizeof(FileSelectParams), "fileselparams"); - ED_fileselect_set_params(sfilen->params, FILE_UNIX, "", "/", 0, 0, 0); + ED_fileselect_set_params(sfilen, FILE_UNIX, "", "/", 0, 0, 0); sfilen->params->pupmenu = NULL; } + sfilen->files = filelist_new(); filelist_setdir(sfilen->files, sfilen->params->dir); filelist_settype(sfilen->files, sfilen->params->type); diff --git a/source/blender/editors/space_ipo/ipo_draw.c b/source/blender/editors/space_ipo/ipo_draw.c new file mode 100644 index 00000000000..b24c4ca59a0 --- /dev/null +++ b/source/blender/editors/space_ipo/ipo_draw.c @@ -0,0 +1,713 @@ +/** + * $Id: drawipo.c 17512 2008-11-20 05:55:42Z aligorith $ + * + * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) Blender Foundation + * + * Contributor(s): Joshua Leung (2009 Recode) + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <stdio.h> +#include <math.h> +#include <string.h> + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifndef _WIN32 +#include <unistd.h> +#else +#include <io.h> +#endif + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" + +#include "DNA_action_types.h" +#include "DNA_curve_types.h" +#include "DNA_ipo_types.h" +#include "DNA_key_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_sequence_types.h" +#include "DNA_userdef_types.h" +#include "DNA_view2d_types.h" +#include "DNA_windowmanager_types.h" + +#include "BKE_curve.h" +#include "BKE_depsgraph.h" +#include "BKE_ipo.h" +#include "BKE_key.h" +#include "BKE_object.h" +#include "BKE_utildefines.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" + +#include "ED_anim_api.h" +#include "ED_util.h" + +#include "UI_resources.h" +#include "UI_view2d.h" + +/* **************************** */ +// XXX stubs to remove! + +// NOTE: the code in this file has yet to be rewritten to get rid of the editipo system which is past its use-by-date - Aligorith + +typedef struct EditIpo { + IpoCurve *icu; + short disptype; + short flag; + unsigned int col; +} EditIpo; + +#define ISPOIN(a, b, c) ( (a->b) && (a->c) ) +#define ISPOIN3(a, b, c, d) ( (a->b) && (a->c) && (a->d) ) +#define ISPOIN4(a, b, c, d, e) ( (a->b) && (a->c) && (a->d) && (a->e) ) + +/* *************************** */ + +/* helper func - draw keyframe vertices only for an IPO-curve */ +static void draw_ipovertices_keyframes(IpoCurve *icu, View2D *v2d, short disptype, short edit, short sel) +{ + BezTriple *bezt= icu->bezt; + float v1[2]; + int a, b; + + bglBegin(GL_POINTS); + + for (a = 0; a < icu->totvert; a++, bezt++) { + /* IPO_DISPBITS is used for displaying curves for bitflag variables */ + if (disptype == IPO_DISPBITS) { + /*if (v2d->cur.xmin < bezt->vec[1][0] < v2d->cur.xmax) {*/ + short ok= 0; + + if (edit) { + if ((bezt->f2 & SELECT) == sel) + ok= 1; + } + else ok= 1; + + if (ok) { + int val= (int)bezt->vec[1][1]; + v1[0]= bezt->vec[1][0]; + + for (b= 0; b < 31; b++) { + if (val & (1<<b)) { + v1[1]= b + 1; + bglVertex3fv(v1); + } + } + } + /*}*/ + } + else { /* normal (non bit) curves */ + if (edit) { + /* Only the vertex of the line, the + * handler are drawn later + */ + if ((bezt->f2 & SELECT) == sel) /* && G.v2d->cur.xmin < bezt->vec[1][0] < G.v2d->cur.xmax)*/ + bglVertex3fv(bezt->vec[1]); + } + else { + /* draw only if in bounds */ + /*if (G.v2d->cur.xmin < bezt->vec[1][0] < G.v2d->cur.xmax)*/ + bglVertex3fv(bezt->vec[1]); + } + } + } + bglEnd(); +} + +/* helper func - draw handle vertex for an IPO-Curve as a round unfilled circle */ +static void draw_ipohandle_control(float x, float y, float xscale, float yscale, float hsize) +{ + static GLuint displist=0; + + /* initialise round circle shape */ + if (displist == 0) { + GLUquadricObj *qobj; + + displist= glGenLists(1); + glNewList(displist, GL_COMPILE_AND_EXECUTE); + + qobj = gluNewQuadric(); + gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); + gluDisk(qobj, 0.07, 0.8, 12, 1); + gluDeleteQuadric(qobj); + + glEndList(); + } + + /* adjust view transform before starting */ + glTranslatef(x, y, 0.0f); + glScalef(1.0/xscale*hsize, 1.0/yscale*hsize, 1.0); + + /* draw! */ + glCallList(displist); + + /* restore view transform */ + glScalef(xscale/hsize, yscale/hsize, 1.0); + glTranslatef(-x, -y, 0.0f); +} + +/* helper func - draw handle vertices only for an IPO-curve (if it is in EditMode) */ +static void draw_ipovertices_handles(IpoCurve *icu, View2D *v2d, short disptype, short sel) +{ + BezTriple *bezt= icu->bezt; + BezTriple *prevbezt = NULL; + float hsize, xscale, yscale; + int a; + + /* get view settings */ + hsize= UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE); + UI_view2d_getscale(v2d, &xscale, &yscale); + + /* set handle color */ + if (sel) UI_ThemeColor(TH_HANDLE_VERTEX_SELECT); + else UI_ThemeColor(TH_HANDLE_VERTEX); + + for (a= 0; a < icu->totvert; a++, prevbezt=bezt, bezt++) { + if (disptype != IPO_DISPBITS) { + if (ELEM(icu->ipo, IPO_BEZ, IPO_MIXED)) { + /* Draw the editmode handels for a bezier curve (others don't have handles) + * if their selection status matches the selection status we're drawing for + * - first handle only if previous beztriple was bezier-mode + * - second handle only if current beztriple is bezier-mode + */ + if ( (!prevbezt && (bezt->ipo==IPO_BEZ)) || (prevbezt && (prevbezt->ipo==IPO_BEZ)) ) { + if ((bezt->f1 & SELECT) == sel)/* && v2d->cur.xmin < bezt->vec[0][0] < v2d->cur.xmax)*/ + draw_ipohandle_control(bezt->vec[0][0], bezt->vec[0][1], xscale, yscale, hsize); + } + + if (bezt->ipo==IPO_BEZ) { + if ((bezt->f3 & SELECT) == sel)/* && v2d->cur.xmin < bezt->vec[2][0] < v2d->cur.xmax)*/ + draw_ipohandle_control(bezt->vec[2][0], bezt->vec[2][1], xscale, yscale, hsize); + } + } + } + } +} + +static void draw_ipovertices(SpaceIpo *sipo, ARegion *ar, int sel) +{ + View2D *v2d= &ar->v2d; + EditIpo *ei= sipo->editipo; + int nr, val = 0; + + /* this shouldn't get called while drawing in selection-buffer anyway */ + //if (G.f & G_PICKSEL) return; + + glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); + + for (nr=0; nr<sipo->totipo; nr++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + /* select colors to use to draw keyframes */ + if (sipo->showkey) { + if (sel) UI_ThemeColor(TH_TEXT_HI); + else UI_ThemeColor(TH_TEXT); + } + else if (ei->flag & IPO_EDIT) { + if (sel) UI_ThemeColor(TH_VERTEX_SELECT); + else UI_ThemeColor(TH_VERTEX); + } + else { + if (sel) UI_ThemeColor(TH_TEXT_HI); + else UI_ThemeColor(TH_TEXT); + + val= (ei->icu->flag & IPO_SELECT)!=0; + if (sel != val) continue; + } + + /* We can't change the color in the middle of + * GL_POINTS because then Blender will segfault + * on TNT2 / Linux with NVidia's drivers + * (at least up to ver. 4349) + */ + + /* draw keyframes, then the handles (if in editmode) */ + draw_ipovertices_keyframes(ei->icu, v2d, ei->disptype, (ei->flag & IPO_EDIT), sel); + + /* Now draw the two vertex of the handles, + * This needs to be done after the keyframes, + * because we can't call glPointSize + * in the middle of a glBegin/glEnd also the + * bug comment before. + */ + if ((ei->flag & IPO_EDIT) && (sipo->flag & SIPO_NOHANDLES)==0) + draw_ipovertices_handles(ei->icu, v2d, ei->disptype, sel); + } + } + + glPointSize(1.0); +} + +/* draw lines for IPO-curve handles only (this is only done in EditMode) */ +static void draw_ipohandles(SpaceIpo *sipo, ARegion *ar, int sel) +{ + EditIpo *ei; + extern unsigned int nurbcol[]; + unsigned int *col; + int a, b; + + /* don't draw handle lines if handles are not shown */ + if (sipo->flag & SIPO_NOHANDLES) + return; + + if (sel) col= nurbcol+4; + else col= nurbcol; + + ei= sipo->editipo; + for (a=0; a<sipo->totipo; a++, ei++) { + if ISPOIN4(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu, disptype!=IPO_DISPBITS) { + if (ELEM(ei->icu->ipo, IPO_BEZ, IPO_MIXED)) { + BezTriple *bezt=ei->icu->bezt, *prevbezt=NULL; + float *fp; + + for (b= 0; b < ei->icu->totvert; b++, prevbezt=bezt, bezt++) { + if ((bezt->f2 & SELECT)==sel) { + fp= bezt->vec[0]; + + /* only draw first handle if previous segment had handles */ + if ( (!prevbezt && (bezt->ipo==IPO_BEZ)) || (prevbezt && (prevbezt->ipo==IPO_BEZ)) ) + { + cpack(col[bezt->h1]); + glBegin(GL_LINE_STRIP); + glVertex2fv(fp); glVertex2fv(fp+3); + glEnd(); + + } + + /* only draw second handle if this segment is bezier */ + if (bezt->ipo == IPO_BEZ) + { + cpack(col[bezt->h2]); + glBegin(GL_LINE_STRIP); + glVertex2fv(fp+3); glVertex2fv(fp+6); + glEnd(); + } + } + else { + /* only draw first handle if previous segment was had handles, and selection is ok */ + if ( ((bezt->f1 & SELECT)==sel) && + ( (!prevbezt && (bezt->ipo==IPO_BEZ)) || (prevbezt && (prevbezt->ipo==IPO_BEZ)) ) ) + { + fp= bezt->vec[0]; + cpack(col[bezt->h1]); + + glBegin(GL_LINE_STRIP); + glVertex2fv(fp); glVertex2fv(fp+3); + glEnd(); + } + + /* only draw second handle if this segment is bezier, and selection is ok */ + if ( ((bezt->f3 & SELECT)==sel) && + (bezt->ipo == IPO_BEZ) ) + { + fp= bezt->vec[1]; + cpack(col[bezt->h2]); + + glBegin(GL_LINE_STRIP); + glVertex2fv(fp); glVertex2fv(fp+3); + glEnd(); + } + } + } + } + } + } +} + +/* helper func - draw one repeat of an ipo-curve: bitflag curve only (this is evil stuff to expose to user like this) */ +static void draw_ipocurve_repeat_bits (IpoCurve *icu, View2D *v2d, float cycxofs) +{ + BezTriple *bezt= icu->bezt; + int a; + + /* loop over each keyframe, drawing a line extending from that point */ + for (a=0, bezt=icu->bezt; a < icu->totvert; a++, bezt++) { + int val= (int)bezt->vec[1][1]; + int b= 0; + + /* for each bit in the int, draw a line if the keyframe incorporates it */ + for (b = 0; b < 31; b++) { + if (val & (1<<b)) { + float v1[2]; + + /* value stays constant */ + v1[1]= b+1; + + glBegin(GL_LINE_STRIP); + /* extend left too if first keyframe, and not cyclic extrapolation */ + if ((a == 0) && !(icu->extrap & IPO_CYCL)) { + v1[0]= v2d->cur.xmin+cycxofs; + glVertex2fv(v1); + } + + /* must pass through current keyframe */ + v1[0]= bezt->vec[1][0] + cycxofs; + glVertex2fv(v1); + + /* 1. if there is a next keyframe, extend until then OR + * 2. extend until 'infinity' if not cyclic extrapolation + */ + if ((a+1) < icu->totvert) v1[0]= (bezt+1)->vec[1][0]+cycxofs; + else if ((icu->extrap & IPO_CYCL)==0) v1[0]= v2d->cur.xmax+cycxofs; + + glVertex2fv(v1); + glEnd(); + } + } + } +} + +/* helper func - draw one repeat of an ipo-curve: normal curve */ +static void draw_ipocurve_repeat_normal (IpoCurve *icu, View2D *v2d, float cycxofs, float cycyofs, float *facp) +{ + BezTriple *prevbezt= icu->bezt; + BezTriple *bezt= prevbezt+1; + float v1[2], v2[2], v3[2], v4[2]; + float *fp, data[120]; + float fac= *(facp); + int b= icu->totvert-1; + int resol; + + glBegin(GL_LINE_STRIP); + + /* extrapolate to left? */ + if ((icu->extrap & IPO_CYCL)==0) { + /* left-side of view comes before first keyframe, so need to extend as not cyclic */ + if (prevbezt->vec[1][0] > v2d->cur.xmin) { + v1[0]= v2d->cur.xmin; + + /* y-value depends on the interpolation */ + if ((icu->extrap==IPO_HORIZ) || (prevbezt->ipo==IPO_CONST) || (icu->totvert==1)) { + /* just extend across the first keyframe's value */ + v1[1]= prevbezt->vec[1][1]; + } + else if (prevbezt->ipo==IPO_LIN) { + /* extrapolate linear dosnt use the handle, use the next points center instead */ + fac= (prevbezt->vec[1][0]-bezt->vec[1][0])/(prevbezt->vec[1][0]-v1[0]); + if (fac) fac= 1.0f/fac; + v1[1]= prevbezt->vec[1][1]-fac*(prevbezt->vec[1][1]-bezt->vec[1][1]); + } + else { + /* based on angle of handle 1 (relative to keyframe) */ + fac= (prevbezt->vec[0][0]-prevbezt->vec[1][0])/(prevbezt->vec[1][0]-v1[0]); + if (fac) fac= 1.0f/fac; + v1[1]= prevbezt->vec[1][1]-fac*(prevbezt->vec[0][1]-prevbezt->vec[1][1]); + } + + glVertex2fv(v1); + } + } + + /* if only one keyframe, add it now */ + if (icu->totvert == 1) { + v1[0]= prevbezt->vec[1][0] + cycxofs; + v1[1]= prevbezt->vec[1][1] + cycyofs; + glVertex2fv(v1); + } + + /* draw curve between first and last keyframe (if there are enough to do so) */ + while (b--) { + if (prevbezt->ipo==IPO_CONST) { + /* Constant-Interpolation: draw segment between previous keyframe and next, but holding same value */ + v1[0]= prevbezt->vec[1][0]+cycxofs; + v1[1]= prevbezt->vec[1][1]+cycyofs; + glVertex2fv(v1); + + v1[0]= bezt->vec[1][0]+cycxofs; + v1[1]= prevbezt->vec[1][1]+cycyofs; + glVertex2fv(v1); + } + else if (prevbezt->ipo==IPO_LIN) { + /* Linear interpolation: just add one point (which should add a new line segment) */ + v1[0]= prevbezt->vec[1][0]+cycxofs; + v1[1]= prevbezt->vec[1][1]+cycyofs; + glVertex2fv(v1); + } + else { + /* Bezier-Interpolation: draw curve as series of segments between keyframes + * - resol determines number of points to sample in between keyframes + */ + + /* resol not depending on horizontal resolution anymore, drivers for example... */ + if (icu->driver) + resol= 32; + else + resol= 3.0*sqrt(bezt->vec[1][0] - prevbezt->vec[1][0]); + + if (resol < 2) { + /* only draw one */ + v1[0]= prevbezt->vec[1][0]+cycxofs; + v1[1]= prevbezt->vec[1][1]+cycyofs; + glVertex2fv(v1); + } + else { + /* clamp resolution to max of 32 */ + if (resol > 32) resol= 32; + + v1[0]= prevbezt->vec[1][0]+cycxofs; + v1[1]= prevbezt->vec[1][1]+cycyofs; + v2[0]= prevbezt->vec[2][0]+cycxofs; + v2[1]= prevbezt->vec[2][1]+cycyofs; + + v3[0]= bezt->vec[0][0]+cycxofs; + v3[1]= bezt->vec[0][1]+cycyofs; + v4[0]= bezt->vec[1][0]+cycxofs; + v4[1]= bezt->vec[1][1]+cycyofs; + + correct_bezpart(v1, v2, v3, v4); + + forward_diff_bezier(v1[0], v2[0], v3[0], v4[0], data, resol, 3); + forward_diff_bezier(v1[1], v2[1], v3[1], v4[1], data+1, resol, 3); + + for (fp= data; resol; resol--, fp+= 3) + glVertex2fv(fp); + } + } + + /* get next pointers */ + prevbezt= bezt; + bezt++; + + /* last point? */ + if (b == 0) { + v1[0]= prevbezt->vec[1][0]+cycxofs; + v1[1]= prevbezt->vec[1][1]+cycyofs; + glVertex2fv(v1); + } + } + + /* extrapolate to right? (see code for left-extrapolation above too) */ + if ((icu->extrap & IPO_CYCL)==0) { + if (prevbezt->vec[1][0] < v2d->cur.xmax) { + v1[0]= v2d->cur.xmax; + + /* y-value depends on the interpolation */ + if ((icu->extrap==IPO_HORIZ) || (prevbezt->ipo==IPO_CONST) || (icu->totvert==1)) { + /* based on last keyframe's value */ + v1[1]= prevbezt->vec[1][1]; + } + else if (prevbezt->ipo==IPO_LIN) { + /* extrapolate linear dosnt use the handle, use the previous points center instead */ + bezt = prevbezt-1; + fac= (prevbezt->vec[1][0]-bezt->vec[1][0])/(prevbezt->vec[1][0]-v1[0]); + if (fac) fac= 1.0f/fac; + v1[1]= prevbezt->vec[1][1]-fac*(prevbezt->vec[1][1]-bezt->vec[1][1]); + } + else { + /* based on angle of handle 1 (relative to keyframe) */ + fac= (prevbezt->vec[2][0]-prevbezt->vec[1][0])/(prevbezt->vec[1][0]-v1[0]); + if (fac) fac= 1.0f/fac; + v1[1]= prevbezt->vec[1][1]-fac*(prevbezt->vec[2][1]-prevbezt->vec[1][1]); + } + + glVertex2fv(v1); + } + } + + glEnd(); + + /* return fac, as we alter it */ + *(facp) = fac; +} + +/* draw all ipo-curves */ +static void draw_ipocurves(SpaceIpo *sipo, ARegion *ar, int sel) +{ + View2D *v2d= &ar->v2d; + EditIpo *ei; + int nr, val/*, pickselcode=0*/; + + /* if we're drawing for GL_SELECT, reset pickselcode first + * - there's only one place that will do this, so it should be fine + */ + //if (G.f & G_PICKSEL) + // pickselcode= 1; + + ei= sipo->editipo; + for (nr=0; nr<sipo->totipo; nr++, ei++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, icu, icu->bezt) { + /* val is used to indicate if curve can be edited */ + //if (G.f & G_PICKSEL) { + // /* when using OpenGL to select stuff (on mouseclick) */ + // glLoadName(pickselcode++); + // val= 1; + //} + //else { + /* filter to only draw those that are selected or unselected (based on drawing mode */ + val= (ei->flag & (IPO_SELECT+IPO_EDIT)) != 0; + val= (val==sel); + //} + + /* only draw those curves that we can draw */ + if (val) { + IpoCurve *icu= ei->icu; + float cycdx=0.0f, cycdy=0.0f, cycxofs=0.0f, cycyofs=0.0f; + const int lastindex= (icu->totvert-1); + float fac= 0.0f; + int cycount=1; + + /* set color for curve curve: + * - bitflag curves (evil) must always be drawn coloured as they cannot work with IPO-Keys + * - when IPO-Keys are shown, individual curves are not editable, so we show by drawing them all black + */ + if ((sipo->showkey) && (ei->disptype!=IPO_DISPBITS)) UI_ThemeColor(TH_TEXT); + else cpack(ei->col); + + /* cyclic curves - get offset and number of repeats to display */ + if (icu->extrap & IPO_CYCL) { + BezTriple *bezt= icu->bezt; + BezTriple *lastbezt= bezt + lastindex; + + /* calculate cycle length and amplitude */ + cycdx= lastbezt->vec[1][0] - bezt->vec[1][0]; + cycdy= lastbezt->vec[1][1] - bezt->vec[1][1]; + + /* check that the cycle does have some length */ + if (cycdx > 0.01f) { + /* count cycles before first frame */ + while (icu->bezt->vec[1][0]+cycxofs > v2d->cur.xmin) { + cycxofs -= cycdx; + if (icu->extrap & IPO_DIR) cycyofs-= cycdy; + cycount++; + } + + /* count cycles after last frame (and adjust offset) */ + fac= 0.0f; + while (lastbezt->vec[1][0]+fac < v2d->cur.xmax) { + cycount++; + fac += cycdx; + } + } + } + + /* repeat process for each repeat */ + while (cycount--) { + /* bitflag curves are drawn differently to normal curves */ + if (ei->disptype==IPO_DISPBITS) + draw_ipocurve_repeat_bits(icu, v2d, cycxofs); + else + draw_ipocurve_repeat_normal(icu, v2d, cycxofs, cycyofs, &fac); + + /* prepare for next cycle by adjusing offsets */ + cycxofs += cycdx; + if (icu->extrap & IPO_DIR) cycyofs += cycdy; + } + + /* vertical line that indicates the end of a speed curve */ + if ((sipo->blocktype==ID_CU) && (icu->adrcode==CU_SPEED)) { + int b= icu->totvert-1; + + if (b) { + BezTriple *bezt= icu->bezt+b; + + glColor3ub(0, 0, 0); + + glBegin(GL_LINES); + glVertex2f(bezt->vec[1][0], 0.0f); + glVertex2f(bezt->vec[1][0], bezt->vec[1][1]); + glEnd(); + } + } + } + } + } +} + +#if 0 +static void draw_ipokey(SpaceIpo *sipo, ARegion *ar) +{ + View2D *v2d= &ar->v2d; + IpoKey *ik; + + glBegin(GL_LINES); + for (ik= sipo->ipokey.first; ik; ik= ik->next) { + if (ik->flag & SELECT) glColor3ub(0xFF, 0xFF, 0x99); + else glColor3ub(0xAA, 0xAA, 0x55); + + glVertex2f(ik->val, v2d->cur.ymin); + glVertex2f(ik->val, v2d->cur.ymax); + } + glEnd(); +} +#endif + +void drawipospace(ScrArea *sa, ARegion *ar) +{ + SpaceIpo *sipo= sa->spacedata.first; + //View2D *v2d= &ar->v2d; + EditIpo *ei; + + + if(sipo->editipo) { + + /* correct scale for degrees? */ + // XXX this should be calculated elsewhere +#if 0 + disptype= -1; + ei= sipo->editipo; + for(a=0; a<sipo->totipo; a++, ei++) { + if(ei->flag & IPO_VISIBLE) { + if(disptype== -1) disptype= ei->disptype; + else if(disptype!=ei->disptype) disptype= 0; + } + } +#endif + // now set grid size (done elsehwere now) + + /* ipokeys */ +#if 0 + if(sipo->showkey) { + //if(sipo->ipokey.first==0) make_ipokey(); + //else update_ipokey_val(); + make_ipokey(); + draw_ipokey(sipo); + } +#endif + + /* map ipo-points for drawing if scaled ipo */ + //if (NLA_IPO_SCALED) + // ANIM_nla_mapping_apply_ipo(OBACT, sipo->ipo, 0, 0); + + /* draw deselect */ + draw_ipocurves(sipo, ar, 0); + draw_ipohandles(sipo, ar, 0); + draw_ipovertices(sipo, ar, 0); + + /* draw select */ + draw_ipocurves(sipo, ar, 1); + draw_ipohandles(sipo, ar, 1); + draw_ipovertices(sipo, ar, 1); + + /* undo mapping of ipo-points for drawing if scaled ipo */ + //if (NLA_IPO_SCALED) + // ANIM_nla_mapping_apply_ipo(OBACT, sipo->ipo, 1, 0); + + } +} diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index cc8e03e0b44..bf028f374bd 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -99,7 +99,6 @@ static void node_mouse_select(SpaceNode *snode, ARegion *ar, short *mval, short ;// node_link_viewer(snode, node); //std_rmouse_transform(node_transform_ext); /* does undo push for select */ - ED_region_tag_redraw(ar); } } @@ -121,6 +120,9 @@ static int node_select_exec(bContext *C, wmOperator *op) node_mouse_select(snode, ar, mval, extend); break; } + + WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL); /* Do we need to pass the scene? */ + return OPERATOR_FINISHED; } @@ -227,6 +229,8 @@ static int node_borderselect_exec(bContext *C, wmOperator *op) } } + WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL); /* Do we need to pass the scene? */ + return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c index 743f1edba3e..fad19f6a023 100644 --- a/source/blender/editors/space_outliner/outliner.c +++ b/source/blender/editors/space_outliner/outliner.c @@ -1357,7 +1357,7 @@ static void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops) else if(soops->outlinevis==SO_USERDEF) { PointerRNA userdefptr; - RNA_pointer_create(NULL, NULL, &RNA_UserPreferences, &U, &userdefptr); + RNA_pointer_create(NULL, &RNA_UserPreferences, &U, &userdefptr); ten= outliner_add_element(soops, &soops->tree, (void*)&userdefptr, NULL, TSE_RNA_STRUCT, -1); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index ccd6e52f577..dfb4e0dea55 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -3480,8 +3480,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, Base *base, Part psys->flag &= ~PSYS_DRAWING; if(psys->lattice){ - end_latt_deform(); - psys->lattice=0; + end_latt_deform(psys->lattice); + psys->lattice= NULL; } wmLoadMatrix(v3d->viewmat); diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 8ac672eb260..675fbc5aab2 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -181,15 +181,6 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl) return (SpaceLink *)v3dn; } -static void view3d_main_area_draw(const bContext *C, ARegion *ar) -{ - /* draw entirely, view changes should be handled here */ - ScrArea *sa= CTX_wm_area(C); - View3D *v3d= sa->spacedata.first; /* XXX get from region */ - - drawview3dspace(CTX_wm_screen(C), CTX_data_scene(C), ar, v3d); -} - /* add handlers, stuff you only do once or on area/region changes */ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar) { diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 48fb6d76703..4fc64782fe8 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -51,6 +51,7 @@ #include "BLI_rand.h" #include "BKE_anim.h" +#include "BKE_context.h" #include "BKE_customdata.h" #include "BKE_image.h" #include "BKE_ipo.h" @@ -76,6 +77,7 @@ #include "ED_keyframing.h" #include "ED_mesh.h" #include "ED_screen.h" +#include "ED_space_api.h" #include "ED_util.h" #include "ED_types.h" @@ -1835,10 +1837,11 @@ static CustomDataMask get_viewedit_datamask(bScreen *screen) return mask; } - - -void drawview3dspace(bScreen *screen, Scene *scene, ARegion *ar, View3D *v3d) +void view3d_main_area_draw(const bContext *C, ARegion *ar) { + Scene *scene= CTX_data_scene(C); + ScrArea *sa= CTX_wm_area(C); + View3D *v3d= sa->spacedata.first; /* XXX get from region */ Scene *sce; Base *base; Object *ob; @@ -1846,7 +1849,7 @@ void drawview3dspace(bScreen *screen, Scene *scene, ARegion *ar, View3D *v3d) Object *obact = OBACT; /* from now on all object derived meshes check this */ - v3d->customdata_mask= get_viewedit_datamask(screen); + v3d->customdata_mask= get_viewedit_datamask(CTX_wm_screen(C)); /* update all objects, ipos, matrices, displists, etc. Flags set by depgraph or manual, no layer check here, gets correct flushed */ @@ -1999,12 +2002,7 @@ void drawview3dspace(bScreen *screen, Scene *scene, ARegion *ar, View3D *v3d) view3d_update_depths(ar, v3d); } - if(G.moving) { -// BIF_drawConstraint(); -// if(obedit || (G.f & G_PARTICLEEDIT)) -// BIF_drawPropCircle(); // only editmode and particles have proportional edit -// BIF_drawSnap(); - } + ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST); // REEB_draw(); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 6f638131679..90bc976f015 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -69,6 +69,7 @@ #include "RNA_access.h" #include "RNA_define.h" +#include "ED_space_api.h" #include "ED_screen.h" #include "ED_types.h" @@ -96,6 +97,7 @@ typedef struct ViewOpsData { int origx, origy, oldx, oldy; int origkey; + void *vh; // XXX temp } ViewOpsData; #define TRACKBALLSIZE (1.1) @@ -362,6 +364,10 @@ static int viewrotate_modal(bContext *C, wmOperator *op, wmEvent *event) default: if(event->type==vod->origkey && event->val==0) { + if(vod->vh) { + ED_region_draw_cb_exit(CTX_wm_region(C)->type, vod->vh); + ED_region_tag_redraw(CTX_wm_region(C)); + } MEM_freeN(vod); op->customdata= NULL; @@ -372,6 +378,12 @@ static int viewrotate_modal(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_RUNNING_MODAL; } +static void vh_draw(const bContext *C, ARegion *ar) +{ + glColor3ub(100, 200, 100); + glRectf(-0.2, -0.2, 0.2, 0.2); +} + static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event) { ViewOpsData *vod; @@ -380,6 +392,8 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event) viewops_data(C, op, event); vod= op->customdata; + vod->vh= ED_region_draw_cb_activate(CTX_wm_region(C)->type, vh_draw, REGION_DRAW_POST); + /* switch from camera view when: */ if(vod->v3d->persp != V3D_PERSP) { @@ -1344,41 +1358,6 @@ void VIEW3D_OT_drawtype(wmOperatorType *ot) /* ********************************************************* */ -void set_render_border(Scene *scene, ARegion *ar, View3D *v3d) -{ - rcti rect; - short val; - - val= 0; // XXX get_border(&rect, 3); - if(val) { - rctf vb; - - calc_viewborder(scene, ar, v3d, &vb); - - 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); - scene->r.border.xmax= ((float)rect.xmax-vb.xmin)/(vb.xmax-vb.xmin); - scene->r.border.ymax= ((float)rect.ymax-vb.ymin)/(vb.ymax-vb.ymin); - - CLAMP(scene->r.border.xmin, 0.0, 1.0); - CLAMP(scene->r.border.ymin, 0.0, 1.0); - CLAMP(scene->r.border.xmax, 0.0, 1.0); - CLAMP(scene->r.border.ymax, 0.0, 1.0); - - /* drawing a border surrounding the entire camera view switches off border rendering - * or the border covers no pixels */ - if ((scene->r.border.xmin <= 0.0 && scene->r.border.xmax >= 1.0 && - scene->r.border.ymin <= 0.0 && scene->r.border.ymax >= 1.0) || - (scene->r.border.xmin == scene->r.border.xmax || - scene->r.border.ymin == scene->r.border.ymax )) - { - scene->r.mode &= ~R_BORDER; - } else { - scene->r.mode |= R_BORDER; - } - } -} - void view3d_border_zoom(Scene *scene, ARegion *ar, View3D *v3d) { diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index 3caa2d25da7..d8025698f02 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -136,6 +136,25 @@ static int retopo_mesh_paint_check() {return 0;} /* end XXX ************* */ + +/* well... in this file a lot of view mode manipulation happens, so let's have it defined here */ +void ED_view3d_exit_paint_modes(bContext *C) +{ + if(G.f & G_VERTEXPAINT) + WM_operator_name_call(C, "VIEW3D_OT_vpaint_toggle", WM_OP_EXEC_REGION_WIN, NULL, NULL); + +// if(G.f & G_TEXTUREPAINT) set_texturepaint(); +// if(G.f & G_WEIGHTPAINT) set_wpaint(); +// if(G.f & G_SCULPTMODE) set_sculptmode(); +// if(G.f & G_PARTICLEEDIT) PE_set_particle_edit(); + + G.f &= ~(G_VERTEXPAINT+G_TEXTUREPAINT+G_WEIGHTPAINT+G_SCULPTMODE+G_PARTICLEEDIT); +} + + + + + static void do_view3d_buttons(bContext *C, void *arg, int event); #define B_SCENELOCK 101 @@ -5368,7 +5387,7 @@ static void do_view3d_buttons(bContext *C, void *arg, int event) if (v3d->modeselect == V3D_OBJECTMODE_SEL) { v3d->flag &= ~V3D_MODE; -// XXX exit_paint_modes(); + ED_view3d_exit_paint_modes(C); ED_armature_exit_posemode(basact); if(obedit) ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* exit editmode and undo */ @@ -5376,7 +5395,7 @@ static void do_view3d_buttons(bContext *C, void *arg, int event) else if (v3d->modeselect == V3D_EDITMODE_SEL) { if(!obedit) { v3d->flag &= ~V3D_MODE; -// XXX exit_paint_modes(); + ED_view3d_exit_paint_modes(C); ED_object_enter_editmode(C, EM_WAITCURSOR); ED_undo_push(C, "Original"); /* here, because all over code enter_editmode is abused */ } @@ -5384,7 +5403,7 @@ static void do_view3d_buttons(bContext *C, void *arg, int event) else if (v3d->modeselect == V3D_SCULPTMODE_SEL) { if (!(G.f & G_SCULPTMODE)) { v3d->flag &= ~V3D_MODE; -// XXX exit_paint_modes(); + ED_view3d_exit_paint_modes(C); if(obedit) ED_object_exit_editmode(C, EM_FREEUNDO); /* exit editmode and undo */ // XXX set_sculptmode(); @@ -5393,16 +5412,16 @@ static void do_view3d_buttons(bContext *C, void *arg, int event) else if (v3d->modeselect == V3D_VERTEXPAINTMODE_SEL) { if (!(G.f & G_VERTEXPAINT)) { v3d->flag &= ~V3D_MODE; -// XXX exit_paint_modes(); + ED_view3d_exit_paint_modes(C); if(obedit) ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* exit editmode and undo */ - -// XXX set_vpaint(); + + WM_operator_name_call(C, "VIEW3D_OT_vpaint_toggle", WM_OP_EXEC_REGION_WIN, NULL, NULL); } } else if (v3d->modeselect == V3D_TEXTUREPAINTMODE_SEL) { if (!(G.f & G_TEXTUREPAINT)) { v3d->flag &= ~V3D_MODE; -// XXX exit_paint_modes(); + ED_view3d_exit_paint_modes(C); if(obedit) ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* exit editmode and undo */ // XXX set_texturepaint(); @@ -5411,7 +5430,7 @@ static void do_view3d_buttons(bContext *C, void *arg, int event) else if (v3d->modeselect == V3D_WEIGHTPAINTMODE_SEL) { if (!(G.f & G_WEIGHTPAINT) && (ob && ob->type == OB_MESH) ) { v3d->flag &= ~V3D_MODE; -// XXX exit_paint_modes(); + ED_view3d_exit_paint_modes(C); if(obedit) ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* exit editmode and undo */ @@ -5431,7 +5450,7 @@ static void do_view3d_buttons(bContext *C, void *arg, int event) else if(v3d->modeselect == V3D_PARTICLEEDITMODE_SEL){ if (!(G.f & G_PARTICLEEDIT)) { v3d->flag &= ~V3D_MODE; -// XXX exit_paint_modes(); + ED_view3d_exit_paint_modes(C); if(obedit) ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* exit editmode and undo */ // XXX PE_set_particle_edit(); diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index d9d58b188ea..8fc00ffd538 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -33,6 +33,7 @@ /* internal exports only */ struct bScreen; +struct ARegion; struct BoundBox; struct Object; struct DerivedMesh; @@ -64,7 +65,7 @@ typedef struct ViewDepths { #define IS_CLIPPED 12000 /* view3d_header.c */ -void view3d_header_buttons(const struct bContext *C, ARegion *ar); +void view3d_header_buttons(const struct bContext *C, struct ARegion *ar); /* view3d_ops.c */ void view3d_operatortypes(void); @@ -83,7 +84,7 @@ void VIEW3D_OT_render_border(struct wmOperatorType *ot); void VIEW3D_OT_drawtype(struct wmOperatorType *ot); /* drawobject.c */ -void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag); +void draw_object(Scene *scene, struct ARegion *ar, View3D *v3d, Base *base, int flag); int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt); void drawcircball(int mode, float *cent, float rad, float tmat[][4]); void draw_object_instance(Scene *scene, View3D *v3d, Object *ob, int dt, int outline); @@ -97,17 +98,17 @@ int draw_armature(Scene *scene, View3D *v3d, Base *base, int dt, int flag); void draw_mesh_textured(Scene *scene, View3D *v3d, Object *ob, struct DerivedMesh *dm, int faceselect); /* view3d_draw.c */ -void drawview3dspace(struct bScreen *screen, Scene *scene, ARegion *ar, View3D *v3d); -void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (* func)(void *)); +void view3d_main_area_draw(const struct bContext *C, struct ARegion *ar); +void draw_depth(Scene *scene, struct ARegion *ar, View3D *v3d, int (* func)(void *)); void view3d_clr_clipping(void); void view3d_set_clipping(View3D *v3d); void add_view3d_after(View3D *v3d, Base *base, int type, int flag); void make_axis_color(char *col, char *col2, char axis); -void calc_viewborder(Scene *scene, ARegion *ar, View3D *v3d, rctf *viewborder_r); +void calc_viewborder(Scene *scene, struct ARegion *ar, View3D *v3d, rctf *viewborder_r); void circf(float x, float y, float rad); void circ(float x, float y, float rad); -void view3d_update_depths(ARegion *ar, View3D *v3d); +void view3d_update_depths(struct ARegion *ar, View3D *v3d); /* view3d_select.c */ void VIEW3D_OT_select(struct wmOperatorType *ot); @@ -116,6 +117,12 @@ void VIEW3D_OT_circle_select(struct wmOperatorType *ot); void VIEW3D_OT_borderselect(struct wmOperatorType *ot); void VIEW3D_OT_lasso_select(struct wmOperatorType *ot); +void view3d_set_viewcontext(struct bContext *C, struct ViewContext *vc); + +/* vpaint.c */ +void VIEW3D_OT_vpaint_toggle(struct wmOperatorType *ot); +void VIEW3D_OT_vpaint(struct wmOperatorType *ot); + /* view3d_view.c */ void VIEW3D_OT_smoothview(struct wmOperatorType *ot); void VIEW3D_OT_setcameratoview(struct wmOperatorType *ot); @@ -124,19 +131,19 @@ void view3d_operator_needs_opengl(const struct bContext *C); int boundbox_clip(View3D *v3d, float obmat[][4], struct BoundBox *bb); -void view3d_project_short_clip(ARegion *ar, View3D *v3d, float *vec, short *adr, float projmat[4][4], float wmat[4][4]); -void view3d_project_short_noclip(ARegion *ar, float *vec, short *adr, float mat[4][4]); -void view3d_project_float(ARegion *a, float *vec, float *adr, float mat[4][4]); +void view3d_project_short_clip(struct ARegion *ar, View3D *v3d, float *vec, short *adr, float projmat[4][4], float wmat[4][4]); +void view3d_project_short_noclip(struct ARegion *ar, float *vec, short *adr, float mat[4][4]); +void view3d_project_float(struct ARegion *a, float *vec, float *adr, float mat[4][4]); void view3d_get_object_project_mat(View3D *v3d, struct Object *ob, float pmat[4][4], float vmat[4][4]); -void view3d_project_float(ARegion *ar, float *vec, float *adr, float mat[4][4]); +void view3d_project_float(struct ARegion *ar, float *vec, float *adr, float mat[4][4]); int get_view3d_viewplane(View3D *v3d, int winxi, int winyi, rctf *viewplane, float *clipsta, float *clipend, float *pixsize); -void initlocalview(Scene *scene, ARegion *ar, View3D *v3d); +void initlocalview(Scene *scene, struct ARegion *ar, View3D *v3d); void restore_localviewdata(View3D *vd); void endlocalview(Scene *scene, ScrArea *sa); -void centerview(ARegion *ar, View3D *v3d); +void centerview(struct ARegion *ar, View3D *v3d); void smooth_view(struct bContext *C, Object *, Object *, float *ofs, float *quat, float *dist, float *lens); diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 73329ac5aa3..da4b752f370 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -79,6 +79,8 @@ void view3d_operatortypes(void) WM_operatortype_append(VIEW3D_OT_lasso_select); WM_operatortype_append(VIEW3D_OT_setcameratoview); WM_operatortype_append(VIEW3D_OT_drawtype); + WM_operatortype_append(VIEW3D_OT_vpaint_toggle); + WM_operatortype_append(VIEW3D_OT_vpaint); transform_operatortypes(); } @@ -88,6 +90,9 @@ void view3d_keymap(wmWindowManager *wm) ListBase *keymap= WM_keymap_listbase(wm, "View3D", SPACE_VIEW3D, 0); wmKeymapItem *km; + /* paint poll checks mode */ + WM_keymap_verify_item(keymap, "VIEW3D_OT_vpaint", LEFTMOUSE, KM_PRESS, 0, 0); + WM_keymap_verify_item(keymap, "VIEW3D_OT_cursor3d", ACTIONMOUSE, KM_PRESS, 0, 0); WM_keymap_verify_item(keymap, "VIEW3D_OT_viewrotate", MIDDLEMOUSE, KM_PRESS, 0, 0); @@ -148,6 +153,8 @@ void view3d_keymap(wmWindowManager *wm) WM_keymap_add_item(keymap, "VIEW3D_OT_render_border", BKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_set_camera_to_view", PAD0, KM_PRESS, KM_ALT|KM_CTRL, 0); + + WM_keymap_add_item(keymap, "VIEW3D_OT_vpaint_toggle", VKEY, KM_PRESS, 0, 0); /* TODO - this is just while we have no way to load a text datablock */ RNA_string_set(WM_keymap_add_item(keymap, "SCRIPT_OT_run_pyfile", PKEY, KM_PRESS, 0, 0)->ptr, "filename", "test.py"); diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index e1cc1f65c15..6664ac11877 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -89,7 +89,7 @@ #include "view3d_intern.h" // own include -static void view3d_set_viewcontext(bContext *C, ViewContext *vc) +void view3d_set_viewcontext(bContext *C, ViewContext *vc) { memset(vc, 0, sizeof(ViewContext)); vc->ar= CTX_wm_region(C); diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 933523cfe54..cc80645ad76 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -993,28 +993,6 @@ void setviewmatrixview3d(Scene *scene, View3D *v3d) } } -void setcameratoview3d(View3D *v3d) -{ - Object *ob; - float dvec[3]; - - ob= v3d->camera; - dvec[0]= v3d->dist*v3d->viewinv[2][0]; - dvec[1]= v3d->dist*v3d->viewinv[2][1]; - dvec[2]= v3d->dist*v3d->viewinv[2][2]; - VECCOPY(ob->loc, dvec); - VecSubf(ob->loc, ob->loc, v3d->ofs); - v3d->viewquat[0]= -v3d->viewquat[0]; - /* */ - /*if (ob->transflag & OB_QUAT) { - QUATCOPY(ob->quat, v3d->viewquat); - } else {*/ - QuatToEul(v3d->viewquat, ob->rot); - /*}*/ - v3d->viewquat[0]= -v3d->viewquat[0]; -} - - /* IGLuint-> GLuint*/ /* Warning: be sure to account for a negative return value * This is an error, "Too many objects in select buffer" diff --git a/source/blender/editors/space_view3d/vpaint.c b/source/blender/editors/space_view3d/vpaint.c new file mode 100644 index 00000000000..f253612259f --- /dev/null +++ b/source/blender/editors/space_view3d/vpaint.c @@ -0,0 +1,1684 @@ +/** + * $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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <math.h> +#include <string.h> + +#ifdef WIN32 +#include <io.h> +#else +#include <unistd.h> +#endif + +#include "MEM_guardedalloc.h" + +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "MTC_matrixops.h" + +#include "DNA_action_types.h" +#include "DNA_armature_types.h" +#include "DNA_brush_types.h" +#include "DNA_cloth_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_modifier_types.h" +#include "DNA_object_types.h" +#include "DNA_object_force.h" +#include "DNA_particle_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_scene_types.h" +#include "DNA_view3d_types.h" +#include "DNA_userdef_types.h" + +#include "BKE_armature.h" +#include "BKE_DerivedMesh.h" +#include "BKE_cloth.h" +#include "BKE_context.h" +#include "BKE_customdata.h" +#include "BKE_depsgraph.h" +#include "BKE_deform.h" +#include "BKE_displist.h" +#include "BKE_global.h" +#include "BKE_mesh.h" +#include "BKE_modifier.h" +#include "BKE_multires.h" +#include "BKE_object.h" +#include "BKE_utildefines.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" + +#include "ED_mesh.h" +#include "ED_object.h" +#include "ED_screen.h" +#include "ED_util.h" +#include "ED_view3d.h" + +#include "view3d_intern.h" + + /* Gvp.mode */ +#define VP_MIX 0 +#define VP_ADD 1 +#define VP_SUB 2 +#define VP_MUL 3 +#define VP_BLUR 4 +#define VP_LIGHTEN 5 +#define VP_DARKEN 6 + +#define MAXINDEX 512000 + +/* XXX */ +static void BIF_undo_push() {} +static void error() {} +static int get_mbut() {return 0;} + +VPaint Gvp= {1.0, 1.0, 1.0, 0.2, 25.0, 1.0, 1.0, 0, VP_AREA+VP_SOFT+VP_SPRAY, 0}; +VPaint Gwp= {1.0, 1.0, 1.0, 1.0, 25.0, 1.0, 1.0, 0, VP_AREA+VP_SOFT, 0}; + +static int *get_indexarray(void) +{ + return MEM_mallocN(sizeof(int)*MAXINDEX + 2, "vertexpaint"); +} + +void free_vertexpaint() +{ + + if(Gvp.vpaint_prev) MEM_freeN(Gvp.vpaint_prev); + Gvp.vpaint_prev= NULL; + + mesh_octree_table(NULL, NULL, NULL, 'e'); +} + +/* in contradiction to cpack drawing colors, the MCOL colors (vpaint colors) are per byte! + so not endian sensitive. Mcol = ABGR!!! so be cautious with cpack calls */ + +unsigned int rgba_to_mcol(float r, float g, float b, float a) +{ + int ir, ig, ib, ia; + unsigned int col; + char *cp; + + ir= floor(255.0*r); + if(ir<0) ir= 0; else if(ir>255) ir= 255; + ig= floor(255.0*g); + if(ig<0) ig= 0; else if(ig>255) ig= 255; + ib= floor(255.0*b); + if(ib<0) ib= 0; else if(ib>255) ib= 255; + ia= floor(255.0*a); + if(ia<0) ia= 0; else if(ia>255) ia= 255; + + cp= (char *)&col; + cp[0]= ia; + cp[1]= ib; + cp[2]= ig; + cp[3]= ir; + + return col; + +} + +static unsigned int vpaint_get_current_col(VPaint *vp) +{ + return rgba_to_mcol(vp->r, vp->g, vp->b, 1.0f); +} + +void do_shared_vertexcol(Mesh *me) +{ + /* if no mcol: do not do */ + /* if tface: only the involved faces, otherwise all */ + MFace *mface; + MTFace *tface; + int a; + short *scolmain, *scol; + char *mcol; + + if(me->mcol==0 || me->totvert==0 || me->totface==0) return; + + scolmain= MEM_callocN(4*sizeof(short)*me->totvert, "colmain"); + + tface= me->mtface; + mface= me->mface; + mcol= (char *)me->mcol; + for(a=me->totface; a>0; a--, mface++, mcol+=16) { + if((tface && tface->mode & TF_SHAREDCOL) || (G.f & G_FACESELECT)==0) { + scol= scolmain+4*mface->v1; + scol[0]++; scol[1]+= mcol[1]; scol[2]+= mcol[2]; scol[3]+= mcol[3]; + scol= scolmain+4*mface->v2; + scol[0]++; scol[1]+= mcol[5]; scol[2]+= mcol[6]; scol[3]+= mcol[7]; + scol= scolmain+4*mface->v3; + scol[0]++; scol[1]+= mcol[9]; scol[2]+= mcol[10]; scol[3]+= mcol[11]; + if(mface->v4) { + scol= scolmain+4*mface->v4; + scol[0]++; scol[1]+= mcol[13]; scol[2]+= mcol[14]; scol[3]+= mcol[15]; + } + } + if(tface) tface++; + } + + a= me->totvert; + scol= scolmain; + while(a--) { + if(scol[0]>1) { + scol[1]/= scol[0]; + scol[2]/= scol[0]; + scol[3]/= scol[0]; + } + scol+= 4; + } + + tface= me->mtface; + mface= me->mface; + mcol= (char *)me->mcol; + for(a=me->totface; a>0; a--, mface++, mcol+=16) { + if((tface && tface->mode & TF_SHAREDCOL) || (G.f & G_FACESELECT)==0) { + scol= scolmain+4*mface->v1; + mcol[1]= scol[1]; mcol[2]= scol[2]; mcol[3]= scol[3]; + scol= scolmain+4*mface->v2; + mcol[5]= scol[1]; mcol[6]= scol[2]; mcol[7]= scol[3]; + scol= scolmain+4*mface->v3; + mcol[9]= scol[1]; mcol[10]= scol[2]; mcol[11]= scol[3]; + if(mface->v4) { + scol= scolmain+4*mface->v4; + mcol[13]= scol[1]; mcol[14]= scol[2]; mcol[15]= scol[3]; + } + } + if(tface) tface++; + } + + MEM_freeN(scolmain); +} + +void make_vertexcol(Scene *scene, int shade) /* single ob */ +{ + Object *ob; + Mesh *me; + + if(scene->obedit) { + error("Unable to perform function in Edit Mode"); + return; + } + + ob= OBACT; + if(!ob || ob->id.lib) return; + me= get_mesh(ob); + if(me==0) return; + + /* copies from shadedisplist to mcol */ + if(!me->mcol) { + CustomData_add_layer(&me->fdata, CD_MCOL, CD_CALLOC, NULL, me->totface); + mesh_update_customdata_pointers(me); + } + + if(shade) + shadeMeshMCol(scene, ob, me); + else + memset(me->mcol, 255, 4*sizeof(MCol)*me->totface); + +// XXX if (me->mr) multires_load_cols(me); + + DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + +} + +static void copy_vpaint_prev(VPaint *vp, unsigned int *mcol, int tot) +{ + if(vp->vpaint_prev) { + MEM_freeN(vp->vpaint_prev); + vp->vpaint_prev= NULL; + } + vp->tot= tot; + + if(mcol==NULL || tot==0) return; + + vp->vpaint_prev= MEM_mallocN(4*sizeof(int)*tot, "vpaint_prev"); + memcpy(vp->vpaint_prev, mcol, 4*sizeof(int)*tot); + +} + +static void copy_wpaint_prev (VPaint *vp, MDeformVert *dverts, int dcount) +{ + if (vp->wpaint_prev) { + free_dverts(vp->wpaint_prev, vp->tot); + vp->wpaint_prev= NULL; + } + + if(dverts && dcount) { + + vp->wpaint_prev = MEM_mallocN (sizeof(MDeformVert)*dcount, "wpaint prev"); + vp->tot = dcount; + copy_dverts (vp->wpaint_prev, dverts, dcount); + } +} + + +void clear_vpaint(Scene *scene) +{ + Mesh *me; + Object *ob; + unsigned int *to, paintcol; + int a; + + if((G.f & G_VERTEXPAINT)==0) return; + + ob= OBACT; + me= get_mesh(ob); + if(!ob || ob->id.lib) return; + + if(me==0 || me->mcol==0 || me->totface==0) return; + + paintcol= vpaint_get_current_col(&Gvp); + + to= (unsigned int *)me->mcol; + a= 4*me->totface; + while(a--) { + *to= paintcol; + to++; + } + BIF_undo_push("Clear vertex colors"); + DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + +} + +void clear_vpaint_selectedfaces(Scene *scene) +{ + Mesh *me; + MFace *mf; + Object *ob; + unsigned int paintcol, *mcol; + int i; + + ob= OBACT; + me= get_mesh(ob); + if(me==0 || me->totface==0) return; + + if(!me->mcol) + make_vertexcol(scene, 0); + + paintcol= vpaint_get_current_col(&Gvp); + + mf = me->mface; + mcol = (unsigned int*)me->mcol; + for (i = 0; i < me->totface; i++, mf++, mcol+=4) { + if (mf->flag & ME_FACE_SEL) { + mcol[0] = paintcol; + mcol[1] = paintcol; + mcol[2] = paintcol; + mcol[3] = paintcol; + } + } + + BIF_undo_push("Clear vertex colors"); + DAG_object_flush_update(scene, ob, OB_RECALC_DATA); +} + + +/* fills in the selected faces with the current weight and vertex group */ +void clear_wpaint_selectedfaces(Scene *scene) +{ + float editbutvweight; + float paintweight= editbutvweight; + Mesh *me; + MFace *mface; + Object *ob; + MDeformWeight *dw, *uw; + int *indexar; + int index, vgroup; + unsigned int faceverts[5]={0,0,0,0,0}; + unsigned char i; + int vgroup_mirror= -1; + + ob= OBACT; + me= ob->data; + if(me==0 || me->totface==0 || me->dvert==0 || !me->mface) return; + + indexar= get_indexarray(); + for(index=0, mface=me->mface; index<me->totface; index++, mface++) { + if((mface->flag & ME_FACE_SEL)==0) + indexar[index]= 0; + else + indexar[index]= index+1; + } + + vgroup= ob->actdef-1; + + /* directly copied from weight_paint, should probaby split into a seperate function */ + /* if mirror painting, find the other group */ + if(Gwp.flag & VP_MIRROR_X) { + bDeformGroup *defgroup= BLI_findlink(&ob->defbase, ob->actdef-1); + if(defgroup) { + bDeformGroup *curdef; + int actdef= 0; + char name[32]; + + BLI_strncpy(name, defgroup->name, 32); + bone_flip_name(name, 0); /* 0 = don't strip off number extensions */ + + for (curdef = ob->defbase.first; curdef; curdef=curdef->next, actdef++) + if (!strcmp(curdef->name, name)) + break; + if(curdef==NULL) { + int olddef= ob->actdef; /* tsk, add_defgroup sets the active defgroup */ + curdef= add_defgroup_name (ob, name); + ob->actdef= olddef; + } + + if(curdef && curdef!=defgroup) + vgroup_mirror= actdef; + } + } + /* end copy from weight_paint*/ + + copy_wpaint_prev(&Gwp, me->dvert, me->totvert); + + for(index=0; index<me->totface; index++) { + if(indexar[index] && indexar[index]<=me->totface) { + mface= me->mface + (indexar[index]-1); + /* just so we can loop through the verts */ + faceverts[0]= mface->v1; + faceverts[1]= mface->v2; + faceverts[2]= mface->v3; + faceverts[3]= mface->v4; + for (i=0; i<3 || faceverts[i]; i++) { + if(!((me->dvert+faceverts[i])->flag)) { + dw= verify_defweight(me->dvert+faceverts[i], vgroup); + if(dw) { + uw= verify_defweight(Gwp.wpaint_prev+faceverts[i], vgroup); + uw->weight= dw->weight; /* set the undio weight */ + dw->weight= paintweight; + + if(Gwp.flag & VP_MIRROR_X) { /* x mirror painting */ + int j= mesh_get_x_mirror_vert(ob, faceverts[i]); + if(j>=0) { + /* copy, not paint again */ + if(vgroup_mirror != -1) { + dw= verify_defweight(me->dvert+j, vgroup_mirror); + uw= verify_defweight(Gwp.wpaint_prev+j, vgroup_mirror); + } else { + dw= verify_defweight(me->dvert+j, vgroup); + uw= verify_defweight(Gwp.wpaint_prev+j, vgroup); + } + uw->weight= dw->weight; /* set the undo weight */ + dw->weight= paintweight; + } + } + } + (me->dvert+faceverts[i])->flag= 1; + } + } + } + } + + index=0; + while (index<me->totvert) { + (me->dvert+index)->flag= 0; + index++; + } + + MEM_freeN(indexar); + copy_wpaint_prev(&Gwp, NULL, 0); + + DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + BIF_undo_push("Set vertex weight"); +} + + +void vpaint_dogamma(Scene *scene) +{ + Mesh *me; + Object *ob; + float igam, fac; + int a, temp; + char *cp, gamtab[256]; + + if((G.f & G_VERTEXPAINT)==0) return; + + ob= OBACT; + me= get_mesh(ob); + if(me==0 || me->mcol==0 || me->totface==0) return; + + igam= 1.0/Gvp.gamma; + for(a=0; a<256; a++) { + + fac= ((float)a)/255.0; + fac= Gvp.mul*pow( fac, igam); + + temp= 255.9*fac; + + if(temp<=0) gamtab[a]= 0; + else if(temp>=255) gamtab[a]= 255; + else gamtab[a]= temp; + } + + a= 4*me->totface; + cp= (char *)me->mcol; + while(a--) { + + cp[1]= gamtab[ cp[1] ]; + cp[2]= gamtab[ cp[2] ]; + cp[3]= gamtab[ cp[3] ]; + + cp+= 4; + } +} + +/* used for both 3d view and image window */ +void sample_vpaint(Scene *scene, ARegion *ar) /* frontbuf */ +{ + unsigned int col; + int x, y; + short mval[2]; + char *cp; + +// getmouseco_areawin(mval); + x= mval[0]; y= mval[1]; + + if(x<0 || y<0) return; + if(x>=ar->winx || y>=ar->winy) return; + + x+= ar->winrct.xmin; + y+= ar->winrct.ymin; + + glReadBuffer(GL_FRONT); + glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col); + glReadBuffer(GL_BACK); + + cp = (char *)&col; + + if(G.f & (G_VERTEXPAINT|G_WEIGHTPAINT)) { + Gvp.r= cp[0]/255.0f; + Gvp.g= cp[1]/255.0f; + Gvp.b= cp[2]/255.0f; + } + else { + Brush *brush= scene->toolsettings->imapaint.brush; + + if(brush) { + brush->rgb[0]= cp[0]/255.0f; + brush->rgb[1]= cp[1]/255.0f; + brush->rgb[2]= cp[2]/255.0f; + + } + } + +} + +static unsigned int mcol_blend(unsigned int col1, unsigned int col2, int fac) +{ + char *cp1, *cp2, *cp; + int mfac; + unsigned int col=0; + + if(fac==0) return col1; + if(fac>=255) return col2; + + mfac= 255-fac; + + cp1= (char *)&col1; + cp2= (char *)&col2; + cp= (char *)&col; + + cp[0]= 255; + cp[1]= (mfac*cp1[1]+fac*cp2[1])/255; + cp[2]= (mfac*cp1[2]+fac*cp2[2])/255; + cp[3]= (mfac*cp1[3]+fac*cp2[3])/255; + + return col; +} + +static unsigned int mcol_add(unsigned int col1, unsigned int col2, int fac) +{ + char *cp1, *cp2, *cp; + int temp; + unsigned int col=0; + + if(fac==0) return col1; + + cp1= (char *)&col1; + cp2= (char *)&col2; + cp= (char *)&col; + + cp[0]= 255; + temp= cp1[1] + ((fac*cp2[1])/255); + if(temp>254) cp[1]= 255; else cp[1]= temp; + temp= cp1[2] + ((fac*cp2[2])/255); + if(temp>254) cp[2]= 255; else cp[2]= temp; + temp= cp1[3] + ((fac*cp2[3])/255); + if(temp>254) cp[3]= 255; else cp[3]= temp; + + return col; +} + +static unsigned int mcol_sub(unsigned int col1, unsigned int col2, int fac) +{ + char *cp1, *cp2, *cp; + int temp; + unsigned int col=0; + + if(fac==0) return col1; + + cp1= (char *)&col1; + cp2= (char *)&col2; + cp= (char *)&col; + + cp[0]= 255; + temp= cp1[1] - ((fac*cp2[1])/255); + if(temp<0) cp[1]= 0; else cp[1]= temp; + temp= cp1[2] - ((fac*cp2[2])/255); + if(temp<0) cp[2]= 0; else cp[2]= temp; + temp= cp1[3] - ((fac*cp2[3])/255); + if(temp<0) cp[3]= 0; else cp[3]= temp; + + return col; +} + +static unsigned int mcol_mul(unsigned int col1, unsigned int col2, int fac) +{ + char *cp1, *cp2, *cp; + int mfac; + unsigned int col=0; + + if(fac==0) return col1; + + mfac= 255-fac; + + cp1= (char *)&col1; + cp2= (char *)&col2; + cp= (char *)&col; + + /* first mul, then blend the fac */ + cp[0]= 255; + cp[1]= (mfac*cp1[1] + fac*((cp2[1]*cp1[1])/255) )/255; + cp[2]= (mfac*cp1[2] + fac*((cp2[2]*cp1[2])/255) )/255; + cp[3]= (mfac*cp1[3] + fac*((cp2[3]*cp1[3])/255) )/255; + + + return col; +} + +static unsigned int mcol_lighten(unsigned int col1, unsigned int col2, int fac) +{ + char *cp1, *cp2, *cp; + int mfac; + unsigned int col=0; + + if(fac==0) return col1; + if(fac>=255) return col2; + + mfac= 255-fac; + + cp1= (char *)&col1; + cp2= (char *)&col2; + cp= (char *)&col; + + /* See if are lighter, if so mix, else dont do anything. + if the paint col is darker then the original, then ignore */ + if (cp1[1]+cp1[2]+cp1[3] > cp2[1]+cp2[2]+cp2[3]) + return col1; + + cp[0]= 255; + cp[1]= (mfac*cp1[1]+fac*cp2[1])/255; + cp[2]= (mfac*cp1[2]+fac*cp2[2])/255; + cp[3]= (mfac*cp1[3]+fac*cp2[3])/255; + + return col; +} + +static unsigned int mcol_darken(unsigned int col1, unsigned int col2, int fac) +{ + char *cp1, *cp2, *cp; + int mfac; + unsigned int col=0; + + if(fac==0) return col1; + if(fac>=255) return col2; + + mfac= 255-fac; + + cp1= (char *)&col1; + cp2= (char *)&col2; + cp= (char *)&col; + + /* See if were darker, if so mix, else dont do anything. + if the paint col is brighter then the original, then ignore */ + if (cp1[1]+cp1[2]+cp1[3] < cp2[1]+cp2[2]+cp2[3]) + return col1; + + cp[0]= 255; + cp[1]= (mfac*cp1[1]+fac*cp2[1])/255; + cp[2]= (mfac*cp1[2]+fac*cp2[2])/255; + cp[3]= (mfac*cp1[3]+fac*cp2[3])/255; + return col; +} + +static void vpaint_blend( unsigned int *col, unsigned int *colorig, unsigned int paintcol, int alpha) +{ + + if(Gvp.mode==VP_MIX || Gvp.mode==VP_BLUR) *col= mcol_blend( *col, paintcol, alpha); + else if(Gvp.mode==VP_ADD) *col= mcol_add( *col, paintcol, alpha); + else if(Gvp.mode==VP_SUB) *col= mcol_sub( *col, paintcol, alpha); + else if(Gvp.mode==VP_MUL) *col= mcol_mul( *col, paintcol, alpha); + else if(Gvp.mode==VP_LIGHTEN) *col= mcol_lighten( *col, paintcol, alpha); + else if(Gvp.mode==VP_DARKEN) *col= mcol_darken( *col, paintcol, alpha); + + /* if no spray, clip color adding with colorig & orig alpha */ + if((Gvp.flag & VP_SPRAY)==0) { + unsigned int testcol=0, a; + char *cp, *ct, *co; + + alpha= (int)(255.0*Gvp.a); + + if(Gvp.mode==VP_MIX || Gvp.mode==VP_BLUR) testcol= mcol_blend( *colorig, paintcol, alpha); + else if(Gvp.mode==VP_ADD) testcol= mcol_add( *colorig, paintcol, alpha); + else if(Gvp.mode==VP_SUB) testcol= mcol_sub( *colorig, paintcol, alpha); + else if(Gvp.mode==VP_MUL) testcol= mcol_mul( *colorig, paintcol, alpha); + else if(Gvp.mode==VP_LIGHTEN) testcol= mcol_lighten( *colorig, paintcol, alpha); + else if(Gvp.mode==VP_DARKEN) testcol= mcol_darken( *colorig, paintcol, alpha); + + cp= (char *)col; + ct= (char *)&testcol; + co= (char *)colorig; + + for(a=0; a<4; a++) { + if( ct[a]<co[a] ) { + if( cp[a]<ct[a] ) cp[a]= ct[a]; + else if( cp[a]>co[a] ) cp[a]= co[a]; + } + else { + if( cp[a]<co[a] ) cp[a]= co[a]; + else if( cp[a]>ct[a] ) cp[a]= ct[a]; + } + } + } +} + + +static int sample_backbuf_area(ViewContext *vc, int *indexar, int totface, int x, int y, float size) +{ + struct ImBuf *ibuf; + int a, tot=0, index; + + if(totface+4>=MAXINDEX) return 0; + + if(size>64.0) size= 64.0; + + ibuf= view3d_read_backbuf(vc, x-size, y-size, x+size, y+size); + if(ibuf) { + unsigned int *rt= ibuf->rect; + + memset(indexar, 0, sizeof(int)*totface+4); /* plus 2! first element is total, +2 was giving valgrind errors, +4 seems ok */ + + size= ibuf->x*ibuf->y; + while(size--) { + + if(*rt) { + index= WM_framebuffer_to_index(*rt); + if(index>0 && index<=totface) + indexar[index] = 1; + } + + rt++; + } + + for(a=1; a<=totface; a++) { + if(indexar[a]) indexar[tot++]= a; + } + + IMB_freeImBuf(ibuf); + } + + return tot; +} + +static int calc_vp_alpha_dl(VPaint *vp, ViewContext *vc, float vpimat[][3], float *vert_nor, short *mval) +{ + float fac, dx, dy; + int alpha; + short vertco[2]; + + if(vp->flag & VP_SOFT) { + project_short_noclip(vc->ar, vc->v3d, vert_nor, vertco); + dx= mval[0]-vertco[0]; + dy= mval[1]-vertco[1]; + + fac= sqrt(dx*dx + dy*dy); + if(fac > vp->size) return 0; + if(vp->flag & VP_HARD) + alpha= 255; + else + alpha= 255.0*vp->a*(1.0-fac/vp->size); + } + else { + alpha= 255.0*vp->a; + } + + if(vp->flag & VP_NORMALS) { + float *no= vert_nor+3; + + /* transpose ! */ + fac= vpimat[2][0]*no[0]+vpimat[2][1]*no[1]+vpimat[2][2]*no[2]; + if(fac>0.0) { + dx= vpimat[0][0]*no[0]+vpimat[0][1]*no[1]+vpimat[0][2]*no[2]; + dy= vpimat[1][0]*no[0]+vpimat[1][1]*no[1]+vpimat[1][2]*no[2]; + + alpha*= fac/sqrt(dx*dx + dy*dy + fac*fac); + } + else return 0; + } + + return alpha; +} + +static void wpaint_blend(MDeformWeight *dw, MDeformWeight *uw, float alpha, float paintval) +{ + + if(dw==NULL || uw==NULL) return; + + if(Gwp.mode==VP_MIX || Gwp.mode==VP_BLUR) + dw->weight = paintval*alpha + dw->weight*(1.0-alpha); + else if(Gwp.mode==VP_ADD) + dw->weight += paintval*alpha; + else if(Gwp.mode==VP_SUB) + dw->weight -= paintval*alpha; + else if(Gwp.mode==VP_MUL) + /* first mul, then blend the fac */ + dw->weight = ((1.0-alpha) + alpha*paintval)*dw->weight; + else if(Gwp.mode==VP_LIGHTEN) { + if (dw->weight < paintval) + dw->weight = paintval*alpha + dw->weight*(1.0-alpha); + } else if(Gwp.mode==VP_DARKEN) { + if (dw->weight > paintval) + dw->weight = paintval*alpha + dw->weight*(1.0-alpha); + } + CLAMP(dw->weight, 0.0f, 1.0f); + + /* if no spray, clip result with orig weight & orig alpha */ + if((Gwp.flag & VP_SPRAY)==0) { + float testw=0.0f; + + alpha= Gwp.a; + if(Gwp.mode==VP_MIX || Gwp.mode==VP_BLUR) + testw = paintval*alpha + uw->weight*(1.0-alpha); + else if(Gwp.mode==VP_ADD) + testw = uw->weight + paintval*alpha; + else if(Gwp.mode==VP_SUB) + testw = uw->weight - paintval*alpha; + else if(Gwp.mode==VP_MUL) + /* first mul, then blend the fac */ + testw = ((1.0-alpha) + alpha*paintval)*uw->weight; + else if(Gwp.mode==VP_LIGHTEN) { + if (uw->weight < paintval) + testw = paintval*alpha + uw->weight*(1.0-alpha); + else + testw = uw->weight; + } else if(Gwp.mode==VP_DARKEN) { + if (uw->weight > paintval) + testw = paintval*alpha + uw->weight*(1.0-alpha); + else + testw = uw->weight; + } + CLAMP(testw, 0.0f, 1.0f); + + if( testw<uw->weight ) { + if(dw->weight < testw) dw->weight= testw; + else if(dw->weight > uw->weight) dw->weight= uw->weight; + } + else { + if(dw->weight > testw) dw->weight= testw; + else if(dw->weight < uw->weight) dw->weight= uw->weight; + } + } + +} + +/* ----------------------------------------------------- */ + +/* used for 3d view, on active object, assumes me->dvert exists */ +/* if mode==1: */ +/* samples cursor location, and gives menu with vertex groups to activate */ +/* else */ +/* sets editbutvweight to the closest weight value to vertex */ +/* note: we cant sample frontbuf, weight colors are interpolated too unpredictable */ +static void sample_wpaint(Scene *scene, ARegion *ar, View3D *v3d, int mode) +{ + ViewContext vc; + Object *ob= OBACT; + Mesh *me= get_mesh(ob); + int index; + short mval[2], sco[2]; + + if (!me) return; + +// getmouseco_areawin(mval); + index= view3d_sample_backbuf(&vc, mval[0], mval[1]); + + if(index && index<=me->totface) { + MFace *mface; + + mface= ((MFace *)me->mface) + index-1; + + if(mode==1) { /* sampe which groups are in here */ + MDeformVert *dv; + int a, totgroup; + + totgroup= BLI_countlist(&ob->defbase); + if(totgroup) { + int totmenu=0; + int *groups=MEM_callocN(totgroup*sizeof(int), "groups"); + + dv= me->dvert+mface->v1; + for(a=0; a<dv->totweight; a++) { + if (dv->dw[a].def_nr<totgroup) + groups[dv->dw[a].def_nr]= 1; + } + dv= me->dvert+mface->v2; + for(a=0; a<dv->totweight; a++) { + if (dv->dw[a].def_nr<totgroup) + groups[dv->dw[a].def_nr]= 1; + } + dv= me->dvert+mface->v3; + for(a=0; a<dv->totweight; a++) { + if (dv->dw[a].def_nr<totgroup) + groups[dv->dw[a].def_nr]= 1; + } + if(mface->v4) { + dv= me->dvert+mface->v4; + for(a=0; a<dv->totweight; a++) { + if (dv->dw[a].def_nr<totgroup) + groups[dv->dw[a].def_nr]= 1; + } + } + for(a=0; a<totgroup; a++) + if(groups[a]) totmenu++; + + if(totmenu==0) { + //notice("No Vertex Group Selected"); + } + else { + bDeformGroup *dg; + short val; + char item[40], *str= MEM_mallocN(40*totmenu+40, "menu"); + + strcpy(str, "Vertex Groups %t"); + for(a=0, dg=ob->defbase.first; dg && a<totgroup; a++, dg= dg->next) { + if(groups[a]) { + sprintf(item, "|%s %%x%d", dg->name, a); + strcat(str, item); + } + } + + val= 0; // XXX pupmenu(str); + if(val>=0) { + ob->actdef= val+1; + DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + } + MEM_freeN(str); + } + MEM_freeN(groups); + } +// else notice("No Vertex Groups in Object"); + } + else { + DerivedMesh *dm; + MDeformWeight *dw; + float editbutvweight; + float w1, w2, w3, w4, co[3], fac; + + dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); + if(dm->getVertCo==NULL) { + //notice("Not supported yet"); + } + else { + /* calc 3 or 4 corner weights */ + dm->getVertCo(dm, mface->v1, co); + project_short_noclip(ar, v3d, co, sco); + w1= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1])); + + dm->getVertCo(dm, mface->v2, co); + project_short_noclip(ar, v3d, co, sco); + w2= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1])); + + dm->getVertCo(dm, mface->v3, co); + project_short_noclip(ar, v3d, co, sco); + w3= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1])); + + if(mface->v4) { + dm->getVertCo(dm, mface->v4, co); + project_short_noclip(ar, v3d, co, sco); + w4= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1])); + } + else w4= 1.0e10; + + fac= MIN4(w1, w2, w3, w4); + if(w1==fac) { + dw= get_defweight(me->dvert+mface->v1, ob->actdef-1); + if(dw) editbutvweight= dw->weight; else editbutvweight= 0.0f; + } + else if(w2==fac) { + dw= get_defweight(me->dvert+mface->v2, ob->actdef-1); + if(dw) editbutvweight= dw->weight; else editbutvweight= 0.0f; + } + else if(w3==fac) { + dw= get_defweight(me->dvert+mface->v3, ob->actdef-1); + if(dw) editbutvweight= dw->weight; else editbutvweight= 0.0f; + } + else if(w4==fac) { + if(mface->v4) { + dw= get_defweight(me->dvert+mface->v4, ob->actdef-1); + if(dw) editbutvweight= dw->weight; else editbutvweight= 0.0f; + } + } + } + dm->release(dm); + } + + } + +} + +static void do_weight_paint_vertex(Object *ob, int index, int alpha, float paintweight, int vgroup_mirror) +{ + Mesh *me= ob->data; + MDeformWeight *dw, *uw; + int vgroup= ob->actdef-1; + + if(Gwp.flag & VP_ONLYVGROUP) { + dw= get_defweight(me->dvert+index, vgroup); + uw= get_defweight(Gwp.wpaint_prev+index, vgroup); + } + else { + dw= verify_defweight(me->dvert+index, vgroup); + uw= verify_defweight(Gwp.wpaint_prev+index, vgroup); + } + if(dw==NULL || uw==NULL) + return; + + wpaint_blend(dw, uw, (float)alpha/255.0, paintweight); + + if(Gwp.flag & VP_MIRROR_X) { /* x mirror painting */ + int j= mesh_get_x_mirror_vert(ob, index); + if(j>=0) { + /* copy, not paint again */ + if(vgroup_mirror != -1) + uw= verify_defweight(me->dvert+j, vgroup_mirror); + else + uw= verify_defweight(me->dvert+j, vgroup); + + uw->weight= dw->weight; + } + } +} + + +void weight_paint(Scene *scene, ARegion *ar, View3D *v3d) +{ + ViewContext vc; + float editbutvweight; // XXX + Object *ob; + Mesh *me; + MFace *mface; + float mat[4][4], imat[4][4], paintweight, *vertexcosnos; + float vpimat[3][3]; + int *indexar, index, totindex, alpha, totw; + int vgroup_mirror= -1; + short mval[2], mvalo[2], firsttime=1; + + if((G.f & G_WEIGHTPAINT)==0) return; + if(scene->obedit) return; +// XXX if(multires_level1_test()) return; + + ob= OBACT; + if(!ob || ob->id.lib) return; + + me= get_mesh(ob); + if(me==NULL || me->totface==0) return; + + /* if nothing was added yet, we make dverts and a vertex deform group */ +// if (!me->dvert) +// create_dverts(&me->id); + +// if(qual & LR_CTRLKEY) { + sample_wpaint(scene, ar, v3d, 0); +// return; +// } +// if(qual & LR_SHIFTKEY) { +// sample_wpaint(scene, ar, v3d, 1); +// return; +// } + + /* ALLOCATIONS! no return after this line */ + /* painting on subsurfs should give correct points too, this returns me->totvert amount */ + vertexcosnos= mesh_get_mapped_verts_nors(scene, ob); + indexar= get_indexarray(); + copy_wpaint_prev(&Gwp, me->dvert, me->totvert); + + /* this happens on a Bone select, when no vgroup existed yet */ + if(ob->actdef<=0) { + Object *modob; + if((modob = modifiers_isDeformedByArmature(ob))) { + bPoseChannel *pchan; + for(pchan= modob->pose->chanbase.first; pchan; pchan= pchan->next) + if(pchan->bone->flag & SELECT) + break; + if(pchan) { + bDeformGroup *dg= get_named_vertexgroup(ob, pchan->name); + if(dg==NULL) + dg= add_defgroup_name(ob, pchan->name); /* sets actdef */ + else + ob->actdef= get_defgroup_num(ob, dg); + } + } + } + if(ob->defbase.first==NULL) { + add_defgroup(ob); + } + + if(ob->lay & v3d->lay); else error("Active object is not in this layer"); + +// XXX persp(PERSP_VIEW); + /* imat for normals */ + Mat4MulMat4(mat, ob->obmat, v3d->viewmat); + Mat4Invert(imat, mat); + Mat3CpyMat4(vpimat, imat); + + /* load projection matrix */ + wmMultMatrix(ob->obmat); + wmGetSingleMatrix(mat); + wmLoadMatrix(v3d->viewmat); + +// getmouseco_areawin(mvalo); + +// getmouseco_areawin(mval); + mvalo[0]= mval[0]; + mvalo[1]= mval[1]; + + /* if mirror painting, find the other group */ + if(Gwp.flag & VP_MIRROR_X) { + bDeformGroup *defgroup= BLI_findlink(&ob->defbase, ob->actdef-1); + if(defgroup) { + bDeformGroup *curdef; + int actdef= 0; + char name[32]; + + BLI_strncpy(name, defgroup->name, 32); + bone_flip_name(name, 0); /* 0 = don't strip off number extensions */ + + for (curdef = ob->defbase.first; curdef; curdef=curdef->next, actdef++) + if (!strcmp(curdef->name, name)) + break; + if(curdef==NULL) { + int olddef= ob->actdef; /* tsk, add_defgroup sets the active defgroup */ + curdef= add_defgroup_name (ob, name); + ob->actdef= olddef; + } + + if(curdef && curdef!=defgroup) + vgroup_mirror= actdef; + } + } + + while (get_mbut() & 0) { +// getmouseco_areawin(mval); + + if(firsttime || mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) { + firsttime= 0; + + /* which faces are involved */ + if(Gwp.flag & VP_AREA) { + totindex= sample_backbuf_area(&vc, indexar, me->totface, mval[0], mval[1], Gwp.size); + } + else { + indexar[0]= view3d_sample_backbuf(&vc, mval[0], mval[1]); + if(indexar[0]) totindex= 1; + else totindex= 0; + } + + MTC_Mat4SwapMat4(v3d->persmat, mat); + + if(Gwp.flag & VP_COLINDEX) { + for(index=0; index<totindex; index++) { + if(indexar[index] && indexar[index]<=me->totface) { + + mface= ((MFace *)me->mface) + (indexar[index]-1); + + if(mface->mat_nr!=ob->actcol-1) { + indexar[index]= 0; + } + } + } + } + + if((G.f & G_FACESELECT) && me->mface) { + for(index=0; index<totindex; index++) { + if(indexar[index] && indexar[index]<=me->totface) { + + mface= ((MFace *)me->mface) + (indexar[index]-1); + + if((mface->flag & ME_FACE_SEL)==0) { + indexar[index]= 0; + } + } + } + } + + /* make sure each vertex gets treated only once */ + /* and calculate filter weight */ + totw= 0; + if(Gwp.mode==VP_BLUR) + paintweight= 0.0f; + else + paintweight= editbutvweight; + + for(index=0; index<totindex; index++) { + if(indexar[index] && indexar[index]<=me->totface) { + mface= me->mface + (indexar[index]-1); + + (me->dvert+mface->v1)->flag= 1; + (me->dvert+mface->v2)->flag= 1; + (me->dvert+mface->v3)->flag= 1; + if(mface->v4) (me->dvert+mface->v4)->flag= 1; + + if(Gwp.mode==VP_BLUR) { + MDeformWeight *dw, *(*dw_func)(MDeformVert *, int) = verify_defweight; + + if(Gwp.flag & VP_ONLYVGROUP) + dw_func= get_defweight; + + dw= dw_func(me->dvert+mface->v1, ob->actdef-1); + if(dw) {paintweight+= dw->weight; totw++;} + dw= dw_func(me->dvert+mface->v2, ob->actdef-1); + if(dw) {paintweight+= dw->weight; totw++;} + dw= dw_func(me->dvert+mface->v3, ob->actdef-1); + if(dw) {paintweight+= dw->weight; totw++;} + if(mface->v4) { + dw= dw_func(me->dvert+mface->v4, ob->actdef-1); + if(dw) {paintweight+= dw->weight; totw++;} + } + } + } + } + + if(Gwp.mode==VP_BLUR) + paintweight/= (float)totw; + + for(index=0; index<totindex; index++) { + + if(indexar[index] && indexar[index]<=me->totface) { + mface= me->mface + (indexar[index]-1); + + if((me->dvert+mface->v1)->flag) { + alpha= calc_vp_alpha_dl(&Gwp, &vc, vpimat, vertexcosnos+6*mface->v1, mval); + if(alpha) { + do_weight_paint_vertex(ob, mface->v1, alpha, paintweight, vgroup_mirror); + } + (me->dvert+mface->v1)->flag= 0; + } + + if((me->dvert+mface->v2)->flag) { + alpha= calc_vp_alpha_dl(&Gwp, &vc, vpimat, vertexcosnos+6*mface->v2, mval); + if(alpha) { + do_weight_paint_vertex(ob, mface->v2, alpha, paintweight, vgroup_mirror); + } + (me->dvert+mface->v2)->flag= 0; + } + + if((me->dvert+mface->v3)->flag) { + alpha= calc_vp_alpha_dl(&Gwp, &vc, vpimat, vertexcosnos+6*mface->v3, mval); + if(alpha) { + do_weight_paint_vertex(ob, mface->v3, alpha, paintweight, vgroup_mirror); + } + (me->dvert+mface->v3)->flag= 0; + } + + if((me->dvert+mface->v4)->flag) { + if(mface->v4) { + alpha= calc_vp_alpha_dl(&Gwp, &vc, vpimat, vertexcosnos+6*mface->v4, mval); + if(alpha) { + do_weight_paint_vertex(ob, mface->v4, alpha, paintweight, vgroup_mirror); + } + (me->dvert+mface->v4)->flag= 0; + } + } + } + } + + MTC_Mat4SwapMat4(v3d->persmat, mat); + + } + + if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) { + + DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + + if(Gwp.flag & (VP_AREA|VP_SOFT)) { + /* draw circle in backbuf! */ +// XXX persp(PERSP_WIN); +// XXX fdrawXORcirc((float)mval[0], (float)mval[1], Gwp.size); +// XXX persp(PERSP_VIEW); + } + + mvalo[0]= mval[0]; + mvalo[1]= mval[1]; + } + } + + if(vertexcosnos) + MEM_freeN(vertexcosnos); + MEM_freeN(indexar); + copy_wpaint_prev(&Gwp, NULL, 0); + + DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + + /* and particles too */ + if(ob->particlesystem.first) { + ParticleSystem *psys; + int i; + + psys= ob->particlesystem.first; + while(psys) { + for(i=0; i<PSYS_TOT_VG; i++) { + if(psys->vgroup[i]==ob->actdef) { + psys->recalc |= PSYS_RECALC_HAIR; + break; + } + } + + psys= psys->next; + } + } + + BIF_undo_push("Weight Paint"); +} + +void set_wpaint(bContext *C, wmOperator *op) /* toggle */ +{ + Object *ob= CTX_data_active_object(C); + Scene *scene= CTX_data_scene(C); + Mesh *me; + + ob= OBACT; + if(!ob || ob->id.lib) return; + me= get_mesh(ob); + + if(me && me->totface>=MAXINDEX) { + error("Maximum number of faces: %d", MAXINDEX-1); + G.f &= ~G_WEIGHTPAINT; + return; + } + + if(G.f & G_WEIGHTPAINT) G.f &= ~G_WEIGHTPAINT; + else G.f |= G_WEIGHTPAINT; + + + /* Weightpaint works by overriding colors in mesh, + * so need to make sure we recalc on enter and + * exit (exit needs doing regardless because we + * should redeform). + */ + if (me) { + DAG_object_flush_update(scene, OBACT, OB_RECALC_DATA); + } + + if(G.f & G_WEIGHTPAINT) { + Object *par; + + mesh_octree_table(ob, NULL, NULL, 's'); + + /* verify if active weight group is also active bone */ + par= modifiers_isDeformedByArmature(ob); + if(par && (par->flag & OB_POSEMODE)) { + bPoseChannel *pchan; + for(pchan= par->pose->chanbase.first; pchan; pchan= pchan->next) + if(pchan->bone->flag & BONE_ACTIVE) + break; + // if(pchan) + // XXX vertexgroup_select_by_name(ob, pchan->name); + } + } + else { + mesh_octree_table(ob, NULL, NULL, 'e'); + } +} + +/* ************ set / clear vertex paint mode ********** */ + +/* retrieve whether cursor should be set or operator should be done */ +static int vp_poll(bContext *C) +{ + if(G.f & G_VERTEXPAINT) { + ScrArea *sa= CTX_wm_area(C); + if(sa->spacetype==SPACE_VIEW3D) { + ARegion *ar= CTX_wm_region(C); + if(ar->regiontype==RGN_TYPE_WINDOW) + return 1; + } + } + return 0; +} + +static void vp_drawcursor(bContext *C, int x, int y) +{ + glTranslatef((float)x, (float)y, 0.0f); + + glColor4ub(255, 255, 255, 128); + glEnable( GL_LINE_SMOOTH ); + glEnable(GL_BLEND); + glutil_draw_lined_arc(0.0, M_PI*2.0, Gvp.size, 40); + glDisable(GL_BLEND); + glDisable( GL_LINE_SMOOTH ); + + glTranslatef((float)-x, (float)-y, 0.0f); +} + +static int set_vpaint(bContext *C, wmOperator *op) /* toggle */ +{ + Object *ob= CTX_data_active_object(C); + Scene *scene= CTX_data_scene(C); + Mesh *me; + + if(object_data_is_libdata(ob)) { + G.f &= ~G_VERTEXPAINT; + return OPERATOR_FINISHED; + } + + me= get_mesh(ob); + + if(me && me->totface>=MAXINDEX) { + error("Maximum number of faces: %d", MAXINDEX-1); + G.f &= ~G_VERTEXPAINT; + return OPERATOR_FINISHED; + } + + if(me && me->mcol==NULL) make_vertexcol(scene, 0); + + /* toggle: end vpaint */ + if(G.f & G_VERTEXPAINT){ + G.f &= ~G_VERTEXPAINT; + + WM_paint_cursor_end(CTX_wm_manager(C), Gvp.paintcursor); + Gvp.paintcursor= NULL; + } + else { + G.f |= G_VERTEXPAINT; + /* Turn off weight painting */ + if (G.f & G_WEIGHTPAINT) + set_wpaint(C, op); + + Gvp.paintcursor = WM_paint_cursor_activate(CTX_wm_manager(C), vp_poll, vp_drawcursor); + } + + if (me) + /* update modifier stack for mapping requirements */ + DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + + WM_event_add_notifier(C, NC_SCENE|ND_MODE, ob); + + return OPERATOR_FINISHED; +} + +void VIEW3D_OT_vpaint_toggle(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name= "Vpaint mode"; + ot->idname= "VIEW3D_OT_vpaint_toggle"; + + /* api callbacks */ + ot->exec= set_vpaint; + ot->poll= ED_operator_object_active; + +} + + + +/* ********************** vertex paint operator ******************* */ + +/* Implementation notes: + +Operator->invoke() + - validate context (add mcol) + - create customdata storage + - call paint once (mouse click) + - add modal handler + +Operator->modal() + - for every mousemove, apply vertex paint + - exit on mouse release, free customdata + (return OPERATOR_FINISHED also removes handler and operator) + +For future: + - implement a stroke event (or mousemove with past positons) + - revise whether customdata should be added in object, in set_vpaint + - store Gvp locally (in scene?) + +*/ + +struct VPaintData { + ViewContext vc; + unsigned int paintcol; + int *indexar; + float *vertexcosnos; + float vpimat[3][3]; +}; + +static void vpaint_exit(bContext *C, wmOperator *op) +{ + struct VPaintData *vpd= op->customdata; + + if(vpd->vertexcosnos) + MEM_freeN(vpd->vertexcosnos); + MEM_freeN(vpd->indexar); + + /* frees prev buffer */ + copy_vpaint_prev(&Gvp, NULL, 0); + + ED_undo_push(C, "Vertex Paint"); + + MEM_freeN(vpd); + op->customdata= NULL; +} + +static int vpaint_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + + switch(event->type) { + case LEFTMOUSE: + if(event->val==0) { /* release */ + vpaint_exit(C, op); + return OPERATOR_FINISHED; + } + /* pass on, first press gets painted too */ + + case MOUSEMOVE: + { + struct VPaintData *vpd= op->customdata; + ViewContext *vc= &vpd->vc; + Object *ob= vc->obact; + Mesh *me= ob->data; + float mat[4][4]; + int *indexar= vpd->indexar; + int totindex, index; + short mval[2]; + + view3d_operator_needs_opengl(C); + + /* load projection matrix */ + wmMultMatrix(ob->obmat); + wmGetSingleMatrix(mat); + wmLoadMatrix(vc->v3d->viewmat); + + mval[0]= event->x - vc->ar->winrct.xmin; + mval[1]= event->y - vc->ar->winrct.ymin; + + /* which faces are involved */ + if(Gvp.flag & VP_AREA) { + totindex= sample_backbuf_area(vc, indexar, me->totface, mval[0], mval[1], Gvp.size); + } + else { + indexar[0]= view3d_sample_backbuf(vc, mval[0], mval[1]); + if(indexar[0]) totindex= 1; + else totindex= 0; + } + + MTC_Mat4SwapMat4(vc->v3d->persmat, mat); + + if(Gvp.flag & VP_COLINDEX) { + for(index=0; index<totindex; index++) { + if(indexar[index] && indexar[index]<=me->totface) { + MFace *mface= ((MFace *)me->mface) + (indexar[index]-1); + + if(mface->mat_nr!=ob->actcol-1) { + indexar[index]= 0; + } + } + } + } + if((G.f & G_FACESELECT) && me->mface) { + for(index=0; index<totindex; index++) { + if(indexar[index] && indexar[index]<=me->totface) { + MFace *mface= ((MFace *)me->mface) + (indexar[index]-1); + + if((mface->flag & ME_FACE_SEL)==0) + indexar[index]= 0; + } + } + } + + for(index=0; index<totindex; index++) { + + if(indexar[index] && indexar[index]<=me->totface) { + MFace *mface= ((MFace *)me->mface) + (indexar[index]-1); + unsigned int *mcol= ( (unsigned int *)me->mcol) + 4*(indexar[index]-1); + unsigned int *mcolorig= ( (unsigned int *)Gvp.vpaint_prev) + 4*(indexar[index]-1); + int alpha; + + if(Gvp.mode==VP_BLUR) { + unsigned int fcol1= mcol_blend( mcol[0], mcol[1], 128); + if(mface->v4) { + unsigned int fcol2= mcol_blend( mcol[2], mcol[3], 128); + vpd->paintcol= mcol_blend( fcol1, fcol2, 128); + } + else { + vpd->paintcol= mcol_blend( mcol[2], fcol1, 170); + } + + } + + alpha= calc_vp_alpha_dl(&Gvp, vc, vpd->vpimat, vpd->vertexcosnos+6*mface->v1, mval); + if(alpha) vpaint_blend( mcol, mcolorig, vpd->paintcol, alpha); + + alpha= calc_vp_alpha_dl(&Gvp, vc, vpd->vpimat, vpd->vertexcosnos+6*mface->v2, mval); + if(alpha) vpaint_blend( mcol+1, mcolorig+1, vpd->paintcol, alpha); + + alpha= calc_vp_alpha_dl(&Gvp, vc, vpd->vpimat, vpd->vertexcosnos+6*mface->v3, mval); + if(alpha) vpaint_blend( mcol+2, mcolorig+2, vpd->paintcol, alpha); + + if(mface->v4) { + alpha= calc_vp_alpha_dl(&Gvp, vc, vpd->vpimat, vpd->vertexcosnos+6*mface->v4, mval); + if(alpha) vpaint_blend( mcol+3, mcolorig+3, vpd->paintcol, alpha); + } + } + } + + MTC_Mat4SwapMat4(vc->v3d->persmat, mat); + + do_shared_vertexcol(me); + + ED_region_tag_redraw(vc->ar); + + DAG_object_flush_update(vc->scene, ob, OB_RECALC_DATA); + } + break; + } + + return OPERATOR_RUNNING_MODAL; +} + +static int vpaint_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + struct VPaintData *vpd; + Object *ob= CTX_data_active_object(C); + Mesh *me; + float mat[4][4], imat[4][4]; + + /* context checks could be a poll() */ + me= get_mesh(ob); + if(me==NULL || me->totface==0) return OPERATOR_CANCELLED; + + if(me->mcol==NULL) make_vertexcol(CTX_data_scene(C), 0); + if(me->mcol==NULL) return OPERATOR_CANCELLED; + + /* make customdata storage */ + op->customdata= vpd= MEM_callocN(sizeof(struct VPaintData), "VPaintData"); + view3d_set_viewcontext(C, &vpd->vc); + + vpd->vertexcosnos= mesh_get_mapped_verts_nors(vpd->vc.scene, ob); + vpd->indexar= get_indexarray(); + vpd->paintcol= vpaint_get_current_col(&Gvp); + + /* for filtering */ + copy_vpaint_prev(&Gvp, (unsigned int *)me->mcol, me->totface); + + /* some old cruft to sort out later */ + Mat4MulMat4(mat, ob->obmat, vpd->vc.v3d->viewmat); + Mat4Invert(imat, mat); + Mat3CpyMat4(vpd->vpimat, imat); + + /* do paint once for click only paint */ + vpaint_modal(C, op, event); + + /* add modal handler */ + WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + + return OPERATOR_RUNNING_MODAL; +} + +void VIEW3D_OT_vpaint(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name= "Vpaint"; + ot->idname= "VIEW3D_OT_vpaint"; + + /* api callbacks */ + ot->invoke= vpaint_invoke; + ot->modal= vpaint_modal; + /* ot->exec= vpaint_exec; <-- needs stroke property */ + ot->poll= vp_poll; + +} + + diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 6f9b34d610c..c0ef862a9c3 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -101,6 +101,7 @@ #include "ED_util.h" #include "UI_view2d.h" #include "WM_types.h" +#include "WM_api.h" #include "BLI_arithb.h" #include "BLI_blenlib.h" @@ -329,13 +330,12 @@ void convertDisplayNumToVec(float *num, float *vec) #endif } -static void viewRedrawForce(TransInfo *t) +static void viewRedrawForce(bContext *C, TransInfo *t) { if (t->spacetype == SPACE_VIEW3D) { - // TRANSFORM_FIX_ME - // need to redraw ALL 3d view - ED_area_tag_redraw(t->sa); + /* Do we need more refined tags? */ + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); } else if (t->spacetype == SPACE_ACTION) { SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first; @@ -347,8 +347,10 @@ static void viewRedrawForce(TransInfo *t) else ED_area_tag_redraw(t->sa); } - else if(t->spacetype == SPACE_NODE) { - ED_area_tag_redraw(t->sa); + else if(t->spacetype == SPACE_NODE) + { + //ED_area_tag_redraw(t->sa); + WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL); } #if 0 // TRANSFORM_FIX_ME else if (t->spacetype==SPACE_IMAGE) { @@ -1101,7 +1103,7 @@ void initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) } -void transformApply(TransInfo *t) +void transformApply(bContext *C, TransInfo *t) { if (t->redraw) { @@ -1111,6 +1113,7 @@ void transformApply(TransInfo *t) selectConstraint(t); if (t->transform) { t->transform(t, t->mval); // calls recalcData() + viewRedrawForce(C, t); } t->redraw = 0; } @@ -1140,6 +1143,7 @@ int transformEnd(bContext *C, TransInfo *t) { exit_code = OPERATOR_CANCELLED; restoreTransObjects(t); // calls recalcData() + viewRedrawForce(C, t); } else { @@ -1850,8 +1854,6 @@ int Warp(TransInfo *t, short mval[2]) ED_area_headerprint(t->sa, str); - viewRedrawForce(t); - helpline(t, gcursor); return 1; @@ -1974,8 +1976,6 @@ int Shear(TransInfo *t, short mval[2]) ED_area_headerprint(t->sa, str); - viewRedrawForce(t); - helpline (t, t->center); return 1; @@ -2247,8 +2247,6 @@ int Resize(TransInfo *t, short mval[2]) ED_area_headerprint(t->sa, str); - viewRedrawForce(t); - if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center); return 1; @@ -2340,8 +2338,6 @@ int ToSphere(TransInfo *t, short mval[2]) ED_area_headerprint(t->sa, str); - viewRedrawForce(t); - return 1; } @@ -2656,8 +2652,6 @@ int Rotation(TransInfo *t, short mval[2]) ED_area_headerprint(t->sa, str); - viewRedrawForce(t); - if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center); return 1; @@ -2765,8 +2759,6 @@ int Trackball(TransInfo *t, short mval[2]) ED_area_headerprint(t->sa, str); - viewRedrawForce(t); - if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center); return 1; @@ -2959,8 +2951,6 @@ int Translation(TransInfo *t, short mval[2]) recalcData(t); ED_area_headerprint(t->sa, str); - - viewRedrawForce(t); drawSnapping(t); @@ -3039,8 +3029,6 @@ int ShrinkFatten(TransInfo *t, short mval[2]) ED_area_headerprint(t->sa, str); - viewRedrawForce(t); - return 1; } @@ -3113,8 +3101,6 @@ int Tilt(TransInfo *t, short mval[2]) ED_area_headerprint(t->sa, str); - viewRedrawForce(t); - helpline (t, t->center); return 1; @@ -3181,8 +3167,6 @@ int CurveShrinkFatten(TransInfo *t, short mval[2]) ED_area_headerprint(t->sa, str); - viewRedrawForce(t); - if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center); return 1; @@ -3272,8 +3256,6 @@ int PushPull(TransInfo *t, short mval[2]) ED_area_headerprint(t->sa, str); - viewRedrawForce(t); - return 1; } @@ -3387,8 +3369,6 @@ int Bevel(TransInfo *t, short mval[2]) ED_area_headerprint(t->sa, str); - viewRedrawForce(t); - return 1; } @@ -3460,8 +3440,6 @@ int BevelWeight(TransInfo *t, short mval[2]) ED_area_headerprint(t->sa, str); - viewRedrawForce(t); - helpline (t, t->center); return 1; @@ -3538,8 +3516,6 @@ int Crease(TransInfo *t, short mval[2]) ED_area_headerprint(t->sa, str); - viewRedrawForce(t); - helpline (t, t->center); return 1; @@ -3657,8 +3633,6 @@ int BoneSize(TransInfo *t, short mval[2]) ED_area_headerprint(t->sa, str); - viewRedrawForce(t); - if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center); return 1; @@ -3727,8 +3701,6 @@ int BoneEnvelope(TransInfo *t, short mval[2]) ED_area_headerprint(t->sa, str); - viewRedrawForce(t); - if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center); return 1; @@ -3795,8 +3767,6 @@ int BoneRoll(TransInfo *t, short mval[2]) ED_area_headerprint(t->sa, str); - viewRedrawForce(t); - if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center); return 1; @@ -3875,8 +3845,6 @@ int BakeTime(TransInfo *t, short mval[2]) ED_area_headerprint(t->sa, str); - viewRedrawForce(t); - helpline (t, t->center); return 1; @@ -3933,8 +3901,6 @@ int Mirror(TransInfo *t, short mval[2]) recalcData(t); ED_area_headerprint(t->sa, str); - - viewRedrawForce(t); } else { @@ -3955,8 +3921,6 @@ int Mirror(TransInfo *t, short mval[2]) recalcData(t); ED_area_headerprint(t->sa, "Select a mirror axis (X, Y, Z)"); - - viewRedrawForce(t); } return 1; @@ -4275,8 +4239,6 @@ int TimeTranslate(TransInfo *t, short mval[2]) recalcData(t); ED_area_headerprint(t->sa, str); - - viewRedrawForce(t); return 1; } @@ -4403,8 +4365,6 @@ int TimeSlide(TransInfo *t, short mval[2]) recalcData(t); ED_area_headerprint(t->sa, str); - - viewRedrawForce(t); return 1; } @@ -4519,8 +4479,6 @@ int TimeScale(TransInfo *t, short mval[2]) recalcData(t); ED_area_headerprint(t->sa, str); - - viewRedrawForce(t); return 1; } diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index a2eb86100bb..75edfb78aba 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -344,7 +344,7 @@ void TFM_OT_transform(struct wmOperatorType *ot); void initTransform(struct bContext *C, struct TransInfo *t, struct wmOperator *op, struct wmEvent *event); void saveTransform(struct bContext *C, struct TransInfo *t, struct wmOperator *op); void transformEvent(TransInfo *t, struct wmEvent *event); -void transformApply(TransInfo *t); +void transformApply(struct bContext *C, TransInfo *t); int transformEnd(struct bContext *C, TransInfo *t); void setTransformViewMatrices(TransInfo *t); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 974c02c89e4..e197e0788f7 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -1021,25 +1021,29 @@ static void createTransPose(bContext *C, TransInfo *t, Object *ob) static void createTransArmatureVerts(bContext *C, TransInfo *t) { - // TRANSFORM_FIX_ME -#if 0 EditBone *ebo; bArmature *arm= t->obedit->data; + ListBase *edbo = arm->edbo; TransData *td; float mtx[3][3], smtx[3][3], delta[3], bonemat[3][3]; t->total = 0; - for (ebo=G.edbo.first;ebo;ebo=ebo->next) { - if(ebo->layer & arm->layer) { - if (t->mode==TFM_BONESIZE) { + for (ebo = edbo->first; ebo; ebo = ebo->next) + { + if(ebo->layer & arm->layer) + { + if (t->mode==TFM_BONESIZE) + { if (ebo->flag & BONE_SELECTED) t->total++; } - else if (t->mode==TFM_BONE_ROLL) { + else if (t->mode==TFM_BONE_ROLL) + { if (ebo->flag & BONE_SELECTED) t->total++; } - else { + else + { if (ebo->flag & BONE_TIPSEL) t->total++; if (ebo->flag & BONE_ROOTSEL) @@ -1055,13 +1059,15 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransEditBone"); - for (ebo=G.edbo.first;ebo;ebo=ebo->next){ - ebo->oldlength= ebo->length; // length==0.0 on extrude, used for scaling radius of bone points + for (ebo = edbo->first; ebo; ebo = ebo->next) + { + ebo->oldlength = ebo->length; // length==0.0 on extrude, used for scaling radius of bone points if(ebo->layer & arm->layer) { - if (t->mode==TFM_BONE_ENVELOPE) { - - if (ebo->flag & BONE_ROOTSEL){ + if (t->mode==TFM_BONE_ENVELOPE) + { + if (ebo->flag & BONE_ROOTSEL) + { td->val= &ebo->rad_head; td->ival= *td->val; @@ -1077,7 +1083,8 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) td++; } - if (ebo->flag & BONE_TIPSEL){ + if (ebo->flag & BONE_TIPSEL) + { td->val= &ebo->rad_tail; td->ival= *td->val; VECCOPY (td->center, ebo->tail); @@ -1094,14 +1101,17 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) } } - else if (t->mode==TFM_BONESIZE) { + else if (t->mode==TFM_BONESIZE) + { if (ebo->flag & BONE_SELECTED) { - if(arm->drawtype==ARM_ENVELOPE) { + if(arm->drawtype==ARM_ENVELOPE) + { td->loc= NULL; td->val= &ebo->dist; td->ival= ebo->dist; } - else { + else + { // abusive storage of scale in the loc pointer :) td->loc= &ebo->xwidth; VECCOPY (td->iloc, td->loc); @@ -1125,8 +1135,10 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) td++; } } - else if (t->mode==TFM_BONE_ROLL) { - if (ebo->flag & BONE_SELECTED) { + else if (t->mode==TFM_BONE_ROLL) + { + if (ebo->flag & BONE_SELECTED) + { td->loc= NULL; td->val= &(ebo->roll); td->ival= ebo->roll; @@ -1140,8 +1152,10 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) td++; } } - else { - if (ebo->flag & BONE_TIPSEL){ + else + { + if (ebo->flag & BONE_TIPSEL) + { VECCOPY (td->iloc, ebo->tail); VECCOPY (td->center, td->iloc); td->loc= ebo->tail; @@ -1166,7 +1180,8 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) td++; } - if (ebo->flag & BONE_ROOTSEL){ + if (ebo->flag & BONE_ROOTSEL) + { VECCOPY (td->iloc, ebo->head); VECCOPY (td->center, td->iloc); td->loc= ebo->head; @@ -1191,7 +1206,6 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) } } } -#endif } /* ********************* meta elements ********* */ diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 8cc20454600..69d2e1c119e 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -421,30 +421,7 @@ void recalcData(TransInfo *t) } } else if (t->obedit) { - if (t->obedit->type == OB_MESH) { - if(t->spacetype==SPACE_IMAGE) { - flushTransUVs(t); - if (G.sima->flag & SI_LIVE_UNWRAP) - unwrap_lscm_live_re_solve(); - } else { - EditMesh *em = ((Mesh *)t->obedit->data)->edit_mesh - /* mirror modifier clipping? */ - if(t->state != TRANS_CANCEL) { - if ((G.qual & LR_CTRLKEY)==0) { - /* Only retopo if not snapping, Note, this is the only case of G.qual being used, but we have no T_SHIFT_MOD - Campbell */ - retopo_do_all(); - } - clipMirrorModifier(t, t->obedit); - } - if((t->options & CTX_NO_MIRROR) == 0 && (G.scene->toolsettings->editbutflag & B_MESH_X_MIRROR)) - editmesh_apply_to_mirror(t); - - DAG_object_flush_update(G.scene, t->obedit, OB_RECALC_DATA); /* sets recalc flags */ - - recalc_editnormals(em); - } - } - else if ELEM(t->obedit->type, OB_CURVE, OB_SURF) { + if ELEM(t->obedit->type, OB_CURVE, OB_SURF) { Nurb *nu= editNurb.first; DAG_object_flush_update(G.scene, t->obedit, OB_RECALC_DATA); /* sets recalc flags */ @@ -463,14 +440,68 @@ void recalcData(TransInfo *t) retopo_do_all(); } } - else if(t->obedit->type==OB_ARMATURE){ /* no recalc flag, does pose */ + else if(t->obedit->type==OB_LATTICE) { + DAG_object_flush_update(G.scene, t->obedit, OB_RECALC_DATA); /* sets recalc flags */ + + if(editLatt->flag & LT_OUTSIDE) outside_lattice(editLatt); + } + else { + DAG_object_flush_update(G.scene, t->obedit, OB_RECALC_DATA); /* sets recalc flags */ + } + } + else if( (t->flag & T_POSE) && t->poseobj) { + Object *ob= t->poseobj; + bArmature *arm= ob->data; + + /* old optimize trick... this enforces to bypass the depgraph */ + if (!(arm->flag & ARM_DELAYDEFORM)) { + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); /* sets recalc flags */ + } + else + where_is_pose(ob); + } + else if(G.f & G_PARTICLEEDIT) { + flushTransParticles(t); + } +#endif + if (t->spacetype==SPACE_NODE) { + flushTransNodes(t); + } + else if (t->obedit) { + if (t->obedit->type == OB_MESH) { + if(t->spacetype==SPACE_IMAGE) { + flushTransUVs(t); + /* TRANSFORM_FIX_ME */ +// if (G.sima->flag & SI_LIVE_UNWRAP) +// unwrap_lscm_live_re_solve(); + } else { + EditMesh *em = ((Mesh*)t->obedit->data)->edit_mesh; + /* mirror modifier clipping? */ + if(t->state != TRANS_CANCEL) { + /* TRANSFORM_FIX_ME */ +// if ((G.qual & LR_CTRLKEY)==0) { +// /* Only retopo if not snapping, Note, this is the only case of G.qual being used, but we have no T_SHIFT_MOD - Campbell */ +// retopo_do_all(); +// } + clipMirrorModifier(t, t->obedit); + } + if((t->options & CTX_NO_MIRROR) == 0 && (t->scene->toolsettings->editbutflag & B_MESH_X_MIRROR)) + editmesh_apply_to_mirror(t); + + DAG_object_flush_update(t->scene, t->obedit, OB_RECALC_DATA); /* sets recalc flags */ + + recalc_editnormals(em); + } + } + else if(t->obedit->type==OB_ARMATURE) { /* no recalc flag, does pose */ bArmature *arm= t->obedit->data; + ListBase *edbo = arm->edbo; EditBone *ebo; TransData *td = t->data; int i; /* Ensure all bones are correctly adjusted */ - for (ebo=G.edbo.first; ebo; ebo=ebo->next){ + for (ebo = edbo->first; ebo; ebo = ebo->next){ if ((ebo->flag & BONE_CONNECTED) && ebo->parent){ /* If this bone has a parent tip that has been moved */ @@ -531,67 +562,14 @@ void recalcData(TransInfo *t) Mat3MulVecfl(t->mat, up_axis); } - ebo->roll = rollBoneToVector(ebo, up_axis); + ebo->roll = ED_rollBoneToVector(ebo, up_axis); } } } if(arm->flag & ARM_MIRROR_EDIT) - transform_armature_mirror_update(); - - } - else if(t->obedit->type==OB_LATTICE) { - DAG_object_flush_update(G.scene, t->obedit, OB_RECALC_DATA); /* sets recalc flags */ + transform_armature_mirror_update(t->obedit); - if(editLatt->flag & LT_OUTSIDE) outside_lattice(editLatt); - } - else { - DAG_object_flush_update(G.scene, t->obedit, OB_RECALC_DATA); /* sets recalc flags */ - } - } - else if( (t->flag & T_POSE) && t->poseobj) { - Object *ob= t->poseobj; - bArmature *arm= ob->data; - - /* old optimize trick... this enforces to bypass the depgraph */ - if (!(arm->flag & ARM_DELAYDEFORM)) { - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); /* sets recalc flags */ - } - else - where_is_pose(ob); - } - else if(G.f & G_PARTICLEEDIT) { - flushTransParticles(t); - } -#endif - if (t->spacetype==SPACE_NODE) { - flushTransNodes(t); - } - else if (t->obedit) { - if (t->obedit->type == OB_MESH) { - if(t->spacetype==SPACE_IMAGE) { - flushTransUVs(t); - /* TRANSFORM_FIX_ME */ -// if (G.sima->flag & SI_LIVE_UNWRAP) -// unwrap_lscm_live_re_solve(); - } else { - EditMesh *em = ((Mesh*)t->obedit->data)->edit_mesh; - /* mirror modifier clipping? */ - if(t->state != TRANS_CANCEL) { - /* TRANSFORM_FIX_ME */ -// if ((G.qual & LR_CTRLKEY)==0) { -// /* Only retopo if not snapping, Note, this is the only case of G.qual being used, but we have no T_SHIFT_MOD - Campbell */ -// retopo_do_all(); -// } - clipMirrorModifier(t, t->obedit); - } - if((t->options & CTX_NO_MIRROR) == 0 && (t->scene->toolsettings->editbutflag & B_MESH_X_MIRROR)) - editmesh_apply_to_mirror(t); - - DAG_object_flush_update(t->scene, t->obedit, OB_RECALC_DATA); /* sets recalc flags */ - - recalc_editnormals(em); - } } } else { @@ -1026,10 +1004,10 @@ void calculateCenter(TransInfo *t) case V3D_ACTIVE: { /* set median, and if if if... do object center */ +#if 0 // TRANSFORM_FIX_ME EditSelection ese; /* EDIT MODE ACTIVE EDITMODE ELEMENT */ -#if 0 // TRANSFORM_FIX_ME if (t->obedit && t->obedit->type == OB_MESH && EM_get_actSelection(&ese)) { EM_editselection_center(t->center, &ese); calculateCenter2D(t); diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index e15fd3780ea..a810f66af06 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -70,7 +70,7 @@ static int transform_modal(bContext *C, wmOperator *op, wmEvent *event) transformEvent(t, event); - transformApply(t); + transformApply(C, t); exit_code = transformEnd(C, t); @@ -104,7 +104,7 @@ static int transform_exec(bContext *C, wmOperator *op) t->options |= CTX_AUTOCONFIRM; - transformApply(t); + transformApply(C, t); transformEnd(C, t); |