svn merge ^/trunk/blender -r48333:48370
authorCampbell Barton <ideasman42@gmail.com>
Thu, 28 Jun 2012 11:20:19 +0000 (11:20 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 28 Jun 2012 11:20:19 +0000 (11:20 +0000)
77 files changed:
CMakeLists.txt
doc/python_api/examples/bpy.ops.1.py
doc/python_api/examples/bpy.ops.2.py
doc/python_api/examples/bpy.ops.py
doc/python_api/rst/bge.types.rst
intern/guardedalloc/MEM_guardedalloc.h
intern/guardedalloc/intern/mallocn.c
release/scripts/modules/bpy/ops.py
release/scripts/startup/bl_ui/space_node.py
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/BKE_mesh.h
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/collision.c
source/blender/blenkernel/intern/mask.c
source/blender/blenkernel/intern/mesh_validate.c
source/blender/blenkernel/intern/modifiers_bmesh.c
source/blender/blenkernel/intern/sequencer.c
source/blender/blenkernel/intern/unit.c
source/blender/blenkernel/intern/writeffmpeg.c
source/blender/blenlib/intern/fileops.c
source/blender/blenlib/intern/path_util.c
source/blender/blenlib/intern/voronoi.c
source/blender/bmesh/CMakeLists.txt
source/blender/bmesh/intern/bmesh_polygon.c
source/blender/bmesh/intern/bmesh_queries.c
source/blender/bmesh/intern/bmesh_queries.h
source/blender/bmesh/operators/bmo_hull.c
source/blender/collada/MeshImporter.cpp
source/blender/collada/SceneExporter.cpp
source/blender/collada/collada_utils.cpp
source/blender/compositor/CMakeLists.txt
source/blender/compositor/intern/COM_OpenCLDevice.cpp
source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h
source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h
source/blender/editors/armature/editarmature.c
source/blender/editors/armature/meshlaplacian.c
source/blender/editors/include/UI_view2d.h
source/blender/editors/interface/resources.c
source/blender/editors/interface/view2d.c
source/blender/editors/io/CMakeLists.txt
source/blender/editors/io/io_collada.c
source/blender/editors/io/io_ops.h
source/blender/editors/screen/screen_ops.c
source/blender/editors/space_node/drawnode.c
source/blender/editors/space_node/node_draw.c
source/blender/editors/space_sequencer/sequencer_buttons.c
source/blender/editors/space_text/text_ops.c
source/blender/editors/space_userpref/space_userpref.c
source/blender/editors/transform/transform.c
source/blender/editors/transform/transform_snap.c
source/blender/imbuf/intern/allocimbuf.c
source/blender/imbuf/intern/imbuf.h
source/blender/imbuf/intern/tiff.c
source/blender/makesdna/DNA_anim_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/makesdna/intern/dna_genfile.c
source/blender/makesrna/intern/rna_constraint.c
source/blender/makesrna/intern/rna_curve.c
source/blender/makesrna/intern/rna_fcurve.c
source/blender/makesrna/intern/rna_main.c
source/blender/makesrna/intern/rna_main_api.c
source/blender/makesrna/intern/rna_mask.c
source/blender/makesrna/intern/rna_mesh.c
source/blender/makesrna/intern/rna_nodetree.c
source/blender/makesrna/intern/rna_object.c
source/blender/makesrna/intern/rna_pose.c
source/blender/opencl/CMakeLists.txt
source/blender/python/intern/bpy_operator.c
source/blender/render/intern/raytrace/rayobject_instance.cpp
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/intern/wm_event_system.c
source/blenderplayer/bad_level_call_stubs/stubs.c
source/gameengine/Converter/BL_ActionActuator.cpp
source/gameengine/GameLogic/CMakeLists.txt
source/gameengine/GameLogic/SCA_PythonKeyboard.cpp
source/gameengine/GameLogic/SConscript
source/gameengine/Rasterizer/RAS_2DFilterManager.cpp

index 65a2894..72a5ebc 100644 (file)
@@ -123,7 +123,7 @@ mark_as_advanced(WITH_PYTHON)  # dont want people disabling this unless they rea
 mark_as_advanced(WITH_PYTHON_SECURITY)  # some distrobutions see this as a security issue, rather than have them patch it, make a build option.
 
 option(WITH_PYTHON_SAFETY "Enable internal API error checking to track invalid data to prevent crash on access (at the expense of some effeciency, only enable for development)." OFF)
-option(WITH_PYTHON_MODULE "Enable building as a python module (experimental, only enable for development)" OFF)
+option(WITH_PYTHON_MODULE "Enable building as a python module which runs without a user interface, like running regular blender in background mode (experimental, only enable for development)" OFF)
 option(WITH_BUILDINFO     "Include extra build details (only disable for development & faster builds)" ON)
 option(WITH_IK_ITASC      "Enable ITASC IK solver (only disable for development & for incompatible C++ compilers)" ON)
 option(WITH_FFTW3         "Enable FFTW3 support (Used for smoke and audio effects)" OFF)
@@ -463,11 +463,6 @@ set(PLATFORM_LINKFLAGS_DEBUG "")
 
 if(UNIX AND NOT APPLE)
 
-       # needed for ubuntu 11.04
-       if(EXISTS "/usr/lib/x86_64-linux-gnu")
-               set(CMAKE_LIBRARY_PATH "/usr/lib/x86_64-linux-gnu;${CMAKE_LIBRARY_PATH}")
-       endif()
-
        # set lib directory if it exists
        if(CMAKE_SYSTEM_NAME MATCHES "Linux")
                if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
index f43be2b..a00dbda 100644 (file)
@@ -1,22 +1,17 @@
 """
-Execution Context
-+++++++++++++++++
+Overriding Context
+------------------
 
-When calling an operator you may want to pass the execution context.
+It is possible to override context members that the operator sees, so that they
+act on specified rather than the selected or active data, or to execute an
+operator in the different part of the user interface.
 
-This determines the context thats given to the operator to run in, and weather
-invoke() is called or execute().
-
-'EXEC_DEFAULT' is used by default but you may want the operator to take user
-interaction with 'INVOKE_DEFAULT'.
-
-The execution context is as a non keyword, string argument in:
-('INVOKE_DEFAULT', 'INVOKE_REGION_WIN', 'INVOKE_REGION_CHANNELS',
-'INVOKE_REGION_PREVIEW', 'INVOKE_AREA', 'INVOKE_SCREEN', 'EXEC_DEFAULT',
-'EXEC_REGION_WIN', 'EXEC_REGION_CHANNELS', 'EXEC_REGION_PREVIEW', 'EXEC_AREA',
-'EXEC_SCREEN')
+The context overrides are passed as a dictionary, with keys matching the context
+member names in bpy.context. For example to override bpy.context.active_object,
+you would pass {'active_object': object}.
 """
 
-# group add popup
+# remove all objects in scene rather than the selected ones
 import bpy
-bpy.ops.object.group_instance_add('INVOKE_DEFAULT')
+override = {'selected_bases': list(bpy.context.scene.object_bases)}
+bpy.ops.object.delete(override)
index 575d020..01e7dc1 100644 (file)
@@ -1,17 +1,22 @@
 """
-Overriding Context
-++++++++++++++++++
+Execution Context
+-----------------
 
-It is possible to override context members that the operator sees, so that they
-act on specified rather than the selected or active data, or to execute an
-operator in the different part of the user interface.
+When calling an operator you may want to pass the execution context.
 
-The context overrides are passed as a dictionary, with keys matching the context
-member names in bpy.context. For example to override bpy.context.active_object,
-you would pass {'active_object': object}.
+This determines the context thats given to the operator to run in, and weather
+invoke() is called or execute().
+
+'EXEC_DEFAULT' is used by default but you may want the operator to take user
+interaction with 'INVOKE_DEFAULT'.
+
+The execution context is as a non keyword, string argument in:
+('INVOKE_DEFAULT', 'INVOKE_REGION_WIN', 'INVOKE_REGION_CHANNELS',
+'INVOKE_REGION_PREVIEW', 'INVOKE_AREA', 'INVOKE_SCREEN', 'EXEC_DEFAULT',
+'EXEC_REGION_WIN', 'EXEC_REGION_CHANNELS', 'EXEC_REGION_PREVIEW', 'EXEC_AREA',
+'EXEC_SCREEN')
 """
 
-# remove all objects in scene rather than the selected ones
+# group add popup
 import bpy
-override = {'selected_bases': list(bpy.context.scene.object_bases)}
-bpy.ops.object.delete(override)
+bpy.ops.object.group_instance_add('INVOKE_DEFAULT')
\ No newline at end of file
index 20e8773..9964ad9 100644 (file)
@@ -1,6 +1,6 @@
 """
 Calling Operators
-+++++++++++++++++
+-----------------
 
 Provides python access to calling operators, this includes operators written in
 C, Python or Macros.
@@ -18,6 +18,26 @@ there is a poll() method to avoid this problem.
 
 Note that the operator ID (bl_idname) in this example is 'mesh.subdivide',
 'bpy.ops' is just the access path for python.
+
+
+Keywords and Positional Arguments
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For calling operators keywords are used for operator properties and
+positional arguments are used to define how the operator is called.
+
+There are 3 optional positional arguments (documented in detail below).
+
+.. code-block:: python
+
+   bpy.ops.test.operator(override_context, execution_context, undo)
+
+* override_context - dict type
+* execution_context - string (enum)
+* undo - boolean
+
+
+Each of these arguments is optional, but must be given in the order above.
 """
 import bpy
 
index ff85df1..f7bdb06 100644 (file)
@@ -72,6 +72,20 @@ Game Types (bge.types)
 
       :type: dictionary {:ref:`keycode<keyboard-keys>`::ref:`status<input-status>`, ...}
 
+
+   .. function:: getClipboard()
+
+      Gets the clipboard text.
+
+      :rtype: string
+
+   .. function:: setClipboard(text)
+
+      Sets the clipboard text.
+
+      :arg text: New clipboard text
+      :type text: string
+
 .. class:: SCA_PythonMouse(PyObjectPlus)
 
    The current mouse.
@@ -242,12 +256,6 @@ Game Types (bge.types)
 
       :type: string
 
-   .. attribute:: channelNames
-
-      A list of channel names that may be used with :data:`setChannel` and :data:`getChannel`.
-
-      :type: list of strings
-
    .. attribute:: frameStart
 
       Specifies the starting frame of the animation.
@@ -308,26 +316,6 @@ Game Types (bge.types)
 
       :type: string
 
-   .. method:: setChannel(channel, matrix)
-
-      Alternative to the 2 arguments, 4 arguments (channel, matrix, loc, size, quat) are also supported.
-
-      :arg channel: A string specifying the name of the bone channel, error raised if not in :data:`channelNames`.
-      :type channel: string
-      :arg matrix: A 4x4 matrix specifying the overriding transformation as an offset from the bone's rest position.
-      :arg  matrix: list [[float]]
-
-      .. note::
-         
-         These values are relative to the bones rest position, currently the api has no way to get this info (which is annoying), but can be worked around by using bones with a rest pose that has no translation.
-
-   .. method:: getChannel(channel)
-
-      :arg channel: A string specifying the name of the bone channel. error raised if not in :data:`channelNames`.
-      :type channel: string
-      :return: (loc, size, quat)
-      :rtype: tuple
-
 .. class:: BL_Shader(PyObjectPlus)
 
    BL_Shader GLSL shaders.
index 1d0a8db..4bb8cba 100644 (file)
@@ -97,10 +97,10 @@ extern "C" {
        void *MEM_dupallocN(void *vmemh) WARN_UNUSED;
 
        /**
-         * Reallocates a block of memory, and returns pointer to the newly
-         * allocated block, the old one is freed. this is not as optimized
-         * as a system realloc but just makes a new allocation and copies
-         * over from existing memory. */
+        * Reallocates a block of memory, and returns pointer to the newly
+        * allocated block, the old one is freed. this is not as optimized
+        * as a system realloc but just makes a new allocation and copies
+        * over from existing memory. */
        void *MEM_reallocN(void *vmemh, size_t len) WARN_UNUSED;
 
        /**
@@ -110,13 +110,13 @@ extern "C" {
        void *MEM_callocN(size_t len, const char * str) WARN_UNUSED;
        
        /** Allocate a block of memory of size len, with tag name str. The
-               * name must be a static, because only a pointer to it is stored !
-               * */
+        * name must be a static, because only a pointer to it is stored !
+        * */
        void *MEM_mallocN(size_t len, const char * str) WARN_UNUSED;
        
        /** Same as callocN, clears memory and uses mmap (disk cached) if supported.
-               Can be free'd with MEM_freeN as usual.
-               * */
+        * Can be free'd with MEM_freeN as usual.
+        * */
        void *MEM_mapallocN(size_t len, const char * str) WARN_UNUSED;
 
        /** Print a list of the names and sizes of all allocated memory
@@ -143,7 +143,7 @@ extern "C" {
        int MEM_check_memory_integrity(void);
 
        /** Set thread locking functions for safe memory allocation from multiple
-           threads, pass NULL pointers to disable thread locking again. */
+        * threads, pass NULL pointers to disable thread locking again. */
        void MEM_set_lock_callback(void (*lock)(void), void (*unlock)(void));
        
        /** Attempt to enforce OSX (or other OS's) to have malloc and stack nonzero */
@@ -195,4 +195,3 @@ public:                                                                       \
 #endif
 
 #endif
-
index f1a8358..c00e946 100644 (file)
@@ -57,7 +57,7 @@
  * lets you count the allocations so as to find the allocator of unfreed memory
  * in situations where the leak is predictable */
 
-// #define DEBUG_MEMCOUNTER
+//#define DEBUG_MEMCOUNTER
 
 #ifdef DEBUG_MEMCOUNTER
    /* set this to the value that isn't being freed */
index 056fcdb..c4e7e6a 100644 (file)
@@ -120,20 +120,28 @@ class BPyOpsSubModOp(object):
     def _parse_args(args):
         C_dict = None
         C_exec = 'EXEC_DEFAULT'
-
-        if len(args) == 0:
-            pass
-        elif len(args) == 1:
-            if type(args[0]) != str:
-                C_dict = args[0]
+        C_undo = False
+
+        is_dict = is_exec = is_undo = False
+
+        for i, arg in enumerate(args):
+            if is_dict is False and isinstance(arg, dict):
+                if is_exec is True or is_undo is True:
+                    raise ValueError("dict arg must come first")
+                C_dict = arg
+                is_dict = True
+            elif is_exec is False and isinstance(arg, str):
+                if is_undo is True:
+                    raise ValueError("string arg must come before the boolean")
+                C_exec = arg
+                is_exec = True
+            elif is_undo is False and isinstance(arg, int):
+                C_undo = arg
+                is_undo = True
             else:
-                C_exec = args[0]
-        elif len(args) == 2:
-            C_exec, C_dict = args
-        else:
-            raise ValueError("1 or 2 args execution context is supported")
+                raise ValueError("1-3 args execution context is supported")
 
-        return C_dict, C_exec
+        return C_dict, C_exec, C_undo
 
     @staticmethod
     def _scene_update(context):
@@ -152,7 +160,7 @@ class BPyOpsSubModOp(object):
         self.func = func
 
     def poll(self, *args):
-        C_dict, C_exec = BPyOpsSubModOp._parse_args(args)
+        C_dict, C_exec, C_undo = BPyOpsSubModOp._parse_args(args)
         return op_poll(self.idname_py(), C_dict, C_exec)
 
     def idname(self):
@@ -174,8 +182,8 @@ class BPyOpsSubModOp(object):
         BPyOpsSubModOp._scene_update(context)
 
         if args:
-            C_dict, C_exec = BPyOpsSubModOp._parse_args(args)
-            ret = op_call(self.idname_py(), C_dict, kw, C_exec)
+            C_dict, C_exec, C_undo = BPyOpsSubModOp._parse_args(args)
+            ret = op_call(self.idname_py(), C_dict, kw, C_exec, C_undo)
         else:
             ret = op_call(self.idname_py(), None, kw)
 
index 70f0f30..d7f25a5 100644 (file)
@@ -32,6 +32,7 @@ class NODE_HT_header(Header):
         snode = context.space_data
         snode_id = snode.id
         id_from = snode.id_from
+        toolsettings = context.tool_settings
 
         row = layout.row(align=True)
         row.template_header()
@@ -86,6 +87,10 @@ class NODE_HT_header(Header):
 
         layout.separator()
 
+        # Snap
+        row = layout.row(align=True)
+        row.prop(toolsettings, "use_snap", text="")
+
         layout.template_running_jobs()
 
 
index c7ddab4..64512dc 100644 (file)
 #ifndef __BKE_DERIVEDMESH_H__
 #define __BKE_DERIVEDMESH_H__
 
-/*
+/**
  * Basic design of the DerivedMesh system:
  *
  * DerivedMesh is a common set of interfaces for mesh systems.
  *
- * There are three main mesh data structures in Blender: Mesh, CDDM, and BMesh.
+ * There are three main mesh data structures in Blender:
+ * #Mesh, #CDDerivedMesh and #BMesh.
+ *
  * These, and a few others, all implement DerivedMesh interfaces, 
  * which contains unified drawing interfaces, a few utility interfaces, 
  * and a bunch of read-only interfaces intended mostly for conversion from 
@@ -67,7 +69,6 @@
  *       as it is and stick with using BMesh and CDDM.
  */
 
-
 #include "DNA_customdata_types.h"
 #include "DNA_meshdata_types.h"
 
@@ -151,7 +152,7 @@ typedef enum DMDirtyFlag {
 
 typedef struct DerivedMesh DerivedMesh;
 struct DerivedMesh {
-       /* Private DerivedMesh data, only for internal DerivedMesh use */
+       /** Private DerivedMesh data, only for internal DerivedMesh use */
        CustomData vertData, edgeData, faceData, loopData, polyData;
        int numVertData, numEdgeData, numTessFaceData, numLoopData, numPolyData;
        int needsFree; /* checked on ->release, is set to 0 for cached results */
@@ -162,10 +163,10 @@ struct DerivedMesh {
        float auto_bump_scale;
        DMDirtyFlag dirty;
 
-       /* calculate vert and face normals */
+       /** Calculate vert and face normals */
        void (*calcNormals)(DerivedMesh *dm);
 
-       /* recalculates mesh tessellation */
+       /** Recalculates mesh tessellation */
        void (*recalcTessellation)(DerivedMesh *dm);
 
        /* Misc. Queries */
@@ -177,7 +178,7 @@ struct DerivedMesh {
        int (*getNumLoops)(DerivedMesh *dm);
        int (*getNumPolys)(DerivedMesh *dm);
 
-       /* copy a single vert/edge/tessellated face from the derived mesh into
+       /** Copy a single vert/edge/tessellated face from the derived mesh into
         * *{vert/edge/face}_r. note that the current implementation
         * of this function can be quite slow, iterating over all
         * elements (editmesh)
@@ -186,7 +187,7 @@ struct DerivedMesh {
        void (*getEdge)(DerivedMesh *dm, int index, struct MEdge *edge_r);
        void (*getTessFace)(DerivedMesh *dm, int index, struct MFace *face_r);
 
-       /* return a pointer to the entire array of verts/edges/face from the
+       /** Return a pointer to the entire array of verts/edges/face from the
         * derived mesh. if such an array does not exist yet, it will be created,
         * and freed on the next ->release(). consider using getVert/Edge/Face if
         * you are only interested in a few verts/edges/faces.
@@ -197,7 +198,7 @@ struct DerivedMesh {
        struct MLoop *(*getLoopArray)(DerivedMesh * dm);
        struct MPoly *(*getPolyArray)(DerivedMesh * dm);
 
-       /* copy all verts/edges/faces from the derived mesh into
+       /** Copy all verts/edges/faces from the derived mesh into
         * *{vert/edge/face}_r (must point to a buffer large enough)
         */
        void (*copyVertArray)(DerivedMesh *dm, struct MVert *vert_r);
@@ -206,7 +207,7 @@ struct DerivedMesh {
        void (*copyLoopArray)(DerivedMesh *dm, struct MLoop *loop_r);
        void (*copyPolyArray)(DerivedMesh *dm, struct MPoly *poly_r);
 
-       /* return a copy of all verts/edges/faces from the derived mesh
+       /** Return a copy of all verts/edges/faces from the derived mesh
         * it is the caller's responsibility to free the returned pointer
         */
        struct MVert *(*dupVertArray)(DerivedMesh * dm);
@@ -215,7 +216,7 @@ struct DerivedMesh {
        struct MLoop *(*dupLoopArray)(DerivedMesh * dm);
        struct MPoly *(*dupPolyArray)(DerivedMesh * dm);
 
-       /* return a pointer to a single element of vert/edge/face custom data
+       /** Return a pointer to a single element of vert/edge/face custom data
         * from the derived mesh (this gives a pointer to the actual data, not
         * a copy)
         */
@@ -223,7 +224,7 @@ struct DerivedMesh {
        void *(*getEdgeData)(DerivedMesh * dm, int index, int type);
        void *(*getTessFaceData)(DerivedMesh * dm, int index, int type);
 
-       /* return a pointer to the entire array of vert/edge/face custom data
+       /** Return a pointer to the entire array of vert/edge/face custom data
         * from the derived mesh (this gives a pointer to the actual data, not
         * a copy)
         */
@@ -231,7 +232,7 @@ struct DerivedMesh {
        void *(*getEdgeDataArray)(DerivedMesh * dm, int type);
        void *(*getTessFaceDataArray)(DerivedMesh * dm, int type);
        
-       /* retrieves the base CustomData structures for 
+       /** Retrieves the base CustomData structures for
         * verts/edges/tessfaces/loops/facdes*/
        CustomData *(*getVertDataLayout)(DerivedMesh * dm);
        CustomData *(*getEdgeDataLayout)(DerivedMesh * dm);
@@ -239,12 +240,12 @@ struct DerivedMesh {
        CustomData *(*getLoopDataLayout)(DerivedMesh * dm);
        CustomData *(*getPolyDataLayout)(DerivedMesh * dm);
        
-       /*copies all customdata for an element source into dst at index dest*/
+       /** Copies all customdata for an element source into dst at index dest */
        void (*copyFromVertCData)(DerivedMesh *dm, int source, CustomData *dst, int dest);
        void (*copyFromEdgeCData)(DerivedMesh *dm, int source, CustomData *dst, int dest);
        void (*copyFromFaceCData)(DerivedMesh *dm, int source, CustomData *dst, int dest);
        
-       /* optional grid access for subsurf */
+       /** Optional grid access for subsurf */
        int (*getNumGrids)(DerivedMesh *dm);
        int (*getGridSize)(DerivedMesh *dm);
        struct CCGElem **(*getGridData)(DerivedMesh * dm);
@@ -255,7 +256,7 @@ struct DerivedMesh {
        unsigned int **(*getGridHidden)(DerivedMesh * dm);
        
 
-       /* Iterate over each mapped vertex in the derived mesh, calling the
+       /** Iterate over each mapped vertex in the derived mesh, calling the
         * given function with the original vert and the mapped vert's new
         * coordinate and normal. For historical reasons the normal can be
         * passed as a float or short array, only one should be non-NULL.
@@ -265,7 +266,7 @@ struct DerivedMesh {
                                               const float no_f[3], const short no_s[3]),
                                  void *userData);
 
-       /* Iterate over each mapped edge in the derived mesh, calling the
+       /** Iterate over each mapped edge in the derived mesh, calling the
         * given function with the original edge and the mapped edge's new
         * coordinates.
         */
@@ -274,7 +275,7 @@ struct DerivedMesh {
                                               const float v0co[3], const float v1co[3]),
                                  void *userData);
 
-       /* Iterate over each mapped face in the derived mesh, calling the
+       /** Iterate over each mapped face in the derived mesh, calling the
         * given function with the original face and the mapped face's (or
         * faces') center and normal.
         */
@@ -283,51 +284,51 @@ struct DerivedMesh {
                                                     const float cent[3], const float no[3]),
                                        void *userData);
 
-       /* Iterate over all vertex points, calling DO_MINMAX with given args.
+       /** Iterate over all vertex points, calling DO_MINMAX with given args.
         *
         * Also called in Editmode
         */
        void (*getMinMax)(DerivedMesh *dm, float min_r[3], float max_r[3]);
 
-       /* Direct Access Operations */
-       /*  o Can be undefined */
-       /*  o Must be defined for modifiers that only deform however */
+       /** Direct Access Operations
+        * - Can be undefined
+        * - Must be defined for modifiers that only deform however */
 
-       /* Get vertex location, undefined if index is not valid */
+       /** Get vertex location, undefined if index is not valid */
        void (*getVertCo)(DerivedMesh *dm, int index, float co_r[3]);
 
-       /* Fill the array (of length .getNumVerts()) with all vertex locations */
+       /** Fill the array (of length .getNumVerts()) with all vertex locations */
        void (*getVertCos)(DerivedMesh *dm, float (*cos_r)[3]);
 
-       /* Get smooth vertex normal, undefined if index is not valid */
+       /** Get smooth vertex normal, undefined if index is not valid */
        void (*getVertNo)(DerivedMesh *dm, int index, float no_r[3]);
 
-       /* Get a map of vertices to faces
+       /** Get a map of vertices to faces
         */
        const struct MeshElemMap *(*getPolyMap)(struct Object *ob, DerivedMesh *dm);
 
-       /* Get the BVH used for paint modes
+       /** Get the BVH used for paint modes
         */
        struct PBVH *(*getPBVH)(struct Object *ob, DerivedMesh *dm);
 
        /* Drawing Operations */
 
-       /* Draw all vertices as bgl points (no options) */
+       /** Draw all vertices as bgl points (no options) */
        void (*drawVerts)(DerivedMesh *dm);
 
-       /* Draw edges in the UV mesh (if exists) */
+       /** Draw edges in the UV mesh (if exists) */
        void (*drawUVEdges)(DerivedMesh *dm);
 
-       /* Draw all edges as lines (no options) 
+       /** Draw all edges as lines (no options)
         *
         * Also called for *final* editmode DerivedMeshes
         */
        void (*drawEdges)(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges);
        
-       /* Draw all loose edges (edges w/ no adjoining faces) */
+       /** Draw all loose edges (edges w/ no adjoining faces) */
        void (*drawLooseEdges)(DerivedMesh *dm);
 
-       /* Draw all faces
+       /** Draw all faces
         *  o Set face normal or vertex normal based on inherited face flag
         *  o Use inherited face material index to call setMaterial
         *  o Only if setMaterial returns true
@@ -337,24 +338,24 @@ struct DerivedMesh {
        void (*drawFacesSolid)(DerivedMesh *dm, float (*partial_redraw_planes)[4],
                               int fast, DMSetMaterial setMaterial);
 
-       /* Draw all faces using MTFace 
-        *  o Drawing options too complicated to enumerate, look at code.
+       /** Draw all faces using MTFace
+        * - Drawing options too complicated to enumerate, look at code.
         */
        void (*drawFacesTex)(DerivedMesh *dm,
                             DMSetDrawOptionsTex setDrawOptions,
                             DMCompareDrawOptions compareDrawOptions,
                             void *userData);
 
-       /* Draw all faces with GLSL materials
+       /** Draw all faces with GLSL materials
         *  o setMaterial is called for every different material nr
         *  o Only if setMaterial returns true
         */
        void (*drawFacesGLSL)(DerivedMesh *dm, DMSetMaterial setMaterial);
 
-       /* Draw mapped faces (no color, or texture)
-        *  o Only if !setDrawOptions or
-        *    setDrawOptions(userData, mapped-face-index, drawSmooth_r)
-        *    returns true
+       /** Draw mapped faces (no color, or texture)
+        * - Only if !setDrawOptions or
+        *   setDrawOptions(userData, mapped-face-index, drawSmooth_r)
+        *   returns true
         *
         * If drawSmooth is set to true then vertex normals should be set and
         * glShadeModel called with GL_SMOOTH. Otherwise the face normal should
@@ -371,36 +372,36 @@ struct DerivedMesh {
                                void *userData,
                                DMDrawFlag flag);
 
-       /* Draw mapped faces using MTFace 
-        *  o Drawing options too complicated to enumerate, look at code.
+       /** Draw mapped faces using MTFace
+        * - Drawing options too complicated to enumerate, look at code.
         */
        void (*drawMappedFacesTex)(DerivedMesh *dm,
                                   DMSetDrawOptions setDrawOptions,
                                   DMCompareDrawOptions compareDrawOptions,
                                   void *userData);
 
-       /* Draw mapped faces with GLSL materials
-        *  o setMaterial is called for every different material nr
-        *  o setDrawOptions is called for every face
-        *  o Only if setMaterial and setDrawOptions return true
+       /** Draw mapped faces with GLSL materials
+        * - setMaterial is called for every different material nr
+        * - setDrawOptions is called for every face
+        * - Only if setMaterial and setDrawOptions return true
         */
        void (*drawMappedFacesGLSL)(DerivedMesh *dm,
                                    DMSetMaterial setMaterial,
                                    DMSetDrawOptions setDrawOptions,
                                    void *userData);
 
-       /* Draw mapped edges as lines
-        *  o Only if !setDrawOptions or setDrawOptions(userData, mapped-edge)
-        *    returns true
+       /** Draw mapped edges as lines
+        * - Only if !setDrawOptions or setDrawOptions(userData, mapped-edge)
+        *   returns true
         */
        void (*drawMappedEdges)(DerivedMesh *dm,
                                DMSetDrawOptions setDrawOptions,
                                void *userData);
 
-       /* Draw mapped edges as lines with interpolation values
-        *  o Only if !setDrawOptions or
-        *    setDrawOptions(userData, mapped-edge, mapped-v0, mapped-v1, t)
-        *    returns true
+       /** Draw mapped edges as lines with interpolation values
+        * - Only if !setDrawOptions or
+        *   setDrawOptions(userData, mapped-edge, mapped-v0, mapped-v1, t)
+        *   returns true
         *
         * NOTE: This routine is optional!
         */
@@ -409,32 +410,32 @@ struct DerivedMesh {
                                      DMSetDrawInterpOptions setDrawInterpOptions,
                                      void *userData);
 
-       /* Draw all faces with materials
-        *  o setMaterial is called for every different material nr
-        *  o setFace is called to verify if a face must be hidden
+       /** Draw all faces with materials
+        * - setMaterial is called for every different material nr
+        * - setFace is called to verify if a face must be hidden
         */
        void (*drawMappedFacesMat)(DerivedMesh *dm,
                                   void (*setMaterial)(void *userData, int, void *attribs),
                                   int (*setFace)(void *userData, int index), void *userData);
 
-       /* Release reference to the DerivedMesh. This function decides internally
+       /** Release reference to the DerivedMesh. This function decides internally
         * if the DerivedMesh will be freed, or cached for later use. */
        void (*release)(DerivedMesh *dm);
 };
 
-/* utility function to initialize a DerivedMesh's function pointers to
+/** utility function to initialize a DerivedMesh's function pointers to
  * the default implementation (for those functions which have a default)
  */
 void DM_init_funcs(DerivedMesh *dm);
 
-/* utility function to initialize a DerivedMesh for the desired number
+/** utility function to initialize a DerivedMesh for the desired number
  * of vertices, edges and faces (doesn't allocate memory for them, just
  * sets up the custom data layers)
  */
 void DM_init(DerivedMesh *dm, DerivedMeshType type, int numVerts, int numEdges, 
              int numFaces, int numLoops, int numPolys);
 
-/* utility function to initialize a DerivedMesh for the desired number
+/** utility function to initialize a DerivedMesh for the desired number
  * of vertices, edges and faces, with a layer setup copied from source
  */
 void DM_from_template(DerivedMesh *dm, DerivedMesh *source,
@@ -442,12 +443,12 @@ void DM_from_template(DerivedMesh *dm, DerivedMesh *source,
                       int numVerts, int numEdges, int numFaces,
                       int numLoops, int numPolys);
 
-/* utility function to release a DerivedMesh's layers
+/** utility function to release a DerivedMesh's layers
  * returns 1 if DerivedMesh has to be released by the backend, 0 otherwise
  */
 int DM_release(DerivedMesh *dm);
 
-/* utility function to convert a DerivedMesh to a Mesh
+/** utility function to convert a DerivedMesh to a Mesh
  */
 void DM_to_mesh(DerivedMesh *dm, struct Mesh *me, struct Object *ob);
 
@@ -459,11 +460,10 @@ void          DM_to_bmesh_ex(struct DerivedMesh *dm, struct BMesh *bm);
 struct BMesh *DM_to_bmesh(struct DerivedMesh *dm);
 
 
-/* utility function to convert a DerivedMesh to a shape key block 
- */
+/** Utility function to convert a DerivedMesh to a shape key block */
 void DM_to_meshkey(DerivedMesh *dm, struct Mesh *me, struct KeyBlock *kb);
 
-/* set the CD_FLAG_NOCOPY flag in custom data layers where the mask is
+/** set the CD_FLAG_NOCOPY flag in custom data layers where the mask is
  * zero for the layer type, so only layer types specified by the mask
  * will be copied
  */
@@ -545,7 +545,7 @@ void DM_ensure_tessface(DerivedMesh *dm);
 
 void DM_update_tessface_data(DerivedMesh *dm);
 
-/* interpolates vertex data from the vertices indexed by src_indices in the
+/** interpolates vertex data from the vertices indexed by src_indices in the
  * source mesh using the given weights and stores the result in the vertex
  * indexed by dest_index in the dest mesh
  */
@@ -553,7 +553,7 @@ void DM_interp_vert_data(struct DerivedMesh *source, struct DerivedMesh *dest,
                          int *src_indices, float *weights,
                          int count, int dest_index);
 
-/* interpolates edge data from the edges indexed by src_indices in the
+/** interpolates edge data from the edges indexed by src_indices in the
  * source mesh using the given weights and stores the result in the edge indexed
  * by dest_index in the dest mesh.
  * if weights is NULL, all weights default to 1.
@@ -566,7 +566,7 @@ void DM_interp_edge_data(struct DerivedMesh *source, struct DerivedMesh *dest,
                          float *weights, EdgeVertWeight *vert_weights,
                          int count, int dest_index);
 
-/* interpolates face data from the faces indexed by src_indices in the
+/** interpolates face data from the faces indexed by src_indices in the
  * source mesh using the given weights and stores the result in the face indexed
  * by dest_index in the dest mesh.
  * if weights is NULL, all weights default to 1.
@@ -592,7 +592,7 @@ void DM_interp_poly_data(struct DerivedMesh *source, struct DerivedMesh *dest,
 /* Temporary? A function to give a colorband to derivedmesh for vertexcolor ranges */
 void vDM_ColorBand_store(struct ColorBand *coba);
 
-/* Simple function to get me->totvert amount of vertices/normals,
+/** Simple function to get me->totvert amount of vertices/normals,
  * correctly deformed and subsurfered. Needed especially when vertexgroups are involved.
  * In use now by vertex/weight paint and particles */
 float *mesh_get_mapped_verts_nors(struct Scene *scene, struct Object *ob);
@@ -641,13 +641,13 @@ int editbmesh_modifier_is_enabled(struct Scene *scene, struct ModifierData *md,
 void makeDerivedMesh(struct Scene *scene, struct Object *ob, struct BMEditMesh *em, 
                      CustomDataMask dataMask, int build_shapekey_layers);
 
-/* returns an array of deform matrices for crazyspace correction, and the
+/** returns an array of deform matrices for crazyspace correction, and the
  * number of modifiers left */
 int editbmesh_get_first_deform_matrices(struct Scene *, struct Object *, struct BMEditMesh *em,
                                         float (**deformmats)[3][3], float (**deformcos)[3]);
 
 void weight_to_rgb(float r_rgb[3], const float weight);
-/* Update the weight MCOL preview layer.
+/** Update the weight MCOL preview layer.
  * If weights are NULL, use object's active vgroup(s).
  * Else, weights must be an array of weight float values.
  *     If indices is NULL, it must be of numVerts length.
@@ -657,7 +657,7 @@ void weight_to_rgb(float r_rgb[3], const float weight);
 void DM_update_weight_mcol(struct Object *ob, struct DerivedMesh *dm, int const draw_flag,
                            float *weights, int num, const int *indices);
 
-/* convert layers requested by a GLSL material to actually available layers in
+/** convert layers requested by a GLSL material to actually available layers in
  * the DerivedMesh, with both a pointer for arrays and an offset for editmesh */
 typedef struct DMVertexAttribs {
        struct {
@@ -689,7 +689,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm,
 void DM_add_tangent_layer(DerivedMesh *dm);
 void DM_calc_auto_bump_scale(DerivedMesh *dm);
 
-/* Set object's bounding box based on DerivedMesh min/max data */
+/** Set object's bounding box based on DerivedMesh min/max data */
 void DM_set_object_boundbox(struct Object *ob, DerivedMesh *dm);
 
 void DM_init_origspace(DerivedMesh *dm);
index 8873406..abd0c4d 100644 (file)
@@ -296,6 +296,7 @@ int BKE_mesh_validate_arrays(
         struct Mesh *me,
         struct MVert *mverts, unsigned int totvert,
         struct MEdge *medges, unsigned int totedge,
+        struct MFace *mfaces, unsigned int totface,
         struct MLoop *mloops, unsigned int totloop,
         struct MPoly *mpolys, unsigned int totpoly,
         struct MDeformVert *dverts, /* assume totvert length */
index 170638f..a0cfc42 100644 (file)
@@ -1490,7 +1490,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
                        }
 
                        /* only counts visible particles */
-                       ++index;
+                       index++;
                }
 
                /* restore objects since they were changed in BKE_object_where_is_calc_time */
index 1bd650e..d99c36b 100644 (file)
@@ -325,8 +325,7 @@ static int cloth_collision_response_static ( ClothModifierData *clmd, CollisionM
 
                        result = 1;
                }
-               else
-               {
+               else {
                        // Apply repulse impulse if distance too short
                        // I_r = -min(dt*kd, max(0, 1d/dt - v_n))
                        // DG: this formula ineeds to be changed for this code since we apply impulses/repulses like this:
index d857229..2767a67 100644 (file)
@@ -64,7 +64,7 @@ static MaskSplinePoint *mask_spline_point_next(MaskSpline *spline, MaskSplinePoi
                if (spline->flag & MASK_SPLINE_CYCLIC) {
                        return &points_array[0];
                }
-               else  {
+               else {
                        return NULL;
                }
        }
@@ -79,7 +79,7 @@ static MaskSplinePoint *mask_spline_point_prev(MaskSpline *spline, MaskSplinePoi
                if (spline->flag & MASK_SPLINE_CYCLIC) {
                        return &points_array[spline->tot_point - 1];
                }
-               else  {
+               else {
                        return NULL;
                }
        }
@@ -94,7 +94,7 @@ static BezTriple *mask_spline_point_next_bezt(MaskSpline *spline, MaskSplinePoin
                if (spline->flag & MASK_SPLINE_CYCLIC) {
                        return &(points_array[0].bezt);
                }
-               else  {
+               else {
                        return NULL;
                }
        }
index 669ae4f..5d39811 100644 (file)
 
 #define SELECT 1
 
+typedef union {
+       uint32_t verts[2];
+       int64_t edval;
+} EdgeUUID;
+
+typedef struct SortFace {
+       EdgeUUID                es[4];
+       unsigned int    index;
+} SortFace;
+
 /* Used to detect polys (faces) using exactly the same vertices. */
 /* Used to detect loops used by no (disjoint) or more than one (intersect) polys. */
 typedef struct SortPoly {
@@ -60,6 +70,84 @@ typedef struct SortPoly {
        int invalid; /* Poly index. */
 } SortPoly;
 
+static void edge_store_assign(uint32_t verts[2],  const uint32_t v1, const uint32_t v2)
+{
+       if (v1 < v2) {
+               verts[0] = v1;
+               verts[1] = v2;
+       }
+       else {
+               verts[0] = v2;
+               verts[1] = v1;
+       }
+}
+
+static void edge_store_from_mface_quad(EdgeUUID es[4], MFace *mf)
+{
+       edge_store_assign(es[0].verts, mf->v1, mf->v2);
+       edge_store_assign(es[1].verts, mf->v2, mf->v3);
+       edge_store_assign(es[2].verts, mf->v3, mf->v4);
+       edge_store_assign(es[3].verts, mf->v4, mf->v1);
+}
+
+static void edge_store_from_mface_tri(EdgeUUID es[4], MFace *mf)
+{
+       edge_store_assign(es[0].verts, mf->v1, mf->v2);
+       edge_store_assign(es[1].verts, mf->v2, mf->v3);
+       edge_store_assign(es[2].verts, mf->v3, mf->v1);
+       es[3].verts[0] = es[3].verts[1] = UINT_MAX;
+}
+
+static int int64_cmp(const void *v1, const void *v2)
+{
+       const int64_t x1 = *(const int64_t *)v1;
+       const int64_t x2 = *(const int64_t *)v2;
+
+       if (x1 > x2) {
+               return 1;
+       }
+       else if (x1 < x2) {
+               return -1;
+       }
+
+       return 0;
+}
+
+static int search_face_cmp(const void *v1, const void *v2)
+{
+       const SortFace *sfa = v1, *sfb = v2;
+
+       if (sfa->es[0].edval > sfb->es[0].edval) {
+               return 1;
+       }
+       else if (sfa->es[0].edval < sfb->es[0].edval) {
+               return -1;
+       }
+
+       else if (sfa->es[1].edval > sfb->es[1].edval) {
+               return 1;
+       }
+       else if (sfa->es[1].edval < sfb->es[1].edval) {
+               return -1;
+       }
+
+       else if (sfa->es[2].edval > sfb->es[2].edval) {
+               return 1;
+       }
+       else if (sfa->es[2].edval < sfb->es[2].edval) {
+               return -1;
+       }
+
+       else if (sfa->es[3].edval > sfb->es[3].edval) {
+               return 1;
+       }
+       else if (sfa->es[3].edval < sfb->es[3].edval) {
+               return -1;
+       }
+
+       return 0;
+}
+
 /* TODO check there is not some standard define of this somewhere! */
 static int int_cmp(const void *v1, const void *v2)
 {
@@ -98,6 +186,7 @@ static int search_polyloop_cmp(const void *v1, const void *v2)
 int BKE_mesh_validate_arrays(Mesh *mesh,
                              MVert *mverts, unsigned int totvert,
                              MEdge *medges, unsigned int totedge,
+                             MFace *mfaces, unsigned int totface,
                              MLoop *mloops, unsigned int totloop,
                              MPoly *mpolys, unsigned int totpoly,
                              MDeformVert *dverts, /* assume totvert length */
@@ -117,6 +206,7 @@ int BKE_mesh_validate_arrays(Mesh *mesh,
        int *v;
 
        short do_edge_free = FALSE;
+       short do_face_free = FALSE;
        short do_polyloop_free = FALSE; /* This regroups loops and polys! */
 
        short verts_fixed = FALSE;
@@ -193,6 +283,143 @@ int BKE_mesh_validate_arrays(Mesh *mesh,
                }
        }
 
+       if (mfaces && !mpolys) {
+#              define REMOVE_FACE_TAG(_mf) { _mf->v3 = 0; do_face_free = TRUE; } (void)0
+#              define CHECK_FACE_VERT_INDEX(a, b) \
+                                       if (mf->a == mf->b) { \
+                                               PRINT("    face %u: verts invalid, " STRINGIFY(a) "/" STRINGIFY(b) " both %u\n", i, mf->a); \
+                                               remove = do_fixes; \
+                                       } (void)0
+#              define CHECK_FACE_EDGE(a, b) \
+                                       if (!BLI_edgehash_haskey(edge_hash, mf->a, mf->b)) { \
+                                               PRINT("    face %u: edge " STRINGIFY(a) "/" STRINGIFY(b) \
+                                                     " (%u,%u) is missing egde data\n", i, mf->a, mf->b); \
+                                               do_edge_recalc = TRUE; \
+                                       }
+
+               MFace *mf;
+               MFace *mf_prev;
+
+               SortFace *sort_faces = MEM_callocN(sizeof(SortFace) * totface, "search faces");
+               SortFace *sf;
+               SortFace *sf_prev;
+               unsigned int totsortface = 0;
+
+               for (i = 0, mf = mfaces, sf = sort_faces; i < totface; i++, mf++) {
+                       int remove = FALSE;
+                       int fidx;
+                       unsigned int fv[4];
+
+                       fidx = mf->v4 ? 3 : 2;
+                       do {
+                               fv[fidx] = *(&(mf->v1) + fidx);
+                               if (fv[fidx] >= totvert) {
+                                       PRINT("    face %u: 'v%d' index out of range, %u\n", i, fidx + 1, fv[fidx]);
+                                       remove = do_fixes;
+                               }
+                       } while (fidx--);
+
+                       if (remove == FALSE) {
+                               if (mf->v4) {
+                                       CHECK_FACE_VERT_INDEX(v1, v2);
+                                       CHECK_FACE_VERT_INDEX(v1, v3);
+                                       CHECK_FACE_VERT_INDEX(v1, v4);
+
+                                       CHECK_FACE_VERT_INDEX(v2, v3);
+                                       CHECK_FACE_VERT_INDEX(v2, v4);
+
+                                       CHECK_FACE_VERT_INDEX(v3, v4);
+                               }
+                               else {
+                                       CHECK_FACE_VERT_INDEX(v1, v2);
+                                       CHECK_FACE_VERT_INDEX(v1, v3);
+
+                                       CHECK_FACE_VERT_INDEX(v2, v3);
+                               }
+
+                               if (remove == FALSE) {
+                                       if (totedge) {
+                                               if (mf->v4) {
+                                                       CHECK_FACE_EDGE(v1, v2);
+                                                       CHECK_FACE_EDGE(v2, v3);
+                                                       CHECK_FACE_EDGE(v3, v4);
+                                                       CHECK_FACE_EDGE(v4, v1);
+                                               }
+                                               else {
+                                                       CHECK_FACE_EDGE(v1, v2);
+                                                       CHECK_FACE_EDGE(v2, v3);
+                                                       CHECK_FACE_EDGE(v3, v1);
+                                               }
+                                       }
+
+                                       sf->index = i;
+
+                                       if (mf->v4) {
+                                               edge_store_from_mface_quad(sf->es, mf);
+
+                                               qsort(sf->es, 4, sizeof(int64_t), int64_cmp);
+                                       }
+                                       else {
+                                               edge_store_from_mface_tri(sf->es, mf);
+                                               qsort(sf->es, 3, sizeof(int64_t), int64_cmp);
+                                       }
+
+                                       totsortface++;
+                                       sf++;
+                               }
+                       }
+
+                       if (remove) {
+                               REMOVE_FACE_TAG(mf);
+                       }
+               }
+
+               qsort(sort_faces, totsortface, sizeof(SortFace), search_face_cmp);
+
+               sf = sort_faces;
+               sf_prev = sf;
+               sf++;
+
+               for (i = 1; i < totsortface; i++, sf++) {
+                       int remove = FALSE;
+
+                       /* on a valid mesh, code below will never run */
+                       if (memcmp(sf->es, sf_prev->es, sizeof(sf_prev->es)) == 0) {
+                               mf = mfaces + sf->index;
+
+                               if (do_verbose) {
+                                       mf_prev = mfaces + sf_prev->index;
+
+                                       if (mf->v4) {
+                                               PRINT("    face %u & %u: are duplicates (%u,%u,%u,%u) (%u,%u,%u,%u)\n",
+                                                     sf->index, sf_prev->index, mf->v1, mf->v2, mf->v3, mf->v4,
+                                                     mf_prev->v1, mf_prev->v2, mf_prev->v3, mf_prev->v4);
+                                       }
+                                       else {
+                                               PRINT("    face %u & %u: are duplicates (%u,%u,%u) (%u,%u,%u)\n",
+                                                     sf->index, sf_prev->index, mf->v1, mf->v2, mf->v3,
+                                                     mf_prev->v1, mf_prev->v2, mf_prev->v3);
+                                       }
+                               }
+
+                               remove = do_fixes;
+                       }
+                       else {
+                               sf_prev = sf;
+                       }
+
+                       if (remove) {
+                               REMOVE_FACE_TAG(mf);
+                       }
+               }
+
+               MEM_freeN(sort_faces);
+
+#              undef REMOVE_FACE_TAG
+#              undef CHECK_FACE_VERT_INDEX
+#              undef CHECK_FACE_EDGE
+       }
+
        /* Checking loops and polys is a bit tricky, as they are quite intricated...
         *
         * Polys must have:
@@ -535,6 +762,10 @@ int BKE_mesh_validate_arrays(Mesh *mesh,
 #   undef REMOVE_POLY_TAG
 
        if (mesh) {
+               if (do_face_free) {
+                       BKE_mesh_strip_loose_faces(mesh);
+               }
+
                if (do_polyloop_free) {
                        BKE_mesh_strip_loose_polysloops(mesh);
                }
@@ -605,6 +836,7 @@ int BKE_mesh_validate(Mesh *me, int do_verbose)
        arrays_fixed = BKE_mesh_validate_arrays(me,
                                                me->mvert, me->totvert,
                                                me->medge, me->totedge,
+                                               me->mface, me->totface,
                                                me->mloop, me->totloop,
                                                me->mpoly, me->totpoly,
                                                me->dvert,
@@ -622,6 +854,7 @@ int BKE_mesh_validate_dm(DerivedMesh *dm)
        return BKE_mesh_validate_arrays(NULL,
                                        dm->getVertArray(dm), dm->getNumVerts(dm),
                                        dm->getEdgeArray(dm), dm->getNumEdges(dm),
+                                       dm->getTessFaceArray(dm), dm->getNumTessFaces(dm),
                                        dm->getLoopArray(dm), dm->getNumLoops(dm),
                                        dm->getPolyArray(dm), dm->getNumPolys(dm),
                                        dm->getVertDataArray(dm, CD_MDEFORMVERT),
index 99bb346..72c3cda 100644 (file)
@@ -72,8 +72,8 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
        BM_data_layer_add(bm, &bm->edata, CD_BWEIGHT);
        BM_data_layer_add(bm, &bm->vdata, CD_BWEIGHT);
 
-       vtable = MEM_callocN(sizeof(void**) * totvert, "vert table in BMDM_Copy");
-       etable = MEM_callocN(sizeof(void**) * totedge, "edge table in BMDM_Copy");
+       vtable = MEM_callocN(sizeof(void **) * totvert, "vert table in BMDM_Copy");
+       etable = MEM_callocN(sizeof(void **) * totedge, "edge table in BMDM_Copy");
 
        /*do verts*/
        mv = mvert = dm->dupVertArray(dm);
index 8cb4711..78ccdc4 100644 (file)
@@ -1220,7 +1220,11 @@ static void seq_open_anim_file(Sequence *seq)
        }
 
        if (seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
-               IMB_anim_set_index_dir(seq->anim, seq->strip->proxy->dir);
+               char dir[FILE_MAX];
+               BLI_strncpy(dir, seq->strip->proxy->dir, sizeof(dir));
+               BLI_path_abs(dir, G.main->name);
+
+               IMB_anim_set_index_dir(seq->anim, dir);
        }
 }
 
@@ -2089,7 +2093,7 @@ static ImBuf *seq_render_mask_strip(
                fp_src = maskbuf;
                fp_dst = ibuf->rect_float;
                i = context.rectx * context.recty;
-               while(--i) {
+               while (--i) {
                        fp_dst[0] = fp_dst[1] = fp_dst[2] = *fp_src;
                        fp_dst[3] = 1.0f;
 
@@ -2115,7 +2119,7 @@ static ImBuf *seq_render_mask_strip(
                fp_src = maskbuf;
                ub_dst = (unsigned char *)ibuf->rect;
                i = context.rectx * context.recty;
-               while(--i) {
+               while (--i) {
                        ub_dst[0] = ub_dst[1] = ub_dst[2] = (unsigned char)(*fp_src * 255.0f); /* already clamped */
                        ub_dst[3] = 255;
 
index aa9cc40..1180d2c 100644 (file)
@@ -125,7 +125,7 @@ static struct bUnitDef buMetricLenDef[] = {
 #endif
        {NULL, NULL, NULL,      NULL, NULL, 0.0, 0.0}
 };
-static struct bUnitCollection buMetricLenCollecton = {buMetricLenDef, 3, 0, sizeof(buMetricLenDef)/sizeof(bUnitDef)};
+static struct bUnitCollection buMetricLenCollecton = {buMetricLenDef, 3, 0, sizeof(buMetricLenDef) / sizeof(bUnitDef)};
 
 static struct bUnitDef buImperialLenDef[] = {
        {"mile", "miles",               "mi", "m", "Miles",             UN_SC_MI, 0.0,  B_UNIT_DEF_NONE},
@@ -137,7 +137,7 @@ static struct bUnitDef buImperialLenDef[] = {
        {"thou", "thou",                "thou", "mil", "Thou",  UN_SC_MIL, 0.0, B_UNIT_DEF_NONE}, /* plural for thou has no 's' */
        {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
 };
-static struct bUnitCollection buImperialLenCollecton = {buImperialLenDef, 4, 0, sizeof(buImperialLenDef)/sizeof(bUnitDef)};
+static struct bUnitCollection buImperialLenCollecton = {buImperialLenDef, 4, 0, sizeof(buImperialLenDef) / sizeof(bUnitDef)};
 
 /* Areas */
 static struct bUnitDef buMetricAreaDef[] = {
@@ -151,7 +151,7 @@ static struct bUnitDef buMetricAreaDef[] = {
        {"square micrometer", "square micrometers",     "µm²", "um2", "Square Micrometers", UN_SC_UM*UN_SC_UM, 0.0,   B_UNIT_DEF_NONE},
        {NULL, NULL, NULL,      NULL, NULL, 0.0, 0.0}
 };
-static struct bUnitCollection buMetricAreaCollecton = {buMetricAreaDef, 3, 0, sizeof(buMetricAreaDef)/sizeof(bUnitDef)};
+static struct bUnitCollection buMetricAreaCollecton = {buMetricAreaDef, 3, 0, sizeof(buMetricAreaDef) / sizeof(bUnitDef)};
 
 static struct bUnitDef buImperialAreaDef[] = {
        {"square mile", "square miles",                 "sq mi", "sq m","Square Miles", UN_SC_MI*UN_SC_MI, 0.0,         B_UNIT_DEF_NONE},
@@ -163,7 +163,7 @@ static struct bUnitDef buImperialAreaDef[] = {
        {"square thou", "square thous",                 "sq mil",NULL,  "Square Thous", UN_SC_MIL*UN_SC_MIL, 0.0,       B_UNIT_DEF_NONE},
        {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
 };
-static struct bUnitCollection buImperialAreaCollecton = {buImperialAreaDef, 4, 0, sizeof(buImperialAreaDef)/sizeof(bUnitDef)};
+static struct bUnitCollection buImperialAreaCollecton = {buImperialAreaDef, 4, 0, sizeof(buImperialAreaDef) / sizeof(bUnitDef)};
 
 /* Volumes */
 static struct bUnitDef buMetricVolDef[] = {
@@ -177,7 +177,7 @@ static struct bUnitDef buMetricVolDef[] = {
        {"cubic micrometer", "cubic micrometers",       "µm³", "um3", "Cubic Micrometers", UN_SC_UM*UN_SC_UM*UN_SC_UM, 0.0,   B_UNIT_DEF_NONE},
        {NULL, NULL, NULL,      NULL, NULL, 0.0, 0.0}
 };
-static struct bUnitCollection buMetricVolCollecton = {buMetricVolDef, 3, 0, sizeof(buMetricVolDef)/sizeof(bUnitDef)};
+static struct bUnitCollection buMetricVolCollecton = {buMetricVolDef, 3, 0, sizeof(buMetricVolDef) / sizeof(bUnitDef)};
 
 static struct bUnitDef buImperialVolDef[] = {
        {"cubic mile", "cubic miles",           "cu mi", "cu m","Cubic Miles", UN_SC_MI*UN_SC_MI*UN_SC_MI, 0.0,         B_UNIT_DEF_NONE},
@@ -189,7 +189,7 @@ static struct bUnitDef buImperialVolDef[] = {
        {"cubic thou", "cubic thous",           "cu mil",NULL,  "Cubic Thous", UN_SC_MIL*UN_SC_MIL*UN_SC_MIL, 0.0,      B_UNIT_DEF_NONE},
        {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
 };
-static struct bUnitCollection buImperialVolCollecton = {buImperialVolDef, 4, 0, sizeof(buImperialVolDef)/sizeof(bUnitDef)};
+static struct bUnitCollection buImperialVolCollecton = {buImperialVolDef, 4, 0, sizeof(buImperialVolDef) / sizeof(bUnitDef)};
 
 /* Mass */
 static struct bUnitDef buMetricMassDef[] = {
@@ -201,7 +201,7 @@ static struct bUnitDef buMetricMassDef[] = {
        {"gram", "grams",                       "g",  NULL,     "Grams", UN_SC_G, 0.0,                          B_UNIT_DEF_NONE},
        {NULL, NULL, NULL,      NULL, NULL, 0.0, 0.0}
 };
-static struct bUnitCollection buMetricMassCollecton = {buMetricMassDef, 2, 0, sizeof(buMetricMassDef)/sizeof(bUnitDef)};
+static struct bUnitCollection buMetricMassCollecton = {buMetricMassDef, 2, 0, sizeof(buMetricMassDef) / sizeof(bUnitDef)};
 
 static struct bUnitDef buImperialMassDef[] = {
        {"ton", "tonnes",       "ton", "t",     "Tonnes", UN_SC_ITON, 0.0,              B_UNIT_DEF_NONE},
@@ -211,7 +211,7 @@ static struct bUnitDef buImperialMassDef[] = {
        {"ounce", "ounces",     "oz", NULL,             "Ounces", UN_SC_OZ, 0.0,        B_UNIT_DEF_NONE},
        {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
 };
-static struct bUnitCollection buImperialMassCollecton = {buImperialMassDef, 3, 0, sizeof(buImperialMassDef)/sizeof(bUnitDef)};
+static struct bUnitCollection buImperialMassCollecton = {buImperialMassDef, 3, 0, sizeof(buImperialMassDef) / sizeof(bUnitDef)};
 
 /* Even if user scales the system to a point where km^3 is used, velocity and
  * acceleration aren't scaled: that's why we have so few units for them */
@@ -222,27 +222,27 @@ static struct bUnitDef buMetricVelDef[] = {
        {"kilometer per hour", "kilometers per hour",   "km/h", NULL,   "Kilometers per hour", UN_SC_KM/3600.0f, 0.0, B_UNIT_DEF_SUPPRESS},
        {NULL, NULL, NULL,      NULL, NULL, 0.0, 0.0}
 };
-static struct bUnitCollection buMetricVelCollecton = {buMetricVelDef, 0, 0, sizeof(buMetricVelDef)/sizeof(bUnitDef)};
+static struct bUnitCollection buMetricVelCollecton = {buMetricVelDef, 0, 0, sizeof(buMetricVelDef) / sizeof(bUnitDef)};
 
 static struct bUnitDef buImperialVelDef[] = {
        {"foot per second", "feet per second",  "ft/s", "fps",  "Feet per second", UN_SC_FT, 0.0,               B_UNIT_DEF_NONE}, /* base unit */
        {"mile per hour", "miles per hour",             "mph", NULL,    "Miles per hour", UN_SC_MI/3600.0f, 0.0,B_UNIT_DEF_SUPPRESS},
        {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
 };
-static struct bUnitCollection buImperialVelCollecton = {buImperialVelDef, 0, 0, sizeof(buImperialVelDef)/sizeof(bUnitDef)};
+static struct bUnitCollection buImperialVelCollecton = {buImperialVelDef, 0, 0, sizeof(buImperialVelDef) / sizeof(bUnitDef)};
 
 /* Acceleration */
 static struct bUnitDef buMetricAclDef[] = {
        {"meter per second squared", "meters per second squared", "m/s²", "m/s2", "Meters per second squared", UN_SC_M, 0.0, B_UNIT_DEF_NONE}, /* base unit */
        {NULL, NULL, NULL,      NULL, NULL, 0.0, 0.0}
 };
-static struct bUnitCollection buMetricAclCollecton = {buMetricAclDef, 0, 0, sizeof(buMetricAclDef)/sizeof(bUnitDef)};
+static struct bUnitCollection buMetricAclCollecton = {buMetricAclDef, 0, 0, sizeof(buMetricAclDef) / sizeof(bUnitDef)};
 
 static struct bUnitDef buImperialAclDef[] = {
        {"foot per second squared", "feet per second squared", "ft/s²", "ft/s2", "Feet per second squared", UN_SC_FT, 0.0, B_UNIT_DEF_NONE}, /* base unit */
        {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
 };
-static struct bUnitCollection buImperialAclCollecton = {buImperialAclDef, 0, 0, sizeof(buImperialAclDef)/sizeof(bUnitDef)};
+static struct bUnitCollection buImperialAclCollecton = {buImperialAclDef, 0, 0, sizeof(buImperialAclDef) / sizeof(bUnitDef)};
 
 /* Time */
 static struct bUnitDef buNaturalTimeDef[] = {
@@ -255,7 +255,7 @@ static struct bUnitDef buNaturalTimeDef[] = {
        {"microsecond", "microseconds", "µs", "us",    "Microseconds", 0.000001, 0.0,  B_UNIT_DEF_NONE},
        {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
 };
-static struct bUnitCollection buNaturalTimeCollecton = {buNaturalTimeDef, 3, 0, sizeof(buNaturalTimeDef)/sizeof(bUnitDef)};
+static struct bUnitCollection buNaturalTimeCollecton = {buNaturalTimeDef, 3, 0, sizeof(buNaturalTimeDef) / sizeof(bUnitDef)};
 
 
 static struct bUnitDef buNaturalRotDef[] = {
@@ -264,7 +264,7 @@ static struct bUnitDef buNaturalRotDef[] = {
 //     {"turn", "turns",                               "t", NULL, "Turns",                     1.0/(M_PI*2.0), 0.0,B_UNIT_DEF_NONE},
        {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
 };
-static struct bUnitCollection buNaturalRotCollection = {buNaturalRotDef, 0, 0, sizeof(buNaturalRotDef)/sizeof(bUnitDef)};
+static struct bUnitCollection buNaturalRotCollection = {buNaturalRotDef, 0, 0, sizeof(buNaturalRotDef) / sizeof(bUnitDef)};
 
 #define UNIT_SYSTEM_TOT (((sizeof(bUnitSystems) / 9) / sizeof(void *)) - 1)
 static struct bUnitCollection *bUnitSystems[][9] = {
index b310163..f72942d 100644 (file)
@@ -924,7 +924,7 @@ void BKE_ffmpeg_filepath_get(char *string, RenderData *rd)
                fe++;
        }
 
-       if (!*fe) {
+       if (*fe == NULL) {
                strcat(string, autosplit);
 
                BLI_path_frame_range(string, rd->sfra, rd->efra, 4);
index ec7b597..5f564f7 100644 (file)
@@ -401,7 +401,7 @@ static void join_dirfile_alloc(char **dst, size_t *alloc_len, const char *dir, c
 {
        size_t len = strlen(dir) + strlen(file) + 1;
 
-       if (!*dst)
+       if (*dst == NULL)
                *dst = MEM_callocN(len + 1, "join_dirfile_alloc path");
        else if (*alloc_len < len)
                *dst = MEM_reallocN(*dst, len + 1);
index 46a0ac6..5542889 100644 (file)
@@ -806,7 +806,7 @@ void BLI_getlastdir(const char *dir, char *last, const size_t maxlen)
 const char *BLI_getDefaultDocumentFolder(void)
 {
 #ifndef WIN32
-       const char *xdg_documents_dir= getenv("XDG_DOCUMENTS_DIR");
+       const char *xdg_documents_dir = getenv("XDG_DOCUMENTS_DIR");
 
        if (xdg_documents_dir)
                return xdg_documents_dir;
index accfbfc..eeb0187 100644 (file)
@@ -28,7 +28,7 @@
  * http://blog.ivank.net/fortunes-algorithm-and-implementation.html
  */
 
-/** \file blender/blenkernel/intern/tracking.c
+/** \file blender/blenkernel/intern/voronoi.c
  *  \ingroup bli
  */
 
index 730b741..4bce7a6 100644 (file)
@@ -32,6 +32,10 @@ set(INC
        ../../../intern/guardedalloc
 )
 
+set(INC_SYS
+
+)
+
 set(SRC
        operators/bmo_bevel.c
        operators/bmo_connect.c
index 0b2c304..094b5af 100644 (file)
@@ -699,14 +699,18 @@ static BMLoop *find_ear(BMFace *f, float (*verts)[3], const int nvert, const int
                if (cos1 > cos_threshold) {
                        if (cos1 > fabsf(cos_v3v3v3(larr[i]->v->co, larr[i4]->v->co, larr[i + 2]->v->co)) &&
                            cos1 > fabsf(cos_v3v3v3(larr[i]->v->co, larr[i + 1]->v->co, larr[i + 2]->v->co)))
+                       {
                                i = !i;
+                       }
                }
                /* Last check we do not get overlapping triangles
                 * (as much as possible, ther are some cases with no good solution!) */
                i4 = (i + 3) % 4;
                if (!bm_face_goodline((float const (*)[3])verts, f, BM_elem_index_get(larr[i4]->v), BM_elem_index_get(larr[i]->v),
                                      BM_elem_index_get(larr[i + 1]->v), nvert))
+               {
                        i = !i;
+               }
 /*             printf("%d\n", i);*/
                bestear = larr[i];
 
index 3ec4c51..b6a56e6 100644 (file)
@@ -189,6 +189,22 @@ BMLoop *BM_loop_other_vert_loop(BMLoop *l, BMVert *v)
 #endif
 }
 
+/**
+ * Get the first loop of a vert. Uses the same initialization code for the first loop of the
+ * iterator API
+ */
+
+BMLoop *BM_vert_find_first_loop(BMVert *v)
+{
+       BMEdge *e;
+
+       if(!v || !v->e)
+               return NULL;
+
+       e = bmesh_disk_faceedge_find_first(v->e, v);
+       return bmesh_radial_faceloop_find_first(e->l, v);
+}
+
 /**
  * Returns TRUE if the vertex is used in a given face.
  */
index 2df5adc..36ffc29 100644 (file)
@@ -42,6 +42,7 @@ BMVert *BM_edge_other_vert(BMEdge *e, BMVert *v);
 BMLoop *BM_face_other_edge_loop(BMFace *f, BMEdge *e, BMVert *v);
 BMLoop *BM_face_other_vert_loop(BMFace *f, BMVert *v_prev, BMVert *v);
 BMLoop *BM_loop_other_vert_loop(BMLoop *l, BMVert *v);
+BMLoop *BM_vert_find_first_loop(BMVert *v);
 
 int     BM_vert_edge_count_nonwire(BMVert *v);
 int     BM_vert_edge_count(BMVert *v);
index 160db7c..cfff3d6 100644 (file)
@@ -140,11 +140,14 @@ static void hull_add_triangle(BMesh *bm, GHash *hull_triangles, BLI_mempool *poo
 
 static int hull_point_tri_side(const HullTriangle *t, const float co[3])
 {
-       float p[3], d;
+       /* Added epsilon to fix bug [#31941], improves output when some
+          vertices are nearly coplanar. Might need further tweaking for
+          other cases though. */
+       float p[3], d, epsilon = 0.0001;
        sub_v3_v3v3(p, co, t->v[0]->co);
        d = dot_v3v3(t->no, p);
-       if (d < 0) return -1;
-       else if (d > 0) return 1;
+       if (d < -epsilon) return -1;
+       else if (d > epsilon) return 1;
        else return 0;
 }
 
index 59927e9..ded937b 100644 (file)
@@ -294,8 +294,7 @@ bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh)  // checks if mesh has su
                                
                }
 
-               else if (type == COLLADAFW::MeshPrimitive::LINES)
-               {
+               else if (type == COLLADAFW::MeshPrimitive::LINES) {
                        // TODO: Add Checker for line syntax here
                }
 
@@ -582,8 +581,7 @@ void MeshImporter::read_lines(COLLADAFW::Mesh *mesh, Mesh *me)
                        COLLADAFW::MeshPrimitive *mp = prim_arr[i];
 
                        int type = mp->getPrimitiveType();
-                       if (type == COLLADAFW::MeshPrimitive::LINES)
-                       {
+                       if (type == COLLADAFW::MeshPrimitive::LINES) {
                                unsigned int edge_count  = mp->getFaceCount();
                                unsigned int *indices    = mp->getPositionIndices().getData();
                                
@@ -857,8 +855,7 @@ void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris) //T
                                indices += vcount;
                        }
                }
-               else if (type == COLLADAFW::MeshPrimitive::LINES)
-               {
+               else if (type == COLLADAFW::MeshPrimitive::LINES) {
                        continue; // read the lines later after all the rest is done
                }
 
index 65f552d..4aaff02 100644 (file)
@@ -57,8 +57,7 @@ void SceneExporter::exportHierarchy(Scene *sce)
        // Now find all exportable base ojects (highest in export hierarchy)
        for (node = this->export_settings->export_set; node; node = node->next) {
                Object *ob = (Object *) node->link;
-               if (bc_is_base_node(this->export_settings->export_set, ob)) 
-               {
+               if (bc_is_base_node(this->export_settings->export_set, ob)) {
                        switch (ob->type) {
                                case OB_MESH:
                                case OB_CAMERA:
@@ -86,8 +85,7 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce)
        // Add associated armature first if available
        bool armature_exported = false;
        Object *ob_arm = bc_get_assigned_armature(ob);
-       if (ob_arm != NULL)
-       {
+       if (ob_arm != NULL) {
                armature_exported = bc_is_in_Export_set(this->export_settings->export_set, ob_arm);
                if (armature_exported && bc_is_marked(ob_arm)) {
                        bc_remove_mark(ob_arm);
index cb9da99..955d699 100644 (file)
@@ -187,8 +187,7 @@ Object *bc_get_assigned_armature(Object *ob)
 Object *bc_get_highest_selected_ancestor_or_self(LinkNode *export_set, Object *ob) 
 {
        Object *ancestor = ob;
-       while (ob->parent && bc_is_marked(ob->parent))
-       {
+       while (ob->parent && bc_is_marked(ob->parent)) {
                ob = ob->parent;
                ancestor = ob;
        }
index 2b1e8b6..30cea82 100644 (file)
@@ -46,6 +46,10 @@ set(INC
        ../../../intern/guardedalloc
 )
 
+set(INC_SYS
+
+)
+
 set(SRC
        COM_compositor.h
        COM_defines.h
index 2dd44f8..eae1ffe 100644 (file)
@@ -23,7 +23,7 @@
 #include "COM_OpenCLDevice.h"
 #include "COM_WorkScheduler.h"
 
-typedef enum COM_VendorID  {NVIDIA=0x10DE, AMD=0x1002} COM_VendorID;
+typedef enum COM_VendorID  {NVIDIA = 0x10DE, AMD = 0x1002} COM_VendorID;
 
 OpenCLDevice::OpenCLDevice(cl_context context, cl_device_id device, cl_program program, cl_int vendorId)
 {
index f992b22..c658d66 100644 (file)
@@ -61,7 +61,7 @@ public:
        
        bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
 
-       void updateDispersion(MemoryBuffer** inputBuffers);
+       void updateDispersion(MemoryBuffer **inputBuffers);
 
 };
 #endif
index d990651..7e4fda0 100644 (file)
@@ -68,7 +68,7 @@ public:
 
 private:
        void determineUV(float *result, float x, float y) const;
-       void updateDispersionAndDistortion(MemoryBuffer** inputBuffers);
+       void updateDispersionAndDistortion(MemoryBuffer **inputBuffers);
 
 };
 #endif
index ea3c868..d4755fc 100644 (file)
@@ -4828,6 +4828,9 @@ static void add_verts_to_dgroups(ReportList *reports, Scene *scene, Object *ob,
        if (numbones == 0)
                return;
        
+       if (ED_vgroup_data_create(ob->data) == FALSE)
+               return;
+
        /* create an array of pointer to bones that are skinnable
         * and fill it with all of the skinnable bones */
        bonelist = MEM_callocN(numbones * sizeof(Bone *), "bonelist");
index ab96656..6b6d2a1 100644 (file)
@@ -667,25 +667,27 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource,
        *err_str = NULL;
 
        /* count triangles and create mask */
-       if (     (use_face_sel = (me->editflag & ME_EDIT_PAINT_MASK) != 0) ||
-                (use_vert_sel = ((me->editflag & ME_EDIT_VERT_SEL) != 0)))
+       if ((use_face_sel = (me->editflag & ME_EDIT_PAINT_MASK) != 0) ||
+           (use_vert_sel = ((me->editflag & ME_EDIT_VERT_SEL) != 0)))
        {
                mask = MEM_callocN(sizeof(int) * me->totvert, "heat_bone_weighting mask");
-       }
 
-       for (a = 0, mp = me->mpoly; a < me->totpoly; mp++, a++) {
                /*  (added selectedVerts content for vertex mask, they used to just equal 1) */
                if (use_vert_sel) {
-                       for (j = 0, ml = me->mloop + mp->loopstart; j < mp->totloop; j++, ml++) {
-                               if (use_vert_sel) {
-                                       mask[ml->v] = (mvert[ml->v].flag & SELECT) != 0;
+                       for (a = 0, mp = me->mpoly; a < me->totpoly; mp++, a++) {
+                               for (j = 0, ml = me->mloop + mp->loopstart; j < mp->totloop; j++, ml++) {
+                                       if (use_vert_sel) {
+                                               mask[ml->v] = (mvert[ml->v].flag & SELECT) != 0;
+                                       }
                                }
                        }
                }
                else if (use_face_sel) {
-                       if (mp->flag & ME_FACE_SEL) {
-                               for (j = 0, ml = me->mloop + mp->loopstart; j < mp->totloop; j++, ml++) {
-                                       mask[ml->v] = 1;
+                       for (a = 0, mp = me->mpoly; a < me->totpoly; mp++, a++) {
+                               if (mp->flag & ME_FACE_SEL) {
+                                       for (j = 0, ml = me->mloop + mp->loopstart; j < mp->totloop; j++, ml++) {
+                                               mask[ml->v] = 1;
+                                       }
                                }
                        }
                }
index 4693882..5039a30 100644 (file)
@@ -166,6 +166,7 @@ void UI_view2d_view_restore(const struct bContext *C);
 View2DGrid *UI_view2d_grid_calc(struct Scene *scene, struct View2D *v2d, short xunits, short xclamp, short yunits, short yclamp, int winx, int winy);
 void UI_view2d_grid_draw(struct View2D *v2d, View2DGrid *grid, int flag);
 void UI_view2d_constant_grid_draw(struct View2D *v2d);
+void UI_view2d_multi_grid_draw(struct View2D *v2d, float step, int level_size, int totlevels);
 void UI_view2d_grid_size(View2DGrid *grid, float *r_dx, float *r_dy);
 void UI_view2d_grid_free(View2DGrid *grid);
 
index fe46a5d..407b230 100644 (file)
@@ -1888,8 +1888,8 @@ void init_userdef_do_versions(void)
                        rgba_char_args_set(btheme->tact.anim_active,    204, 112, 26, 102); 
                        
                        /* NLA Colors */
-                       rgba_char_args_set(btheme->tnla.anim_active,    204, 112, 26, 102); /* same as dopesheet above */
-                       rgba_char_args_set(btheme->tnla.anim_non_active,153, 135, 97, 77);
+                       rgba_char_args_set(btheme->tnla.anim_active,     204, 112, 26, 102); /* same as dopesheet above */
+                       rgba_char_args_set(btheme->tnla.anim_non_active, 153, 135, 97, 77);
                        
                        rgba_char_args_set(btheme->tnla.nla_tweaking,   77, 243, 26, 77);
                        rgba_char_args_set(btheme->tnla.nla_tweakdupli, 217, 0, 0, 255);
index 51e1b30..9a783b4 100644 (file)
@@ -1328,6 +1328,54 @@ void UI_view2d_constant_grid_draw(View2D *v2d)
        glEnd();
 }
 
+/* Draw a multi-level grid in given 2d-region */
+void UI_view2d_multi_grid_draw(View2D *v2d, float step, int level_size, int totlevels)
+{
+       int offset = -10;
+       float lstep = step;
+       int level;
+       
+       for (level = 0; level < totlevels; ++level) {
+               int i;
+               float start;
+               
+               UI_ThemeColorShade(TH_BACK, offset);
+               
+               i = (v2d->cur.xmin >= 0.0f ? -(int)(-v2d->cur.xmin / lstep) : (int)(v2d->cur.xmin / lstep));
+               start = i * lstep;
+               
+               glBegin(GL_LINES);
+               for (; start < v2d->cur.xmax; start += lstep, ++i) {
+                       if (i == 0 || (level < totlevels-1 && i % level_size == 0))
+                               continue;
+                       glVertex2f(start, v2d->cur.ymin);
+                       glVertex2f(start, v2d->cur.ymax);
+               }
+               
+               i = (v2d->cur.ymin >= 0.0f ? -(int)(-v2d->cur.ymin / lstep) : (int)(v2d->cur.ymin / lstep));
+               start = i * lstep;
+               
+               for (; start < v2d->cur.ymax; start += lstep, ++i) {
+                       if (i == 0 || (level < totlevels-1 && i % level_size == 0))
+                               continue;
+                       glVertex2f(v2d->cur.xmin, start);
+                       glVertex2f(v2d->cur.xmax, start);
+               }
+               
+               /* X and Y axis */
+               UI_ThemeColorShade(TH_BACK, offset-8);
+               glVertex2f(0.0f, v2d->cur.ymin);
+               glVertex2f(0.0f, v2d->cur.ymax);
+               glVertex2f(v2d->cur.xmin, 0.0f);
+               glVertex2f(v2d->cur.xmax, 0.0f);
+               
+               glEnd();
+               
+               lstep *= level_size;
+               offset -= 6;
+       }
+}
+
 /* the price we pay for not exposting structs :( */
 void UI_view2d_grid_size(View2DGrid *grid, float *r_dx, float *r_dy)
 {
index 0c417c5..7db2304 100644 (file)
@@ -31,6 +31,10 @@ set(INC
        ../../collada
 )
 
+set(INC_SYS
+
+)
+
 set(SRC
        io_collada.c
        io_ops.c
index dca38e5..20ac333 100644 (file)
@@ -24,7 +24,7 @@
  * ***** END GPL LICENSE BLOCK *****
  */
 
-/** \file blender/editors/io/collada.c
+/** \file blender/editors/io/io_collada.c
  *  \ingroup collada
  */
 #ifdef WITH_COLLADA
@@ -157,59 +157,59 @@ void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr)
 
        row = uiLayoutRow(box, 0);
        split = uiLayoutSplit(row, 0.6f, UI_LAYOUT_ALIGN_RIGHT);
-       col   = uiLayoutColumn(split,0);
+       col   = uiLayoutColumn(split, FALSE);
        uiItemR(col, imfptr, "apply_modifiers", 0, NULL, ICON_NONE);
-       col   = uiLayoutColumn(split,0);
+       col   = uiLayoutColumn(split, FALSE);
        uiItemR(col, imfptr, "export_mesh_type_selection", 0, "", ICON_NONE);
        uiLayoutSetEnabled(col, RNA_boolean_get(imfptr, "apply_modifiers"));
 
-       row = uiLayoutRow(box, 0);
+       row = uiLayoutRow(box, FALSE);
        uiItemR(row, imfptr, "selected", 0, NULL, ICON_NONE);
 
-       row = uiLayoutRow(box, 0);
+       row = uiLayoutRow(box, FALSE);
        uiItemR(row, imfptr, "include_children", 0, NULL, ICON_NONE);
        uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected"));
 
-       row = uiLayoutRow(box, 0);
+       row = uiLayoutRow(box, FALSE);
        uiItemR(row, imfptr, "include_armatures", 0, NULL, ICON_NONE);
        uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected"));
 
        // Texture options
        box = uiLayoutBox(layout);
-       row = uiLayoutRow(box, 0);
+       row = uiLayoutRow(box, FALSE);
        uiItemL(row, IFACE_("Texture Options:"), ICON_TEXTURE_DATA);
 
-       row = uiLayoutRow(box, 0);
+       row = uiLayoutRow(box, FALSE);
        uiItemR(row, imfptr, "active_uv_only", 0, NULL, ICON_NONE);
 
-       row = uiLayoutRow(box, 0);
+       row = uiLayoutRow(box, FALSE);
        uiItemR(row, imfptr, "include_uv_textures", 0, NULL, ICON_NONE);
 
-       row = uiLayoutRow(box, 0);
+       row = uiLayoutRow(box, FALSE);
        uiItemR(row, imfptr, "include_material_textures", 0, NULL, ICON_NONE);
 
-       row = uiLayoutRow(box, 0);
+       row = uiLayoutRow(box, FALSE);
        uiItemR(row, imfptr, "use_texture_copies", 1, NULL, ICON_NONE);
 
 
        // Armature options
        box = uiLayoutBox(layout);
-       row = uiLayoutRow(box, 0);
+       row = uiLayoutRow(box, FALSE);
        uiItemL(row, IFACE_("Armature Options:"), ICON_ARMATURE_DATA);
 
-       row = uiLayoutRow(box, 0);
+       row = uiLayoutRow(box, FALSE);
        uiItemR(row, imfptr, "deform_bones_only", 0, NULL, ICON_NONE);
-       row = uiLayoutRow(box, 0);
+       row = uiLayoutRow(box, FALSE);
        uiItemR(row, imfptr, "second_life", 0, NULL, ICON_NONE);
 
        /* Collada options: */
        box = uiLayoutBox(layout);
-       row = uiLayoutRow(box, 0);
+       row = uiLayoutRow(box, FALSE);
        uiItemL(row, IFACE_("Collada Options:"), ICON_MODIFIER);
 
-       row = uiLayoutRow(box, 0);
+       row = uiLayoutRow(box, FALSE);
        uiItemR(row, imfptr, "use_object_instantiation", 0, NULL, ICON_NONE);
-       row = uiLayoutRow(box, 0);
+       row = uiLayoutRow(box, FALSE);
        uiItemR(row, imfptr, "sort_by_name", 0, NULL, ICON_NONE);
 
 }
index 1e2c444..4c04b34 100644 (file)
@@ -24,7 +24,7 @@
  * ***** END GPL LICENSE BLOCK *****
  */
 
-/** \file blender/editor/io/io_collada.h
+/** \file blender/editor/io/io_ops.h
  *  \ingroup editor/io
  */
 
index cacd6d0..6782cd5 100644 (file)
@@ -458,7 +458,7 @@ int ED_operator_editmball(bContext *C)
 
 int ED_operator_mask(bContext *C)
 {
-       SpaceClip *sc= CTX_wm_space_clip(C);
+       SpaceClip *sc = CTX_wm_space_clip(C);
 
        return ED_space_clip_check_show_maskedit(sc);
 }
index 1190ac3..99d3a32 100644 (file)
@@ -1195,7 +1195,7 @@ static void node_common_set_butfunc(bNodeType *ntype)
 
 /* ****************** BUTTON CALLBACKS FOR SHADER NODES ***************** */
 
-static void node_buts_image_user(uiLayout *layout, bContext *C, PointerRNA *imaptr, PointerRNA *iuserptr)
+static void node_buts_image_user(uiLayout *layout, bContext *C, PointerRNA *ptr, PointerRNA *imaptr, PointerRNA *iuserptr)
 {
        uiLayout *col;
        int source;
@@ -1221,18 +1221,17 @@ static void node_buts_image_user(uiLayout *layout, bContext *C, PointerRNA *imap
 
        if (ELEM(source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) {
                col = uiLayoutColumn(layout, TRUE);
-               uiItemR(col, iuserptr, "frame_duration", 0, NULL, ICON_NONE);
-               uiItemR(col, iuserptr, "frame_start", 0, NULL, ICON_NONE);
-               uiItemR(col, iuserptr, "frame_offset", 0, NULL, ICON_NONE);
-               uiItemR(col, iuserptr, "use_cyclic", 0, NULL, ICON_NONE);
-               uiItemR(col, iuserptr, "use_auto_refresh", UI_ITEM_R_ICON_ONLY, NULL, ICON_NONE);
+               uiItemR(col, ptr, "frame_duration", 0, NULL, ICON_NONE);
+               uiItemR(col, ptr, "frame_start", 0, NULL, ICON_NONE);
+               uiItemR(col, ptr, "frame_offset", 0, NULL, ICON_NONE);
+               uiItemR(col, ptr, "use_cyclic", 0, NULL, ICON_NONE);
+               uiItemR(col, ptr, "use_auto_refresh", UI_ITEM_R_ICON_ONLY, NULL, ICON_NONE);
        }
 
        col = uiLayoutColumn(layout, FALSE);
 
        if (RNA_enum_get(imaptr, "type") == IMA_TYPE_MULTILAYER)
-               uiItemR(col, iuserptr, "layer", 0, NULL, ICON_NONE);
-
+               uiItemR(col, ptr, "layer", 0, NULL, ICON_NONE);
 }
 
 static void node_shader_buts_material(uiLayout *layout, bContext *C, PointerRNA *ptr)
@@ -1312,7 +1311,7 @@ static void node_shader_buts_tex_image(uiLayout *layout, bContext *C, PointerRNA
        uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL);
        uiItemR(layout, ptr, "color_space", 0, "", ICON_NONE);
 
-       node_buts_image_user(layout, C, &imaptr, &iuserptr);
+       node_buts_image_user(layout, C, ptr, &imaptr, &iuserptr);
 }
 
 static void node_shader_buts_tex_environment(uiLayout *layout, bContext *C, PointerRNA *ptr)
@@ -1324,7 +1323,7 @@ static void node_shader_buts_tex_environment(uiLayout *layout, bContext *C, Poin
        uiItemR(layout, ptr, "color_space", 0, "", ICON_NONE);
        uiItemR(layout, ptr, "projection", 0, "", ICON_NONE);
 
-       node_buts_image_user(layout, C, &imaptr, &iuserptr);
+       node_buts_image_user(layout, C, ptr, &imaptr, &iuserptr);
 }
 
 static void node_shader_buts_tex_sky(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -1457,7 +1456,7 @@ static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA *
        imaptr = RNA_pointer_get(ptr, "image");
        RNA_pointer_create((ID *)ptr->id.data, &RNA_ImageUser, node->storage, &iuserptr);
        
-       node_buts_image_user(layout, C, &imaptr, &iuserptr);
+       node_buts_image_user(layout, C, ptr, &imaptr, &iuserptr);
 }
 
 static void node_composit_buts_renderlayers(uiLayout *layout, bContext *C, PointerRNA *ptr)
index c65bbd6..f9aa0df 100644 (file)
@@ -1095,7 +1095,9 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d)
        snode->aspect= (v2d->cur.xmax - v2d->cur.xmin)/((float)ar->winx);
        // XXX snode->curfont= uiSetCurFont_ext(snode->aspect);
 
-       UI_view2d_constant_grid_draw(v2d);
+       /* grid */
+       UI_view2d_multi_grid_draw(v2d, 25.0f, 5, 2);
+
        /* backdrop */
        draw_nodespace_back_pix(ar, snode, color_manage);
        
index 1e452f2..7dbcabe 100644 (file)
@@ -58,7 +58,7 @@ void sequencer_buttons_register(ARegionType *art)
        pt = MEM_callocN(sizeof(PanelType), "spacetype sequencer panel gpencil");
        strcpy(pt->idname, "SEQUENCER_PT_gpencil");
        strcpy(pt->label, N_("Grease Pencil"));
-       pt->draw= gpencil_panel_standard;
+       pt->draw = gpencil_panel_standard;
        BLI_addtail(&art->paneltypes, pt);
 }
 
index 3ebc4eb..f0275fb 100644 (file)
@@ -830,7 +830,7 @@ void TEXT_OT_paste(wmOperatorType *ot)
 
 static int text_duplicate_line_exec(bContext *C, wmOperator *UNUSED(op))
 {
-       Text *text= CTX_data_edit_text(C);
+       Text *text = CTX_data_edit_text(C);
        
        txt_duplicate_line(text);
        
@@ -1341,7 +1341,7 @@ static int move_lines_exec(bContext *C, wmOperator *op)
        txt_move_lines(text, direction);
        
        text_update_cursor_moved(C);
-       WM_event_add_notifier(C, NC_TEXT|NA_EDITED, text);
+       WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
 
        /* run the script while editing, evil but useful */
        if (CTX_wm_space_text(C)->live_edit)
@@ -1352,7 +1352,7 @@ static int move_lines_exec(bContext *C, wmOperator *op)
 
 void TEXT_OT_move_lines(wmOperatorType *ot)
 {
-       static EnumPropertyItem direction_items[]= {
+       static EnumPropertyItem direction_items[] = {
                {TXT_MOVE_LINE_UP, "UP", 0, "Up", ""},
                {TXT_MOVE_LINE_DOWN, "DOWN", 0, "Down", ""},
                {0, NULL, 0, NULL, NULL}
index 248f73b..5376b82 100644 (file)
@@ -57,23 +57,23 @@ static SpaceLink *userpref_new(const bContext *UNUSED(C))
 {
        ARegion *ar;
        SpaceUserPref *spref;
-       
-       spref= MEM_callocN(sizeof(SpaceUserPref), "inituserpref");
-       spref->spacetype= SPACE_USERPREF;
-       
+
+       spref = MEM_callocN(sizeof(SpaceUserPref), "inituserpref");
+       spref->spacetype = SPACE_USERPREF;
+
        /* header */
-       ar= MEM_callocN(sizeof(ARegion), "header for userpref");
-       
+       ar = MEM_callocN(sizeof(ARegion), "header for userpref");
+
        BLI_addtail(&spref->regionbase, ar);
-       ar->regiontype= RGN_TYPE_HEADER;
-       ar->alignment= RGN_ALIGN_BOTTOM;
-       
+       ar->regiontype = RGN_TYPE_HEADER;
+       ar->alignment = RGN_ALIGN_BOTTOM;
+
        /* main area */
-       ar= MEM_callocN(sizeof(ARegion), "main area for userpref");
-       
+       ar = MEM_callocN(sizeof(ARegion), "main area for userpref");
+
        BLI_addtail(&spref->regionbase, ar);
-       ar->regiontype= RGN_TYPE_WINDOW;
-       
+       ar->regiontype = RGN_TYPE_WINDOW;
+
        return (SpaceLink *)spref;
 }
 
@@ -93,10 +93,10 @@ static void userpref_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa
 
 static SpaceLink *userpref_duplicate(SpaceLink *sl)
 {
-       SpaceUserPref *sprefn= MEM_dupallocN(sl);
-       
+       SpaceUserPref *sprefn = MEM_dupallocN(sl);
+
        /* clear or remove stuff from old */
-       
+
        return (SpaceLink *)sprefn;
 }
 
@@ -155,41 +155,41 @@ static void userpref_header_listener(ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn
 /* only called once, from space/spacetypes.c */
 void ED_spacetype_userpref(void)
 {
-       SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype userpref");
+       SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype userpref");
        ARegionType *art;
-       
-       st->spaceid= SPACE_USERPREF;
+
+       st->spaceid = SPACE_USERPREF;
        strncpy(st->name, "Userpref", BKE_ST_MAXNAME);
-       
-       st->new= userpref_new;
-       st->free= userpref_free;
-       st->init= userpref_init;
-       st->duplicate= userpref_duplicate;
-       st->operatortypes= userpref_operatortypes;
-       st->keymap= userpref_keymap;
-       
+
+       st->new = userpref_new;
+       st->free = userpref_free;
+       st->init = userpref_init;
+       st->duplicate = userpref_duplicate;
+       st->operatortypes = userpref_operatortypes;
+       st->keymap = userpref_keymap;
+
        /* regions: main window */
-       art= MEM_callocN(sizeof(ARegionType), "spacetype userpref region");
+       art = MEM_callocN(sizeof(ARegionType), "spacetype userpref region");
        art->regionid = RGN_TYPE_WINDOW;
-       art->init= userpref_main_area_init;
-       art->draw= userpref_main_area_draw;
-       art->listener= userpref_main_area_listener;
-       art->keymapflag= ED_KEYMAP_UI;
+       art->init = userpref_main_area_init;
+       art->draw = userpref_main_area_draw;
+       art->listener = userpref_main_area_listener;
+       art->keymapflag = ED_KEYMAP_UI;
 
        BLI_addhead(&st->regiontypes, art);
-       
+
        /* regions: header */
-       art= MEM_callocN(sizeof(ARegionType), "spacetype userpref region");
+       art = MEM_callocN(sizeof(ARegionType), "spacetype userpref region");
        art->regionid = RGN_TYPE_HEADER;
-       art->prefsizey= HEADERY;
-       art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_HEADER;
-       art->listener= userpref_header_listener;
-       art->init= userpref_header_area_init;
-       art->draw= userpref_header_area_draw;
-       
+       art->prefsizey = HEADERY;
+       art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_HEADER;
+       art->listener = userpref_header_listener;
+       art->init = userpref_header_area_init;
+       art->draw = userpref_header_area_draw;
+
        BLI_addhead(&st->regiontypes, art);
-       
-       
+
+
        BKE_spacetype_register(st);
 }
 
index cedb09e..4dee351 100644 (file)
@@ -3542,6 +3542,11 @@ void initTranslation(TransInfo *t)
                t->snap[1] = 0.125f;
                t->snap[2] = 0.0625f;
        }
+       else if (t->spacetype == SPACE_NODE) {
+               t->snap[0] = 0.0f;
+               t->snap[1] = 125.0f;
+               t->snap[2] = 25.0f;
+       }
        else {
                t->snap[0] = 0.0f;
                t->snap[1] = t->snap[2] = 1.0f;
@@ -5004,8 +5009,11 @@ void projectSVData(TransInfo *t, int final)
        for (i = 0, sv = sld->sv; i < sld->totsv; sv++, i++) {
                BMIter fiter;
                BMFace *f;
+               BMIter liter_v;
+               BMLoop *l_v;
+               float uv_med[2] = {0.0, 0.0};
+               int tot_loops = 0;
                
-
                /* BMESH_TODO, this interpolates between vertex/loops which are not moved
                 * (are only apart of a face attached to a slide vert), couldn't we iterate BM_LOOPS_OF_VERT
                 * here and only interpolate those? */
@@ -5034,6 +5042,8 @@ void projectSVData(TransInfo *t, int final)
                        
                        /* project onto copied projection face */
                        BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
+                               /* only affected verts will get interpolated */
+                               char affected = FALSE;
                                f_copy_flip = f_copy;
 
                                if (BM_elem_flag_test(l->e, BM_ELEM_SELECT) || BM_elem_flag_test(l->prev->e, BM_ELEM_SELECT)) {
@@ -5058,6 +5068,8 @@ void projectSVData(TransInfo *t, int final)
                                        if (!f_copy_flip) {
                                                continue;  /* shouldn't happen, but protection */
                                        }
+
+                                       affected = TRUE;
                                }
                                else {
                                        /* the loop is attached to only one vertex and not a selected edge,
@@ -5094,10 +5106,15 @@ void projectSVData(TransInfo *t, int final)
                                                                f_copy_flip = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)e_sel->l->radial_next->f);
                                                        }
                                                }
+
+                                               affected = TRUE;
                                        }
 
                                }
                                
+                               if(!affected)
+                                       continue;
+
                                /* only loop data, no vertex data since that contains shape keys,
                                 * and we do not want to mess up other shape keys */
                                BM_loop_interp_from_face(em->bm, l, f_copy_flip, FALSE, FALSE);
@@ -5121,8 +5138,23 @@ void projectSVData(TransInfo *t, int final)
                                BM_elem_hide_set(em->bm, f, is_hide);
                        }
                }
+
+               /* make sure every loop of the vertex has identical uv data. Use this temporarily to
+                * fix #31581 until proper data correction/ support for islands is done */
+               BM_ITER_ELEM (l_v, &liter_v, sv->v, BM_LOOPS_OF_VERT) {
+                       MLoopUV *uv = CustomData_bmesh_get(&em->bm->ldata, l_v->head.data, CD_MLOOPUV);
+                       add_v2_v2(uv_med, uv->uv);
+                       tot_loops++;
+               }
+
+               mul_v2_fl(uv_med, 1.0/tot_loops);
+
+               BM_ITER_ELEM (l_v, &liter_v, sv->v, BM_LOOPS_OF_VERT) {
+                       MLoopUV *uv = CustomData_bmesh_get(&em->bm->ldata, l_v->head.data, CD_MLOOPUV);
+                       copy_v2_v2(uv->uv, uv_med);
+               }
        }
-       
+
        BLI_smallhash_release(&visit);
 }
 
index 90b6795..d485b88 100644 (file)
@@ -459,7 +459,7 @@ void initSnapping(TransInfo *t, wmOperator *op)
        }
        /* use scene defaults only when transform is modal */
        else if (t->flag & T_MODAL) {
-               if (ELEM(t->spacetype, SPACE_VIEW3D, SPACE_IMAGE)) {
+               if (ELEM3(t->spacetype, SPACE_VIEW3D, SPACE_IMAGE, SPACE_NODE)) {
                        if (ts->snap_flag & SCE_SNAP) {
                                t->modifiers |= MOD_SNAP;
                        }
index 0ecd5cf..93ee5a4 100644 (file)
@@ -352,7 +352,7 @@ ImBuf *IMB_allocImBuf(unsigned int x, unsigned int y, uchar planes, unsigned int
                ibuf->planes = planes;
                ibuf->ftype = TGA;
                ibuf->channels = 4;  /* float option, is set to other values when buffers get assigned */
-               ibuf->ppm[0] = ibuf->ppm[1] = 150.0 / 0.0254; /* 150dpi -> pixels-per-meter */
+               ibuf->ppm[0] = ibuf->ppm[1] = IMB_DPI_DEFAULT / 0.0254; /* IMB_DPI_DEFAULT -> pixels-per-meter */
                
                if (flags & IB_rect) {
                        if (imb_addrectImBuf(ibuf) == FALSE) {
index 47b4b7b..999aae8 100644 (file)
@@ -72,5 +72,7 @@ typedef unsigned char uchar;
 #define TRUE 1
 #define FALSE 0
 
+#define IMB_DPI_DEFAULT 72.0f
+
 #endif /* __IMBUF_H__ */
 
index 556ec64..30dc615 100644 (file)
@@ -811,7 +811,7 @@ int imb_savetiff(ImBuf *ibuf, const char *name, int flags)
                yres = (float)(ibuf->ppm[1] * 0.0254);
        }
        else {
-               xres = yres = 150.0f;
+               xres = yres = IMB_DPI_DEFAULT;
        }
 
        TIFFSetField(image, TIFFTAG_XRESOLUTION,     xres);
index 55fb332..17ee872 100644 (file)
@@ -891,7 +891,7 @@ typedef enum eAnimData_Flag {
 typedef enum eAnimData_Recalc {
        ADT_RECALC_DRIVERS              = (1<<0),
        ADT_RECALC_ANIM                 = (1<<1),
-       ADT_RECALC_ALL                  = (ADT_RECALC_DRIVERS|ADT_RECALC_ANIM)
+       ADT_RECALC_ALL                  = (ADT_RECALC_DRIVERS | ADT_RECALC_ANIM)
 } eAnimData_Recalc;
 
 /* Base Struct for Anim ------------------------------------- */
index 3bceb02..6a8022c 100644 (file)
@@ -625,7 +625,7 @@ typedef struct GameData {
        short ticrate, maxlogicstep, physubstep, maxphystep;
        short obstacleSimulation, pad1;
        float levelHeight;
-       float deactivationtime, lineardeactthreshold, angulardeactthreshold,pad2;
+       float deactivationtime, lineardeactthreshold, angulardeactthreshold, pad2;
 } GameData;
 
 #define STEREO_NOSTEREO                1
index 2498cba..8be7433 100644 (file)
@@ -659,10 +659,10 @@ static eSDNA_Type sdna_type_nr(const char *dna_type)
        if     ((strcmp(dna_type, "char") == 0) || (strcmp(dna_type, "const char") == 0))          return SDNA_TYPE_CHAR;
        else if ((strcmp(dna_type, "uchar") == 0) || (strcmp(dna_type, "unsigned char") == 0))     return SDNA_TYPE_UCHAR;
        else if ( strcmp(dna_type, "short") == 0)                                                  return SDNA_TYPE_SHORT;
-       else if ((strcmp(dna_type, "ushort") == 0)||(strcmp(dna_type, "unsigned short") == 0))     return SDNA_TYPE_USHORT;
+       else if ((strcmp(dna_type, "ushort") == 0) || (strcmp(dna_type, "unsigned short") == 0))   return SDNA_TYPE_USHORT;
        else if ( strcmp(dna_type, "int") == 0)                                                    return SDNA_TYPE_INT;
        else if ( strcmp(dna_type, "long") == 0)                                                   return SDNA_TYPE_LONG;
-       else if ((strcmp(dna_type, "ulong") == 0)||(strcmp(dna_type, "unsigned long") == 0))       return SDNA_TYPE_ULONG;
+       else if ((strcmp(dna_type, "ulong") == 0) || (strcmp(dna_type, "unsigned long") == 0))     return SDNA_TYPE_ULONG;
        else if ( strcmp(dna_type, "float") == 0)                                                  return SDNA_TYPE_FLOAT;
        else if ( strcmp(dna_type, "double") == 0)                                                 return SDNA_TYPE_DOUBLE;
        else if ( strcmp(dna_type, "int64_t") == 0)                                                return SDNA_TYPE_INT64;
index ae8b0c5..e44d6a1 100644 (file)
@@ -1116,7 +1116,7 @@ static void rna_def_constraint_action(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Object Action",
                                 "Bones only: apply the object's transformation channels of the action "
                                 "to the constrained bone, instead of bone's channels");
-       RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+       RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
 
        prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_TIME);
        RNA_def_property_int_sdna(prop, NULL, "start");
index f70fe90..86d06b7 100644 (file)
@@ -1187,7 +1187,7 @@ static void rna_def_curve_spline_points(BlenderRNA *brna, PropertyRNA *cprop)
        RNA_def_function_ui_description(func, "Remove a spline from a curve");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        parm= RNA_def_pointer(func, "spline", "Spline", "", "The spline to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
 #endif
 }
 
index 333f687..144b8a7 100644 (file)
@@ -1136,9 +1136,9 @@ static void rna_def_drivertarget(BlenderRNA *brna)
                {0, "WORLD_SPACE", 0, "World Space", "Transforms include effects of parenting/restpose and constraints"},
                {DTAR_FLAG_LOCALSPACE, "TRANSFORM_SPACE", 0, "Transform Space",
                                       "Transforms don't include parenting/restpose or constraints"},
-               {DTAR_FLAG_LOCALSPACE|DTAR_FLAG_LOCAL_CONSTS, "LOCAL_SPACE", 0, "Local Space",
-                                                             "Transforms include effects of constraints but not "
-                                                             "parenting/restpose"},
+               {DTAR_FLAG_LOCALSPACE | DTAR_FLAG_LOCAL_CONSTS, "LOCAL_SPACE", 0, "Local Space",
+                                                               "Transforms include effects of constraints but not "
+                                                               "parenting/restpose"},
                {0, NULL, 0, NULL, NULL}
        };
        
index 6ac032e..c98e1f3 100644 (file)
@@ -255,7 +255,7 @@ static void rna_Main_movieclips_begin(CollectionPropertyIterator *iter, PointerR
 
 static void rna_Main_masks_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
-       Main *bmain= (Main*)ptr->data;
+       Main *bmain = (Main*)ptr->data;
        rna_iterator_listbase_begin(iter, &bmain->mask, NULL);
 }
 
index 98b3c0a..c702972 100644 (file)
@@ -1548,12 +1548,12 @@ void RNA_def_main_masks(BlenderRNA *brna, PropertyRNA *cprop)
        PropertyRNA *parm;
 
        RNA_def_property_srna(cprop, "BlendDataMasks");
-       srna= RNA_def_struct(brna, "BlendDataMasks", NULL);
+       srna = RNA_def_struct(brna, "BlendDataMasks", NULL);
        RNA_def_struct_sdna(srna, "Main");
        RNA_def_struct_ui_text(srna, "Main Masks", "Collection of masks");
 
-       func= RNA_def_function(srna, "tag", "rna_Main_masks_tag");
-       parm= RNA_def_boolean(func, "value", 0, "Value", "");
+       func = RNA_def_function(srna, "tag", "rna_Main_masks_tag");
+       parm = RNA_def_boolean(func, "value", 0, "Value", "");
        RNA_def_property_flag(parm, PROP_REQUIRED);
 
        /* new func */
@@ -1565,10 +1565,10 @@ void RNA_def_main_masks(BlenderRNA *brna, PropertyRNA *cprop)
        RNA_def_function_return(func, parm);
 
        /* remove func */
-       func= RNA_def_function(srna, "remove", "rna_Main_masks_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_masks_remove");
        RNA_def_function_ui_description(func, "Remove a masks from the current blendfile.");
-       parm= RNA_def_pointer(func, "mask", "Mask", "", "Mask to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
+       parm = RNA_def_pointer(func, "mask", "Mask", "", "Mask to remove");
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
 }
 
 #endif
index 51dfa02..b879d2b 100644 (file)
@@ -66,7 +66,7 @@ static void rna_Mask_update_data(Main *UNUSED(bmain), Scene *UNUSED(scene), Poin
 {
        Mask *mask = ptr->id.data;
 
-       WM_main_add_notifier(NC_MASK|ND_DATA, mask);
+       WM_main_add_notifier(NC_MASK | ND_DATA, mask);
        DAG_id_tag_update( &mask->id, 0);
 }
 
@@ -327,7 +327,7 @@ static MaskLayer *rna_Mask_layer_new(Mask *mask, const char *name)
 {
        MaskLayer *masklay = BKE_mask_layer_new(mask, name);
 
-       WM_main_add_notifier(NC_MASK|NA_EDITED, mask);
+       WM_main_add_notifier(NC_MASK | NA_EDITED, mask);
 
        return masklay;
 }
@@ -336,7 +336,7 @@ void rna_Mask_layer_remove(Mask *mask, MaskLayer *masklay)
 {
        BKE_mask_layer_remove(mask, masklay);
 
-       WM_main_add_notifier(NC_MASK|NA_EDITED, mask);
+       WM_main_add_notifier(NC_MASK | NA_EDITED, mask);
 }
 
 static void rna_MaskLayer_spline_add(ID *id, MaskLayer *masklay, int number)
@@ -347,7 +347,7 @@ static void rna_MaskLayer_spline_add(ID *id, MaskLayer *masklay, int number)
        for (i = 0; i < number; i++)
                BKE_mask_spline_add(masklay);
 
-       WM_main_add_notifier(NC_MASK|NA_EDITED, mask);
+       WM_main_add_notifier(NC_MASK | NA_EDITED, mask);
 }
 
 static void rna_Mask_start_frame_set(PointerRNA *ptr, int value)
@@ -526,14 +526,14 @@ static void rna_def_mask_splines(BlenderRNA *brna)
        prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
        RNA_def_property_struct_type(prop, "MaskSpline");
        RNA_def_property_pointer_funcs(prop, "rna_MaskLayer_active_spline_get", "rna_MaskLayer_active_spline_set", NULL, NULL);
-       RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_UNLINK);
+       RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
        RNA_def_property_ui_text(prop, "Active Spline", "Active spline of masking layer");
 
        /* active point */
        prop = RNA_def_property(srna, "active_point", PROP_POINTER, PROP_NONE);
        RNA_def_property_struct_type(prop, "MaskSplinePoint");
        RNA_def_property_pointer_funcs(prop, "rna_MaskLayer_active_spline_point_get", "rna_MaskLayer_active_spline_point_set", NULL, NULL);
-       RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_UNLINK);
+       RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
        RNA_def_property_ui_text(prop, "Active Spline", "Active spline of masking layer");
 }
 
@@ -675,7 +675,7 @@ static void rna_def_masklayers(BlenderRNA *brna, PropertyRNA *cprop)
        prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
        RNA_def_property_struct_type(prop, "MaskLayer");
        RNA_def_property_pointer_funcs(prop, "rna_Mask_layer_active_get", "rna_Mask_layer_active_set", NULL, NULL);
-       RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_UNLINK);
+       RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
        RNA_def_property_ui_text(prop, "Active Shape", "Active layer in this mask");
 }
 
index 7daa0d9..f13cf65 100644 (file)
@@ -2374,7 +2374,7 @@ static void rna_def_loop_colors(BlenderRNA *brna, PropertyRNA *cprop)
        RNA_def_function_ui_description(func, "Remove a vertex color layer");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        parm = RNA_def_pointer(func, "layer", "Layer", "", "The layer to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
 #endif
 
        prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED);
@@ -2551,7 +2551,7 @@ static void rna_def_uv_textures(BlenderRNA *brna, PropertyRNA *cprop)
        RNA_def_function_ui_description(func, "Remove a vertex color layer");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        parm = RNA_def_pointer(func, "layer", "Layer", "", "The layer to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
 #endif
 
        prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED);
index dea1d8c..5c55e64 100644 (file)
@@ -1944,6 +1944,10 @@ static void def_cmp_image(StructRNA *srna)
        RNA_def_property_ui_text(prop, "Image", "");
        RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
        
+       /* NB: image user properties used in the UI are redefined in def_node_image_user,
+        * to trigger correct updates of the node editor. RNA design problem that prevents
+        * updates from nested structs ...
+        */
        RNA_def_struct_sdna_from(srna, "ImageUser", "storage");
        def_node_image_user(srna);
 }
@@ -2049,10 +2053,10 @@ static void def_cmp_dilate_erode(StructRNA *srna)
        PropertyRNA *prop;
 
        static EnumPropertyItem type_items[] = {
-           {CMP_NODE_DILATEERODE_STEP,            "STEP",      0, "Step",      ""},
-           {CMP_NODE_DILATEERODE_DISTANCE_THRESH, "THRESHOLD", 0, "Threshold", ""},
-           {CMP_NODE_DILATEERODE_DISTANCE,        "DISTANCE",  0, "Distance",  ""},
-           {CMP_NODE_DILATEERODE_DISTANCE_FEATHER,"FEATHER",  0,  "Feather",  ""},
+           {CMP_NODE_DILATEERODE_STEP,             "STEP",      0, "Step",      ""},
+           {CMP_NODE_DILATEERODE_DISTANCE_THRESH,  "THRESHOLD", 0, "Threshold", ""},
+           {CMP_NODE_DILATEERODE_DISTANCE,         "DISTANCE",  0, "Distance",  ""},
+           {CMP_NODE_DILATEERODE_DISTANCE_FEATHER, "FEATHER",   0, "Feather",  ""},
            {0, NULL, 0, NULL, NULL}
        };
        
@@ -3551,14 +3555,14 @@ static void def_cmp_keyingscreen(StructRNA *srna)
        RNA_def_property_struct_type(prop, "MovieClip");
        RNA_def_property_flag(prop, PROP_EDITABLE);
        RNA_def_property_ui_text(prop, "Movie Clip", "");
-       RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+       RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
 
        RNA_def_struct_sdna_from(srna, "NodeKeyingScreenData", "storage");
 
        prop = RNA_def_property(srna, "tracking_object", PROP_STRING, PROP_NONE);
        RNA_def_property_string_sdna(prop, NULL, "tracking_object");
        RNA_def_property_ui_text(prop, "Tracking Object", "");
-       RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+       RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
 }
 
 static void def_cmp_keying(StructRNA *srna)
@@ -3571,19 +3575,19 @@ static void def_cmp_keying(StructRNA *srna)
        RNA_def_property_float_sdna(prop, NULL, "screen_balance");
        RNA_def_property_range(prop, 0.0f, 1.0f);
        RNA_def_property_ui_text(prop, "Screen Balance", "Balance between two non-primary channels primary channel is comparing against");
-       RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+       RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
 
        prop = RNA_def_property(srna, "despill_factor", PROP_FLOAT, PROP_FACTOR);
        RNA_def_property_float_sdna(prop, NULL, "despill_factor");
        RNA_def_property_range(prop, 0.0f, 1.0f);
        RNA_def_property_ui_text(prop, "Despill", "Factor of despilling screen color from image");
-       RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+       RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
 
        prop = RNA_def_property(srna, "clip_black", PROP_FLOAT, PROP_FACTOR);
        RNA_def_property_float_sdna(prop, NULL, "clip_black");
        RNA_def_property_range(prop, 0.0f, 1.0f);
        RNA_def_property_ui_text(prop, "Clip Black", "Value of non-scaled matte pixel which considers as fully background pixel");
-       RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+       RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
 
        prop = RNA_def_property(srna, "clip_white", PROP_FLOAT, PROP_FACTOR);
        RNA_def_property_float_sdna(prop, NULL, "clip_white");
@@ -3595,31 +3599,31 @@ static void def_cmp_keying(StructRNA *srna)
        RNA_def_property_int_sdna(prop, NULL, "blur_pre");
        RNA_def_property_range(prop, 0, 2048);
        RNA_def_property_ui_text(prop, "Pre Blur", "Chroma pre-blur size which applies before running keyer");
-       RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+       RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
 
        prop = RNA_def_property(srna, "blur_post", PROP_INT, PROP_NONE);
        RNA_def_property_int_sdna(prop, NULL, "blur_post");
        RNA_def_property_range(prop, 0, 2048);
        RNA_def_property_ui_text(prop, "Post Blur", "Matte blur size which applies after clipping and dilate/eroding");
-       RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+       RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
 
        prop = RNA_def_property(srna, "dilate_distance", PROP_INT, PROP_NONE);
        RNA_def_property_int_sdna(prop, NULL, "dilate_distance");
        RNA_def_property_range(prop, -100, 100);
        RNA_def_property_ui_text(prop, "Dilate/Erode", "Matte dilate/erode side");
-       RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+       RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
 
        prop = RNA_def_property(srna, "edge_kernel_radius", PROP_INT, PROP_NONE);
        RNA_def_property_int_sdna(prop, NULL, "edge_kernel_radius");
        RNA_def_property_range(prop, 0, 100);
        RNA_def_property_ui_text(prop, "Edge Kernel Radius", "Radius of kernel used to detect whether pixel belongs to edge");
-       RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+       RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
 
        prop = RNA_def_property(srna, "edge_kernel_tolerance", PROP_FLOAT, PROP_FACTOR);
        RNA_def_property_float_sdna(prop, NULL, "edge_kernel_tolerance");
        RNA_def_property_range(prop, 0.0f, 1.0f);
        RNA_def_property_ui_text(prop, "Edge Kernel Tolerance", "Tolerance to pixels inside kernel which are treating as belonging to the same plane");
-       RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+       RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
 
        prop = RNA_def_property(srna, "feather_falloff", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "feather_falloff");
index 5072bda..51c49cf 100644 (file)
@@ -952,8 +952,8 @@ static void rna_GameObjectSettings_physics_type_set(PointerRNA *ptr, int value)
                        break;
                case OB_BODY_TYPE_CHARACTER:
                        ob->gameflag |= OB_COLLISION | OB_GHOST | OB_CHARACTER;
-                       ob->gameflag &= ~(OB_SENSOR | OB_OCCLUDER | OB_DYNAMIC | OB_RIGID_BODY | OB_SOFT_BODY | OB_ACTOR
-                                    | OB_ANISOTROPIC_FRICTION | OB_DO_FH | OB_ROT_FH | OB_COLLISION_RESPONSE | OB_NAVMESH);
+                       ob->gameflag &= ~(OB_SENSOR | OB_OCCLUDER | OB_DYNAMIC | OB_RIGID_BODY | OB_SOFT_BODY | OB_ACTOR |
+                                     OB_ANISOTROPIC_FRICTION | OB_DO_FH | OB_ROT_FH | OB_COLLISION_RESPONSE | OB_NAVMESH);
                break;
                case OB_BODY_TYPE_STATIC:
                        ob->gameflag |= OB_COLLISION;
@@ -1544,17 +1544,17 @@ static void rna_def_object_game_settings(BlenderRNA *brna)
        RNA_def_property_range(prop, 0.0, 1000.0);
        RNA_def_property_ui_text(prop, "Velocity Max", "Clamp velocity to this maximum speed");
        
-       prop= RNA_def_property(srna, "step_height", PROP_FLOAT, PROP_NONE);
+       prop = RNA_def_property(srna, "step_height", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "step_height");
        RNA_def_property_range(prop, 0.0, 1.0);
        RNA_def_property_ui_text(prop, "Step Height", "Maximum height of steps the character can run over");
 
-       prop= RNA_def_property(srna, "jump_speed", PROP_FLOAT, PROP_NONE);
+       prop = RNA_def_property(srna, "jump_speed", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "jump_speed");
        RNA_def_property_range(prop, 0.0, 1000.0);
        RNA_def_property_ui_text(prop, "Jump Force", "Upward velocity applied to the character when jumping (with the Motion actuator)");
 
-       prop= RNA_def_property(srna, "fall_speed", PROP_FLOAT, PROP_NONE);
+       prop = RNA_def_property(srna, "fall_speed", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "fall_speed");
        RNA_def_property_range(prop, 0.0, 1000.0);
        RNA_def_property_ui_text(prop, "Fall Speed Max", "Maximum speed at which the character will fall");
index eaf1ae0..bb8a29f 100644 (file)
@@ -1118,8 +1118,8 @@ static void rna_def_pose_itasc(BlenderRNA *brna)
                {ITASC_INITIAL_REITERATION, "INITIAL", 0, "Initial",
                                            "The solver reiterates (converges) on the first frame but not on "
                                            "subsequent frame"},
-               {ITASC_INITIAL_REITERATION|ITASC_REITERATION, "ALWAYS", 0, "Always",
-                                                             "The solver reiterates (converges) on all frames"},
+               {ITASC_INITIAL_REITERATION | ITASC_REITERATION, "ALWAYS", 0, "Always",
+                                                               "The solver reiterates (converges) on all frames"},
                {0, NULL, 0, NULL, NULL}
        };
 
index 9c8ce83..6b645e0 100644 (file)
@@ -28,6 +28,10 @@ set(INC
        .
 )
 
+set(INC_SYS
+
+)
+
 set(SRC
     OCL_opencl.h
     intern/clew.h
index 1056227..7375ad4 100644 (file)
@@ -147,6 +147,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
 
        /* note that context is an int, python does the conversion in this case */
        int context = WM_OP_EXEC_DEFAULT;
+       int is_undo = FALSE;
 
        /* XXX Todo, work out a better solution for passing on context,
         * could make a tuple from self and pack the name and Context into it... */
@@ -157,7 +158,8 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
                return NULL;
        }
        
-       if (!PyArg_ParseTuple(args, "sO|O!s:_bpy.ops.call", &opname, &context_dict, &PyDict_Type, &kw, &context_str))
+       if (!PyArg_ParseTuple(args, "sO|O!si:_bpy.ops.call",
+                             &opname, &context_dict, &PyDict_Type, &kw, &context_str, &is_undo))
                return NULL;
 
        ot = WM_operatortype_find(opname, TRUE);
@@ -236,7 +238,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
                                PyThreadState *ts = PyEval_SaveThread();
 #endif
 
-                               operator_ret = WM_operator_call_py(C, ot, context, &ptr, reports);
+                               operator_ret = WM_operator_call_py(C, ot, context, &ptr, reports, is_undo);
 
 #ifdef BPY_RELEASE_GIL
                                /* regain GIL */
index 92a4121..bfbc1c6 100644 (file)
@@ -77,32 +77,32 @@ typedef struct InstanceRayObject {
 
 RayObject *RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob)
 {
-       InstanceRayObject *obj= (InstanceRayObject*)MEM_callocN(sizeof(InstanceRayObject), "InstanceRayObject");
-       assert( RE_rayobject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */       
-       
+       InstanceRayObject *obj = (InstanceRayObject *)MEM_callocN(sizeof(InstanceRayObject), "InstanceRayObject");
+       assert(RE_rayobject_isAligned(obj) );  /* RayObject API assumes real data to be 4-byte aligned */
+
        obj->rayobj.api = &instance_api;
        obj->target = target;
        obj->ob = ob;
        obj->target_ob = target_ob;
-       
+
        copy_m4_m4(obj->target2global, transform);
        invert_m4_m4(obj->global2target, obj->target2global);
-       
-       return RE_rayobject_unalignRayAPI((RayObject*) obj);
+
+       return RE_rayobject_unalignRayAPI((RayObject *) obj);
 }
 
 static int  RE_rayobject_instance_intersect(RayObject *o, Isect *isec)
 {
-       InstanceRayObject *obj = (InstanceRayObject*)o;
+       InstanceRayObject *obj = (InstanceRayObject *)o;
        float start[3], dir[3], idot_axis[3], dist;
        int changed = 0, i, res;
-       
+
        // TODO - this is disabling self intersection on instances
        if (isec->orig.ob == obj->ob && obj->ob) {
                changed = 1;
                isec->orig.ob = obj->target_ob;
        }
-       
+
        // backup old values
        copy_v3_v3(start, isec->start);
        copy_v3_v3(dir, isec->dir);
@@ -113,16 +113,16 @@ static int  RE_rayobject_instance_intersect(RayObject *o, Isect *isec)
        mul_m4_v3(obj->global2target, isec->start);
        mul_mat3_m4_v3(obj->global2target, isec->dir);
        isec->dist *= normalize_v3(isec->dir);
-       
+
        // update idot_axis and bv_index
-       for (i=0; i<3; i++) {
-               isec->idot_axis[i]              = 1.0f / isec->dir[i];
-               
-               isec->bv_index[2*i]             = isec->idot_axis[i] < 0.0 ? 1 : 0;
-               isec->bv_index[2*i+1]   = 1 - isec->bv_index[2*i];
-               
-               isec->bv_index[2*i]             = i+3*isec->bv_index[2*i];
-               isec->bv_index[2*i+1]   = i+3*isec->bv_index[2*i+1];
+       for (i = 0; i < 3; i++) {
+               isec->idot_axis[i]        = 1.0f / isec->dir[i];
+
+               isec->bv_index[2 * i]     = isec->idot_axis[i] < 0.0 ? 1 : 0;
+               isec->bv_index[2 * i + 1] = 1 - isec->bv_index[2 * i];
+
+               isec->bv_index[2 * i]     = i + 3 * isec->bv_index[2 * i];
+               isec->bv_index[2 * i + 1] = i + 3 * isec->bv_index[2 * i + 1];
        }
 
        // raycast
@@ -143,11 +143,11 @@ static int  RE_rayobject_instance_intersect(RayObject *o, Isect *isec)
                isec->dist = len_v3(vec);
                isec->hit.ob = obj->ob;
 
-#ifdef RT_USE_LAST_HIT 
+#ifdef RT_USE_LAST_HIT
                // TODO support for last hit optimization in instances that can jump
                // directly to the last hit face.
                // For now it jumps directly to the last-hit instance root node.
-               isec->last_hit = RE_rayobject_unalignRayAPI((RayObject*) obj);
+               isec->last_hit = RE_rayobject_unalignRayAPI((RayObject *) obj);
 #endif
        }
 
@@ -155,19 +155,19 @@ static int  RE_rayobject_instance_intersect(RayObject *o, Isect *isec)
        copy_v3_v3(isec->start, start);
        copy_v3_v3(isec->dir, dir);
        copy_v3_v3(isec->idot_axis, idot_axis);
-       
+
        if (changed)
                isec->orig.ob = obj->ob;
 
        // restore bv_index
-       for (i=0; i<3; i++) {
-               isec->bv_index[2*i]             = isec->idot_axis[i] < 0.0 ? 1 : 0;
-               isec->bv_index[2*i+1]   = 1 - isec->bv_index[2*i];
-               
-               isec->bv_index[2*i]             = i+3*isec->bv_index[2*i];
-               isec->bv_index[2*i+1]   = i+3*isec->bv_index[2*i+1];
+       for (i = 0; i < 3; i++) {
+               isec->bv_index[2 * i]     = isec->idot_axis[i] < 0.0 ? 1 : 0;
+               isec->bv_index[2 * i + 1] = 1 - isec->bv_index[2 * i];
+
+               isec->bv_index[2 * i]     = i + 3 * isec->bv_index[2 * i];
+               isec->bv_index[2 * i + 1] = i + 3 * isec->bv_index[2 * i + 1];
        }
-               
+
        return res;
 }
 
@@ -188,7 +188,7 @@ static void RE_rayobject_instance_bb(RayObject *o, float *min, float *max)
        //TODO:
        // *better bb.. calculated without rotations of bb
        // *maybe cache that better-fitted-BB at the InstanceRayObject
-       InstanceRayObject *obj = (InstanceRayObject*)o;
+       InstanceRayObject *obj = (InstanceRayObject *)o;
 
        float m[3], M[3], t[3];
        int i, j;
@@ -196,8 +196,8 @@ static void RE_rayobject_instance_bb(RayObject *o, float *min, float *max)
        RE_rayobject_merge_bb(obj->target, m, M);
 
        //There must be a faster way than rotating all the 8 vertexs of the BB
-       for (i=0; i<8; i++) {
-               for (j=0; j<3; j++) t[j] = i&(1<<j) ? M[j] : m[j];
+       for (i = 0; i < 8; i++) {
+               for (j = 0; j < 3; j++) t[j] = i & (1 << j) ? M[j] : m[j];
                mul_m4_v3(obj->target2global, t);
                DO_MINMAX(t, min, max);
        }
index bfea3f3..5011c78 100644 (file)
@@ -193,13 +193,13 @@ struct wmOperatorTypeMacro *WM_operatortype_macro_define(struct wmOperatorType *
 
 
 int                    WM_operator_poll                (struct bContext *C, struct wmOperatorType *ot);
-int                    WM_operator_poll_context(struct bContext *C, struct wmOperatorType *ot, int context);
+int                    WM_operator_poll_context(struct bContext *C, struct wmOperatorType *ot, short context);
 int                    WM_operator_call                (struct bContext *C, struct wmOperator *op);
 int                    WM_operator_call_notest(struct bContext *C, struct wmOperator *op);
 int                    WM_operator_repeat              (struct bContext *C, struct wmOperator *op);
 int                    WM_operator_repeat_check(const struct bContext *C, struct wmOperator *op);
-int                    WM_operator_name_call   (struct bContext *C, const char *opstring, int context, struct PointerRNA *properties);
-int                    WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, int context, struct PointerRNA *properties, struct ReportList *reports);
+int                    WM_operator_name_call   (struct bContext *C, const char *opstring, short context, struct PointerRNA *properties);
+int                    WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, short context, struct PointerRNA *properties, struct ReportList *reports, short is_undo);
 
 void           WM_operator_properties_alloc(struct PointerRNA **ptr, struct IDProperty **properties, const char *opstring); /* used for keymap and macro items */
 void           WM_operator_properties_sanitize(struct PointerRNA *ptr, const short no_context); /* make props context sensitive or not */
index e55f740..9795c48 100644 (file)
@@ -417,7 +417,7 @@ int WM_operator_poll(bContext *C, wmOperatorType *ot)
 }
 
 /* sets up the new context and calls 'wm_operator_invoke()' with poll_only */
-int WM_operator_poll_context(bContext *C, wmOperatorType *ot, int context)
+int WM_operator_poll_context(bContext *C, wmOperatorType *ot, short context)
 {
        return wm_operator_call_internal(C, ot, NULL, NULL, context, TRUE);
 }
@@ -1068,7 +1068,7 @@ static int wm_operator_call_internal(bContext *C, wmOperatorType *ot, PointerRNA
 
 
 /* invokes operator in context */
-int WM_operator_name_call(bContext *C, const char *opstring, int context, PointerRNA *properties)
+int WM_operator_name_call(bContext *C, const char *opstring, short context, PointerRNA *properties)
 {
        wmOperatorType *ot = WM_operatortype_find(opstring, 0);
        if (ot)
@@ -1082,7 +1082,7 @@ int WM_operator_name_call(bContext *C, const char *opstring, int context, Pointe
  * - poll() must be called by python before this runs.
  * - reports can be passed to this function (so python can report them as exceptions)
  */
-int WM_operator_call_py(bContext *C, wmOperatorType *ot, int context, PointerRNA *properties, ReportList *reports)
+int WM_operator_call_py(bContext *C, wmOperatorType *ot, short context, PointerRNA *properties, ReportList *reports, short is_undo)
 {
        int retval = OPERATOR_CANCELLED;
 
@@ -1091,13 +1091,13 @@ int WM_operator_call_py(bContext *C, wmOperatorType *ot, int context, PointerRNA
        op = wm_operator_create(wm, ot, properties, reports);
 
        if (op->type->exec) {
-               if (op->type->flag & OPTYPE_UNDO)
+               if (is_undo && op->type->flag & OPTYPE_UNDO)
                        wm->op_undo_depth++;
 
                retval = op->type->exec(C, op);
                OPERATOR_RETVAL_CHECK(retval);
 
-               if (op->type->flag & OPTYPE_UNDO && CTX_wm_manager(C) == wm)
+               if (is_undo && op->type->flag & OPTYPE_UNDO && CTX_wm_manager(C) == wm)
                        wm->op_undo_depth--;
        }
        else
@@ -1110,11 +1110,11 @@ int WM_operator_call_py(bContext *C, wmOperatorType *ot, int context, PointerRNA
         * we could have some more obvious way of doing this like passing a flag.
         */
        wmWindowManager *wm = CTX_wm_manager(C);
-       if (wm) wm->op_undo_depth++;
+       if (!is_undo && wm) wm->op_undo_depth++;
 
        retval = wm_operator_call_internal(C, ot, properties, reports, context, FALSE);
        
-       if (wm && (wm == CTX_wm_manager(C))) wm->op_undo_depth--;
+       if (!is_undo && wm && (wm == CTX_wm_manager(C))) wm->op_undo_depth--;
 
        /* keep the reports around if needed later */
        if ((retval & OPERATOR_RUNNING_MODAL) ||
index 97fb943..53f3dac 100644 (file)
@@ -449,7 +449,7 @@ struct wmOperatorType *WM_operatortype_find(const char *idname, int quiet) {retu
 struct GHashIterator *WM_operatortype_iter() {return (struct GHashIterator *) NULL;}
 struct wmOperatorType *WM_operatortype_exists(const char *idname) {return (struct wmOperatorType *) NULL;}
 struct wmOperatorTypeMacro *WM_operatortype_macro_define(struct wmOperatorType *ot, const char *idname) {return (struct wmOperatorTypeMacro *) NULL;}
-int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, int context, struct PointerRNA *properties, struct ReportList *reports) {return 0;}
+int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, short context, short is_undo, struct PointerRNA *properties, struct ReportList *reports) {return 0;}
 int WM_operatortype_remove(const char *idname) {return 0;}
 int WM_operator_poll(struct bContext *C, struct wmOperatorType *ot) {return 0;}
 int WM_operator_poll_context(struct bContext *C, struct wmOperatorType *ot, int context) {return 0;}
index 9869dfb..b580fc3 100644 (file)
@@ -350,6 +350,9 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
 
 PyObject* BL_ActionActuator::PyGetChannel(PyObject* value)
 {
+       PyErr_SetString(PyExc_NotImplementedError, "BL_ActionActuator.getChannel() no longer works, please use BL_ArmatureObject.channels instead");
+       return NULL;
+#if 0 // XXX To be removed in a later version (first removed in 2.64)
        const char *string= _PyUnicode_AsString(value);
 
        if (GetParent()->GetGameObjectType() != SCA_IObject::OBJ_ARMATURE)
@@ -407,6 +410,7 @@ PyObject* BL_ActionActuator::PyGetChannel(PyObject* value)
                pchan->size[0], pchan->size[1], pchan->size[2],
                pchan->quat[0], pchan->quat[1], pchan->quat[2], pchan->quat[3] );
 #endif
+#endif
 }
 
 /*     setChannel                                                         */
@@ -416,6 +420,10 @@ KX_PYMETHODDEF_DOC(BL_ActionActuator, setChannel,
 "\t - matrix    : A 4x4 matrix specifying the overriding transformation\n"
 "\t               as an offset from the bone's rest position.\n")
 {
+       PyErr_SetString(PyExc_NotImplementedError, "BL_ActionActuator.setChannel() no longer works, please use BL_ArmatureObject.channels instead");
+       return NULL;
+
+#if 0 // XXX To be removed in a later version (first removed in 2.64)
        BL_ArmatureObject *obj = (BL_ArmatureObject*)GetParent();
        char *string;
        PyObject *pymat= NULL;
@@ -497,6 +505,7 @@ KX_PYMETHODDEF_DOC(BL_ActionActuator, setChannel,
        }
        
        Py_RETURN_NONE;
+#endif
 }
 
 /* ------------------------------------------------------------------------- */
@@ -583,6 +592,10 @@ int BL_ActionActuator::pyattr_set_action(void *self_v, const KX_PYATTRIBUTE_DEF
 
 PyObject* BL_ActionActuator::pyattr_get_channel_names(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 {
+       PyErr_SetString(PyExc_NotImplementedError, "BL_ActionActuator.channelNames no longer works, please use BL_ArmatureObject.channels instead");
+       return NULL;
+
+#if 0 // XXX To be removed in a later version (first removed in 2.64)
        BL_ActionActuator* self= static_cast<BL_ActionActuator*>(self_v);
        PyObject *ret= PyList_New(0);
        PyObject *item;
@@ -605,6 +618,7 @@ PyObject* BL_ActionActuator::pyattr_get_channel_names(void *self_v, const KX_PYA
        }
        
        return ret;
+#endif
 }
 
 PyObject* BL_ActionActuator::pyattr_get_use_continue(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
index 64f198f..e511704 100644 (file)
@@ -32,6 +32,7 @@ set(INC
        ../../../intern/container
        ../../../intern/moto/include
        ../../../intern/string
+       ../../../intern/ghost
 )
 
 set(INC_SYS
index 46c43b5..f83b23f 100644 (file)
@@ -28,6 +28,8 @@
 #include "SCA_PythonKeyboard.h"
 #include "SCA_IInputDevice.h"
 
+#include "GHOST_C-api.h"
+
 /* ------------------------------------------------------------------------- */
 /* Native functions                                                          */
 /* ------------------------------------------------------------------------- */
@@ -55,6 +57,23 @@ SCA_PythonKeyboard::~SCA_PythonKeyboard()
 /* Python functions                                                          */
 /* ------------------------------------------------------------------------- */
 
+/* clipboard */
+static PyObject* gPyGetClipboard(PyObject* args, PyObject* kwds)
+{
+       char *buf = (char *)GHOST_getClipboard(0);
+       return PyUnicode_FromString(buf?buf:"");
+}
+
+static PyObject* gPySetClipboard(PyObject* args, PyObject* value)
+{
+       char* buf;
+       if (!PyArg_ParseTuple(value,"s:setClipboard",&buf))
+               Py_RETURN_NONE;
+
+       GHOST_putClipboard((GHOST_TInt8 *)buf, 0);
+       Py_RETURN_NONE;
+}
+
 /* Integration hooks ------------------------------------------------------- */
 PyTypeObject SCA_PythonKeyboard::Type = {
        PyVarObject_HEAD_INIT(NULL, 0)
@@ -79,6 +98,8 @@ PyTypeObject SCA_PythonKeyboard::Type = {
 };
 
 PyMethodDef SCA_PythonKeyboard::Methods[] = {
+       {"getClipboard", (PyCFunction) gPyGetClipboard, METH_VARARGS, "getCliboard doc"},
+       {"setClipboard", (PyCFunction) gPySetClipboard, METH_VARARGS, "setCliboard doc"},
        {NULL,NULL} //Sentinel
 };
 
index e33169b..da3c0fa 100644 (file)
@@ -3,7 +3,7 @@ Import ('env')
 
 sources = env.Glob('*.cpp') + env.Glob('Joystick/*.cpp')
 
-incs = '. #/intern/string #intern/container'
+incs = '. #/intern/string #intern/container #intern/ghost'
 incs += ' #/source/gameengine/Expressions #/intern/moto/include'
 incs += ' #/source/gameengine/Rasterizer #/source/gameengine/SceneGraph'
 incs += ' #/source/blender/blenlib'
index 0a1958e..f2c2d18 100644 (file)
@@ -324,22 +324,23 @@ void RAS_2DFilterManager::SetupTextures(bool depth, bool luminance)
 void RAS_2DFilterManager::UpdateOffsetMatrix(RAS_ICanvas* canvas)
 {
        RAS_Rect canvas_rect = canvas->GetWindowArea();
-       canvaswidth = canvas->GetWidth();
-       canvasheight = canvas->GetHeight();
-
-       texturewidth = canvaswidth + canvas_rect.GetLeft();
-       textureheight = canvasheight + canvas_rect.GetBottom();
+       texturewidth = canvas->GetWidth();
+       textureheight = canvas->GetHeight();
        GLint i,j;
-       i = 0;
-       while ((1 << i) <= texturewidth)
-               i++;
-       texturewidth = (1 << (i));
 
-       // Now for height
-       i = 0;
-       while ((1 << i) <= textureheight)
-               i++;
-       textureheight = (1 << (i));
+       if (!GL_ARB_texture_non_power_of_two)
+       {
+               i = 0;
+               while ((1 << i) <= texturewidth)
+                       i++;
+               texturewidth = (1 << (i));
+
+               // Now for height
+               i = 0;
+               while ((1 << i) <= textureheight)
+                       i++;
+               textureheight = (1 << (i));
+       }
 
        GLfloat xInc = 1.0f / (GLfloat)texturewidth;
        GLfloat yInc = 1.0f / (GLfloat)textureheight;
@@ -400,6 +401,7 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
 
        GLuint  viewport[4]={0};
        glGetIntegerv(GL_VIEWPORT,(GLint *)viewport);
+       RAS_Rect rect = canvas->GetWindowArea();
 
        if (canvaswidth != canvas->GetWidth() || canvasheight != canvas->GetHeight())
        {
@@ -417,19 +419,19 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
        if (need_depth) {
                glActiveTextureARB(GL_TEXTURE1);
                glBindTexture(GL_TEXTURE_2D, texname[1]);
-               glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, 0, 0, texturewidth,textureheight, 0);
+               glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, rect.GetLeft(), rect.GetBottom(), rect.GetWidth(), rect.GetHeight(), 0);
        }
        
        if (need_luminance) {
                glActiveTextureARB(GL_TEXTURE2);
                glBindTexture(GL_TEXTURE_2D, texname[2]);
-               glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, 0, 0, texturewidth,textureheight, 0);
+               glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, rect.GetLeft(), rect.GetBottom(), rect.GetWidth(), rect.GetHeight(), 0);
        }
 
        // reverting to texunit 0, without this we get bug [#28462]
        glActiveTextureARB(GL_TEXTURE0);
 
-       glViewport(0,0, texturewidth, textureheight);
+       glViewport(rect.GetLeft(), rect.GetBottom(), texturewidth, textureheight);
 
        glDisable(GL_DEPTH_TEST);
        // in case the previous material was wire
@@ -452,7 +454,7 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
 
                        glActiveTextureARB(GL_TEXTURE0);
                        glBindTexture(GL_TEXTURE_2D, texname[0]);
-                       glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, texturewidth, textureheight, 0);
+                       glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rect.GetLeft(), rect.GetBottom(), rect.GetWidth(), rect.GetHeight(), 0); // Don't use texturewidth and textureheight in case we don't have NPOT support
                        glClear(GL_COLOR_BUFFER_BIT);
 
                        glBegin(GL_QUADS);