2.5
authorTon Roosendaal <ton@blender.org>
Sat, 10 Jan 2009 14:19:14 +0000 (14:19 +0000)
committerTon Roosendaal <ton@blender.org>
Sat, 10 Jan 2009 14:19:14 +0000 (14:19 +0000)
- Weightpaint back (CTRL+TAB or menu)
  Also weightpaint is sortof non-modal, allowing to use all existing
  hotkeys while in paint mode. Only leftmouse is overridden.
- Made vpaint and wpaint entirely local, stored in scene (and saved!)
- Small bugfix (also in 2.48): on weightpaint mode, all armature objects
  in 3d window were drawing as active poses. Now only the armature
  deformer is.

Nice point for the UI agenda: are paint modes on ACTION mouse? Only then
you can combine it with SELECT mouse...

22 files changed:
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/scene.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/editors/animation/anim_deps.c
source/blender/editors/armature/editarmature.c
source/blender/editors/armature/meshlaplacian.c
source/blender/editors/armature/poseobject.c
source/blender/editors/include/ED_anim_api.h
source/blender/editors/include/ED_armature.h
source/blender/editors/include/ED_mesh.h
source/blender/editors/include/ED_view3d.h
source/blender/editors/mesh/meshtools.c
source/blender/editors/object/object_edit.c
source/blender/editors/space_view3d/drawarmature.c
source/blender/editors/space_view3d/view3d_header.c
source/blender/editors/space_view3d/view3d_intern.h
source/blender/editors/space_view3d/view3d_ops.c
source/blender/editors/space_view3d/view3d_select.c
source/blender/editors/space_view3d/vpaint.c
source/blender/editors/util/ed_util.c
source/blender/makesdna/DNA_scene_types.h

index d160c75a03b420fd98a742d3de29be1a0ca2a8e5..063a0e4a31fd730b182be422309496159d7acec0 100644 (file)
@@ -2054,15 +2054,16 @@ static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask)
 {
        Mesh *me = ob->data;
        float min[3], max[3];
-       int needMapping= 0; //
+       //int needMapping= 0; 
+       
+       Object *obact = scene->basact?scene->basact->object:NULL;
+       int editing = (FACESEL_PAINT_TEST)|(G.f & G_PARTICLEEDIT);
+       int needMapping = editing && (ob==obact);
        
        clear_mesh_caches(ob);
 
-// XXX         Object *obact = scene->basact?scene->basact->object:NULL;
-//             int editing = (FACESEL_PAINT_TEST)|(G.f & G_PARTICLEEDIT);
-//             int needMapping = editing && (ob==obact);
-//             if( (G.f & G_WEIGHTPAINT) && ob==obact ) {
-       if(dataMask & CD_MASK_WEIGHTPAINT) {
+       if( (G.f & G_WEIGHTPAINT) && ob==obact ) {
+//     if(dataMask & CD_MASK_WEIGHTPAINT) {
                MCol *wpcol = (MCol*)calc_weightpaint_colors(ob);
                int layernum = CustomData_number_of_layers(&me->fdata, CD_MCOL);
                int prevactive = CustomData_get_active_layer(&me->fdata, CD_MCOL);
index 91783a3c85f404def8f1f1217c9d59e984dd3070..3fc1d2a610310c7c4df584147fd0f4f4c30f0217 100644 (file)
@@ -167,7 +167,12 @@ void free_scene(Scene *sce)
        BLI_freelistN(&sce->transform_spaces);
        BLI_freelistN(&sce->r.layers);
        
-       if(sce->toolsettings){
+       if(sce->toolsettings) {
+               if(sce->toolsettings->vpaint)
+                       MEM_freeN(sce->toolsettings->vpaint);
+               if(sce->toolsettings->wpaint)
+                       MEM_freeN(sce->toolsettings->wpaint);
+               
                MEM_freeN(sce->toolsettings);
                sce->toolsettings = NULL;       
        }
index ac0b819aa6b82b747998fd7a56d29d27b29c215f..8c979a68d9a11376cd7987ef085de5cb329bf096 100644 (file)
@@ -3604,7 +3604,10 @@ static void direct_link_scene(FileData *fd, Scene *sce)
        sce->radio= newdataadr(fd, sce->radio);
        
        sce->toolsettings= newdataadr(fd, sce->toolsettings);
-
+       if(sce->toolsettings) {
+               sce->toolsettings->vpaint= newdataadr(fd, sce->toolsettings->vpaint);
+               sce->toolsettings->wpaint= newdataadr(fd, sce->toolsettings->wpaint);
+       }
        sce->sculptdata.session= NULL;
        /* SculptData textures */
        for(a=0; a<MAX_MTEX; ++a)
index 57dde906fa3fa73463078407aec48e47baa8048e..436980ef421da381b3100d351eef2de3caf33228 100644 (file)
@@ -1472,6 +1472,10 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
 
                writestruct(wd, DATA, "Radio", 1, sce->radio);
                writestruct(wd, DATA, "ToolSettings", 1, sce->toolsettings);
+               if(sce->toolsettings->vpaint)
+                       writestruct(wd, DATA, "VPaint", 1, sce->toolsettings->vpaint);
+               if(sce->toolsettings->wpaint)
+                       writestruct(wd, DATA, "VPaint", 1, sce->toolsettings->wpaint);
 
                for(a=0; a<MAX_MTEX; ++a)
                        writestruct(wd, DATA, "MTex", 1, sce->sculptdata.mtex[a]);
index eaf4ef7ae123ec6347a4553e93495df645179b27..07816228daddcb40d2be70d2e6fded094100a5e5 100644 (file)
@@ -89,6 +89,15 @@ void ED_anim_dag_flush_update(const bContext *C)
        DAG_scene_flush_update(scene, screen_view3d_layers(screen), 0);
 }
 
+/* flushes changes from object to all relations in scene */
+void ED_anim_object_flush_update(const bContext *C, Object *ob)
+{
+       Scene *scene= CTX_data_scene(C);
+       bScreen *screen= CTX_wm_screen(C);
+       
+       DAG_object_update_flags(scene, ob, screen_view3d_layers(screen));
+}
+
 
 /* results in fully updated anim system */
 /* in future sound should be on WM level, only 1 sound can play! */
index 06855d4446d77f72ca652f369223c54dd97bc2a0..99f89d84328e9bf91eb0ad3de8a5dcd89d388880 100644 (file)
@@ -99,10 +99,7 @@ static void error_libdata() {}
 static void BIF_undo_push() {}
 static void adduplicate() {}
 static void countall() {}
-static void vertexgroup_select_by_name() {}
 static void deselect_actionchannels() {}
-static void add_vert_to_defgroup() {}
-static void create_dverts() {}
 static void select_actionchannel_by_name() {}
 /* ************* XXX *************** */
 
@@ -3563,7 +3560,7 @@ static int bone_looper(Object *ob, Bone *bone, void *data,
 }
 
 /* called from editview.c, for mode-less pose selection */
-/* assumes scene obact and basact... XXX */
+/* assumes scene obact and basact is still on old situation */
 int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits, short extend)
 {
        Object *ob= base->object;
@@ -3605,8 +3602,8 @@ int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, shor
                /* in weightpaint we select the associated vertex group too */
                if (G.f & G_WEIGHTPAINT) {
                        if (nearBone->flag & BONE_ACTIVE) {
-                               vertexgroup_select_by_name(ob, nearBone->name);
-                               DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+                               vertexgroup_select_by_name(OBACT, nearBone->name);
+                               DAG_object_flush_update(scene, OBACT, OB_RECALC_DATA);
                        }
                }
                
index 807339b08e037688b808a5f0bb8466c7b1726d73..8807b21e65323e7f855099a8aac9256fc8331142 100644 (file)
 
 #include "BLO_sys_types.h" // for intptr_t support
 
+#include "ED_armature.h"
+#include "ED_mesh.h"
+
 #include "meshlaplacian.h"
 
 
 /* ************* XXX *************** */
-static void remove_vert_defgroup() {}
-static int mesh_get_x_mirror_vert() {return 0;}
 static void waitcursor() {}
 static void progress_bar() {}
 static void start_progress_bar() {}
 static void end_progress_bar() {}
-static float get_vert_defgroup() {return 0.0;}
-static void add_vert_to_defgroup() {}
-#define WEIGHT_REPLACE 0
-#define WEIGHT_ADD 0
 static void error() {}
 /* ************* XXX *************** */
 
index 94e5492a337bc77f7e44161b715ae3cd5d15e04b..08a670b958284674e3d178ad0cbe159e283f05f0 100644 (file)
@@ -52,6 +52,7 @@
 #include "BKE_action.h"
 #include "BKE_armature.h"
 #include "BKE_blender.h"
+#include "BKE_context.h"
 #include "BKE_constraint.h"
 #include "BKE_deform.h"
 #include "BKE_depsgraph.h"
 #include "BIF_gl.h"
 
 #include "ED_armature.h"
+#include "ED_anim_api.h"
 #include "ED_keyframing.h"
 #include "ED_object.h"
+#include "ED_mesh.h"
 #include "ED_view3d.h"
 
 #include "armature_intern.h"
@@ -81,8 +84,6 @@ static void error() {};
 static void BIF_undo_push() {}
 static void countall() {}
 static void add_constraint() {}
-static void vertexgroup_select_by_name() {}
-static int screen_view3d_layers() {return 0;}
 static void select_actionchannel_by_name() {}
 static int autokeyframe_cfra_can_key() {return 0;}
 static void autokeyframe_pose_cb_func() {}
@@ -194,7 +195,7 @@ int ED_pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan)
 /* For the object with pose/action: create path curves for selected bones 
  * This recalculates the WHOLE path within the pchan->pathsf and pchan->pathef range
  */
-void pose_calculate_path(Scene *scene, Object *ob)
+void pose_calculate_path(bContext *C, Scene *scene, Object *ob)
 {
        bArmature *arm;
        bPoseChannel *pchan;
@@ -230,10 +231,10 @@ void pose_calculate_path(Scene *scene, Object *ob)
        /* hack: for unsaved files, set OB_RECALC so that paths can get calculated */
        if ((ob->recalc & OB_RECALC)==0) {
                ob->recalc |= OB_RECALC;
-               DAG_object_update_flags(scene, ob, screen_view3d_layers());
+               ED_anim_object_flush_update(C, ob);
        }
        else
-               DAG_object_update_flags(scene, ob, screen_view3d_layers());
+               ED_anim_object_flush_update(C, ob);
        
        
        /* malloc the path blocks */
@@ -288,7 +289,7 @@ void pose_calculate_path(Scene *scene, Object *ob)
 /* For the object with pose/action: update paths for those that have got them
  * This should selectively update paths that exist...
  */
-void pose_recalculate_paths(Scene *scene, Object *ob)
+void pose_recalculate_paths(bContext *C, Scene *scene, Object *ob)
 {
        bArmature *arm;
        bPoseChannel *pchan;
@@ -324,10 +325,10 @@ void pose_recalculate_paths(Scene *scene, Object *ob)
        /* hack: for unsaved files, set OB_RECALC so that paths can get calculated */
        if ((ob->recalc & OB_RECALC)==0) {
                ob->recalc |= OB_RECALC;
-               DAG_object_update_flags(scene, ob, screen_view3d_layers());
+               ED_anim_object_flush_update(C, ob);
        }
        else
-               DAG_object_update_flags(scene, ob, screen_view3d_layers());
+               ED_anim_object_flush_update(C, ob);
        
        for (CFRA=sfra; CFRA<=efra; CFRA++) {
                /* do all updates */
@@ -1628,7 +1629,7 @@ void pose_special_editmenu(Scene *scene)
                pose_flip_names();
        }
        else if(nr==3) {
-               pose_calculate_path(ob);
+               pose_calculate_path(C, ob);
        }
        else if(nr==4) {
                pose_clear_paths(ob);
index 863446fe59f1afd331bbdc0b443773a017e20b53..8b3d5df61bad2c3e6ef31db9d829836e9528dd29 100644 (file)
@@ -30,6 +30,7 @@
 #define ED_ANIM_API_H
 
 struct ID;
+struct Scene;
 struct ListBase;
 struct bContext;
 struct wmWindowManager;
@@ -321,8 +322,11 @@ void ANIM_nla_mapping_apply_ipo(struct Object *ob, struct Ipo *ipo, short restor
 
 /* --------- anim_deps.c, animation updates -------- */
 
-/* generic update flush, reads from Context screen (layers) and scene */
+       /* generic update flush, reads from Context screen (layers) and scene */
 void ED_anim_dag_flush_update(const struct bContext *C);
+       /* only flush object */
+void ED_anim_object_flush_update(const struct bContext *C, struct Object *ob);
+       /* flush + do the actual update for all involved objects */
 void ED_update_for_newframe(const struct bContext *C, int mute);
 
 /* pose <-> action syncing */
index 17d6b25b93b3c35f166ca32211f3951b59b1c438..09b7f864f3ed555d5eed9b86f0ad1359f7fe886a 100644 (file)
@@ -91,7 +91,7 @@ void ED_armature_edit_remake(struct Object *obedit);
 int ED_do_pose_selectbuffer(struct Scene *scene, struct Base *base, unsigned int *buffer, 
                                                        short hits, short extend);
 void mouse_armature(struct bContext *C, short mval[2], int extend);
-
+struct Bone *get_indexed_bone (struct Object *ob, int index);
 float ED_rollBoneToVector(EditBone *bone, float new_up_axis[3]);
 
 void transform_armature_mirror_update(struct Object *obedit);
index 02419b9aca913b4371142bca1889b095ef3a8ad6..db97665a5713aea0133af66635acaafdaf46644f 100644 (file)
@@ -28,6 +28,7 @@
 #ifndef ED_MESH_H
 #define ED_MESH_H
 
+struct ID;
 struct View3D;
 struct ARegion;
 struct EditMesh;
@@ -130,12 +131,17 @@ int                       EM_init_backbuf_circle(struct ViewContext *vc, short xs, short ys, short r
 #define WEIGHT_SUBTRACT 3
 
 void           add_defgroup (Object *ob);
-void           remove_vert_defgroup (Object *ob, struct bDeformGroup   *dg, int vertnum);
+void           create_dverts(struct ID *id);
+float          get_vert_defgroup (Object *ob, struct bDeformGroup *dg, int vertnum);
+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);
+void           vertexgroup_select_by_name(Object *ob, char *name);
+void           add_vert_to_defgroup (Object *ob, struct bDeformGroup *dg, int vertnum, 
+                           float weight, int assignmode);
+
+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);
 
 
 #endif /* ED_MESH_H */
index 60a5ff8481e7bab7e1d735bdae7a82712db23677..4f4afd2abb4f1526f1ab88d1c3caea5994982aaa 100644 (file)
@@ -53,29 +53,6 @@ typedef struct ViewContext {
        short mval[2];
 } ViewContext;
 
-typedef struct VPaint {
-       float r, g, b, a;
-       float size;                     /* of brush */
-       float gamma, mul;
-       short mode, flag;
-       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 */
-#define VP_COLINDEX    1
-#define VP_AREA                2
-#define VP_SOFT                4
-#define VP_NORMALS     8
-#define VP_SPRAY       16
-#define VP_MIRROR_X    32
-#define VP_HARD                64
-#define VP_ONLYVGROUP  128
-
-
 
 float *give_cursor(struct Scene *scene, struct View3D *v3d);
 
index 1c95103bcc9c6cda9597b9d272cfb8c2f895b83f..4f5426b44efb0e02b89d67a0846579c9b6780ba4 100644 (file)
@@ -725,7 +725,7 @@ intptr_t mesh_octree_table(Object *ob, EditMesh *em, float *co, char mode)
                 * we are using the undeformed coordinates*/
                INIT_MINMAX(min, max);
 
-               if(me->edit_mesh==em) {
+               if(em && me->edit_mesh==em) {
                        EditVert *eve;
                        
                        for(eve= em->verts.first; eve; eve= eve->next)
@@ -766,7 +766,7 @@ intptr_t mesh_octree_table(Object *ob, EditMesh *em, float *co, char mode)
                
                MeshOctree.table= MEM_callocN(MOC_RES*MOC_RES*MOC_RES*sizeof(void *), "sym table");
                
-               if(me->edit_mesh==em) {
+               if(em && me->edit_mesh==em) {
                        EditVert *eve;
 
                        for(eve= em->verts.first; eve; eve= eve->next) {
index e3fa8b22463976df9f666c6eebbecda75d066cc3..c6cbbf90b79a5abc904f9049c379df65c853a764 100644 (file)
@@ -1629,7 +1629,6 @@ void OBJECT_OT_set_restrictview(wmOperatorType *ot)
 /* ************* Slow Parent ******************* */
 static int object_set_slowparent_exec(bContext *C, wmOperator *op)
 {
-       Scene *scene= CTX_data_scene(C);
 
        CTX_DATA_BEGIN(C, Base*, base, visible_bases) {
                                
index 6f341c6a6feba0ed7e854014e7d1e211de4a28a0..9fa045830abbdc47ebbc8a07822dc44f950779af 100644 (file)
@@ -62,6 +62,7 @@
 #include "BKE_DerivedMesh.h"
 #include "BKE_global.h"
 #include "BKE_main.h"
+#include "BKE_modifier.h"
 #include "BKE_object.h"
 #include "BKE_ipo.h"
 #include "BKE_utildefines.h"
@@ -2542,9 +2543,10 @@ int draw_armature(Scene *scene, View3D *v3d, Base *base, int dt, int flag)
                                        if ((flag & DRAW_SCENESET)==0) {
                                                if(ob==OBACT) 
                                                        arm->flag |= ARM_POSEMODE;
-                                               else if(G.f & G_WEIGHTPAINT)
-                                                       arm->flag |= ARM_POSEMODE;
-                                       
+                                               else if(G.f & G_WEIGHTPAINT) {
+                                                       if(OBACT && ob==modifiers_isDeformedByArmature(OBACT))
+                                                               arm->flag |= ARM_POSEMODE;
+                                               }
                                                draw_pose_paths(scene, v3d, ob);
                                        }
                                }       
index d8025698f026f772b825c8356bb36e5b9816b42d..fa90730fb05c8895a9ecba384940358139512577 100644 (file)
@@ -142,9 +142,10 @@ 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);
+       else if(G.f & G_VERTEXPAINT)
+               WM_operator_name_call(C, "VIEW3D_OT_wpaint_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();
        
@@ -5434,7 +5435,7 @@ static void do_view3d_buttons(bContext *C, void *arg, int event)
                                if(obedit) 
                                        ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR);      /* exit editmode and undo */
                                
-// XXX                         set_wpaint();
+                               WM_operator_name_call(C, "VIEW3D_OT_wpaint_toggle", WM_OP_EXEC_REGION_WIN, NULL, NULL);
                        }
                } 
                else if (v3d->modeselect == V3D_POSEMODE_SEL) {
index 8fc00ffd538a7c2906cb7678e555475857db7518..baf5a849bd436bb4ad21b09a885fb10687768bbc 100644 (file)
@@ -122,6 +122,8 @@ 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);
+void VIEW3D_OT_wpaint_toggle(struct wmOperatorType *ot);
+void VIEW3D_OT_wpaint(struct wmOperatorType *ot);
 
 /* view3d_view.c */
 void VIEW3D_OT_smoothview(struct wmOperatorType *ot);
index da4b752f37030ce66ec2756c686f1176579afb0e..3bc3cd76341cf3c3f891bd42c63238caeab3f8b0 100644 (file)
@@ -80,7 +80,9 @@ void view3d_operatortypes(void)
        WM_operatortype_append(VIEW3D_OT_setcameratoview);
        WM_operatortype_append(VIEW3D_OT_drawtype);
        WM_operatortype_append(VIEW3D_OT_vpaint_toggle);
+       WM_operatortype_append(VIEW3D_OT_wpaint_toggle);
        WM_operatortype_append(VIEW3D_OT_vpaint);
+       WM_operatortype_append(VIEW3D_OT_wpaint);
        
        transform_operatortypes();
 }
@@ -92,6 +94,7 @@ void view3d_keymap(wmWindowManager *wm)
        
        /* paint poll checks mode */
        WM_keymap_verify_item(keymap, "VIEW3D_OT_vpaint", LEFTMOUSE, KM_PRESS, 0, 0);
+       WM_keymap_verify_item(keymap, "VIEW3D_OT_wpaint", LEFTMOUSE, KM_PRESS, 0, 0);
        
        WM_keymap_verify_item(keymap, "VIEW3D_OT_cursor3d", ACTIONMOUSE, KM_PRESS, 0, 0);
        
@@ -155,6 +158,7 @@ void view3d_keymap(wmWindowManager *wm)
        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);
+       WM_keymap_add_item(keymap, "VIEW3D_OT_wpaint_toggle", TABKEY, KM_PRESS, KM_CTRL, 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");
index 6664ac1187730eb14520fc54c1ff44bd73d2085d..2a6d7f3269af904a30ef0c268604b9ec0b42f93f 100644 (file)
@@ -1067,14 +1067,14 @@ static void mouse_select(bContext *C, short *mval, short extend, short obcenter)
                                        basact->flag|= SELECT;
                                        basact->object->flag= basact->flag;
                                        
+                                       WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, basact->object);
+                                       WM_event_add_notifier(C, NC_OBJECT|ND_BONE_ACTIVE, basact->object);
+                                       
                                        /* in weightpaint, we use selected bone to select vertexgroup, so no switch to new active object */
                                        if(G.f & G_WEIGHTPAINT) {
                                                /* prevent activating */
                                                basact= NULL;
                                        }
-                                       
-                                       WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, basact->object);
-                                       WM_event_add_notifier(C, NC_OBJECT|ND_BONE_ACTIVE, basact->object);
 
                                }
                                /* prevent bone selecting to pass on to object selecting */
@@ -1449,7 +1449,7 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op)
                                        while (base->selcol == (*col & 0xFFFF)) {       /* we got an object */
                                                
                                                if(*col & 0xFFFF0000) {                                 /* we got a bone */
-                                                       bone = NULL; // XXX get_indexed_bone(base->object, *col & ~(BONESEL_ANY));
+                                                       bone = get_indexed_bone(base->object, *col & ~(BONESEL_ANY));
                                                        if(bone) {
                                                                if(selecting) {
                                                                        bone->flag |= BONE_SELECTED;
index f253612259f9f5b6ae4d922dc317ba5d493be3fc..73d0096739cdfe9d94f63cb72e85d23e91de958b 100644 (file)
@@ -90,7 +90,7 @@
 
 #include "view3d_intern.h"
 
-       /* Gvp.mode */
+       /* vp->mode */
 #define VP_MIX 0
 #define VP_ADD 1
 #define VP_SUB 2
 /* 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 VPaint *new_vpaint(int wpaint)
+{
+       VPaint *vp= MEM_callocN(sizeof(VPaint), "VPaint");
+       
+       vp->r= 1.0f;
+       vp->g= 1.0f;
+       vp->b= 1.0f;
+       vp->a= 0.2f;
+       vp->size= 25.0f;
+       vp->gamma= vp->mul= 1.0f;
+       
+       vp->flag= VP_AREA+VP_SOFT+VP_SPRAY;
+       
+       if(wpaint) {
+               vp->a= 1.0f;
+               vp->flag= VP_AREA+VP_SOFT;
+       }
+       return vp;
+}
 
 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 */
@@ -269,18 +277,18 @@ static void copy_vpaint_prev(VPaint *vp, unsigned int *mcol, int tot)
        
 }
 
-static void copy_wpaint_prev (VPaint *vp, MDeformVert *dverts, int dcount)
+static void copy_wpaint_prev (VPaint *wp, MDeformVert *dverts, int dcount)
 {
-       if (vp->wpaint_prev) {
-               free_dverts(vp->wpaint_prev, vp->tot);
-               vp->wpaint_prev= NULL;
+       if (wp->wpaint_prev) {
+               free_dverts(wp->wpaint_prev, wp->tot);
+               wp->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);
+               wp->wpaint_prev = MEM_mallocN (sizeof(MDeformVert)*dcount, "wpaint prev");
+               wp->tot = dcount;
+               copy_dverts (wp->wpaint_prev, dverts, dcount);
        }
 }
 
@@ -300,7 +308,7 @@ void clear_vpaint(Scene *scene)
 
        if(me==0 || me->mcol==0 || me->totface==0) return;
 
-       paintcol= vpaint_get_current_col(&Gvp);
+       paintcol= vpaint_get_current_col(scene->toolsettings->vpaint);
 
        to= (unsigned int *)me->mcol;
        a= 4*me->totface;
@@ -328,7 +336,7 @@ void clear_vpaint_selectedfaces(Scene *scene)
        if(!me->mcol)
                make_vertexcol(scene, 0);
 
-       paintcol= vpaint_get_current_col(&Gvp);
+       paintcol= vpaint_get_current_col(scene->toolsettings->vpaint);
 
        mf = me->mface;
        mcol = (unsigned int*)me->mcol;
@@ -349,6 +357,7 @@ void clear_vpaint_selectedfaces(Scene *scene)
 /* fills in the selected faces with the current weight and vertex group */
 void clear_wpaint_selectedfaces(Scene *scene)
 {
+       VPaint *wp= scene->toolsettings->wpaint;
        float editbutvweight;
        float paintweight= editbutvweight;
        Mesh *me;
@@ -377,7 +386,7 @@ void clear_wpaint_selectedfaces(Scene *scene)
        
        /* 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) {
+       if(wp->flag & VP_MIRROR_X) {
                bDeformGroup *defgroup= BLI_findlink(&ob->defbase, ob->actdef-1);
                if(defgroup) {
                        bDeformGroup *curdef;
@@ -402,7 +411,7 @@ void clear_wpaint_selectedfaces(Scene *scene)
        }
        /* end copy from weight_paint*/
        
-       copy_wpaint_prev(&Gwp, me->dvert, me->totvert);
+       copy_wpaint_prev(wp, me->dvert, me->totvert);
        
        for(index=0; index<me->totface; index++) {
                if(indexar[index] && indexar[index]<=me->totface) {
@@ -416,20 +425,20 @@ void clear_wpaint_selectedfaces(Scene *scene)
                                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= verify_defweight(wp->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 */
+                                               if(wp->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);
+                                                                       uw= verify_defweight(wp->wpaint_prev+j, vgroup_mirror);
                                                                } else {
                                                                        dw= verify_defweight(me->dvert+j, vgroup);
-                                                                       uw= verify_defweight(Gwp.wpaint_prev+j, vgroup);
+                                                                       uw= verify_defweight(wp->wpaint_prev+j, vgroup);
                                                                }
                                                                uw->weight= dw->weight; /* set the undo weight */
                                                                dw->weight= paintweight;
@@ -449,7 +458,7 @@ void clear_wpaint_selectedfaces(Scene *scene)
        }
        
        MEM_freeN(indexar);
-       copy_wpaint_prev(&Gwp, NULL, 0);
+       copy_wpaint_prev(wp, NULL, 0);
 
        DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
        BIF_undo_push("Set vertex weight");
@@ -458,6 +467,7 @@ void clear_wpaint_selectedfaces(Scene *scene)
 
 void vpaint_dogamma(Scene *scene)
 {
+       VPaint *vp= scene->toolsettings->vpaint;
        Mesh *me;
        Object *ob;
        float igam, fac;
@@ -470,11 +480,11 @@ void vpaint_dogamma(Scene *scene)
        me= get_mesh(ob);
        if(me==0 || me->mcol==0 || me->totface==0) return;
 
-       igam= 1.0/Gvp.gamma;
+       igam= 1.0/vp->gamma;
        for(a=0; a<256; a++) {
                
                fac= ((float)a)/255.0;
-               fac= Gvp.mul*pow( fac, igam);
+               fac= vp->mul*pow( fac, igam);
                
                temp= 255.9*fac;
                
@@ -498,6 +508,7 @@ void vpaint_dogamma(Scene *scene)
 /* used for both 3d view and image window */
 void sample_vpaint(Scene *scene, ARegion *ar)  /* frontbuf */
 {
+       VPaint *vp= scene->toolsettings->vpaint;
        unsigned int col;
        int x, y;
        short mval[2];
@@ -519,9 +530,9 @@ void sample_vpaint(Scene *scene, ARegion *ar)       /* frontbuf */
        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;
+               vp->r= cp[0]/255.0f;
+               vp->g= cp[1]/255.0f;
+               vp->b= cp[2]/255.0f;
        }
        else {
                Brush *brush= scene->toolsettings->imapaint.brush;
@@ -684,29 +695,29 @@ static unsigned int mcol_darken(unsigned int col1, unsigned int col2, int fac)
        return col;
 }
 
-static void vpaint_blend( unsigned int *col, unsigned int *colorig, unsigned int paintcol, int alpha)
+static void vpaint_blend(VPaint *vp, 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(vp->mode==VP_MIX || vp->mode==VP_BLUR) *col= mcol_blend( *col, paintcol, alpha);
+       else if(vp->mode==VP_ADD) *col= mcol_add( *col, paintcol, alpha);
+       else if(vp->mode==VP_SUB) *col= mcol_sub( *col, paintcol, alpha);
+       else if(vp->mode==VP_MUL) *col= mcol_mul( *col, paintcol, alpha);
+       else if(vp->mode==VP_LIGHTEN) *col= mcol_lighten( *col, paintcol, alpha);
+       else if(vp->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) {
+       if((vp->flag & VP_SPRAY)==0) {
                unsigned int testcol=0, a;
                char *cp, *ct, *co;
                
-               alpha= (int)(255.0*Gvp.a);
+               alpha= (int)(255.0*vp->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);
+               if(vp->mode==VP_MIX || vp->mode==VP_BLUR) testcol= mcol_blend( *colorig, paintcol, alpha);
+               else if(vp->mode==VP_ADD) testcol= mcol_add( *colorig, paintcol, alpha);
+               else if(vp->mode==VP_SUB) testcol= mcol_sub( *colorig, paintcol, alpha);
+               else if(vp->mode==VP_MUL) testcol= mcol_mul( *colorig, paintcol, alpha);
+               else if(vp->mode==VP_LIGHTEN)  testcol= mcol_lighten( *colorig, paintcol, alpha);
+               else if(vp->mode==VP_DARKEN)   testcol= mcol_darken( *colorig, paintcol, alpha);
                
                cp= (char *)col;
                ct= (char *)&testcol;
@@ -802,49 +813,49 @@ static int calc_vp_alpha_dl(VPaint *vp, ViewContext *vc, float vpimat[][3], floa
        return alpha;
 }
 
-static void wpaint_blend(MDeformWeight *dw, MDeformWeight *uw, float alpha, float paintval)
+static void wpaint_blend(VPaint *wp, MDeformWeight *dw, MDeformWeight *uw, float alpha, float paintval)
 {
        
        if(dw==NULL || uw==NULL) return;
        
-       if(Gwp.mode==VP_MIX || Gwp.mode==VP_BLUR)
+       if(wp->mode==VP_MIX || wp->mode==VP_BLUR)
                dw->weight = paintval*alpha + dw->weight*(1.0-alpha);
-       else if(Gwp.mode==VP_ADD)
+       else if(wp->mode==VP_ADD)
                dw->weight += paintval*alpha;
-       else if(Gwp.mode==VP_SUB) 
+       else if(wp->mode==VP_SUB) 
                dw->weight -= paintval*alpha;
-       else if(Gwp.mode==VP_MUL) 
+       else if(wp->mode==VP_MUL) 
                /* first mul, then blend the fac */
                dw->weight = ((1.0-alpha) + alpha*paintval)*dw->weight;
-       else if(Gwp.mode==VP_LIGHTEN) {
+       else if(wp->mode==VP_LIGHTEN) {
                if (dw->weight < paintval)
                        dw->weight = paintval*alpha + dw->weight*(1.0-alpha);
-       } else if(Gwp.mode==VP_DARKEN) {
+       } else if(wp->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) {
+       if((wp->flag & VP_SPRAY)==0) {
                float testw=0.0f;
                
-               alpha= Gwp.a;
-               if(Gwp.mode==VP_MIX || Gwp.mode==VP_BLUR)
+               alpha= wp->a;
+               if(wp->mode==VP_MIX || wp->mode==VP_BLUR)
                        testw = paintval*alpha + uw->weight*(1.0-alpha);
-               else if(Gwp.mode==VP_ADD)
+               else if(wp->mode==VP_ADD)
                        testw = uw->weight + paintval*alpha;
-               else if(Gwp.mode==VP_SUB) 
+               else if(wp->mode==VP_SUB) 
                        testw = uw->weight - paintval*alpha;
-               else if(Gwp.mode==VP_MUL) 
+               else if(wp->mode==VP_MUL) 
                        /* first mul, then blend the fac */
                        testw = ((1.0-alpha) + alpha*paintval)*uw->weight;              
-               else if(Gwp.mode==VP_LIGHTEN) {
+               else if(wp->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) {
+               } else if(wp->mode==VP_DARKEN) {
                        if (uw->weight > paintval)
                                testw = paintval*alpha + uw->weight*(1.0-alpha);
                        else
@@ -872,7 +883,7 @@ static void wpaint_blend(MDeformWeight *dw, MDeformWeight *uw, float alpha, floa
 /* 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)
+void sample_wpaint(Scene *scene, ARegion *ar, View3D *v3d, int mode)
 {
        ViewContext vc;
        Object *ob= OBACT;
@@ -1009,26 +1020,26 @@ static void sample_wpaint(Scene *scene, ARegion *ar, View3D *v3d, int mode)
        
 }
 
-static void do_weight_paint_vertex(Object *ob, int index, int alpha, float paintweight, int vgroup_mirror)
+static void do_weight_paint_vertex(VPaint *wp, Object *ob, int index, int alpha, float paintweight, int vgroup_mirror)
 {
        Mesh *me= ob->data;
-       MDeformWeight   *dw, *uw;
+       MDeformWeight *dw, *uw;
        int vgroup= ob->actdef-1;
        
-       if(Gwp.flag & VP_ONLYVGROUP) {
+       if(wp->flag & VP_ONLYVGROUP) {
                dw= get_defweight(me->dvert+index, vgroup);
-               uw= get_defweight(Gwp.wpaint_prev+index, vgroup);
+               uw= get_defweight(wp->wpaint_prev+index, vgroup);
        }
        else {
                dw= verify_defweight(me->dvert+index, vgroup);
-               uw= verify_defweight(Gwp.wpaint_prev+index, vgroup);
+               uw= verify_defweight(wp->wpaint_prev+index, vgroup);
        }
        if(dw==NULL || uw==NULL)
                return;
        
-       wpaint_blend(dw, uw, (float)alpha/255.0, paintweight);
+       wpaint_blend(wp, dw, uw, (float)alpha/255.0, paintweight);
        
-       if(Gwp.flag & VP_MIRROR_X) {    /* x mirror painting */
+       if(wp->flag & VP_MIRROR_X) {    /* x mirror painting */
                int j= mesh_get_x_mirror_vert(ob, index);
                if(j>=0) {
                        /* copy, not paint again */
@@ -1043,150 +1054,222 @@ static void do_weight_paint_vertex(Object *ob, int index, int alpha, float paint
 }
 
 
-void weight_paint(Scene *scene, ARegion *ar, View3D *v3d)
+/* *************** set wpaint operator ****************** */
+/* retrieve whether cursor should be set or operator should be done */
+static int wp_poll(bContext *C)
 {
-       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) {
+               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 wp_drawcursor(bContext *C, int x, int y)
+{
+       ToolSettings *ts= CTX_data_tool_settings(C);
        
-       if((G.f & G_WEIGHTPAINT)==0) return;
-       if(scene->obedit) return;
-// XXX if(multires_level1_test()) return;
+       glTranslatef((float)x, (float)y, 0.0f);
        
-       ob= OBACT;
-       if(!ob || ob->id.lib) return;
+       glColor4ub(200, 200, 255, 128);
+       glEnable( GL_LINE_SMOOTH );
+       glEnable(GL_BLEND);
+       glutil_draw_lined_arc(0.0, M_PI*2.0, ts->wpaint->size, 40);
+       glDisable(GL_BLEND);
+       glDisable( GL_LINE_SMOOTH );
+       
+       glTranslatef((float)-x, (float)-y, 0.0f);
+}
 
+static int set_wpaint(bContext *C, wmOperator *op)             /* toggle */
+{              
+       Object *ob= CTX_data_active_object(C);
+       Scene *scene= CTX_data_scene(C);
+       VPaint *wp= scene->toolsettings->wpaint;
+       Mesh *me;
+       
        me= get_mesh(ob);
-       if(me==NULL || me->totface==0) return;
+       if(ob->id.lib || me==NULL) return OPERATOR_CANCELLED;
        
-       /* 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;
-//     }
+       if(me && me->totface>=MAXINDEX) {
+               error("Maximum number of faces: %d", MAXINDEX-1);
+               G.f &= ~G_WEIGHTPAINT;
+               return OPERATOR_CANCELLED;
+       }
        
-       /* 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))) {
+       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).
+               */
+       DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+       
+       if(G.f & G_WEIGHTPAINT) {
+               Object *par;
+               
+               if(wp==NULL)
+                       wp= scene->toolsettings->wpaint= new_vpaint(1);
+               
+               wp->paintcursor = WM_paint_cursor_activate(CTX_wm_manager(C), wp_poll, wp_drawcursor);
+               
+               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= modob->pose->chanbase.first; pchan; pchan= pchan->next)
-                               if(pchan->bone->flag & SELECT)
+                       for(pchan= par->pose->chanbase.first; pchan; pchan= pchan->next)
+                               if(pchan->bone->flag & BONE_ACTIVE)
                                        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(pchan)
+                                       vertexgroup_select_by_name(ob, pchan->name);
                }
        }
-       if(ob->defbase.first==NULL) {
-               add_defgroup(ob);
-       }       
-       
-       if(ob->lay & v3d->lay); else error("Active object is not in this layer");
+       else {
+               if(wp)
+                       WM_paint_cursor_end(CTX_wm_manager(C), wp->paintcursor);
+               
+               mesh_octree_table(ob, NULL, NULL, 'e');
+       }
        
-// XXX persp(PERSP_VIEW);
-       /* imat for normals */
-       Mat4MulMat4(mat, ob->obmat, v3d->viewmat);
-       Mat4Invert(imat, mat);
-       Mat3CpyMat4(vpimat, imat);
+       WM_event_add_notifier(C, NC_SCENE|ND_MODE, ob);
        
-       /* load projection matrix */
-       wmMultMatrix(ob->obmat);
-       wmGetSingleMatrix(mat);
-       wmLoadMatrix(v3d->viewmat);
+       return OPERATOR_FINISHED;
+}
+
+void VIEW3D_OT_wpaint_toggle(wmOperatorType *ot)
+{
        
-//     getmouseco_areawin(mvalo);
+       /* identifiers */
+       ot->name= "Weight Paint Mode";
+       ot->idname= "VIEW3D_OT_wpaint_toggle";
        
-//     getmouseco_areawin(mval);
-       mvalo[0]= mval[0];
-       mvalo[1]= mval[1];
+       /* api callbacks */
+       ot->exec= set_wpaint;
+       ot->poll= ED_operator_object_active;
        
-       /* 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))
+/* ************ weight paint operator ********** */
+
+struct WPaintData {
+       ViewContext vc;
+       int *indexar;
+       int vgroup_mirror;
+       float *vertexcosnos;
+       float wpimat[3][3];
+};
+
+static void wpaint_exit(bContext *C, wmOperator *op)
+{
+       ToolSettings *ts= CTX_data_tool_settings(C);
+       Object *ob= CTX_data_active_object(C);
+       struct WPaintData *wpd= op->customdata;
+       
+       if(wpd->vertexcosnos)
+               MEM_freeN(wpd->vertexcosnos);
+       MEM_freeN(wpd->indexar);
+       
+       /* frees prev buffer */
+       copy_wpaint_prev(ts->wpaint, NULL, 0);
+       
+       /* and particles too */
+       if(ob->particlesystem.first) {
+               ParticleSystem *psys;
+               int i;
+               
+               for(psys= ob->particlesystem.first; psys; psys= psys->next) {
+                       for(i=0; i<PSYS_TOT_VG; i++) {
+                               if(psys->vgroup[i]==ob->actdef) {
+                                       psys->recalc |= PSYS_RECALC_HAIR;
                                        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;
+       DAG_object_flush_update(CTX_data_scene(C), ob, OB_RECALC_DATA);
+       
+       ED_undo_push(C, "Weight Paint");
+       
+       MEM_freeN(wpd);
+       op->customdata= NULL;
+}
+
+
+static int wpaint_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+       ToolSettings *ts= CTX_data_tool_settings(C);
+       VPaint *wp= ts->wpaint;
+       float editbutvweight= 1.0f; // XXX
+       
+       switch(event->type) {
+               case LEFTMOUSE:
+                       if(event->val==0) { /* release */
+                               wpaint_exit(C, op);
+                               return OPERATOR_FINISHED;
+                       }
+                       /* pass on, first press gets painted too */
+                       
+               case MOUSEMOVE: 
+               {
+                       struct WPaintData *wpd= op->customdata;
+                       ViewContext *vc= &wpd->vc;
+                       Object *ob= vc->obact;
+                       Mesh *me= ob->data;
+                       float mat[4][4];
+                       float paintweight= editbutvweight; // XXX
+                       int *indexar= wpd->indexar;
+                       int totindex, index, alpha, totw;
+                       short mval[2];
+                       
+                       view3d_operator_needs_opengl(C);
+                       
+                       /* load projection matrix */
+                       wmMultMatrix(ob->obmat);
+                       wmGetSingleMatrix(mat);
+                       wmLoadMatrix(wpd->vc.v3d->viewmat);
+                       
+                       MTC_Mat4SwapMat4(wpd->vc.v3d->persmat, mat);
+                       
+                       mval[0]= event->x - vc->ar->winrct.xmin;
+                       mval[1]= event->y - vc->ar->winrct.ymin;
                        
                        /* which faces are involved */
-                       if(Gwp.flag & VP_AREA) {
-                               totindex= sample_backbuf_area(&vc, indexar, me->totface, mval[0], mval[1], Gwp.size);
+                       if(wp->flag & VP_AREA) {
+                               totindex= sample_backbuf_area(vc, indexar, me->totface, mval[0], mval[1], wp->size);
                        }
                        else {
-                               indexar[0]= view3d_sample_backbuf(&vc, mval[0], mval[1]);
+                               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) {
+                       if(wp->flag & VP_COLINDEX) {
                                for(index=0; index<totindex; index++) {
                                        if(indexar[index] && indexar[index]<=me->totface) {
-                                       
-                                               mface= ((MFace *)me->mface) + (indexar[index]-1);
-                                       
+                                               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 *)me->mface) + (indexar[index]-1);
-                                       
+                                               MFace *mface= ((MFace *)me->mface) + (indexar[index]-1);
+                                               
                                                if((mface->flag & ME_FACE_SEL)==0) {
                                                        indexar[index]= 0;
                                                }
@@ -1197,24 +1280,24 @@ void weight_paint(Scene *scene, ARegion *ar, View3D *v3d)
                        /* make sure each vertex gets treated only once */
                        /* and calculate filter weight */
                        totw= 0;
-                       if(Gwp.mode==VP_BLUR) 
+                       if(wp->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);
+                                       MFace *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) {
+                                       if(wp->mode==VP_BLUR) {
                                                MDeformWeight *dw, *(*dw_func)(MDeformVert *, int) = verify_defweight;
                                                
-                                               if(Gwp.flag & VP_ONLYVGROUP)
+                                               if(wp->flag & VP_ONLYVGROUP)
                                                        dw_func= get_defweight;
                                                
                                                dw= dw_func(me->dvert+mface->v1, ob->actdef-1);
@@ -1231,43 +1314,43 @@ void weight_paint(Scene *scene, ARegion *ar, View3D *v3d)
                                }
                        }
                        
-                       if(Gwp.mode==VP_BLUR) 
+                       if(wp->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);
+                                       MFace *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);
+                                               alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v1, mval);
                                                if(alpha) {
-                                                       do_weight_paint_vertex(ob, mface->v1, alpha, paintweight, vgroup_mirror);
+                                                       do_weight_paint_vertex(wp, ob, mface->v1, alpha, paintweight, wpd->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);
+                                               alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v2, mval);
                                                if(alpha) {
-                                                       do_weight_paint_vertex(ob, mface->v2, alpha, paintweight, vgroup_mirror);
+                                                       do_weight_paint_vertex(wp, ob, mface->v2, alpha, paintweight, wpd->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);
+                                               alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v3, mval);
                                                if(alpha) {
-                                                       do_weight_paint_vertex(ob, mface->v3, alpha, paintweight, vgroup_mirror);
+                                                       do_weight_paint_vertex(wp, ob, mface->v3, alpha, paintweight, wpd->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);
+                                                       alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v4, mval);
                                                        if(alpha) {
-                                                               do_weight_paint_vertex(ob, mface->v4, alpha, paintweight, vgroup_mirror);
+                                                               do_weight_paint_vertex(wp, ob, mface->v4, alpha, paintweight, wpd->vgroup_mirror);
                                                        }
                                                        (me->dvert+mface->v4)->flag= 0;
                                                }
@@ -1275,104 +1358,134 @@ void weight_paint(Scene *scene, ARegion *ar, View3D *v3d)
                                }
                        }
                        
-                       MTC_Mat4SwapMat4(v3d->persmat, mat);
-                       
-               }
-               
-               if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
-
-                       DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+                       MTC_Mat4SwapMat4(vc->v3d->persmat, mat);
                        
-                       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];
+                       DAG_object_flush_update(vc->scene, ob, OB_RECALC_DATA);
+                       ED_region_tag_redraw(vc->ar);
                }
        }
-       
-       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");
+       return OPERATOR_RUNNING_MODAL;
 }
 
-void set_wpaint(bContext *C, wmOperator *op)           /* toggle */
-{              
-       Object *ob= CTX_data_active_object(C);
+static int wpaint_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
        Scene *scene= CTX_data_scene(C);
+       ToolSettings *ts= CTX_data_tool_settings(C);
+       VPaint *wp= ts->wpaint;
+       Object *ob= CTX_data_active_object(C);
+       struct WPaintData *wpd;
        Mesh *me;
+       float mat[4][4], imat[4][4];
        
-       ob= OBACT;
-       if(!ob || ob->id.lib) return;
-       me= get_mesh(ob);
+       if(scene->obedit) return OPERATOR_CANCELLED;
+       // XXX  if(multires_level1_test()) return;
        
-       if(me && me->totface>=MAXINDEX) {
-               error("Maximum number of faces: %d", MAXINDEX-1);
-               G.f &= ~G_WEIGHTPAINT;
-               return;
-       }
+       me= get_mesh(ob);
+       if(me==NULL || me->totface==0) return OPERATOR_CANCELLED;
        
-       if(G.f & G_WEIGHTPAINT) G.f &= ~G_WEIGHTPAINT;
-       else G.f |= G_WEIGHTPAINT;
+       /* if nothing was added yet, we make dverts and a vertex deform group */
+       if (!me->dvert)
+               create_dverts(&me->id);
        
+       /* make customdata storage */
+       op->customdata= wpd= MEM_callocN(sizeof(struct WPaintData), "WPaintData");
+       view3d_set_viewcontext(C, &wpd->vc);
+       wpd->vgroup_mirror= -1;
+       
+       //      if(qual & LR_CTRLKEY) {
+       //              sample_wpaint(scene, ar, v3d, 0);
+       //              return;
+       //      }
+       //      if(qual & LR_SHIFTKEY) {
+       //              sample_wpaint(scene, ar, v3d, 1);
+       //              return;
+       //      }
        
-       /* 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);
-       }
+       /* ALLOCATIONS! no return after this line */
+       /* painting on subsurfs should give correct points too, this returns me->totvert amount */
+       wpd->vertexcosnos= mesh_get_mapped_verts_nors(scene, ob);
+       wpd->indexar= get_indexarray();
+       copy_wpaint_prev(wp, me->dvert, me->totvert);
        
-       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)) {
+       /* 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= par->pose->chanbase.first; pchan; pchan= pchan->next)
-                               if(pchan->bone->flag & BONE_ACTIVE)
+                       for(pchan= modob->pose->chanbase.first; pchan; pchan= pchan->next)
+                               if(pchan->bone->flag & SELECT)
                                        break;
-                       //                      if(pchan)
-                       // XXX                          vertexgroup_select_by_name(ob, pchan->name);
+                       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);
+                       }
                }
        }
-       else {
-               mesh_octree_table(ob, NULL, NULL, 'e');
+       if(ob->defbase.first==NULL) {
+               add_defgroup(ob);
+       }       
+       
+       //      if(ob->lay & v3d->lay); else error("Active object is not in this layer");
+       
+       /* imat for normals */
+       Mat4MulMat4(mat, ob->obmat, wpd->vc.v3d->viewmat);
+       Mat4Invert(imat, mat);
+       Mat3CpyMat4(wpd->wpimat, imat);
+       
+       /* if mirror painting, find the other group */
+       if(wp->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)
+                               wpd->vgroup_mirror= actdef;
+               }
        }
+       
+       /* do paint once for click only paint */
+       wpaint_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_wpaint(wmOperatorType *ot)
+{
+       
+       /* identifiers */
+       ot->name= "Weight Paint";
+       ot->idname= "VIEW3D_OT_wpaint";
+       
+       /* api callbacks */
+       ot->invoke= wpaint_invoke;
+       ot->modal= wpaint_modal;
+       /* ot->exec= vpaint_exec; <-- needs stroke property */
+       ot->poll= wp_poll;
+       
 }
 
+
 /* ************ set / clear vertex paint mode ********** */
 
 /* retrieve whether cursor should be set or operator should be done */
@@ -1391,12 +1504,14 @@ static int vp_poll(bContext *C)
 
 static void vp_drawcursor(bContext *C, int x, int y)
 {
+       ToolSettings *ts= CTX_data_tool_settings(C);
+       
        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);
+       glutil_draw_lined_arc(0.0, M_PI*2.0, ts->vpaint->size, 40);
        glDisable(GL_BLEND);
        glDisable( GL_LINE_SMOOTH );
        
@@ -1407,6 +1522,7 @@ static int set_vpaint(bContext *C, wmOperator *op)                /* toggle */
 {      
        Object *ob= CTX_data_active_object(C);
        Scene *scene= CTX_data_scene(C);
+       VPaint *vp= scene->toolsettings->vpaint;
        Mesh *me;
        
        if(object_data_is_libdata(ob)) {
@@ -1425,19 +1541,26 @@ static int set_vpaint(bContext *C, wmOperator *op)              /* toggle */
        if(me && me->mcol==NULL) make_vertexcol(scene, 0);
        
        /* toggle: end vpaint */
-       if(G.f & G_VERTEXPAINT){
+       if(G.f & G_VERTEXPAINT) {
+               
                G.f &= ~G_VERTEXPAINT;
                
-               WM_paint_cursor_end(CTX_wm_manager(C), Gvp.paintcursor);
-               Gvp.paintcursor= NULL;
+               if(vp) {
+                       WM_paint_cursor_end(CTX_wm_manager(C), vp->paintcursor);
+                       vp->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(vp==NULL)
+                       vp= scene->toolsettings->vpaint= new_vpaint(0);
+               
+               vp->paintcursor = WM_paint_cursor_activate(CTX_wm_manager(C), vp_poll, vp_drawcursor);
        }
        
        if (me)
@@ -1453,7 +1576,7 @@ void VIEW3D_OT_vpaint_toggle(wmOperatorType *ot)
 {
        
        /* identifiers */
-       ot->name= "Vpaint mode";
+       ot->name= "Vertex Paint Mode";
        ot->idname= "VIEW3D_OT_vpaint_toggle";
        
        /* api callbacks */
@@ -1481,8 +1604,7 @@ Operator->modal()
 
 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?)
+  - revise whether op->customdata should be added in object, in set_vpaint
 
 */
 
@@ -1496,6 +1618,7 @@ struct VPaintData {
 
 static void vpaint_exit(bContext *C, wmOperator *op)
 {
+       ToolSettings *ts= CTX_data_tool_settings(C);
        struct VPaintData *vpd= op->customdata;
        
        if(vpd->vertexcosnos)
@@ -1503,7 +1626,7 @@ static void vpaint_exit(bContext *C, wmOperator *op)
        MEM_freeN(vpd->indexar);
        
        /* frees prev buffer */
-       copy_vpaint_prev(&Gvp, NULL, 0);
+       copy_vpaint_prev(ts->vpaint, NULL, 0);
        
        ED_undo_push(C, "Vertex Paint");
        
@@ -1513,6 +1636,8 @@ static void vpaint_exit(bContext *C, wmOperator *op)
 
 static int vpaint_modal(bContext *C, wmOperator *op, wmEvent *event)
 {
+       ToolSettings *ts= CTX_data_tool_settings(C);
+       VPaint *vp= ts->vpaint;
        
        switch(event->type) {
                case LEFTMOUSE:
@@ -1544,8 +1669,8 @@ static int vpaint_modal(bContext *C, wmOperator *op, wmEvent *event)
                        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);
+                       if(vp->flag & VP_AREA) {
+                               totindex= sample_backbuf_area(vc, indexar, me->totface, mval[0], mval[1], vp->size);
                        }
                        else {
                                indexar[0]= view3d_sample_backbuf(vc, mval[0], mval[1]);
@@ -1555,7 +1680,7 @@ static int vpaint_modal(bContext *C, wmOperator *op, wmEvent *event)
                        
                        MTC_Mat4SwapMat4(vc->v3d->persmat, mat);
                        
-                       if(Gvp.flag & VP_COLINDEX) {
+                       if(vp->flag & VP_COLINDEX) {
                                for(index=0; index<totindex; index++) {
                                        if(indexar[index] && indexar[index]<=me->totface) {
                                                MFace *mface= ((MFace *)me->mface) + (indexar[index]-1);
@@ -1582,10 +1707,10 @@ static int vpaint_modal(bContext *C, wmOperator *op, wmEvent *event)
                                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);
+                                       unsigned int *mcolorig= ( (unsigned int *)vp->vpaint_prev) + 4*(indexar[index]-1);
                                        int alpha;
                                        
-                                       if(Gvp.mode==VP_BLUR) {
+                                       if(vp->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);
@@ -1597,18 +1722,18 @@ static int vpaint_modal(bContext *C, wmOperator *op, wmEvent *event)
                                                
                                        }
                                        
-                                       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(vp, vc, vpd->vpimat, vpd->vertexcosnos+6*mface->v1, mval);
+                                       if(alpha) vpaint_blend(vp, 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(vp, vc, vpd->vpimat, vpd->vertexcosnos+6*mface->v2, mval);
+                                       if(alpha) vpaint_blend(vp, 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);
+                                       alpha= calc_vp_alpha_dl(vp, vc, vpd->vpimat, vpd->vertexcosnos+6*mface->v3, mval);
+                                       if(alpha) vpaint_blend(vp, 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);
+                                               alpha= calc_vp_alpha_dl(vp, vc, vpd->vpimat, vpd->vertexcosnos+6*mface->v4, mval);
+                                               if(alpha) vpaint_blend(vp, mcol+3, mcolorig+3, vpd->paintcol, alpha);
                                        }
                                }
                        }
@@ -1629,6 +1754,8 @@ static int vpaint_modal(bContext *C, wmOperator *op, wmEvent *event)
 
 static int vpaint_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
+       ToolSettings *ts= CTX_data_tool_settings(C);
+       VPaint *vp= ts->vpaint;
        struct VPaintData *vpd;
        Object *ob= CTX_data_active_object(C);
        Mesh *me;
@@ -1647,10 +1774,10 @@ static int vpaint_invoke(bContext *C, wmOperator *op, wmEvent *event)
        
        vpd->vertexcosnos= mesh_get_mapped_verts_nors(vpd->vc.scene, ob);
        vpd->indexar= get_indexarray();
-       vpd->paintcol= vpaint_get_current_col(&Gvp);
+       vpd->paintcol= vpaint_get_current_col(vp);
        
        /* for filtering */
-       copy_vpaint_prev(&Gvp, (unsigned int *)me->mcol, me->totface);
+       copy_vpaint_prev(vp, (unsigned int *)me->mcol, me->totface);
        
        /* some old cruft to sort out later */
        Mat4MulMat4(mat, ob->obmat, vpd->vc.v3d->viewmat);
@@ -1670,7 +1797,7 @@ void VIEW3D_OT_vpaint(wmOperatorType *ot)
 {
        
        /* identifiers */
-       ot->name= "Vpaint";
+       ot->name= "Vertex Paint";
        ot->idname= "VIEW3D_OT_vpaint";
        
        /* api callbacks */
index ed311e0ff0c39bc884a166490e892eb08dcf670e..ae75c9d967b5f64073883ee9c3d25dc395cda6e3 100644 (file)
@@ -58,6 +58,9 @@ void ED_editors_exit(bContext *C)
        /* frees all editmode undos */
        undo_editmode_clear();
        
+       /* global in meshtools... */
+       mesh_octree_table(ob, NULL, NULL, 'e');
+       
        if(ob) {
                if(ob->type==OB_MESH) {
                        Mesh *me= ob->data;
index 1dfdd940cfa0faeb7232c752d5cca693323d1525..ad280f46b2654347b4806a30003a18bd9653f4b0 100644 (file)
@@ -374,7 +374,34 @@ typedef struct TransformOrientation {
        float mat[3][3];
 } TransformOrientation;
 
+typedef struct VPaint {
+       float r, g, b, a;
+       float size;                                                     /* of brush */
+       float gamma, mul;
+       short mode, flag;
+       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;
+
+/* VPaint flag */
+#define VP_COLINDEX    1
+#define VP_AREA                2
+#define VP_SOFT                4
+#define VP_NORMALS     8
+#define VP_SPRAY       16
+#define VP_MIRROR_X    32
+#define VP_HARD                64
+#define VP_ONLYVGROUP  128
+
+
+
 typedef struct ToolSettings {
+       VPaint *vpaint;         /* vertex paint */
+       VPaint *wpaint;         /* weight paint */
+       
        /* Subdivide Settings */
        short cornertype;
        short editbutflag;