svn merge -r37793:37865 https://svn.blender.org/svnroot/bf-blender/trunk/blender
authorCampbell Barton <ideasman42@gmail.com>
Mon, 18 Jul 2011 14:15:02 +0000 (14:15 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 18 Jul 2011 14:15:02 +0000 (14:15 +0000)
Merge info was  /trunk/blender:36835-37793,37865-38157
so this should merge in missing files.

37 files changed:
CMakeLists.txt
intern/ghost/intern/GHOST_SystemCocoa.mm
release/scripts/startup/bl_ui/properties_data_mesh.py
release/scripts/startup/bl_ui/space_view3d_toolbar.py
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/BKE_paint.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/cdderivedmesh.c
source/blender/blenkernel/intern/paint.c
source/blender/blenlib/intern/math_geom.c
source/blender/editors/armature/armature_ops.c
source/blender/editors/armature/editarmature.c
source/blender/editors/include/ED_mesh.h
source/blender/editors/include/ED_view3d.h
source/blender/editors/interface/interface_templates.c
source/blender/editors/mesh/editmesh.c
source/blender/editors/mesh/editmesh_mods.c
source/blender/editors/object/object_intern.h
source/blender/editors/object/object_ops.c
source/blender/editors/object/object_vgroup.c
source/blender/editors/sculpt_paint/paint_image.c
source/blender/editors/sculpt_paint/paint_intern.h
source/blender/editors/sculpt_paint/paint_ops.c
source/blender/editors/sculpt_paint/paint_utils.c
source/blender/editors/sculpt_paint/paint_vertex.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/space_view3d.c
source/blender/editors/space_view3d/view3d_header.c
source/blender/editors/space_view3d/view3d_select.c
source/blender/makesdna/DNA_mesh_types.h
source/blender/makesdna/DNA_object_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_mesh.c
source/blender/makesrna/intern/rna_object.c
source/blender/makesrna/intern/rna_scene.c
source/blender/python/generic/mathutils_geometry.c

index f7e8d7dc172dd47278578b28866e4f93435835a5..88a1c63adadb0c484a7b04526c6fd2bc03a07817 100644 (file)
@@ -53,6 +53,7 @@ if(NOT EXECUTABLE_OUTPUT_PATH)
        set(FIRST_RUN "TRUE")
 endif()
 
+
 # this starts out unset
 list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/build_files/cmake/Modules")
 
@@ -144,7 +145,7 @@ option(WITH_IMAGE_HDR           "Enable HDR Image Support" ON)
 option(WITH_IMAGE_REDCODE       "Enable RedCode Image Support" OFF)
 
 # Audio/Video format support
-option(WITH_CODEC_FFMPEG        "Enable FFMPeg Support (http://ffmpeg.org)" OFF)
+option(WITH_CODEC_FFMPEG        "Enable FFMPeg Support (http://ffmpeg.mplayerhq.hu)" OFF)
 option(WITH_CODEC_SNDFILE       "Enable libsndfile Support (http://www.mega-nerd.com/libsndfile)" OFF)
 if(APPLE OR (WIN32 AND NOT UNIX))
        option(WITH_CODEC_QUICKTIME     "Enable Quicktime Support" OFF)
@@ -242,24 +243,11 @@ TEST_SSE_SUPPORT()
 set(WITH_BINRELOC OFF)
 
 # MAXOSX only, set to avoid uninitialized 
-set(EXETYPE)
-
-# C/C++ flags
-set(PLATFORM_CFLAGS)
+set(EXETYPE "")
 
 # these are added to later on.
-set(C_WARNINGS)
-set(CXX_WARNINGS)
-
-# libraries to link the binary with passed to target_link_libraries()
-# known as LLIBS to scons
-set(PLATFORM_LINKLIBS)
-
-# Added to linker flags in setup_liblinks
-# - CMAKE_EXE_LINKER_FLAGS
-# - CMAKE_EXE_LINKER_FLAGS_DEBUG
-set(PLATFORM_LINKFLAGS)
-set(PLATFORM_LINKFLAGS_DEBUG)
+set(C_WARNINGS "")
+set(CXX_WARNINGS "")
 
 
 # disabled for now, not supported
@@ -362,7 +350,7 @@ if(UNIX AND NOT APPLE)
        endif()
 
        if(WITH_CODEC_FFMPEG)
-               set(FFMPEG /usr CACHE PATH "FFMPEG Directory")
+               set(FFMPEG /usr CACHE FILEPATH "FFMPEG Directory")
                mark_as_advanced(FFMPEG)
                set(FFMPEG_INCLUDE_DIRS ${FFMPEG}/include)
                set(FFMPEG_LIBRARIES avformat avcodec avutil avdevice swscale CACHE STRING "FFMPEG Libraries")
@@ -406,18 +394,18 @@ if(UNIX AND NOT APPLE)
        endif()
 
        if(WITH_OPENCOLLADA)
-               set(OPENCOLLADA /usr/local/opencollada CACHE PATH "OpenCollada Directory")
+               set(OPENCOLLADA /usr/local/opencollada CACHE FILEPATH "OpenCollada Directory")
                mark_as_advanced(OPENCOLLADA)
                set(OPENCOLLADA_LIBPATH ${OPENCOLLADA}/lib)
                set(OPENCOLLADA_LIBRARIES OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver pcre ftoa buffer xml2)
                set(OPENCOLLADA_INCLUDE_DIR ${OPENCOLLADA})
 
-               set(PCRE /usr CACHE PATH "PCRE Directory")
+               set(PCRE /usr CACHE FILEPATH "PCRE Directory")
                mark_as_advanced(PCRE)
                set(PCRE_LIBPATH ${PCRE}/lib)
                set(PCRE_LIB pcre)
 
-               set(EXPAT /usr CACHE PATH "Expat Directory")
+               set(EXPAT /usr CACHE FILEPATH "Expat Directory")
                mark_as_advanced(EXPAT)
                set(EXPAT_LIBPATH ${EXPAT}/lib)
                set(EXPAT_LIB expat)
@@ -431,24 +419,24 @@ if(UNIX AND NOT APPLE)
        endif()
 
        # OpenSuse needs lutil, ArchLinux not, for now keep, can avoid by using --as-needed
-       set(PLATFORM_LINKLIBS "-lutil -lc -lm -lpthread -lstdc++")
+       set(LLIBS "-lutil -lc -lm -lpthread -lstdc++")
 
        if(NOT WITH_HEADLESS)
                find_package(X11 REQUIRED)
                find_path(X11_XF86keysym_INCLUDE_PATH X11/XF86keysym.h ${X11_INC_SEARCH_PATH})
                mark_as_advanced(X11_XF86keysym_INCLUDE_PATH)
 
-               list(APPEND PLATFORM_LINKLIBS ${X11_X11_LIB})
+               list(APPEND LLIBS ${X11_X11_LIB})
 
                if(WITH_X11_XINPUT)
-                       list(APPEND PLATFORM_LINKLIBS ${X11_Xinput_LIB})
+                       list(APPEND LLIBS ${X11_Xinput_LIB})
                endif()
        endif()
 
        if(CMAKE_SYSTEM_NAME MATCHES "Linux")
                if(NOT WITH_PYTHON_MODULE)
                        # BSD's dont use libdl.so
-                       list(APPEND PLATFORM_LINKLIBS -ldl)
+                       list(APPEND LLIBS -ldl)
                        # binreloc is linux only
                        set(BINRELOC_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/extern/binreloc/include)
                        set(WITH_BINRELOC ON)
@@ -559,15 +547,13 @@ elseif(WIN32)
 
        if(MSVC)
                if(CMAKE_CL_64)
-                       set(PLATFORM_LINKLIBS ws2_32 vfw32 winmm kernel32 user32 gdi32 comdlg32 advapi32 shfolder shell32 ole32 oleaut32 uuid)
+                       set(LLIBS ws2_32 vfw32 winmm kernel32 user32 gdi32 comdlg32 advapi32 shfolder shell32 ole32 oleaut32 uuid)
                else()
-                       set(PLATFORM_LINKLIBS ws2_32 vfw32 winmm kernel32 user32 gdi32 comdlg32 advapi32 shfolder shell32 ole32 oleaut32 uuid)
+                       set(LLIBS ws2_32 vfw32 winmm kernel32 user32 gdi32 comdlg32 advapi32 shfolder shell32 ole32 oleaut32 uuid)
                endif()
-
-               add_definitions(/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /D_CONSOLE /D_LIB)
-
-               set(CMAKE_CXX_FLAGS "/nologo /J /W0 /Gd /wd4018 /wd4244 /wd4305 /wd4800 /wd4065 /wd4267 /we4013" CACHE STRING "MSVC MT C++ flags " FORCE)
-               set(CMAKE_C_FLAGS   "/nologo /J /W0 /Gd /wd4018 /wd4244 /wd4305 /wd4800 /wd4065 /wd4267 /we4013 /EHsc" CACHE STRING "MSVC MT C++ flags " FORCE)
+               
+               set(CMAKE_CXX_FLAGS "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /D_CONSOLE /D_LIB /nologo /Ob1 /J /W0 /Gd /wd4018 /wd4244 /wd4305 /wd4800 /wd4065 /wd4267 /we4013" CACHE STRING "MSVC MT C++ flags " FORCE)
+               set(CMAKE_C_FLAGS   "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /D_CONSOLE /D_LIB /nologo /Ob1 /J /W0 /Gd /wd4018 /wd4244 /wd4305 /wd4800 /wd4065 /wd4267 /we4013 /EHsc" CACHE STRING "MSVC MT C++ flags " FORCE)
 
                if(CMAKE_CL_64)
                        set(CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /Od /Gm /EHsc /RTC1 /MTd /W3 /nologo /Zi /J" CACHE STRING "MSVC MT flags " FORCE)
@@ -604,22 +590,24 @@ elseif(WIN32)
                endif()
                set(JPEG_LIBRARIES libjpeg)
 
-               set(ZLIB_INCLUDE_DIRS ${LIBDIR}/zlib/include)
+               set(ZLIB ${LIBDIR}/zlib)
+               set(ZLIB_INCLUDE_DIRS ${ZLIB}/include)
+               set(ZLIB_LIBPATH ${ZLIB}/lib)
                if(CMAKE_CL_64)
-                       set(ZLIB_LIBRARIES ${LIBDIR}/zlib/lib/libz.lib)
+                       set(ZLIB_LIBRARIES libz)
                else()
-                       set(ZLIB_LIBRARIES ${LIBDIR}/zlib/lib/zlib.lib)
+                       set(ZLIB_LIBRARIES zlib)
                endif()
 
-               set(PTHREADS_INCLUDE_DIRS ${LIBDIR}/pthreads/include)
-               set(PTHREADS_LIBRARIES ${LIBDIR}/pthreads/lib/pthreadVC2.lib)
-
+               set(PTHREADS ${LIBDIR}/pthreads)
+               set(PTHREADS_INCLUDE_DIRS ${PTHREADS}/include)
+               set(PTHREADS_LIBPATH ${PTHREADS}/lib)
+               set(PTHREADS_LIBRARIES pthreadVC2)
+               
                set(FREETYPE ${LIBDIR}/freetype)
-               set(FREETYPE_INCLUDE_DIRS
-                       ${LIBDIR}/freetype/include
-                       ${LIBDIR}/freetype/include/freetype2
-               )
-               set(FREETYPE_LIBRARY ${LIBDIR}/freetype/lib/freetype2ST.lib)
+               set(FREETYPE_INCLUDE_DIRS ${FREETYPE}/include ${FREETYPE}/include/freetype2)
+               set(FREETYPE_LIBPATH ${FREETYPE}/lib)
+               set(FREETYPE_LIBRARY freetype2ST)
 
                if(WITH_FFTW3)
                        set(FFTW3 ${LIBDIR}/fftw3)
@@ -650,17 +638,10 @@ elseif(WIN32)
                endif()
 
                if(WITH_CODEC_FFMPEG)
-                       set(FFMPEG_INCLUDE_DIRS
-                               ${LIBDIR}/ffmpeg/include
-                               ${LIBDIR}/ffmpeg/include/msvc
-                       )
-                       set(FFMPEG_LIBRARIES
-                               ${LIBDIR}/ffmpeg/lib/avcodec-52.lib
-                               ${LIBDIR}/ffmpeg/lib/avformat-52.lib
-                               ${LIBDIR}/ffmpeg/lib/avdevice-52.lib
-                               ${LIBDIR}/ffmpeg/lib/avutil-50.lib
-                               ${LIBDIR}/ffmpeg/lib/swscale-0.lib
-                       )
+                       set(FFMPEG ${LIBDIR}/ffmpeg)
+                       set(FFMPEG_INCLUDE_DIRS ${FFMPEG}/include ${FFMPEG}/include/msvc)
+                       set(FFMPEG_LIBRARIES avcodec-52 avformat-52 avdevice-52 avutil-50 swscale-0)
+                       set(FFMPEG_LIBPATH ${FFMPEG}/lib)
                endif()
 
                if(WITH_IMAGE_OPENEXR)
@@ -695,16 +676,17 @@ elseif(WIN32)
                endif()
 
                if(WITH_IMAGE_TIFF)
-                       set(TIFF_LIBRARY ${LIBDIR}/tiff/lib/libtiff.lib)
-                       set(TIFF_INCLUDE_DIR ${LIBDIR}/tiff/include)
+                       set(TIFF ${LIBDIR}/tiff)
+                       set(TIFF_LIBRARY libtiff)
+                       set(TIFF_INCLUDE_DIR ${TIFF}/include)
+                       set(TIFF_LIBPATH ${TIFF}/lib)
                endif()
 
                if(WITH_JACK)
-                       set(JACK_INCLUDE_DIRS
-                               ${LIBDIR}/jack/include/jack
-                               ${LIBDIR}/jack/include
-                       )
-                       set(JACK_LIBRARIES ${LIBDIR}/jack/lib/libjack.lib)
+                       set(JACK ${LIBDIR}/jack)
+                       set(JACK_INCLUDE_DIRS ${JACK}/include/jack ${JACK}/include)
+                       set(JACK_LIBRARIES libjack)
+                       set(JACK_LIBPATH ${JACK}/lib)
                endif()
 
                if(WITH_PYTHON)
@@ -714,24 +696,23 @@ elseif(WIN32)
                        set(PYTHON_LIBRARIES ${LIBDIR}/python/lib/python32.lib)
                endif()
 
-               set(PLATFORM_LINKFLAGS "/SUBSYSTEM:CONSOLE /STACK:2097152 /INCREMENTAL:NO /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:msvcmrt.lib /NODEFAULTLIB:msvcurt.lib /NODEFAULTLIB:msvcrtd.lib")
-
                # MSVC only, Mingw doesnt need
                if(CMAKE_CL_64)
-                       set(PLATFORM_LINKFLAGS "/MACHINE:X64 /OPT:NOREF ${PLATFORM_LINKFLAGS}")
+                       set(PLATFORM_LINKFLAGS "/SUBSYSTEM:CONSOLE /MACHINE:X64 /STACK:2097152 /OPT:NOREF /INCREMENTAL:NO /NODEFAULTLIB:\"msvcrt.lib\" /NODEFAULTLIB:\"msvcmrt.lib\" /NODEFAULTLIB:\"msvcurt.lib\" /NODEFAULTLIB:\"msvcrtd.lib\" ")
                else()
-                       set(PLATFORM_LINKFLAGS "/MACHINE:IX86 /LARGEADDRESSAWARE ${PLATFORM_LINKFLAGS}")
+                       set(PLATFORM_LINKFLAGS "/SUBSYSTEM:CONSOLE /MACHINE:IX86 /STACK:2097152 /INCREMENTAL:NO /LARGEADDRESSAWARE /NODEFAULTLIB:\"msvcrt.lib\" /NODEFAULTLIB:\"msvcmrt.lib\" /NODEFAULTLIB:\"msvcurt.lib\" /NODEFAULTLIB:\"msvcrtd.lib\" ")
                endif()
 
-               set(PLATFORM_LINKFLAGS_DEBUG "/NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:libc.lib")
+               set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:libcmt.lib;libc.lib ")
 
        else()
                # keep GCC spesific stuff here
                if(CMAKE_COMPILER_IS_GNUCC)
-                       set(PLATFORM_LINKLIBS "-lshell32 -lshfolder -lgdi32 -lmsvcrt -lwinmm -lmingw32 -lm -lws2_32 -lz -lstdc++ -lole32 -luuid")
+                       set(LLIBS "-lshell32 -lshfolder -lgdi32 -lmsvcrt -lwinmm -lmingw32 -lm -lws2_32 -lz -lstdc++ -lole32 -luuid")
                        set(PLATFORM_CFLAGS "-pipe -funsigned-char -fno-strict-aliasing")
 
-                       add_definitions(-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE)
+                       set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE")
+                       set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE")
                endif()
 
                add_definitions(-DFREE_WINDOWS)
@@ -941,7 +922,7 @@ elseif(APPLE)
                set(SAMPLERATE_LIBPATH ${SAMPLERATE}/lib)
        endif()
 
-       set(PLATFORM_LINKLIBS stdc++ SystemStubs)
+       set(LLIBS stdc++ SystemStubs)
 
        if(WITH_COCOA)
                set(PLATFORM_CFLAGS "-pipe -funsigned-char -DGHOST_COCOA")
@@ -1165,18 +1146,6 @@ elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
 
 endif()
 
-# MSVC2010 fails to links C++ libs right
-if(MSVC10)
-       if(WITH_IMAGE_OPENEXR)
-               message(WARNING "MSVC 2010 does not support OpenEXR, disabling WITH_IMAGE_OPENEXR. To enable support use Use MSVC 2008")
-               set(WITH_IMAGE_OPENEXR OFF)
-       endif()
-       if(WITH_OPENCOLLADA)
-               message(WARNING "MSVC 2010 does not support OpenCollada, disabling WITH_OPENCOLLADA. To enable support use Use MSVC 2008")
-               set(WITH_OPENCOLLADA OFF)
-       endif()
-endif()
-
 if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
        if(WITH_IK_ITASC OR WITH_MOD_FLUID)
                message(WARNING "Using Clang as CXX compiler: disabling WITH_IK_ITASC and WITH_MOD_FLUID, these features will be missing.")
index bb3d6e3aee331257e563f01162a1c68b43348faf..69423f2dfbf83c74cbf4e89997efdcad0a87b1fc 100644 (file)
@@ -1498,18 +1498,15 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
                                                GHOST_TInt32 x_mouse= mousePos.x;
                                                GHOST_TInt32 y_mouse= mousePos.y;
                                                GHOST_TInt32 x_accum, y_accum, x_cur, y_cur, x, y;
-                                               GHOST_Rect bounds, windowBounds, correctedBounds;
+                                               GHOST_Rect bounds, correctedBounds;
                                                
                                                /* fallback to window bounds */
                                                if(window->getCursorGrabBounds(bounds)==GHOST_kFailure)
                                                        window->getClientBounds(bounds);
                                                
                                                //Switch back to Cocoa coordinates orientation (y=0 at botton,the same as blender internal btw!), and to client coordinates
-                                               window->getClientBounds(windowBounds);
-                                               window->screenToClient(bounds.m_l, bounds.m_b, correctedBounds.m_l, correctedBounds.m_t);
-                                               window->screenToClient(bounds.m_r, bounds.m_t, correctedBounds.m_r, correctedBounds.m_b);
-                                               correctedBounds.m_b = (windowBounds.m_b - windowBounds.m_t) - correctedBounds.m_b;
-                                               correctedBounds.m_t = (windowBounds.m_b - windowBounds.m_t) - correctedBounds.m_t;
+                                               window->screenToClient(bounds.m_l, bounds.m_b, correctedBounds.m_l, correctedBounds.m_b);
+                                               window->screenToClient(bounds.m_r, bounds.m_t, correctedBounds.m_r, correctedBounds.m_t);
                                                
                                                //Update accumulation counts
                                                window->getCursorGrabAccum(x_accum, y_accum);
index 618a88f08799523312ee25d18f1fa1abab840937..013ba8b44d1a904e262aa05da2bcd2b3be5552e6 100644 (file)
@@ -134,7 +134,8 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, bpy.types.Panel):
 
         ob = context.object
         group = ob.vertex_groups.active
-
+        
+        
         rows = 2
         if group:
             rows = 5
@@ -143,6 +144,9 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, bpy.types.Panel):
         row.template_list(ob, "vertex_groups", ob.vertex_groups, "active_index", rows=rows)
 
         col = row.column(align=True)
+        # Jason was here, this was replaced by hardcoded list view checkboxes. #
+        #col.prop(group, "flag")
+        
         col.operator("object.vertex_group_add", icon='ZOOMIN', text="")
         col.operator("object.vertex_group_remove", icon='ZOOMOUT', text="")
         col.menu("MESH_MT_vertex_group_specials", icon='DOWNARROW_HLT', text="")
@@ -153,6 +157,14 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, bpy.types.Panel):
         if group:
             row = layout.row()
             row.prop(group, "name")
+        #Jason was here
+        # add buttons to make it faster to lock/unlock vgroups
+        if ob.mode == 'WEIGHT_PAINT' and len(ob.vertex_groups) > 0:
+            row = layout.row()
+            sub = row.row(align=True)
+            sub.operator("object.vertex_group_lock_all", text="Lock All")
+            sub.operator("object.vertex_group_invert_locks", text="Invert Locks")
+            sub.operator("object.vertex_group_unlock_all", text="Unlock All")
 
         if ob.mode == 'EDIT' and len(ob.vertex_groups) > 0:
             row = layout.row()
index 52eb76d071032d303663c89123b061ffb5269af2..ac47380d363410ecee60463fda75a91575a0753e 100644 (file)
@@ -639,6 +639,8 @@ class VIEW3D_PT_tools_brush(PaintPanel, bpy.types.Panel):
         elif context.weight_paint_object and brush:
             layout.prop(context.tool_settings, "vertex_group_weight", text="Weight", slider=True)
             layout.prop(context.tool_settings, "use_auto_normalize", text="Auto Normalize")
+            # Jason was here
+            layout.prop(context.tool_settings, "use_multipaint", text="Multi-Paint")
 
             col = layout.column()
 
index 55ade5fe5d987b9cb6e6207e8e19719a24d7361c..1d060846175e2923d3e1080e976a04fc75e05aa1 100644 (file)
@@ -222,6 +222,9 @@ struct DerivedMesh {
        /* Draw all vertices as bgl points (no options) */
        void (*drawVerts)(DerivedMesh *dm);
 
+       /* Jason Draw all selected vertices as bgl points (no options) */
+       void (*drawSelectedVerts)(DerivedMesh *dm);
+
        /* Draw edges in the UV mesh (if exists) */
        void (*drawUVEdges)(DerivedMesh *dm);
 
index ef16129e1e7fcd0792e5e994e974f6c2a7d8bfaf..cee97e7631f2a690f8ee87e17435449f5e58429d 100644 (file)
@@ -59,7 +59,8 @@ void paint_brush_set(struct Paint *paint, struct Brush *br);
  * Texture paint could be removed since selected faces are not used
  * however hiding faces is useful */
 int paint_facesel_test(struct Object *ob);
-
+/* Jason */
+int paint_vertsel_test(struct Object *ob);
 /* Session data (mode-specific) */
 
 typedef struct SculptSession {
index d9c98bc0200af2a4e782ec1b32add26497d7370e..a35ad48e5997f0031ea7b6a22d9d5fb44c1d0d7e 100644 (file)
@@ -40,6 +40,9 @@
 #include "DNA_cloth_types.h"
 #include "DNA_key_types.h"
 #include "DNA_meshdata_types.h"
+// Jason
+#include "DNA_armature_types.h"
+
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h" // N_T
 
@@ -72,6 +75,8 @@
 #include "GPU_material.h"
 
 #include "ED_sculpt.h" /* for ED_sculpt_modifiers_changed */
+// Jason was here, this is for multi-paint
+#include "ED_armature.h"
 
 ///////////////////////////////////
 ///////////////////////////////////
@@ -1602,19 +1607,50 @@ void weight_to_rgb(float input, float *fr, float *fg, float *fb)
        }
 }
 
-static void calc_weightpaint_vert_color(Object *ob, ColorBand *coba, int vert, unsigned char *col)
+static void calc_weightpaint_vert_color(Object *ob, ColorBand *coba, int vert, unsigned char *col, char *dg_flags, int selected, int unselected, int multipaint, int auto_normalize)
 {
        Mesh *me = ob->data;
-       float colf[4], input = 0.0f;
+       float colf[4], input = 0.0f;// Jason
        int i;
+       char make_black = FALSE;
+       char was_a_nonzero = FALSE;
 
        if (me->dvert) {
-               for (i=0; i<me->dvert[vert].totweight; i++)
-                       if (me->dvert[vert].dw[i].def_nr==ob->actdef-1)
-                               input+=me->dvert[vert].dw[i].weight;            
-       }
+               for (i=0; i<me->dvert[vert].totweight; i++) {
+                       // Jason was here
+                       // in multipaint, get the average if auto normalize is inactive
+                       // get the sum if it is active
+                       if(multipaint && selected > 1) {
+                               if(dg_flags[me->dvert[vert].dw[i].def_nr]) {
+                                       if(me->dvert[vert].dw[i].weight) {
+                                               input+=me->dvert[vert].dw[i].weight;
+                                               was_a_nonzero = TRUE;
+                                       }
+                               }
+                       } else if (me->dvert[vert].dw[i].def_nr==ob->actdef-1) {
+                               input+=me->dvert[vert].dw[i].weight;
+                       }
+               }
+               
+               // Jason was here
+               // make it black if the selected groups have no weight on a vertex
+               if(!make_black && multipaint && selected > 1) {
+                       if(!was_a_nonzero) {
+                               make_black = TRUE;
+                       } else if (!auto_normalize){
+                               // get the average
+                               input /= selected;
+                       }
 
-       CLAMP(input, 0.0f, 1.0f);
+               }
+       }
+       
+       if(make_black) {
+               input = -1;
+       }else {
+               CLAMP(input, 0.0f, 1.0f);
+       }
+       
        
        if(coba)
                do_colorband(coba, input, colf);
@@ -1633,26 +1669,69 @@ void vDM_ColorBand_store(ColorBand *coba)
 {
        stored_cb= coba;
 }
-
-static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm)
+/* TODO move duplicates to header */
+/* Jason was here duplicate function in paint_vertex.c*/
+static char* get_selected_defgroups(Object *ob, int defcnt) {
+       bPoseChannel *chan;
+       bPose *pose;
+       bDeformGroup *defgroup;
+       //Bone *bone;
+       char *dg_flags = MEM_callocN(defcnt*sizeof(char), "dg_selected_flags");
+       int i;
+       Object *armob = ED_object_pose_armature(ob);
+
+       if(armob) {
+               pose = armob->pose;
+               for (chan=pose->chanbase.first; chan; chan=chan->next) {
+                       for (i = 0, defgroup = ob->defbase.first; i < defcnt && defgroup; defgroup = defgroup->next, i++) {
+                               if(!strcmp(defgroup->name, chan->bone->name)) {
+                                       dg_flags[i] = (chan->bone->flag & BONE_SELECTED);
+                               }
+                       }
+               }
+       }
+       
+       return dg_flags;
+}
+/* TODO move duplicates to header */
+/* Jason was here duplicate function */
+static int count_true(char *list, int len)
+{
+       int i;
+       int cnt = 0;
+       for(i = 0; i < len; i++) {
+               if (list[i]) {
+                       cnt++;
+               }
+       }
+       return cnt;
+}
+static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int multipaint, int auto_normalize)
 {
        Mesh *me = ob->data;
        MFace *mf = me->mface;
        ColorBand *coba= stored_cb;     /* warning, not a local var */
        unsigned char *wtcol;
        int i;
-       
+       // Jason was here
+       int defcnt = BLI_countlist(&ob->defbase);
+       char *dg_flags = get_selected_defgroups(ob, defcnt);
+       int selected = count_true(dg_flags, defcnt);
+       int unselected = defcnt - selected;
+
        wtcol = MEM_callocN (sizeof (unsigned char) * me->totface*4*4, "weightmap");
        
        memset(wtcol, 0x55, sizeof (unsigned char) * me->totface*4*4);
        for (i=0; i<me->totface; i++, mf++) {
-               calc_weightpaint_vert_color(ob, coba, mf->v1, &wtcol[(i*4 + 0)*4]); 
-               calc_weightpaint_vert_color(ob, coba, mf->v2, &wtcol[(i*4 + 1)*4]); 
-               calc_weightpaint_vert_color(ob, coba, mf->v3, &wtcol[(i*4 + 2)*4]); 
+               calc_weightpaint_vert_color(ob, coba, mf->v1, &wtcol[(i*4 + 0)*4], dg_flags, selected, unselected, multipaint, auto_normalize); 
+               calc_weightpaint_vert_color(ob, coba, mf->v2, &wtcol[(i*4 + 1)*4], dg_flags, selected, unselected, multipaint, auto_normalize); 
+               calc_weightpaint_vert_color(ob, coba, mf->v3, &wtcol[(i*4 + 2)*4], dg_flags, selected, unselected, multipaint, auto_normalize); 
                if (mf->v4)
-                       calc_weightpaint_vert_color(ob, coba, mf->v4, &wtcol[(i*4 + 3)*4]); 
+                       calc_weightpaint_vert_color(ob, coba, mf->v4, &wtcol[(i*4 + 3)*4], dg_flags, selected, unselected, multipaint, auto_normalize); 
        }
-       
+       // Jason
+       MEM_freeN(dg_flags);
+
        CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol, dm->numFaceData);
 }
 
@@ -1859,7 +1938,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
                                }
 
                                if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT))
-                                       add_weight_mcol_dm(ob, dm);
+                                       add_weight_mcol_dm(ob, dm, scene->toolsettings->multipaint, scene->toolsettings->auto_normalize);// Jason
 
                                /* Constructive modifiers need to have an origindex
                                 * otherwise they wont have anywhere to copy the data from.
@@ -1969,7 +2048,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
                CDDM_calc_normals(finaldm);
 
                if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT))
-                       add_weight_mcol_dm(ob, finaldm);
+                       add_weight_mcol_dm(ob, finaldm, scene->toolsettings->multipaint, scene->toolsettings->auto_normalize);// Jason
        } else if(dm) {
                finaldm = dm;
        } else {
@@ -1981,7 +2060,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
                }
 
                if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT))
-                       add_weight_mcol_dm(ob, finaldm);
+                       add_weight_mcol_dm(ob, finaldm, scene->toolsettings->multipaint, scene->toolsettings->auto_normalize);// Jason
        }
 
        /* add an orco layer if needed */
index 72ee9b55800ff13cc029f2d7d2982e16036fde3f..d850cb57c6478e4a98663bb5fe2553f509dc3648 100644 (file)
@@ -268,6 +268,35 @@ static void cdDM_update_normals_from_pbvh(DerivedMesh *dm)
 
        BLI_pbvh_update(cddm->pbvh, PBVH_UpdateNormals, face_nors);
 }
+// Jason
+static void cdDM_drawSelectedVerts(DerivedMesh *dm)
+{
+       CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
+       MVert *mv = cddm->mvert;
+       int i;
+       if( GPU_buffer_legacy(dm) ) {
+               glBegin(GL_POINTS);
+               for(i = 0; i < dm->numVertData; i++, mv++) {
+                       if((mv->flag & 1)) {//TODO define selected
+                               glColor3f(1.0f, 1.0f, 0.0f);
+                       }else {
+                               glColor3f(0.0f, 0.0f, 0.0f);
+                       }
+                       if(!(mv->flag & ME_HIDE)) {
+                               glVertex3fv(mv->co);
+                       }
+               }
+               glEnd();
+       }
+       else {  /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
+               GPU_vertex_setup(dm);
+               if( !GPU_buffer_legacy(dm) ) {
+                       if(dm->drawObject->nelements)   glDrawArrays(GL_POINTS,0, dm->drawObject->nelements);
+                       else                                                    glDrawArrays(GL_POINTS,0, dm->drawObject->nlooseverts);
+               }
+               GPU_buffer_unbind();
+       }
+}
 
 static void cdDM_drawVerts(DerivedMesh *dm)
 {
@@ -1509,6 +1538,8 @@ static CDDerivedMesh *cdDM_create(const char *desc)
        dm->getFaceMap = cdDM_getFaceMap;
 
        dm->drawVerts = cdDM_drawVerts;
+       // Jason
+       dm->drawSelectedVerts = cdDM_drawSelectedVerts;
 
        dm->drawUVEdges = cdDM_drawUVEdges;
        dm->drawEdges = cdDM_drawEdges;
index d00eb6192da6e59ad65f0841a716f9964c10ad5b..9a0fc541bcedddd479b71d3913ec5586640f8367 100644 (file)
@@ -96,7 +96,11 @@ int paint_facesel_test(Object *ob)
 {
        return (ob && ob->type==OB_MESH && ob->data && (((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_MASK) && (ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT)));
 }
-
+/* Jason */
+int paint_vertsel_test(Object *ob)
+{
+       return (ob && ob->type==OB_MESH && ob->data && (((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) && (ob->mode & (OB_MODE_WEIGHT_PAINT)));
+}
 void paint_init(Paint *p, const char col[3])
 {
        Brush *brush;
index fc329fe1bf13ca7d0461de1bb6ad1b725be750e0..9d945e9baa30268695f4d77871324c909658fcd6 100644 (file)
@@ -430,7 +430,7 @@ int isect_line_sphere_v2(const float l1[2], const float l2[2],
            l2[1] - l1[1]
        };
 
-       const float a= dot_v2v2(ldir, ldir);
+       const float a= dot_v3v3(ldir, ldir);
 
        const float b= 2.0f *
                (ldir[0] * (l1[0] - sp[0]) +
index 16b748737ca6505219b133a727cdbe3672a105b5..7bc9bb48a4c63f8a516eb6f4aa61be6cb019c9c0 100644 (file)
@@ -265,7 +265,7 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
        
                /* set flags */
        WM_keymap_add_menu(keymap, "VIEW3D_MT_bone_options_toggle", WKEY, KM_PRESS, KM_SHIFT, 0);
-       WM_keymap_add_menu(keymap, "VIEW3D_MT_bone_options_enable", WKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
+       WM_keymap_add_menu(keymap, "VIEW3D_MT_bone_options_enable", WKEY, KM_PRESS, KM_CTRL, 0);
        WM_keymap_add_menu(keymap, "VIEW3D_MT_bone_options_disable", WKEY, KM_PRESS, KM_ALT, 0);
                
                /* armature/bone layers */
@@ -343,7 +343,7 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
        
                /* set flags */
        WM_keymap_add_menu(keymap, "VIEW3D_MT_bone_options_toggle", WKEY, KM_PRESS, KM_SHIFT, 0);
-       WM_keymap_add_menu(keymap, "VIEW3D_MT_bone_options_enable", WKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
+       WM_keymap_add_menu(keymap, "VIEW3D_MT_bone_options_enable", WKEY, KM_PRESS, KM_CTRL, 0);
        WM_keymap_add_menu(keymap, "VIEW3D_MT_bone_options_disable", WKEY, KM_PRESS, KM_ALT, 0);
 
                /* armature/bone layers */
index 2035220612197b9fd1e09819046788775d785fa1..f5293948a7b890390d16622e3aa73d293cc551ca 100644 (file)
@@ -4260,28 +4260,69 @@ static int bone_looper(Object *ob, Bone *bone, void *data,
        
        return count;
 }
+// Jason
+Bone* get_other_selected_bone(Object *ob) {
+       Bone *bone;
+       int i;
+       bone = get_indexed_bone(ob, 0);
+       for(i = 0; bone;){
+               if(bone->flag & BONE_SELECTED) {
+                       return bone;
+               }
+               i++;
+               bone = get_indexed_bone(ob, i);
+       }
 
+       return NULL;
+}
 /* called from editview.c, for mode-less pose selection */
 /* 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;
        Bone *nearBone;
-       
+       // Jason
+       Bone *new_act_bone;
+
        if (!ob || !ob->pose) return 0;
 
        nearBone= get_bone_from_selectbuffer(scene, base, buffer, hits, 1);
-       
+
        /* if the bone cannot be affected, don't do anything */
        if ((nearBone) && !(nearBone->flag & BONE_UNSELECTABLE)) {
                bArmature *arm= ob->data;
                
                /* since we do unified select, we don't shift+select a bone if the armature object was not active yet */
-               if (!(extend) || (base != scene->basact)) {
-                       ED_pose_deselectall(ob, 0);
-                       nearBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
-                       arm->act_bone= nearBone;
-                       
+               /* Jason was here, I'm doing a select for multibone painting */
+               if ((base != scene->basact)) {//if (!(extend) || (base != scene->basact)) {
+                       /* Jason was here */
+                       /* only deselect all if they aren't using 'shift' */
+                       if(!extend) {
+                               ED_pose_deselectall(ob, 0);
+                               nearBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
+                               arm->act_bone= nearBone;
+                               ED_vgroup_select_by_name(OBACT, nearBone->name);
+                       }
+                       else {
+                               // Jason deselect this bone specifically if it is selected already
+                               if (nearBone->flag & BONE_SELECTED) {
+                                       nearBone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
+                                       if(nearBone == arm->act_bone) {
+                                               // make a different bone the active one if it exists
+                                               new_act_bone = get_other_selected_bone(ob);
+                                               if(new_act_bone) {
+                                                       new_act_bone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
+                                                       arm->act_bone = new_act_bone;
+                                                       ED_vgroup_select_by_name(OBACT, new_act_bone->name);
+                                               }
+                                       }
+                               // or select the bone if they are using shift
+                               } else {
+                                       nearBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
+                                       arm->act_bone= nearBone;
+                               }
+                       } 
+                       DAG_id_tag_update(&OBACT->id, OB_RECALC_DATA);
                                // XXX old cruft! use notifiers instead
                        //select_actionchannel_by_name(ob->action, nearBone->name, 1);
                }
@@ -5045,6 +5086,10 @@ void POSE_OT_select_inverse(wmOperatorType *ot)
 static int pose_de_select_all_exec(bContext *C, wmOperator *op)
 {
        int action = RNA_enum_get(op->ptr, "action");
+       //Jason
+       Object *ob = NULL;
+       Scene *scene= CTX_data_scene(C);
+       int multipaint = scene->toolsettings->multipaint;
 
        if (action == SEL_TOGGLE) {
                action= CTX_DATA_COUNT(C, selected_pose_bones) ? SEL_DESELECT : SEL_SELECT;
@@ -5074,7 +5119,12 @@ static int pose_de_select_all_exec(bContext *C, wmOperator *op)
        CTX_DATA_END;
 
        WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, NULL);
-       
+       // Jason
+       if(multipaint) {
+               ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+               DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+       }
+
        return OPERATOR_FINISHED;
 }
 
index 8bb77ad43a04710418d8bb964a593ecf5f7f9dbe..8005032f0a59caa62d519362350d24863417db67 100644 (file)
@@ -122,7 +122,9 @@ int                 EM_texFaceCheck(struct EditMesh *em);
 int                    EM_vertColorCheck(struct EditMesh *em);
 
 void           undo_push_mesh(struct bContext *C, const char *name);
-
+/* Jason */
+void           paintvert_flush_flags(struct Object *ob);
+void           paintvert_deselect_all_visible(struct Object *ob, int action, short flush_flags);
 
 /* editmesh_lib.c */
 
index dfe0a30474868ac6addefa938beaf4b4e2b07283..62feeb151fa1b8e0064b3ec76c4395150e2b1faa 100644 (file)
@@ -215,6 +215,9 @@ void ED_view3d_project_float(struct ARegion *a, const float vec[3], float adr[2]
 void ED_view3d_calc_camera_border(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, struct rctf *viewborder_r, short do_shift);
 
 /* drawobject.c iterators */
+/*Jason*/
+void mesh_obmode_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct MVert *mv, int x, int y, int index), void *userData, int clipVerts);
+
 void mesh_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct EditVert *eve, int x, int y, int index), void *userData, int clipVerts);
 void mesh_foreachScreenEdge(struct ViewContext *vc, void (*func)(void *userData, struct EditEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, int clipVerts);
 void mesh_foreachScreenFace(struct ViewContext *vc, void (*func)(void *userData, struct EditFace *efa, int x, int y, int index), void *userData);
index 32a20e82d2f2d3bb12ced7a7d05bf4858df08e1e..fdc6dfb3d0f4b94cb03ffae5f4160811615b3c95 100644 (file)
@@ -2119,6 +2119,12 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe
                //uiItemR(row, itemptr, "mute", 0, "", ICON_MUTE_IPO_OFF);
                uiBlockSetEmboss(block, UI_EMBOSS);
        }
+       /* Jason was here: I need the RNA struct for vertex groups */
+       else if(RNA_struct_is_a(itemptr->type, &RNA_VertexGroup)) {
+               uiItemL(sub, name, icon);
+               uiBlockSetEmboss(block, UI_EMBOSS);
+               uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "flag", 0, 0, 0, 0, 0,  NULL);
+       }
        else
                uiItemL(sub, name, icon); /* fails, backdrop LISTROW... */
 
index ec08bfccda3fcb0335191d8024dd46edad3889d1..73ceb0fb3d7717ad9640a013fa42506bfbfd8f21 100644 (file)
@@ -1959,3 +1959,96 @@ void em_setup_viewcontext(bContext *C, ViewContext *vc)
                vc->em= me->edit_mesh;
        }
 }
+
+
+/* Jason (similar to void paintface_flush_flags(Object *ob))
+ * copy the vertex flags, most importantly selection from the mesh to the final derived mesh,
+ * use in object mode when selecting vertices (while painting) */
+void paintvert_flush_flags(Object *ob)
+{
+       Mesh *me= get_mesh(ob);
+       DerivedMesh *dm= ob->derivedFinal;
+       MVert *verts, *mv, *mv_orig;
+       int *index_array = NULL;
+       int totvert;
+       int i;
+       
+       if(me==NULL || dm==NULL)
+               return;
+
+       index_array = dm->getVertDataArray(dm, CD_ORIGINDEX);
+       
+       verts = dm->getVertArray(dm);
+       totvert = dm->getNumVerts(dm);
+       
+       mv= verts;
+       
+       for (i= 0; i<totvert; i++, mv++) { /* loop over derived mesh faces */
+               if(index_array) {
+                       mv_orig= me->mvert + index_array[i];
+                       mv->flag= mv_orig->flag;
+               } else {
+                       mv_orig= me->mvert + i;
+                       mv->flag= mv_orig->flag;
+               }
+       }
+}
+/* Jason note: caller needs to run paintvert_flush_flags(ob) after this */
+void paintvert_deselect_all_visible(Object *ob, int action, short flush_flags)
+{
+       Mesh *me;
+       MVert *mvert;
+       int a;
+
+       me= get_mesh(ob);
+       if(me==NULL) return;
+       
+       if(action == SEL_INVERT) {
+               mvert= me->mvert;
+               a= me->totvert;
+               while(a--) {
+                       if((mvert->flag & ME_HIDE) == 0) {
+                               mvert->flag ^= SELECT;
+                       }
+                       mvert++;
+               }
+       }
+       else {
+               if (action == SEL_TOGGLE) {
+                       action = SEL_SELECT;
+
+                       mvert= me->mvert;
+                       a= me->totvert;
+                       while(a--) {
+                               if((mvert->flag & ME_HIDE) == 0 && mvert->flag & SELECT) {
+                                       action = SEL_DESELECT;
+                                       break;
+                               }
+                               mvert++;
+                       }
+               }
+
+               mvert= me->mvert;
+               a= me->totvert;
+               while(a--) {
+                       if((mvert->flag & ME_HIDE) == 0) {
+                               switch (action) {
+                               case SEL_SELECT:
+                                       mvert->flag |= SELECT;
+                                       break;
+                               case SEL_DESELECT:
+                                       mvert->flag &= ~SELECT;
+                                       break;
+                               case SEL_INVERT:
+                                       mvert->flag ^= SELECT;
+                                       break;
+                               }
+                       }
+                       mvert++;
+               }
+       }
+
+       if(flush_flags) {
+               paintvert_flush_flags(ob);
+       }
+}
\ No newline at end of file
index 9497370a4fa2ca98cb9a969adc0baedb89e03149..0f7538249bc64d2fc466e223417b6c4f774c866d 100644 (file)
@@ -328,6 +328,7 @@ int EM_init_backbuf_circle(ViewContext *vc, short xs, short ys, short rads)
        /* method in use for face selecting too */
        if(vc->obedit==NULL) {
                if(paint_facesel_test(vc->obact));
+               else if(paint_vertsel_test(vc->obact));// Jason, vertex selecting
                else return 0;
        }
        else if(vc->v3d->drawtype<OB_SOLID || (vc->v3d->flag & V3D_ZBUF_SELECT)==0) return 0;
index 801880f0f3266116a4e5f763cca223b0a84bf43c..1d3d0a311e07d0263b621484ec6e4e7afd5b9a04 100644 (file)
@@ -199,6 +199,11 @@ void OBJECT_OT_vertex_group_copy(struct wmOperatorType *ot);
 void OBJECT_OT_vertex_group_normalize(struct wmOperatorType *ot);
 void OBJECT_OT_vertex_group_normalize_all(struct wmOperatorType *ot);
 void OBJECT_OT_vertex_group_levels(struct wmOperatorType *ot);
+/* Jason was here */
+void OBJECT_OT_vertex_group_lock_all(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_invert_locks(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_unlock_all(struct wmOperatorType *ot);
+
 void OBJECT_OT_vertex_group_invert(struct wmOperatorType *ot);
 void OBJECT_OT_vertex_group_blend(struct wmOperatorType *ot);
 void OBJECT_OT_vertex_group_clean(struct wmOperatorType *ot);
index ff9b13379a2197a3a0d23618946112d96bee38df..c9e6004510c30e2f4cdaf1ac377bb7e74cb840bf 100644 (file)
@@ -173,6 +173,11 @@ void ED_operatortypes_object(void)
        WM_operatortype_append(OBJECT_OT_vertex_group_copy);
        WM_operatortype_append(OBJECT_OT_vertex_group_normalize);
        WM_operatortype_append(OBJECT_OT_vertex_group_normalize_all);
+       /* Jason was here */
+       WM_operatortype_append(OBJECT_OT_vertex_group_invert_locks);
+       WM_operatortype_append(OBJECT_OT_vertex_group_lock_all);
+       WM_operatortype_append(OBJECT_OT_vertex_group_unlock_all);
+
        WM_operatortype_append(OBJECT_OT_vertex_group_invert);
        WM_operatortype_append(OBJECT_OT_vertex_group_levels);
        WM_operatortype_append(OBJECT_OT_vertex_group_blend);
index 52ba9460818d26c0aec13f36172afcb6aacf36f7..4250e7e76fbca7a2a7221e1d117920e20eda07f1 100644 (file)
@@ -846,7 +846,33 @@ static void vgroup_normalize_all(Object *ob, int lock_active)
 
        if (dvert_array) MEM_freeN(dvert_array);
 }
-
+/* Jason was here */
+static void vgroup_invert_locks(Object *ob)
+{
+       bDeformGroup *dg = ob->defbase.first;
+       while(dg) {
+               dg->flag = !dg->flag;
+               dg = dg->next;
+       }
+}
+/* Jason was here */
+static void vgroup_lock_all(Object *ob)
+{
+       bDeformGroup *dg = ob->defbase.first;
+       while(dg) {
+               dg->flag = TRUE;
+               dg = dg->next;
+       }
+}
+/* Jason was here */
+static void vgroup_unlock_all(Object *ob)
+{
+       bDeformGroup *dg = ob->defbase.first;
+       while(dg) {
+               dg->flag = FALSE;
+               dg = dg->next;
+       }
+}
 
 static void vgroup_invert(Object *ob, int auto_assign, int auto_remove)
 {
@@ -1831,7 +1857,75 @@ void OBJECT_OT_vertex_group_normalize_all(wmOperatorType *ot)
 
        RNA_def_boolean(ot->srna, "lock_active", TRUE, "Lock Active", "Keep the values of the active group while normalizing others.");
 }
+/* Jason was here */
+static int vertex_group_invert_locks_exec(bContext *C, wmOperator *op)
+{
+       Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
 
+       vgroup_invert_locks(ob);
+
+       return OPERATOR_FINISHED;
+}
+/* Jason was here */
+void OBJECT_OT_vertex_group_invert_locks(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Invert All Vertex Group Locks";
+       ot->idname= "OBJECT_OT_vertex_group_invert_locks";
+
+       /* api callbacks */
+       ot->poll= vertex_group_poll;
+       ot->exec= vertex_group_invert_locks_exec;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+/* Jason was here */
+static int vertex_group_lock_all_exec(bContext *C, wmOperator *op)
+{
+       Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+
+       vgroup_lock_all(ob);
+
+       return OPERATOR_FINISHED;
+}
+/* Jason was here */
+void OBJECT_OT_vertex_group_lock_all(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Turn on all Vertex Group Locks";
+       ot->idname= "OBJECT_OT_vertex_group_lock_all";
+
+       /* api callbacks */
+       ot->poll= vertex_group_poll;
+       ot->exec= vertex_group_lock_all_exec;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+/* Jason was here */
+static int vertex_group_unlock_all_exec(bContext *C, wmOperator *op)
+{
+       Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+
+       vgroup_unlock_all(ob);
+
+       return OPERATOR_FINISHED;
+}
+/* Jason was here */
+void OBJECT_OT_vertex_group_unlock_all(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Turn off all Vertex Group Locks";
+       ot->idname= "OBJECT_OT_vertex_group_unlock_all";
+
+       /* api callbacks */
+       ot->poll= vertex_group_poll;
+       ot->exec= vertex_group_unlock_all_exec;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
 static int vertex_group_invert_exec(bContext *C, wmOperator *op)
 {
        Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
index c9a6aa87cd0c7ec79412d0374b7b078010ecce93..3843f2e371b2c01b08d52de462941b98fbc8f50d 100644 (file)
@@ -5395,7 +5395,11 @@ int facemask_paint_poll(bContext *C)
 {
        return paint_facesel_test(CTX_data_active_object(C));
 }
-
+// Jason
+int vert_paint_poll(bContext *C)
+{
+       return paint_vertsel_test(CTX_data_active_object(C));
+}
 /* use project paint to re-apply an image */
 static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
 {
index 5a0ee19d6c935d1588d70d6e36be5bbe94b2fab7..9894469fa82d9e8346ff491b06dcfee75ad2f9e2 100644 (file)
@@ -121,6 +121,9 @@ void PAINT_OT_face_select_all(struct wmOperatorType *ot);
 void PAINT_OT_face_select_inverse(struct wmOperatorType *ot);
 void PAINT_OT_face_select_hide(struct wmOperatorType *ot);
 void PAINT_OT_face_select_reveal(struct wmOperatorType *ot);
+/* Jason */
+void PAINT_OT_vert_select_all(struct wmOperatorType *ot);
+int vert_paint_poll(struct bContext *C);
 
 int facemask_paint_poll(struct bContext *C);
 
index 69af50415cc283a453485888f7d5047193cd0523..6aab104b79ab94a6888dcdd8202eb3459ea13f0a 100644 (file)
@@ -373,6 +373,9 @@ void ED_operatortypes_paint(void)
        WM_operatortype_append(PAINT_OT_weight_sample);
        WM_operatortype_append(PAINT_OT_weight_sample_group);
 
+       /* Jason, vertex selection */
+       WM_operatortype_append(PAINT_OT_vert_select_all);
+
        /* vertex */
        WM_operatortype_append(PAINT_OT_vertex_paint_toggle);
        WM_operatortype_append(PAINT_OT_vertex_paint);
@@ -607,6 +610,16 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
 
        WM_keymap_verify_item(keymap, "PAINT_OT_weight_from_bones", WKEY, KM_PRESS, 0, 0);
 
+       // Jason
+       /*Weight paint's Vertex Selection Mode */
+       keymap= WM_keymap_find(keyconf, "Weight Paint Vertex Selection", 0, 0);
+       keymap->poll= vert_paint_poll;
+       WM_keymap_add_item(keymap, "PAINT_OT_vert_select_all", AKEY, KM_PRESS, 0, 0);
+       WM_keymap_add_item(keymap, "VIEW3D_OT_select_border", BKEY, KM_PRESS, 0, 0);
+       WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0);
+       RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_SHIFT|KM_CTRL, 0)->ptr, "deselect", 1);
+       WM_keymap_add_item(keymap, "VIEW3D_OT_select_circle", CKEY, KM_PRESS, 0, 0);
+
        /* Image/Texture Paint mode */
        keymap= WM_keymap_find(keyconf, "Image Paint", 0, 0);
        keymap->poll= image_texture_paint_poll;
index 09f5c32bea0a71c5faa7c83cc85ebfb24349651e..18f595360922e1e2abd576bfc72045d026aab8c1 100644 (file)
@@ -358,6 +358,30 @@ void PAINT_OT_face_select_all(wmOperatorType *ot)
        WM_operator_properties_select_all(ot);
 }
 
+/* Jason */
+static int vert_select_all_exec(bContext *C, wmOperator *op)
+{
+       Object *ob= CTX_data_active_object(C);
+       paintvert_deselect_all_visible(ob, RNA_enum_get(op->ptr, "action"), TRUE);
+       ED_region_tag_redraw(CTX_wm_region(C));
+       return OPERATOR_FINISHED;
+}
+
+/* Jason */
+void PAINT_OT_vert_select_all(wmOperatorType *ot)
+{
+       ot->name= "Vertex Selection";
+       ot->description= "Change selection for all vertices";
+       ot->idname= "PAINT_OT_vert_select_all";
+
+       ot->exec= vert_select_all_exec;
+       ot->poll= vert_paint_poll;
+
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       WM_operator_properties_select_all(ot);
+}
+
 static int face_select_inverse_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Object *ob= CTX_data_active_object(C);
index 3da19ba7346ebe37c74946fe846bdf20c99e8133..2ccf53a35fdbe5c3b59605c759fe2320f02f248c 100644 (file)
@@ -75,6 +75,7 @@
 #include "BKE_paint.h"
 #include "BKE_report.h"
 
+
 #include "WM_api.h"
 #include "WM_types.h"
 
@@ -385,7 +386,6 @@ void vpaint_fill(Object *ob, unsigned int paintcol)
        DAG_id_tag_update(&me->id, 0);
 }
 
-
 /* fills in the selected faces with the current weight and vertex group */
 void wpaint_fill(VPaint *wp, Object *ob, float paintweight)
 {
@@ -401,7 +401,7 @@ void wpaint_fill(VPaint *wp, Object *ob, float paintweight)
        
        me= ob->data;
        if(me==NULL || me->totface==0 || me->dvert==NULL || !me->mface) return;
-       
+
        selected= (me->editflag & ME_EDIT_PAINT_MASK);
 
        indexar= get_indexarray(me);
@@ -792,7 +792,7 @@ static float calc_vp_alpha_dl(VPaint *vp, ViewContext *vc, float vpimat[][3], fl
        return alpha;
 }
 
-static void wpaint_blend(VPaint *wp, MDeformWeight *dw, MDeformWeight *uw, float alpha, float paintval, int flip)
+static void wpaint_blend(VPaint *wp, MDeformWeight *dw, MDeformWeight *uw, float alpha, float paintval, int flip, int multipaint)
 {
        Brush *brush = paint_brush(&wp->paint);
        int tool = brush->vertexpaint_tool;
@@ -830,7 +830,8 @@ static void wpaint_blend(VPaint *wp, MDeformWeight *dw, MDeformWeight *uw, float
                if (dw->weight > paintval)
                        dw->weight = paintval*alpha + dw->weight*(1.0f-alpha);
        }
-       CLAMP(dw->weight, 0.0f, 1.0f);
+       // Jason delay clamping until the end so multi-paint can function when the active group is at the limits
+       //CLAMP(dw->weight, 0.0f, 1.0f);
        
        /* if no spray, clip result with orig weight & orig alpha */
        if((wp->flag & VP_SPRAY)==0) {
@@ -857,15 +858,16 @@ static void wpaint_blend(VPaint *wp, MDeformWeight *dw, MDeformWeight *uw, float
                        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;
+               //CLAMP(testw, 0.0f, 1.0f);
+               if(!multipaint) {
+                       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;
+                       }
                }
        }
        
@@ -1096,15 +1098,453 @@ static void do_weight_paint_auto_normalize(MDeformVert *dvert,
                }
        }
 }
+// Jason was here: the active group should be involved in auto normalize
+static void do_weight_paint_auto_normalize_all_groups(MDeformVert *dvert, char *map)
+{
+//     MDeformWeight *dw = dvert->dw;
+       float sum=0.0f, fac=0.0f;
+       int i, tot=0;
+
+       if (!map)
+               return;
+
+       for (i=0; i<dvert->totweight; i++) {
+               if (map[dvert->dw[i].def_nr]) {
+                       tot += 1;
+                       sum += dvert->dw[i].weight;
+               }
+       }
+       
+       if (!tot || sum == 1.0f)
+               return;
+
+       fac = sum;
+       fac = fac==0.0f ? 1.0f : 1.0f / fac;
+
+       for (i=0; i<dvert->totweight; i++) {
+               if (map[dvert->dw[i].def_nr]) {
+                       dvert->dw[i].weight *= fac;
+               }
+       }
+}
+/* Jason was here */
+/*
+See if the current deform vertex has a locked group
+*/
+static char has_locked_group(MDeformVert *dvert, char *flags)
+{
+       int i;
+       for(i = 0; i < dvert->totweight; i++) {
+               if(flags[(dvert->dw+i)->def_nr] && (dvert->dw+i)->weight > 0.0f) {
+                       return TRUE;
+               }
+       }
+       return FALSE;
+}
+/*Jason was here
+gen_lck_flags gets the status of "flag" for each bDeformGroup
+in ob->defbase and returns an array containing them
+*/
+static char* gen_lck_flags(Object* ob, int defcnt, char *map)
+{
+       char is_locked = FALSE;
+       int i;
+       //int defcnt = BLI_countlist(&ob->defbase);
+       char *flags = MEM_mallocN(defcnt*sizeof(char), "defflags");
+       bDeformGroup *defgroup;
+       int selected = 0;
+
+       for(i = 0, defgroup = ob->defbase.first; i < defcnt && defgroup; defgroup = defgroup->next, i++) {
+               flags[i] = defgroup->flag;
+               if(flags[i]) {
+                       is_locked = TRUE;
+               }
+       }
+       if(is_locked){
+               return flags;
+       }
+       // don't forget to free it if it is unneeded
+       MEM_freeN(flags);
+       return NULL;
+}
+/* Jason was here */
+static int has_locked_group_selected(int defcnt, char *selection, char *flags) {
+       int i;
+       for(i = 0; i < defcnt; i++) {
+               if(selection[i] && flags[i]) {
+                       return TRUE;
+               }
+       }
+       return FALSE;
+}
+
+/* Jason was here */
+static int has_unselected_unlocked_bone_group(int defcnt, char *selection, int selected, char *flags, char *bone_groups) {
+       int i;
+       if(defcnt == selected) {
+               return FALSE;
+       }
+       for(i = 0; i < defcnt; i++) {
+               if(bone_groups[i] && !selection[i] && !flags[i]) {
+                       return TRUE;
+               }
+       }
+       return FALSE;
+}
+
+/*Jason*/
+static void multipaint_selection(MDeformVert *dvert, float change, char *selection, int defcnt) {
+       int i;
+       MDeformWeight *dw;
+       float val;
+       // make sure they are all at most 1 after the change
+       for(i = 0; i < defcnt; i++) {
+               if(selection[i]) {
+                       dw = defvert_find_index(dvert, i);
+                       if(dw && dw->weight) {
+                               val = dw->weight * change;
+                               if(val > 1) {
+                                       // Jason TODO: when the change is reduced, you need to recheck the earlier values to make sure they are not 0 (precision error)
+                                       change = 1.0f/dw->weight;
+                               }
+                               // the value should never reach zero while multi-painting if it was nonzero beforehand
+                               if(val <= 0) {
+                                       return;
+                               }
+                       }
+               }
+       }
+       // apply the valid change
+       for(i = 0; i < defcnt; i++) {
+               if(selection[i]) {
+                       dw = defvert_find_index(dvert, i);
+                       if(dw && dw->weight) {
+                               dw->weight = dw->weight * change;
+                       }
+               }
+       }
+}
+/*Jason*/
+// move all change onto valid, unchanged groups.  If there is change left over, then return it.
+// assumes there are valid groups to shift weight onto
+static float redistribute_change(MDeformVert *ndv, char *change_status, int changeme, int changeto, char *validmap, float totchange, float total_valid) {
+       float was_change;
+       float change;
+       float oldval;
+       MDeformWeight *ndw;
+       int i;
+       do {
+               // assume there is no change until you see one
+               was_change = FALSE;
+               // change each group by the same amount each time
+               change = totchange/total_valid;
+               for(i = 0; i < ndv->totweight && total_valid && totchange; i++) {
+                       ndw = (ndv->dw+i);
+                       // change only the groups with a valid status
+                       if(change_status[ndw->def_nr] == changeme) {
+                               oldval = ndw->weight;
+                               // if auto normalize is active, don't worry about upper bounds
+                               if(!validmap && ndw->weight + change > 1) {
+                                       totchange -= 1-ndw->weight;
+                                       ndw->weight = 1;
+                                       // stop the changes to this group
+                                       change_status[ndw->def_nr] = changeto;
+                                       total_valid--;
+                               } else if(ndw->weight + change < 0) { // check the lower bound
+                                       totchange -= ndw->weight;
+                                       ndw->weight = 0;
+                                       change_status[ndw->def_nr] = changeto;
+                                       total_valid--;
+                               } else {// a perfectly valid change occurred to ndw->weight
+                                       totchange -= change;
+                                       ndw->weight += change;
+                               }
+                               // see if there was a change
+                               if(oldval != ndw->weight) {
+                                       was_change = TRUE;
+                               }
+                       }
+               }
+       // don't go again if there was no change, if there is no valid group, or there is no change left
+       }while(was_change && total_valid && totchange);
+       // left overs
+       return totchange;
+}
+/*Jason*/
+// observe the changes made to the weights of groups.
+// make sure all locked groups on the vertex have the same deformation
+// by moving the changes made to groups onto other unlocked groups
+static void enforce_locks(MDeformVert *odv, MDeformVert *ndv, int defcnt, char *flags, char *bone_groups, char *validmap) {
+       float totchange = 0.0f;
+       float totchange_allowed = 0.0f;
+       float left_over;
+       float change;
+       int total_valid = 0;
+       int total_changed = 0;
+       int i;
+       MDeformWeight *ndw;
+       MDeformWeight *odw;
+       MDeformWeight *ndw2;
+       MDeformWeight *odw2;
+       int designatedw = -1;
+       int designatedw_changed = FALSE;
+       float storedw;
+       char *change_status;
+       char new_weight_has_zero = FALSE;
+
+       if(!flags || !has_locked_group(ndv, flags)) {
+               return;
+       }
+       // record if a group was changed, unlocked and not changed, or locked
+       change_status = MEM_callocN(sizeof(char)*defcnt, "unlocked_unchanged");
+
+       for(i = 0; i < defcnt; i++) {
+               ndw = defvert_find_index(ndv, i);
+               odw = defvert_find_index(odv, i);
+               // the weights are zero, so we can assume a lot
+               if(!ndw || !odw) {
+                       if (!flags[i] && bone_groups[i]){
+                               defvert_verify_index(odv, i);
+                               defvert_verify_index(ndv, i);
+                               total_valid++;
+                               change_status[i] = 1; // can be altered while redistributing
+                       }
+                       continue;
+               }
+               // locked groups should not be changed
+               if(flags[i]) {
+                       ndw->weight = odw->weight;
+               } else if(ndw->weight != odw->weight) { // changed groups are handled here
+                       totchange += ndw->weight-odw->weight;
+                       change_status[i] = 2; // was altered already
+                       total_changed++;
+                       if(ndw->weight == 0) {
+                               new_weight_has_zero = TRUE;
+                       } else if(designatedw == -1){
+                               designatedw = i;
+                       }
+               } // unchanged, unlocked bone groups are handled here
+               else if (bone_groups[i]){
+                       totchange_allowed += ndw->weight;
+                       total_valid++;
+                       change_status[i] = 1; // can be altered while redistributing
+               }
+       }
+       // if there was any change, redistribute it
+       if(total_changed) {
+               // auto normalize will allow weights to temporarily go above 1 in redistribution
+               if(validmap && total_changed < 0 && total_valid) {
+                       totchange_allowed = total_valid;
+               }
+               // there needs to be change allowed, or you should not bother
+               if(totchange_allowed) {
+                       // the way you modify the unlocked+unchanged groups is different depending
+                       // on whether or not you are painting the weight(s) up or down
+                       if(totchange < 0) {
+                               totchange_allowed = total_valid - totchange_allowed;
+                       } else {
+                               totchange_allowed *= -1;
+                       }
+                       left_over = 0;
+                       if(fabs(totchange_allowed) < fabs(totchange)) {
+                               // this amount goes back onto the changed, unlocked weights
+                               left_over = fabs(fabs(totchange)-fabs(totchange_allowed));
+                               if(totchange > 0) {
+                                       left_over *= -1;
+                               }
+                       }else {
+                               // all of the change will be permitted
+                               totchange_allowed = -totchange;
+                       }
+                       // move the weight evenly between the allowed groups, move excess back onto the used groups based on the change
+                       totchange_allowed = redistribute_change(ndv, change_status, 1, -1, validmap, totchange_allowed, total_valid);
+                       left_over += totchange_allowed;
+                       if(left_over) {
+                               // more than one nonzero weights were changed with the same ratio, so keep them changed that way!
+                               if(total_changed > 1 && !new_weight_has_zero && designatedw >= 0) {
+                                       // this dw is special, it is used as a base to determine how to change the others
+                                       ndw = defvert_find_index(ndv, designatedw);
+                                       odw = defvert_find_index(odv, designatedw);
+                                       storedw = ndw->weight;
+                                       for(i = 0; i < ndv->totweight; i++) {
+                                               if(change_status[ndw->def_nr] == 2) {
+                                                       odw2 = (odv->dw+i);
+                                                       ndw2 = (ndv->dw+i);
+                                                       if(!designatedw_changed) {
+                                                               ndw->weight = (totchange_allowed + odw->weight + odw2->weight)/(1 + ndw2->weight/ndw->weight);
+                                                               designatedw_changed = TRUE;
+                                                       }
+                                                       ndw2->weight = ndw->weight*ndw2->weight/storedw;
+                                               }
+                                       }
+                               }
+                               // a weight was changed to zero, only one weight was changed, or designatedw is still -1
+                               // put weight back as evenly as possible
+                               else {
+                                       redistribute_change(ndv, change_status, 2, -2, validmap, left_over, total_changed);
+                               }
+                       }
+               } else {
+                       // reset the weights
+                       for(i = 0; i < ndv->totweight; i++) {
+                               (ndv->dw+i)->weight = (odv->dw+i)->weight;
+                       }
+               }
+       }
+
+       MEM_freeN(change_status);
+}
+/*Jason*/
+// multi-paint's initial, potential change is computed here based on the user's stroke
+static float get_mp_change(MDeformVert *odv, char *selection, float brush_change) {
+       float selwsum = 0.0f;
+       int i;
+       MDeformWeight *dw;
+       for(i=0; i < odv->totweight; i++) {
+               if(selection[(dw = (odv->dw+i))->def_nr]) {
+                       selwsum += dw->weight;
+               }
+       }
+       if(selwsum && selwsum+brush_change > 0) {
+               return (selwsum+brush_change)/selwsum;
+       }
+       return 0.0f;
+}
+/*Jason*/
+// change the weights back to the wv's weights
+// it assumes you already have the correct pointer index
+static void reset_to_prev(MDeformVert *wv, MDeformVert *dv) {
+       int i;
+       MDeformWeight *d;
+       MDeformWeight *w;
+       for(i = 0; i < dv->totweight; i++) {
+               d = dv->dw+i;
+               w = defvert_find_index(wv, d->def_nr);
+               // if there was no w when there is a d, then the old weight was 0
+               if(w) {
+                       d->weight = w->weight;
+               } else {
+                       d->weight = 0;
+               }
+       }
+}
+/* Jason */
+static void clamp_weights(MDeformVert *dvert) {
+       int i;
+       for (i = 0; i < dvert->totweight; i++) {
+               CLAMP((dvert->dw+i)->weight, 0.0f, 1.0f);
+       }
+}
+/*Jason*/
+/* fresh start to make multi-paint and locking modular */
+static void apply_mp_lcks_normalize(Object *ob, Mesh *me, int index, MDeformWeight *dw, int defcnt, float change, float oldw, float neww, char *selection, int selected, char *bone_groups, char *validmap, char *flags, int multipaint) {
+       MDeformVert *dvert = me->dvert+index;
+       MDeformVert *dv = MEM_mallocN(sizeof (*(me->dvert+index)), "oldMDeformVert");
+
+       int i;
+
+       dv->dw= MEM_dupallocN(dvert->dw);
+       dv->flag = dvert->flag;
+       dv->totweight = dvert->totweight;
+       // do not multi-paint if a locked group is selected or the active group is locked
+       // !flags[dw->def_nr] helps if nothing is selected, but active group is locked
+       if(!flags || flags && !has_locked_group_selected(defcnt, selection, flags) && !flags[dw->def_nr]) {
+               if(multipaint && selected > 1) {
+                       if(change && change!=1) {
+                               multipaint_selection(dvert, change, selection, defcnt);
+                       }
+               } else {// this lets users paint normally, but don't let them paint locked groups
+                       dw->weight = neww;
+               }
+       }
+       clamp_weights(me->dvert+index);
+
+       enforce_locks(dv, dvert, defcnt, flags, bone_groups, validmap);
+
+       do_weight_paint_auto_normalize_all_groups(dvert, validmap);
+       
+       MEM_freeN(dv->dw);
+       MEM_freeN(dv);
+}
+
+/* Jason was here duplicate function I used in DerivedMesh.c*/
+static char* get_selected_defgroups(Object *ob, int defcnt) {
+       bPoseChannel *chan;
+       bPose *pose;
+       bDeformGroup *defgroup;
+       //Bone *bone;
+       char *dg_flags = MEM_callocN(defcnt*sizeof(char), "dg_selected_flags");
+       int i;
+       Object *armob = ED_object_pose_armature(ob);
+
+       if(armob) {
+               pose = armob->pose;
+               for (chan=pose->chanbase.first; chan; chan=chan->next) {
+                       for (i = 0, defgroup = ob->defbase.first; i < defcnt && defgroup; defgroup = defgroup->next, i++) {
+                               if(!strcmp(defgroup->name, chan->bone->name)) {
+                                       dg_flags[i] = (chan->bone->flag & BONE_SELECTED);
+                               }
+                       }
+               }
+       }
+       // the array has whether or not the corresponding group is selected
+       return dg_flags;
+}
+/* TODO move duplicates to header */
+/* Jason was here duplicate function */
+static int count_true(char *list, int len)
+{
+       int i;
+       int cnt = 0;
+       for(i = 0; i < len; i++) {
+               if (list[i]) {
+                       cnt++;
+               }
+       }
+       return cnt;
+}
+// within the current dvert index, get the dw that is selected and has a weight above 0
+// this helps multi-paint
+static int get_first_selected_nonzero_weight(MDeformVert *dvert, char *selection) {
+       int i;
+       MDeformWeight *dw;
+       for(i=0; i< dvert->totweight; i++) {
+               dw = dvert->dw+i;
+               if(selection[dw->def_nr] && dw->weight > 0) {
+                       return i;
+               }
+       }
+       return -1;
+}
+// Jason
+static char *wpaint_make_validmap(Object *ob);
 
 static void do_weight_paint_vertex(VPaint *wp, Object *ob, int index, 
                                   float alpha, float paintweight, int flip, 
-                                  int vgroup_mirror, char *validmap)
+                                  int vgroup_mirror, char *validmap, int multipaint)
 {
        Mesh *me= ob->data;
-       MDeformWeight *dw, *uw;
+       MDeformWeight *dw, *uw, *tdw, *tuw;
        int vgroup= ob->actdef-1;
-       
+
+       /* Jason was here */
+       char *flags;
+       char *bone_groups;
+       char *selection;
+       int selected;
+       float oldw;
+       float neww;
+       float testw;
+       int defcnt;
+       float change = 0;
+       int i;
+       // Need to know which groups are bone groups
+       if(validmap) {
+               bone_groups = validmap;
+       }else {
+               bone_groups = wpaint_make_validmap(ob);
+       }
+
        if(wp->flag & VP_ONLYVGROUP) {
                dw= defvert_find_index(me->dvert+index, vgroup);
                uw= defvert_find_index(wp->wpaint_prev+index, vgroup);
@@ -1115,9 +1555,60 @@ static void do_weight_paint_vertex(VPaint *wp, Object *ob, int index,
        }
        if(dw==NULL || uw==NULL)
                return;
+       /* Jason was here */
+       flags = gen_lck_flags(ob, defcnt = BLI_countlist(&ob->defbase), bone_groups);
+       selection = get_selected_defgroups(ob, defcnt);
+       selected = count_true(selection, defcnt);
+       if(!selected && ob->actdef) {
+               selected = 1;
+       }
        
-       wpaint_blend(wp, dw, uw, alpha, paintweight, flip);
-       do_weight_paint_auto_normalize(me->dvert+index, vgroup, validmap);
+       oldw = dw->weight;
+       wpaint_blend(wp, dw, uw, alpha, paintweight, flip, multipaint && selected >1);
+       neww = dw->weight;
+       dw->weight = oldw;
+       // setup multi-paint
+       if(selected > 1 && multipaint) {
+               tdw = dw;
+               tuw = uw;
+               change = get_mp_change(wp->wpaint_prev+index, selection, neww-oldw);
+               if(change) {
+                       if(!tdw->weight) {
+                               i = get_first_selected_nonzero_weight(me->dvert+index, selection);
+                               if(i>=0) {
+                                       tdw = ((me->dvert+index)->dw+i);
+                                       tuw = defvert_verify_index(wp->wpaint_prev+index, tdw->def_nr);
+                               } else {
+                                       change = 0;
+                               }
+                       }
+                       if(change && tdw->weight * change && tuw->weight) {
+                               if(tdw->weight != tuw->weight) {
+                                       testw = tuw->weight*change;
+                                       if( testw > tuw->weight ) {
+                                               if(change > tdw->weight/tuw->weight) {
+                                                       reset_to_prev(wp->wpaint_prev+index, me->dvert+index);
+                                               } else {
+                                                       change = 0;
+                                               }
+                                       } else {
+                                               if(change < tdw->weight/tuw->weight) {
+                                                       reset_to_prev(wp->wpaint_prev+index, me->dvert+index);
+                                               } else {
+                                                       change = 0;
+                                               }
+                                       }
+                               }
+                       } else {
+                               change = 0;
+                       }
+               }
+       }
+       /* Jason was here */
+       apply_mp_lcks_normalize(ob, me, index, dw, defcnt, change, oldw, neww, selection, selected, bone_groups, validmap, flags, multipaint);
+
+       // dvert may have been altered greatly
+       dw = defvert_find_index(me->dvert+index, vgroup);
 
        if(me->editflag & ME_EDIT_MIRROR_X) {   /* x mirror painting */
                int j= mesh_get_x_mirror_vert(ob, index);
@@ -1127,15 +1618,22 @@ static void do_weight_paint_vertex(VPaint *wp, Object *ob, int index,
                                uw= defvert_verify_index(me->dvert+j, vgroup_mirror);
                        else
                                uw= defvert_verify_index(me->dvert+j, vgroup);
-                               
-                       uw->weight= dw->weight;
-
-                       do_weight_paint_auto_normalize(me->dvert+j, vgroup, validmap);
+                       /* Jason */
+                       //uw->weight= dw->weight;
+                       /* Jason */
+                       apply_mp_lcks_normalize(ob, me, j, uw, defcnt, change, oldw, neww, selection, selected, bone_groups, validmap, flags, multipaint);
                }
        }
+       /* Jason */
+       if(flags) {
+               MEM_freeN(flags);
+       }
+       MEM_freeN(selection);
+       if(!validmap) {
+               MEM_freeN(bone_groups);
+       }
 }
 
-
 /* *************** set wpaint operator ****************** */
 
 static int set_wpaint(bContext *C, wmOperator *UNUSED(op))             /* toggle */
@@ -1297,7 +1795,7 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, wmEvent *UNUSED
        struct WPaintData *wpd;
        Mesh *me;
        float mat[4][4], imat[4][4];
-       
+
        if(scene->obedit) return OPERATOR_CANCELLED;
        
        me= get_mesh(ob);
@@ -1308,13 +1806,14 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, wmEvent *UNUSED
                ED_vgroup_data_create(&me->id);
                WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
        }
-       
+
+
        /* make mode data storage */
        wpd= MEM_callocN(sizeof(struct WPaintData), "WPaintData");
        paint_stroke_set_mode_data(stroke, wpd);
        view3d_set_viewcontext(C, &wpd->vc);
        wpd->vgroup_mirror= -1;
-       
+
        /*set up auto-normalize, and generate map for detecting which
          vgroups affect deform bones*/
        wpd->auto_normalize = ts->auto_normalize;
@@ -1369,7 +1868,7 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, wmEvent *UNUSED
        if(me->editflag & ME_EDIT_MIRROR_X) {
                wpaint_mirror_vgroup_ensure(ob, &wpd->vgroup_mirror);
        }
-       
+
        return 1;
 }
 
@@ -1501,7 +2000,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
                                if(alpha) {
                                        do_weight_paint_vertex(wp, ob, mface->v1, 
                                                alpha, paintweight, flip, wpd->vgroup_mirror, 
-                                               wpd->vgroup_validmap);
+                                               wpd->vgroup_validmap, ts->multipaint);
                                }
                                (me->dvert+mface->v1)->flag= 0;
                        }
@@ -1511,7 +2010,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
                                if(alpha) {
                                        do_weight_paint_vertex(wp, ob, mface->v2, 
                                                alpha, paintweight, flip, wpd->vgroup_mirror, 
-                                               wpd->vgroup_validmap);
+                                               wpd->vgroup_validmap, ts->multipaint);
                                }
                                (me->dvert+mface->v2)->flag= 0;
                        }
@@ -1521,7 +2020,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
                                if(alpha) {
                                        do_weight_paint_vertex(wp, ob, mface->v3, 
                                                alpha, paintweight, flip, wpd->vgroup_mirror, 
-                                               wpd->vgroup_validmap);
+                                               wpd->vgroup_validmap, ts->multipaint);
                                }
                                (me->dvert+mface->v3)->flag= 0;
                        }
@@ -1532,7 +2031,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
                                        if(alpha) {
                                                do_weight_paint_vertex(wp, ob, mface->v4, 
                                                        alpha, paintweight, flip, wpd->vgroup_mirror,
-                                                       wpd->vgroup_validmap);
+                                                       wpd->vgroup_validmap, ts->multipaint);
                                        }
                                        (me->dvert+mface->v4)->flag= 0;
                                }
index e314d249e6d44040be888af3594974275420638d..67ac571db1d191db5dd7c514df132d87e70ea367 100644 (file)
@@ -58,6 +58,7 @@
 #include "BKE_anim.h"                  //for the where_on_path function
 #include "BKE_constraint.h" // for the get_constraint_target function
 #include "BKE_DerivedMesh.h"
+
 #include "BKE_deform.h"
 #include "BKE_displist.h"
 #include "BKE_font.h"
@@ -1657,7 +1658,45 @@ void mesh_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, EditVe
 
        dm->release(dm);
 }
+/*Jason */
+static void mesh_obmode_foreachScreenVert__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
+{
+       struct { void (*func)(void *userData, MVert *mv, int x, int y, int index); void *userData; ViewContext vc; int clipVerts; } *data = userData;
+       Mesh *me = data->vc.obact->data;
+       MVert *mv = me->mvert+index;
+       //MVert *dmv = CDDM_get_verts(data->vc.obact->derivedFinal)+index;
+       //MVert *mv = CDDM_get_verts(data->vc.obact->derivedFinal)+index;
+       if ((mv->flag & ME_HIDE)==0) {
+               short s[2]= {IS_CLIPPED, 0};
 
+               if (data->clipVerts) {
+                       view3d_project_short_clip(data->vc.ar, co, s, 1);
+               } else {
+                       view3d_project_short_noclip(data->vc.ar, co, s);
+               }
+
+               if (s[0]!=IS_CLIPPED)
+                       data->func(data->userData, mv, s[0], s[1], index);
+       }
+}
+/*Jason*/
+void mesh_obmode_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, MVert *mv, int x, int y, int index), void *userData, int clipVerts)
+{
+       struct { void (*func)(void *userData, MVert *mv, int x, int y, int index); void *userData; ViewContext vc; int clipVerts; } data;
+       DerivedMesh *dm = mesh_get_derived_final(vc->scene, vc->obact, CD_MASK_BAREMESH);
+
+       data.vc= *vc;
+       data.func = func;
+       data.userData = userData;
+       data.clipVerts = clipVerts;
+       
+       if(clipVerts)
+               ED_view3d_local_clipping(vc->rv3d, vc->obact->obmat); /* for local clipping lookups */
+
+       dm->foreachMappedVert(dm, mesh_obmode_foreachScreenVert__mapFunc, &data);
+
+       dm->release(dm);
+}
 static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, float *v0co, float *v1co)
 {
        struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; ViewContext vc; int clipVerts; } *data = userData;
@@ -2737,6 +2776,16 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
                                glDisable(GL_LIGHTING);
 
                                GPU_disable_material();
+                               // Jason
+                               if(paint_vertsel_test(ob)) {
+                                       glColor3f(0.0f, 0.0f, 0.0f);
+                                       glPointSize(2.0f);
+                                       dm->drawEdges(dm, (dt==OB_WIRE || totface==0), me->drawflag);
+                                       glPointSize(3.0f);
+                                       dm->drawSelectedVerts(dm);
+                                       //draw_obmode_dm_verts(dm, 1);
+                                       glPointSize(1.0f);
+                               }
                        }
                        else if(ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_TEXTURE_PAINT)) {
                                if(me->mcol)
index 6833dec2e4373813176debedee88ffcb55e3fdbc..8773a67447f184c53ab5c657e28c20e6f590f994 100644 (file)
@@ -371,6 +371,10 @@ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar)
        keymap= WM_keymap_find(wm->defaultconf, "Face Mask", 0, 0);
        WM_event_add_keymap_handler(&ar->handlers, keymap);
        
+       /* Jason */
+       keymap= WM_keymap_find(wm->defaultconf, "Weight Paint Vertex Selection", 0, 0);
+       WM_event_add_keymap_handler(&ar->handlers, keymap);
+
        /* pose is not modal, operator poll checks for this */
        keymap= WM_keymap_find(wm->defaultconf, "Pose", 0, 0);
        WM_event_add_keymap_handler(&ar->handlers, keymap);
index 75c8d5cae73110c7628f60d629da4f8c3f7042e0..a1a73b27b8dc97c4e6e900dfd9330af85767761e 100644 (file)
@@ -495,9 +495,13 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
                /* Manipulators aren't used in weight paint mode */
                
                PointerRNA meshptr;
-
                RNA_pointer_create(&ob->id, &RNA_Mesh, ob->data, &meshptr);
-               uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+               //uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+               // Jason
+               row= uiLayoutRow(layout, 1);
+               // TODO: make it so at most one can be active.
+               uiItemR(row, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+               uiItemR(row, &meshptr, "wp_vert_sel", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
        } else {
                const char *str_menu;
 
index 9290e1fc631748db451a00e595aaa126c00abc01..94049e6d3858211211ccbcc8de5d9e5b33afbf39 100644 (file)
@@ -197,6 +197,22 @@ static void EM_backbuf_checkAndSelectFaces(EditMesh *em, int select)
                }
        }
 }
+/* Jason */
+static void EM_backbuf_checkAndSelectTVerts(Mesh *me, int select)
+{
+       MVert *mv = me->mvert;
+       int a;
+
+       if (mv) {
+               for(a=1; a<=me->totvert; a++, mv++) {
+                       if(EM_check_backbuf(a)) {
+                               if(!(mv->flag & ME_HIDE)) {
+                                       mv->flag = select?(mv->flag|SELECT):(mv->flag&~SELECT);
+                               }
+                       }
+               }
+       }
+}
 
 static void EM_backbuf_checkAndSelectTFaces(Mesh *me, int select)
 {
@@ -231,7 +247,7 @@ static int view3d_selectable_data(bContext *C)
                        if (ob->mode & OB_MODE_SCULPT) {
                                return 0;
                        }
-                       if (ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT) && !paint_facesel_test(ob)) {
+                       if (ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT) && !paint_facesel_test(ob) && !paint_vertsel_test(ob)) {//Jason
                                return 0;
                        }
                }
@@ -625,7 +641,15 @@ static void do_lasso_select_curve(ViewContext *vc, int mcords[][2], short moves,
        ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
        nurbs_foreachScreenVert(vc, do_lasso_select_curve__doSelect, &data);
 }
+/* Jason */
+static void do_obmode_lasso_select__doSelect(void *userData, MVert *mv, int x, int y)
+{
+       struct { int (*mcords)[2]; short moves; short select; } *data = userData;
 
+       if (lasso_inside(data->mcords, data->moves, x, y)) {
+               mv->flag = data->select?(mv->flag|SELECT):(mv->flag&~SELECT);
+       }
+}
 static void do_lasso_select_lattice__doSelect(void *userData, BPoint *bp, int x, int y)
 {
        struct { int (*mcords)[2]; short moves; short select; } *data = userData;
@@ -726,7 +750,63 @@ static void do_lasso_select_meta(ViewContext *vc, int mcords[][2], short moves,
                }
        }
 }
+/* Jason */
+static void do_obmode_box_select__doSelect(void *userData, MVert *mv, int x, int y)
+{
+       struct { ViewContext vc; rcti *rect; int select; } *data = userData;
+
+       if (BLI_in_rcti(data->rect, x, y)) {
+               mv->flag = data->select?(mv->flag|SELECT):(mv->flag&~SELECT);
+       }
+}
+/* Jason */
+int do_paintvert_box_select(ViewContext *vc, rcti *rect, int select, int extend)
+{
+       Object *ob= vc->obact;
+       Mesh *me= ob?ob->data:NULL;
+       int sx= rect->xmax-rect->xmin+1;
+       int sy= rect->ymax-rect->ymin+1;
+
+       struct { ViewContext vc; rcti *rect; int select; } data = {NULL};
+
+       if(me==NULL || me->totvert==0 || sx*sy <= 0)
+               return OPERATOR_CANCELLED;
+
+       if(extend==0 && select)
+               paintvert_deselect_all_visible(ob, SEL_DESELECT, FALSE); /* flush selection at the end */
+
+       ED_view3d_init_mats_rv3d(ob, vc->rv3d);
+       data.vc = *vc;
+       data.rect = rect;
+       data.select= select;
+
+       mesh_obmode_foreachScreenVert(vc, do_obmode_box_select__doSelect, &data, 1);
+
+       paintvert_flush_flags(ob);
+
+       return OPERATOR_FINISHED;
+}
+/* Jason */
+static void do_lasso_select_paintvert(ViewContext *vc, int mcords[][2], short moves, short extend, short select)
+{
+       Object *ob= vc->obact;
+       Mesh *me= ob?ob->data:NULL;
+
+       struct { int (*mcords)[2]; short moves; short select; } data = {NULL};
+
+       if(me==NULL || me->totvert==0)
+               return;
+
+       if(extend==0 && select)
+               paintvert_deselect_all_visible(ob, SEL_DESELECT, FALSE); /* flush selection at the end */
+       ED_view3d_init_mats_rv3d(ob, vc->rv3d);
+       data.select = select;
+       data.mcords = mcords;
+       data.moves= moves;
+       mesh_obmode_foreachScreenVert(vc, do_obmode_lasso_select__doSelect, &data, 1);
 
+       paintvert_flush_flags(ob);
+}
 static void do_lasso_select_paintface(ViewContext *vc, int mcords[][2], short moves, short extend, short select)
 {
        Object *ob= vc->obact;
@@ -789,6 +869,8 @@ static void view3d_lasso_select(bContext *C, ViewContext *vc, int mcords[][2], s
        if(vc->obedit==NULL) { /* Object Mode */
                if(paint_facesel_test(ob))
                        do_lasso_select_paintface(vc, mcords, moves, extend, select);
+               else if(paint_vertsel_test(ob))
+                       do_lasso_select_paintvert(vc, mcords, moves, extend, select);
                else if(ob && ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT))
                        ;
                else if(ob && ob->mode & OB_MODE_PARTICLE_EDIT)
@@ -1792,6 +1874,9 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op)
                else if(vc.obact && paint_facesel_test(vc.obact)) {
                        ret= do_paintface_box_select(&vc, &rect, select, extend);
                }
+               else if(vc.obact && paint_vertsel_test(vc.obact)) {
+                       ret= do_paintvert_box_select(&vc, &rect, select, extend);
+               }
                else if(vc.obact && vc.obact->mode & OB_MODE_PARTICLE_EDIT) {
                        ret= PE_border_select(C, &rect, select, extend);
                }
@@ -1827,6 +1912,70 @@ void VIEW3D_OT_select_border(wmOperatorType *ot)
        /* rna */
        WM_operator_properties_gesture_border(ot, TRUE);
 }
+/*Jason*/
+static void findnearestWPvert__doClosest(void *userData, MVert *mv, int x, int y, int index)
+{
+       struct { MVert *mv; short dist, select; int mval[2]; } *data = userData;
+       float temp = abs(data->mval[0]-x) + abs(data->mval[1]-y);
+       mv = mv+index;
+       if((mv->flag & SELECT)==data->select)
+               temp += 5;
+
+       if(temp<data->dist) {
+               data->dist = temp;
+
+               data->mv = mv;
+       }
+}
+/*Jason*/
+static MVert *findnearestWPvert(ViewContext *vc, Object *obact, Mesh *me, const int mval[2], int sel)
+{
+       /* sel==1: selected gets a disadvantage */
+       struct { MVert *mv; short dist, select; int mval[2]; } data = {NULL};
+
+       data.dist = 100;
+       data.select = sel;
+       data.mval[0]= mval[0];
+       data.mval[1]= mval[1];
+
+       mesh_obmode_foreachScreenVert(vc, findnearestWPvert__doClosest, &data, 1);
+
+       return data.mv;
+}
+/* Jason */
+/* mouse selection in weight paint */
+/* gets called via generic mouse select operator */
+int mouse_wp_select(bContext *C, const int mval[2], short extend, Object *obact, Mesh* me)
+{
+       MVert *mv;
+       ViewContext *vc = NULL;
+       vc = MEM_callocN(sizeof(ViewContext), "wp_m_sel_viewcontext");
+       vc->ar= CTX_wm_region(C);
+       vc->scene= CTX_data_scene(C);
+       vc->v3d= CTX_wm_view3d(C);
+       vc->rv3d= CTX_wm_region_view3d(C);
+       vc->obact= obact;
+       vc->mval[0] = mval[0];
+       vc->mval[1] = mval[1];
+
+       ED_view3d_init_mats_rv3d(obact, vc->rv3d);
+
+       if(mv = findnearestWPvert(vc, obact, me, mval, 1)) {
+               if(extend) {
+                       mv->flag ^= 1;
+               } else {
+                       paintvert_deselect_all_visible(obact, SEL_DESELECT, FALSE);
+                       mv->flag |= 1;
+               }
+               paintvert_flush_flags(obact);
+               WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obact->data);
+
+               MEM_freeN(vc);
+               return 1;
+       }
+       MEM_freeN(vc);
+       return 0;
+}
 
 /* ****** Mouse Select ****** */
 
@@ -1839,9 +1988,11 @@ static int view3d_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
        short center= RNA_boolean_get(op->ptr, "center");
        short enumerate= RNA_boolean_get(op->ptr, "enumerate");
        int     retval = 0;
+       // Jason
+       Mesh *me;
+       Scene *scene = CTX_data_scene(C);
 
        view3d_operator_needs_opengl(C);
-       
        if(obedit) {
                if(obedit->type==OB_MESH)
                        retval = mouse_mesh(C, event->mval, extend);
@@ -1861,8 +2012,12 @@ static int view3d_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
                return PE_mouse_particles(C, event->mval, extend);
        else if(obact && paint_facesel_test(obact))
                retval = paintface_mouse_select(C, obact, event->mval, extend);
-       else
+       /*Jason*/
+       else if (paint_vertsel_test(obact) && (me = (Mesh*)(obact->data))) {
+               retval = mouse_wp_select(C, event->mval, extend, obact, me);
+       } else {
                retval = mouse_select(C, event->mval, extend, center, enumerate);
+       }
 
        /* passthrough allows tweaks
         * FINISHED to signal one operator worked
@@ -1906,6 +2061,18 @@ static void mesh_circle_doSelectVert(void *userData, EditVert *eve, int x, int y
                eve->f = data->select?(eve->f|1):(eve->f&~1);
        }
 }
+/* Jason */
+static void mesh_obmode_circle_doSelectVert(void *userData, MVert *mv, int x, int y, int UNUSED(index))
+{
+       struct {ViewContext *vc; short select; int mval[2]; float radius; } *data = userData;
+       int mx = x - data->mval[0], my = y - data->mval[1];
+       float r = sqrt(mx*mx + my*my);
+
+       if (r<=data->radius) {
+               mv->flag = data->select?(mv->flag|1):(mv->flag&~1);
+       }
+}
+
 static void mesh_circle_doSelectEdge(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int UNUSED(index))
 {
        struct {ViewContext *vc; short select; int mval[2]; float radius; } *data = userData;
@@ -1985,6 +2152,27 @@ static void paint_facesel_circle_select(ViewContext *vc, int select, const int m
        }
 }
 
+/* Jason */
+static void paint_vertsel_circle_select(ViewContext *vc, int select, const int mval[2], float rad)
+{
+       Object *ob= vc->obact;
+       Mesh *me = ob?ob->data:NULL;
+
+       struct {ViewContext *vc; short select; int mval[2]; float radius; } data = {NULL};
+       if (me) {
+               ED_view3d_init_mats_rv3d(ob, vc->rv3d);
+               data.radius = rad;
+               data.vc = vc;
+               data.select = select;
+               data.mval[0]= mval[0];
+               data.mval[1]= mval[1];
+
+               mesh_obmode_foreachScreenVert(vc, mesh_obmode_circle_doSelectVert, &data, 1);
+
+               paintvert_flush_flags(ob);
+       }
+}
+
 
 static void nurbscurve_circle_doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y)
 {
@@ -2239,8 +2427,8 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
        int select;
        
        select= (gesture_mode==GESTURE_MODAL_SELECT);
-
-       if( CTX_data_edit_object(C) || paint_facesel_test(obact) ||
+                                                                                                                               // Jason
+       if( CTX_data_edit_object(C) || paint_facesel_test(obact) || paint_vertsel_test(obact) ||
                (obact && (obact->mode & (OB_MODE_PARTICLE_EDIT|OB_MODE_POSE))) )
        {
                ViewContext vc;
@@ -2259,6 +2447,10 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
                else if(paint_facesel_test(obact)) {
                        paint_facesel_circle_select(&vc, select, mval, (float)radius);
                        WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obact->data);
+               }/* Jason */
+               else if(paint_vertsel_test(obact)) {
+                       paint_vertsel_circle_select(&vc, select, mval, (float)radius);
+                       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obact->data);
                }
                else if(obact->mode & OB_MODE_POSE)
                        pose_circle_select(&vc, select, mval, (float)radius);
index 6ad60ac2df9c1f9baf025c68dbd04266c54e9790..bbd21a89f0a2b96dad1db7b19778ed37d3906eee 100644 (file)
@@ -125,7 +125,7 @@ typedef struct TFace {
 
 #define ME_EDIT_PAINT_MASK (1 << 3)
 #define ME_EDIT_MIRROR_TOPO (1 << 4)
-
+#define ME_EDIT_VERT_SEL (1 << 5)// Jason
 
 /* me->flag */
 /* #define ME_ISDONE           1 */
index dfc7d42793d1bd6a24f7b388047fa5227b1bbcdf..b1b3e779824946261ec337273c5568eddbb36213 100644 (file)
@@ -62,6 +62,8 @@ struct bGPdata;
 typedef struct bDeformGroup {
        struct bDeformGroup *next, *prev;
        char name[32];
+       /* Jason was here: need this flag for locking weights */
+       char flag, pad[7];
 } bDeformGroup;
 #define MAX_VGROUP_NAME 32
 
index f351a48b998d6ac26a138ddbcc6dd36962a56764..251329a04f6f343fe79fb974d2a1263a7ce9f24f 100644 (file)
@@ -724,10 +724,13 @@ typedef struct ToolSettings {
        short snap_flag, snap_target;
        short proportional, prop_mode;
        char proportional_objects; /* proportional edit, object mode */
-       char pad[3];
+       char pad[7];
 
        int auto_normalize; /*auto normalizing mode in wpaint*/
 
+       //Jason
+       int multipaint; /* paint multiple bones in wpaint */
+
        short sculpt_paint_settings; /* user preferences for sculpt and paint */
        short pad1;
        int sculpt_paint_unified_size; /* unified radius of brush in pixels */
index 9175806e2bb9f44ebb4e43d83aa6b4e01778636f..6fe130d027e346080a052e19d081f237781aa44a 100644 (file)
@@ -214,6 +214,8 @@ int rna_object_shapekey_index_set(struct ID *id, PointerRNA value, int current);
 void rna_Object_internal_update_data(struct Main *bmain, struct Scene *scene, struct PointerRNA *ptr);
 void rna_Mesh_update_draw(struct Main *bmain, struct Scene *scene, struct PointerRNA *ptr);
 void rna_TextureSlot_update(struct Main *bmain, struct Scene *scene, struct PointerRNA *ptr);
+//Jason
+void rna_update_active_object(struct Main *bmain, struct Scene *scene, struct PointerRNA *ptr);
 
 /* basic poll functions for object types */
 int rna_Armature_object_poll(struct PointerRNA *ptr, struct PointerRNA value);
index 80c98e8c428b5f9d83cacd925b923701d7861ddb..c1b92f8fc56d939062011eaa64468f7cb416ff86 100644 (file)
@@ -2077,6 +2077,12 @@ static void rna_def_mesh(BlenderRNA *brna)
        RNA_def_property_ui_icon(prop, ICON_FACESEL_HLT, 0);
        RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
 
+       /* Jason */
+       prop= RNA_def_property(srna, "wp_vert_sel", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "editflag", ME_EDIT_VERT_SEL);
+       RNA_def_property_ui_text(prop, "Vertex Selection", "Vertex Selection for auto brushes");
+       RNA_def_property_ui_icon(prop, ICON_VERTEXSEL, 0);
+       RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
 
        /* readonly editmesh info - use for extrude menu */
        prop= RNA_def_property(srna, "total_vert_sel", PROP_INT, PROP_UNSIGNED);
index dd66e49fdec1ad2f228aafb8776d1cc191055ee3..8dc229920e9d83e496573ef7990dbb08f48218d8 100644 (file)
@@ -218,6 +218,16 @@ void rna_Object_internal_update_data(Main *UNUSED(bmain), Scene *UNUSED(scene),
        DAG_id_tag_update(ptr->id.data, OB_RECALC_DATA);
        WM_main_add_notifier(NC_OBJECT|ND_DRAW, ptr->id.data);
 }
+// Jason
+void rna_update_active_object(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+       Object *ob;
+       Base *basact = scene->basact;
+       if(basact && (ob = basact->object)) {
+               DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+               WM_main_add_notifier(NC_OBJECT|ND_DRAW, &ob->id);
+       }
+}
 
 void rna_Object_active_shape_update(Main *bmain, Scene *scene, PointerRNA *ptr)
 {
@@ -1256,6 +1266,11 @@ static void rna_def_vertex_group(BlenderRNA *brna)
        RNA_def_struct_name_property(srna, prop);
        RNA_def_property_string_funcs(prop, NULL, NULL, "rna_VertexGroup_name_set");
        RNA_def_property_update(prop, NC_GEOM|ND_DATA|NA_RENAME, "rna_Object_internal_update_data"); /* update data because modifiers may use [#24761] */
+       /* Jason was here */
+       prop= RNA_def_property(srna, "flag", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_ui_text(prop, "", "Maintain the relative weights for the group");
+       RNA_def_property_boolean_sdna(prop, "bDeformGroup", "flag", 0);
+       RNA_def_property_update(prop, NC_GEOM|ND_DATA|NA_RENAME, "rna_Object_internal_update_data"); /* update data because modifiers may use [#24761] */
 
        prop= RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED);
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);
index 662ce04552e952374e392a5529361f4ea6b63a88..11a1c3a023de51d39de22709b40f00d49f75cb80 100644 (file)
@@ -1088,6 +1088,14 @@ static void rna_def_tool_settings(BlenderRNA  *brna)
        RNA_def_property_ui_text(prop, "WPaint Auto-Normalize", 
                "Ensure all bone-deforming vertex groups add up to 1.0 while "
                 "weight painting");
+       RNA_def_property_update(prop, 0, "rna_update_active_object");
+
+       prop = RNA_def_property(srna, "use_multipaint", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "multipaint", 1);
+       RNA_def_property_ui_text(prop, "WPaint Multi-Paint", 
+               "Paint across all selected bones while "
+                "weight painting");
+       RNA_def_property_update(prop, 0, "rna_update_active_object");
 
        prop= RNA_def_property(srna, "vertex_paint", PROP_POINTER, PROP_NONE);
        RNA_def_property_pointer_sdna(prop, NULL, "vpaint");
index 26844a5003d6bdcb8c1a2e8b3d6cb23d5f5bc905..55c1e69d55814addda04e1f643286f9d01b7255f 100644 (file)
@@ -680,7 +680,7 @@ static PyObject *M_Geometry_intersect_line_sphere_2d(PyObject *UNUSED(self), PyO
 
                PyObject *ret= PyTuple_New(2);
 
-               switch(isect_line_sphere_v2(line_a->vec, line_b->vec, sphere_co->vec, sphere_radius, isect_a, isect_b)) {
+               switch(isect_line_sphere_v3(line_a->vec, line_b->vec, sphere_co->vec, sphere_radius, isect_a, isect_b)) {
                case 1:
                        if(!(!clip || (((lambda= line_point_factor_v2(isect_a, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_a= FALSE;
                        use_b= FALSE;