Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Eagar <joeedh@gmail.com>2009-01-09 21:32:33 +0300
committerJoseph Eagar <joeedh@gmail.com>2009-01-09 21:32:33 +0300
commitdbe6735ae5a33f9763e1eb58478bb562e421f65b (patch)
tree5ba1d86f8083a2858da0fe9b7b44022eed8282a9 /source/blender/editors
parent4746ada4e3618834103f392a1dc9bfcba159f80d (diff)
parente60be63d23bce8c8fe9b749a17c1f3dc3fd56711 (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')
-rw-r--r--source/blender/editors/armature/SConscript2
-rw-r--r--source/blender/editors/armature/editarmature.c6
-rw-r--r--source/blender/editors/include/ED_armature.h3
-rw-r--r--source/blender/editors/include/ED_fileselect.h8
-rw-r--r--source/blender/editors/include/ED_mesh.h18
-rw-r--r--source/blender/editors/include/ED_space_api.h12
-rw-r--r--source/blender/editors/include/ED_view3d.h6
-rw-r--r--source/blender/editors/interface/keyval.c540
-rw-r--r--source/blender/editors/mesh/SConscript1
-rw-r--r--source/blender/editors/mesh/editdeform.c1063
-rw-r--r--source/blender/editors/mesh/mesh_intern.h8
-rw-r--r--source/blender/editors/object/object_edit.c147
-rw-r--r--source/blender/editors/object/object_intern.h2
-rw-r--r--source/blender/editors/object/object_ops.c2
-rw-r--r--source/blender/editors/screen/area.c48
-rw-r--r--source/blender/editors/screen/screen_edit.c3
-rw-r--r--source/blender/editors/screen/screendump.c131
-rw-r--r--source/blender/editors/sculpt/sculpt.c346
-rw-r--r--source/blender/editors/sculpt/sculpt_intern.h28
-rw-r--r--source/blender/editors/sculpt/stroke.c58
-rw-r--r--source/blender/editors/space_api/spacetypes.c55
-rw-r--r--source/blender/editors/space_file/file_draw.c10
-rw-r--r--source/blender/editors/space_file/file_header.c2
-rw-r--r--source/blender/editors/space_file/file_ops.c4
-rw-r--r--source/blender/editors/space_file/filesel.c23
-rw-r--r--source/blender/editors/space_file/space_file.c30
-rw-r--r--source/blender/editors/space_ipo/ipo_draw.c713
-rw-r--r--source/blender/editors/space_node/node_select.c6
-rw-r--r--source/blender/editors/space_outliner/outliner.c2
-rw-r--r--source/blender/editors/space_view3d/drawobject.c4
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c9
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c18
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c49
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c37
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h31
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c7
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c22
-rw-r--r--source/blender/editors/space_view3d/vpaint.c1684
-rw-r--r--source/blender/editors/transform/transform.c64
-rw-r--r--source/blender/editors/transform/transform.h2
-rw-r--r--source/blender/editors/transform/transform_conversions.c58
-rw-r--r--source/blender/editors/transform/transform_generics.c142
-rw-r--r--source/blender/editors/transform/transform_ops.c4
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);