Merging r38454 through r38515 from trunk into soc-2011-tomato
authorSergey Sharybin <sergey.vfx@gmail.com>
Tue, 19 Jul 2011 19:58:01 +0000 (19:58 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Tue, 19 Jul 2011 19:58:01 +0000 (19:58 +0000)
24 files changed:
GNUmakefile
intern/ghost/intern/GHOST_SystemX11.cpp
release/scripts/modules/addon_utils.py
release/scripts/modules/bpy/path.py
release/scripts/modules/bpy_extras/io_utils.py
release/scripts/startup/bl_operators/object_align.py
release/scripts/startup/bl_operators/uvcalc_smart_project.py
release/scripts/startup/bl_ui/properties_material.py
release/scripts/startup/bl_ui/space_userpref.py
source/blender/blenkernel/intern/particle_system.c
source/blender/blenkernel/intern/sequencer.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/space_node/node_edit.c
source/blender/editors/space_node/node_ops.c
source/blender/makesdna/DNA_scene_types.h
source/blender/makesrna/intern/rna_object.c
source/blender/makesrna/intern/rna_object_api.c
source/blender/modifiers/intern/MOD_util.h
source/blender/nodes/intern/SHD_util.c
source/blender/python/generic/bgl.c
source/blender/python/intern/bpy_rna.c
source/blender/windowmanager/intern/wm_operators.c
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/tests/check_deprecated.py [new file with mode: 0644]

index b55890f9271b9bedc64cd17bb42ba4a74efd7a43..d1a60ce5e37bc92ba3ea1cc3b5484ef532e2a98b 100644 (file)
@@ -99,14 +99,18 @@ test:
 
 # run pep8 check check on scripts we distribute.
 test_pep8:
-       python source/tests/pep8.py > test_pep8.log 2>&1
+       python3 source/tests/pep8.py > test_pep8.log 2>&1
        @echo "written: test_pep8.log"
 
 # run some checks on our cmakefiles.
 test_cmake:
-       python build_files/cmake/cmake_consistency_check.py > test_cmake_consistency.log 2>&1
+       python3 build_files/cmake/cmake_consistency_check.py > test_cmake_consistency.log 2>&1
        @echo "written: test_cmake_consistency.log"
 
+# run deprecation tests, see if we have anything to remove.
+test_deprecated:
+       python3 source/tests/check_deprecated.py
+
 clean:
        make -C $(BUILD_DIR) clean
 
index 3ebd24c008b32abaef3cce4951db212c32bba84d..dd296fa979c5e3a78a00f80d48fffd026ca532cf 100644 (file)
@@ -150,8 +150,9 @@ GHOST_SystemX11(
        if (gettimeofday(&tv,NULL) == -1) {
                GHOST_ASSERT(false,"Could not instantiate timer!");
        }
-
-       m_start_time = GHOST_TUns64(tv.tv_sec*1000 + tv.tv_usec/1000);
+       
+       // Taking care not to overflow the tv.tv_sec*1000
+       m_start_time = GHOST_TUns64(tv.tv_sec)*1000 + tv.tv_usec/1000;
        
        
        /* use detectable autorepeate, mac and windows also do this */
@@ -199,7 +200,8 @@ getMilliSeconds(
                GHOST_ASSERT(false,"Could not compute time!");
        }
 
-       return  GHOST_TUns64(tv.tv_sec*1000 + tv.tv_usec/1000) - m_start_time;
+       // Taking care not to overflow the tv.tv_sec*1000
+       return  GHOST_TUns64(tv.tv_sec)*1000 + tv.tv_usec/1000 - m_start_time;
 }
        
        GHOST_TUns8 
index 07f1dc618dcc4223e03f3dbf8892ca62af7cc651..cf74282d06489a05d88f5b74ce8bd6fed181abc5 100644 (file)
@@ -31,6 +31,8 @@ __all__ = (
 import bpy as _bpy
 
 
+error_duplicates = False
+
 def paths():
     # RELEASE SCRIPTS: official scripts distributed in Blender releases
     paths = _bpy.utils.script_paths("addons")
@@ -47,8 +49,11 @@ def paths():
 
 
 def modules(module_cache):
+    global error_duplicates
     import os
 
+    error_duplicates = False
+
     path_list = paths()
 
     # fake module importing
@@ -117,7 +122,12 @@ def modules(module_cache):
             modules_stale -= {mod_name}
             mod = module_cache.get(mod_name)
             if mod:
-                if mod.__time__ != os.path.getmtime(mod_path):
+                if mod.__file__ != mod_path:
+                    print("multiple addons with the same name:\n  %r\n  %r" %
+                          (mod.__file__, mod_path))
+                    error_duplicates = True
+
+                elif mod.__time__ != os.path.getmtime(mod_path):
                     print("reloading addon:", mod_name, mod.__time__, os.path.getmtime(mod_path), mod_path)
                     del module_cache[mod_name]
                     mod = None
index 5e95428f6419f9fb2ccbbec48090871de1de05f9..74d043f8a544242e9c0053d4730be8dd7b757f94 100644 (file)
@@ -35,7 +35,7 @@ def abspath(path, start=None):
     :type start: string
     """
     if path.startswith("//"):
-        return _os.path.join(_os.path.dirname(_bpy.data.filepath if start is None else start), path[2:])
+        return _os.path.join(_os.path.dirname(_bpy.data.filepath) if start is None else start, path[2:])
 
     return path
 
index cfa2233f7b60fed2fc76a316a05c68afa5d491a7..9545e20b025cccee97da5fdeee5bcc03fb45d2cb 100644 (file)
@@ -22,6 +22,7 @@ __all__ = (
     "ExportHelper",
     "ImportHelper",
     "axis_conversion",
+    "axis_conversion_ensure",
     "create_derived_objects",
     "free_derived_objects",
     "unpack_list",
@@ -154,12 +155,50 @@ def axis_conversion(from_forward='Y', from_up='Z', to_forward='Y', to_up='Z'):
     if from_forward == to_forward and from_up == to_up:
         return Matrix().to_3x3()
 
+    if from_forward[-1] == from_up[-1] or to_forward[-1] == to_up[-1]:
+        raise Exception("invalid axis arguments passed, "
+                        "can't use up/forward on the same axis.")
+
     value = reduce(int.__or__, (_axis_convert_num[a] << (i * 3) for i, a in enumerate((from_forward, from_up, to_forward, to_up))))
 
     for i, axis_lut in enumerate(_axis_convert_lut):
         if value in axis_lut:
             return Matrix(_axis_convert_matrix[i])
-    assert("internal error")
+    assert(0)
+
+    
+def axis_conversion_ensure(operator, forward_attr, up_attr):
+    """
+    Function to ensure an operator has valid axis conversion settings, intended
+    to be used from :class:`Operator.check`.
+
+    :arg operator: the operator to access axis attributes from.
+    :type operator: :class:`Operator`
+    :arg forward_attr: 
+    :type forward_attr: string
+    :arg up_attr: the directory the *filepath* will be referenced from (normally the export path).
+    :type up_attr: string
+    :return: True if the value was modified.
+    :rtype: boolean
+    """
+    def validate(axis_forward, axis_up):
+        if axis_forward[-1] == axis_up[-1]:
+            axis_up = axis_up[0:-1] + 'XYZ'[('XYZ'.index(axis_up[-1]) + 1) % 3]
+        
+        return axis_forward, axis_up
+    
+    change = False
+
+    axis = getattr(operator, forward_attr), getattr(operator, up_attr)
+    axis_new = validate(*axis)
+
+    if axis != axis_new:
+        setattr(operator, forward_attr, axis_new[0])
+        setattr(operator, up_attr, axis_new[1])
+
+        return True
+    else:
+        return False
 
 
 # return a tuple (free, object list), free is True if memory should be freed later with free_derived_objects()
index 3202a717001cc4acc867b2348fa0c7ce965d078d..d215f3476cf5679f045a8c46bc6d8a9498bf010c 100644 (file)
 import bpy
 from mathutils import Vector
 
-
-def align_objects(align_x, align_y, align_z, align_mode, relative_to):
+def GlobalBB_LQ(bb_world):
+    
+    # Initialize the variables with the 8th vertex
+    left, right, front, back, down, up =\
+    bb_world[7][0],\
+    bb_world[7][0],\
+    bb_world[7][1],\
+    bb_world[7][1],\
+    bb_world[7][2],\
+    bb_world[7][2]
+    
+    # Test against the other 7 verts
+    for i in range (7):
+        
+        # X Range
+        val = bb_world[i][0]
+        if val < left:
+            left = val
+            
+        if val > right:
+            right = val
+            
+        # Y Range
+        val = bb_world[i][1]
+        if val < front:
+            front = val
+            
+        if val > back:
+            back = val
+            
+        # Z Range
+        val = bb_world[i][2]
+        if val < down:
+            down = val
+            
+        if val > up:
+            up = val
+        
+    return (Vector((left, front, up)), Vector((right, back, down)))
+
+def GlobalBB_HQ(obj):
+    
+    matrix_world = obj.matrix_world.copy()
+    
+    # Initialize the variables with the last vertex
+    
+    verts = obj.data.vertices
+    
+    val = verts[-1].co * matrix_world
+    
+    left, right, front, back, down, up =\
+    val[0],\
+    val[0],\
+    val[1],\
+    val[1],\
+    val[2],\
+    val[2]
+    
+    # Test against all other verts
+    for i in range (len(verts)-1):
+        
+        vco = verts[i].co * matrix_world
+        
+        # X Range
+        val = vco[0]
+        if val < left:
+            left = val
+            
+        if val > right:
+            right = val
+            
+        # Y Range
+        val = vco[1]
+        if val < front:
+            front = val
+            
+        if val > back:
+            back = val
+            
+        # Z Range
+        val = vco[2]
+        if val < down:
+            down = val
+            
+        if val > up:
+            up = val
+        
+    return (Vector((left, front, up)), Vector((right, back, down)))
+
+
+def align_objects(align_x, align_y, align_z, align_mode, relative_to, bb_quality):
 
     cursor = bpy.context.scene.cursor_location
 
-    Left_Up_Front_SEL = [0.0, 0.0, 0.0]
-    Right_Down_Back_SEL = [0.0, 0.0, 0.0]
+    Left_Front_Up_SEL = [0.0, 0.0, 0.0]
+    Right_Back_Down_SEL = [0.0, 0.0, 0.0]
 
     flag_first = True
 
@@ -42,78 +131,89 @@ def align_objects(align_x, align_y, align_z, align_mode, relative_to):
         return False
 
     for obj, bb_world in objs:
-        Left_Up_Front = bb_world[1]
-        Right_Down_Back = bb_world[7]
+        
+        if bb_quality:
+            GBB = GlobalBB_HQ(obj)
+        else:
+            GBB = GlobalBB_LQ(bb_world)
+            
+        Left_Front_Up = GBB[0]
+        Right_Back_Down = GBB[1]
 
         # Active Center
 
         if obj == bpy.context.active_object:
 
-            center_active_x = (Left_Up_Front[0] + Right_Down_Back[0]) / 2.0
-            center_active_y = (Left_Up_Front[1] + Right_Down_Back[1]) / 2.0
-            center_active_z = (Left_Up_Front[2] + Right_Down_Back[2]) / 2.0
+            center_active_x = (Left_Front_Up[0] + Right_Back_Down[0]) / 2.0
+            center_active_y = (Left_Front_Up[1] + Right_Back_Down[1]) / 2.0
+            center_active_z = (Left_Front_Up[2] + Right_Back_Down[2]) / 2.0
 
-            size_active_x = (Right_Down_Back[0] - Left_Up_Front[0]) / 2.0
-            size_active_y = (Right_Down_Back[1] - Left_Up_Front[1]) / 2.0
-            size_active_z = (Left_Up_Front[2] - Right_Down_Back[2]) / 2.0
+            size_active_x = (Right_Back_Down[0] - Left_Front_Up[0]) / 2.0
+            size_active_y = (Right_Back_Down[1] - Left_Front_Up[1]) / 2.0
+            size_active_z = (Left_Front_Up[2] - Right_Back_Down[2]) / 2.0
 
         # Selection Center
 
         if flag_first:
             flag_first = False
 
-            Left_Up_Front_SEL[0] = Left_Up_Front[0]
-            Left_Up_Front_SEL[1] = Left_Up_Front[1]
-            Left_Up_Front_SEL[2] = Left_Up_Front[2]
+            Left_Front_Up_SEL[0] = Left_Front_Up[0]
+            Left_Front_Up_SEL[1] = Left_Front_Up[1]
+            Left_Front_Up_SEL[2] = Left_Front_Up[2]
 
-            Right_Down_Back_SEL[0] = Right_Down_Back[0]
-            Right_Down_Back_SEL[1] = Right_Down_Back[1]
-            Right_Down_Back_SEL[2] = Right_Down_Back[2]
+            Right_Back_Down_SEL[0] = Right_Back_Down[0]
+            Right_Back_Down_SEL[1] = Right_Back_Down[1]
+            Right_Back_Down_SEL[2] = Right_Back_Down[2]
 
         else:
             # X axis
-            if Left_Up_Front[0] < Left_Up_Front_SEL[0]:
-                Left_Up_Front_SEL[0] = Left_Up_Front[0]
+            if Left_Front_Up[0] < Left_Front_Up_SEL[0]:
+                Left_Front_Up_SEL[0] = Left_Front_Up[0]
             # Y axis
-            if Left_Up_Front[1] < Left_Up_Front_SEL[1]:
-                Left_Up_Front_SEL[1] = Left_Up_Front[1]
+            if Left_Front_Up[1] < Left_Front_Up_SEL[1]:
+                Left_Front_Up_SEL[1] = Left_Front_Up[1]
             # Z axis
-            if Left_Up_Front[2] > Left_Up_Front_SEL[2]:
-                Left_Up_Front_SEL[2] = Left_Up_Front[2]
+            if Left_Front_Up[2] > Left_Front_Up_SEL[2]:
+                Left_Front_Up_SEL[2] = Left_Front_Up[2]
 
             # X axis
-            if Right_Down_Back[0] > Right_Down_Back_SEL[0]:
-                Right_Down_Back_SEL[0] = Right_Down_Back[0]
+            if Right_Back_Down[0] > Right_Back_Down_SEL[0]:
+                Right_Back_Down_SEL[0] = Right_Back_Down[0]
             # Y axis
-            if Right_Down_Back[1] > Right_Down_Back_SEL[1]:
-                Right_Down_Back_SEL[1] = Right_Down_Back[1]
+            if Right_Back_Down[1] > Right_Back_Down_SEL[1]:
+                Right_Back_Down_SEL[1] = Right_Back_Down[1]
             # Z axis
-            if Right_Down_Back[2] < Right_Down_Back_SEL[2]:
-                Right_Down_Back_SEL[2] = Right_Down_Back[2]
+            if Right_Back_Down[2] < Right_Back_Down_SEL[2]:
+                Right_Back_Down_SEL[2] = Right_Back_Down[2]
 
-    center_sel_x = (Left_Up_Front_SEL[0] + Right_Down_Back_SEL[0]) / 2.0
-    center_sel_y = (Left_Up_Front_SEL[1] + Right_Down_Back_SEL[1]) / 2.0
-    center_sel_z = (Left_Up_Front_SEL[2] + Right_Down_Back_SEL[2]) / 2.0
+    center_sel_x = (Left_Front_Up_SEL[0] + Right_Back_Down_SEL[0]) / 2.0
+    center_sel_y = (Left_Front_Up_SEL[1] + Right_Back_Down_SEL[1]) / 2.0
+    center_sel_z = (Left_Front_Up_SEL[2] + Right_Back_Down_SEL[2]) / 2.0
 
     # Main Loop
 
     for obj, bb_world in objs:
         bb_world = [Vector(v[:]) * obj.matrix_world for v in obj.bound_box]
+        
+        if bb_quality:
+            GBB = GlobalBB_HQ(obj)
+        else:
+            GBB = GlobalBB_LQ(bb_world)
+            
+        Left_Front_Up = GBB[0]
+        Right_Back_Down = GBB[1]
 
-        Left_Up_Front = bb_world[1]
-        Right_Down_Back = bb_world[7]
-
-        center_x = (Left_Up_Front[0] + Right_Down_Back[0]) / 2.0
-        center_y = (Left_Up_Front[1] + Right_Down_Back[1]) / 2.0
-        center_z = (Left_Up_Front[2] + Right_Down_Back[2]) / 2.0
+        center_x = (Left_Front_Up[0] + Right_Back_Down[0]) / 2.0
+        center_y = (Left_Front_Up[1] + Right_Back_Down[1]) / 2.0
+        center_z = (Left_Front_Up[2] + Right_Back_Down[2]) / 2.0
 
-        positive_x = Right_Down_Back[0]
-        positive_y = Right_Down_Back[1]
-        positive_z = Left_Up_Front[2]
+        positive_x = Right_Back_Down[0]
+        positive_y = Right_Back_Down[1]
+        positive_z = Left_Front_Up[2]
 
-        negative_x = Left_Up_Front[0]
-        negative_y = Left_Up_Front[1]
-        negative_z = Right_Down_Back[2]
+        negative_x = Left_Front_Up[0]
+        negative_y = Left_Front_Up[1]
+        negative_z = Right_Back_Down[2]
 
         obj_loc = obj.location
 
@@ -228,7 +328,7 @@ def align_objects(align_x, align_y, align_z, align_mode, relative_to):
     return True
 
 
-from bpy.props import EnumProperty
+from bpy.props import EnumProperty, BoolProperty
 
 
 class AlignObjects(bpy.types.Operator):
@@ -237,6 +337,11 @@ class AlignObjects(bpy.types.Operator):
     bl_label = "Align Objects"
     bl_options = {'REGISTER', 'UNDO'}
 
+    bb_quality = BoolProperty(
+            name="High Quality",
+            description="Enables high quality calculation of the bounding box for perfect results on complex shape meshes with rotation/scale (Slow)",
+            default=False)
+
     align_mode = EnumProperty(items=(
             ('OPT_1', "Negative Sides", ""),
             ('OPT_2', "Centers", ""),
@@ -269,10 +374,10 @@ class AlignObjects(bpy.types.Operator):
 
     def execute(self, context):
         align_axis = self.align_axis
-        ret = align_objects('X' in align_axis, 'Y' in align_axis, 'Z' in align_axis, self.align_mode, self.relative_to)
+        ret = align_objects('X' in align_axis, 'Y' in align_axis, 'Z' in align_axis, self.align_mode, self.relative_to, self.bb_quality)
 
         if not ret:
             self.report({'WARNING'}, "No objects with bound-box selected")
             return {'CANCELLED'}
         else:
-            return {'FINISHED'}
+            return {'FINISHED'}
\ No newline at end of file
index 7ea89cfa47923145c1a087a44ee14fd3f0c181ec..9c3be84b807e29b94ce70eed87aef2adcc8b73ef 100644 (file)
@@ -747,14 +747,8 @@ def packIslands(islandList):
 
 
 def VectoQuat(vec):
-    a3 = vec.normalized()
-    up = Vector((0.0, 0.0, 1.0))
-    if abs(a3.dot(up)) == 1.0:
-        up = Vector((0.0, 1.0, 0.0))
-
-    a1 = a3.cross(up).normalized()
-    a2 = a3.cross(a1)
-    return Matrix((a1, a2, a3)).to_quaternion()
+    vec = vec.normalized()
+    return vec.to_track_quat('Z', 'X' if abs(vec.x) > 0.5 else 'Y').inverted()
 
 
 class thickface(object):
index 45c15bd1ce699a8ad6ef133a5405b15057b7b569..2a52ae23782a57238a3f246ab0072f3efdaf2931 100644 (file)
@@ -174,6 +174,7 @@ class MATERIAL_PT_pipeline(MaterialButtonsPanel, bpy.types.Panel):
         row.prop(mat, "use_transparency")
         sub = row.column()
         sub.prop(mat, "offset_z")
+
         sub.active = mat_type and mat.use_transparency and mat.transparency_method == 'Z_TRANSPARENCY'
 
         row = layout.row()
@@ -199,6 +200,7 @@ class MATERIAL_PT_pipeline(MaterialButtonsPanel, bpy.types.Panel):
         col.prop(mat, "shadow_cast_alpha", text="Casting Alpha")
         col.prop(mat, "use_cast_buffer_shadows")
         col.prop(mat, "use_cast_approximate")
+        col.prop(mat, "pass_index")
 
 
 class MATERIAL_PT_diffuse(MaterialButtonsPanel, bpy.types.Panel):
@@ -729,7 +731,8 @@ class MATERIAL_PT_options(MaterialButtonsPanel, bpy.types.Panel):
         col.prop(mat, "use_vertex_color_paint")
         col.prop(mat, "use_vertex_color_light")
         col.prop(mat, "use_object_color")
-        col.prop(mat, "pass_index")
+        if simple_material(base_mat):
+            col.prop(mat, "pass_index")
 
 
 class MATERIAL_PT_shadow(MaterialButtonsPanel, bpy.types.Panel):
index 6a809aefb9dfbf98df6daae06ebe457258fa8dcf..139b3205835d3c7847e8f4418666cc3f20847514 100644 (file)
@@ -889,6 +889,16 @@ class USERPREF_PT_addons(bpy.types.Panel):
                 return True
         return False
 
+    @staticmethod
+    def draw_error(layout, message):
+        lines = message.split("\n")
+        box = layout.box()
+        rowsub = box.row()
+        rowsub.label(lines[0])
+        rowsub.label(icon='ERROR')
+        for l in lines[1:]:
+            box.label(l)
+
     def draw(self, context):
         layout = self.layout
 
@@ -909,6 +919,14 @@ class USERPREF_PT_addons(bpy.types.Panel):
 
         col = split.column()
 
+        # set in addon_utils.modules(...)
+        if addon_utils.error_duplicates:
+            self.draw_error(col,
+                            "Multiple addons using the same name found!\n"
+                            "likely a problem with the script search path.\n"
+                            "(see console for details)",
+                            )
+
         filter = context.window_manager.addon_filter
         search = context.window_manager.addon_search.lower()
         support = context.window_manager.addon_support
index 63a9c224971b344327d79cf315c55075dee7c5ff..1423f520b9534c1bc23109825250675814db1b31 100644 (file)
@@ -3987,7 +3987,7 @@ static void system_step(ParticleSimulationData *sim, float cfra)
                BKE_ptcache_id_time(pid, sim->scene, 0.0f, &startframe, &endframe, NULL);
 
                /* clear everythin on start frame */
-               if((int)cfra == startframe) {
+               if(cfra == startframe) {
                        BKE_ptcache_id_reset(sim->scene, pid, PTCACHE_RESET_OUTDATED);
                        BKE_ptcache_validate(cache, startframe);
                        cache->flag &= ~PTCACHE_REDO_NEEDED;
index 265cc3eeb79988315d84240467e5873ab106942c..d6a152a52809cb308ea9a59cf6836bbefd23cc73 100644 (file)
@@ -3232,9 +3232,10 @@ int seq_swap(Sequence *seq_a, Sequence *seq_b, const char **error_str)
 {
        char name[sizeof(seq_a->name)];
 
-       if(seq_a->len != seq_b->len)
+       if(seq_a->len != seq_b->len) {
                *error_str= "Strips must be the same length";
                return 0;
+       }
 
        /* type checking, could be more advanced but disalow sound vs non-sound copy */
        if(seq_a->type != seq_b->type) {
index e61ffa847dc2ecea4b04a9a230e9d7e138031765..6f16ada261eeae92e3711dff0df229ec9809d8f8 100644 (file)
@@ -10387,8 +10387,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        sce->gm.attrib = sce->r.attrib;
 
                        //Stereo
-                       sce->gm.xsch = sce->r.xsch;
-                       sce->gm.ysch = sce->r.ysch;
                        sce->gm.stereomode = sce->r.stereomode;
                        /* reassigning stereomode NO_STEREO and DOME to a separeted flag*/
                        if (sce->gm.stereomode == 1){ //1 = STEREO_NOSTEREO
index e760c9021c25835787da5764e6d86cabbb79337d..abc7b273ec991bc248be1a4f2c87ebe3686fa907 100644 (file)
@@ -2000,12 +2000,13 @@ bNode *node_add_node(SpaceNode *snode, Scene *scene, int type, float locx, float
 
 /* ****************** Duplicate *********************** */
 
-static int node_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
+static int node_duplicate_exec(bContext *C, wmOperator *op)
 {
        SpaceNode *snode= CTX_wm_space_node(C);
        bNodeTree *ntree= snode->edittree;
        bNode *node, *newnode, *lastnode;
        bNodeLink *link, *newlink, *lastlink;
+       int keep_inputs = RNA_boolean_get(op->ptr, "keep_inputs");
        
        ED_preview_kill_jobs(C);
        
@@ -2033,10 +2034,11 @@ static int node_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
         */
        lastlink = ntree->links.last;
        for (link=ntree->links.first; link; link=link->next) {
-               /* this creates new links between copied nodes,
-                * as well as input links from unselected (when fromnode==NULL) !
+               /* This creates new links between copied nodes.
+                * If keep_inputs is set, also copies input links from unselected (when fromnode==NULL)!
                 */
-               if (link->tonode && (link->tonode->flag & NODE_SELECT)) {
+               if (link->tonode && (link->tonode->flag & NODE_SELECT)
+                       && (keep_inputs || (link->fromnode && (link->fromnode->flag & NODE_SELECT)))) {
                        newlink = MEM_callocN(sizeof(bNodeLink), "bNodeLink");
                        newlink->flag = link->flag;
                        newlink->tonode = link->tonode->new_node;
@@ -2096,6 +2098,8 @@ void NODE_OT_duplicate(wmOperatorType *ot)
        
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+       
+       RNA_def_boolean(ot->srna, "keep_inputs", 0, "Keep Inputs", "Keep the input links to duplicated nodes");
 }
 
 /* *************************** add link op ******************** */
@@ -2114,9 +2118,9 @@ static void node_remove_extra_links(SpaceNode *snode, bNodeSocket *tsock, bNodeL
                if(tlink) {
                        /* try to move the existing link to the next available socket */
                        if (tlink->tonode) {
-                               /* is there a free input socket with same type? */
+                               /* is there a free input socket with the target type? */
                                for(sock= tlink->tonode->inputs.first; sock; sock= sock->next) {
-                                       if(sock->type==tlink->fromsock->type)
+                                       if(sock->type==tlink->tosock->type)
                                                if(nodeCountSocketLinks(snode->edittree, sock) < sock->limit)
                                                        break;
                                }
index 4d181a3489489e75d3795e7609882755adffc037..4bb0283690bc494d6070052c45bbaaebf9280789 100644 (file)
@@ -101,11 +101,18 @@ void node_operatortypes(void)
 void ED_operatormacros_node(void)
 {
        wmOperatorType *ot;
+       wmOperatorTypeMacro *mot;
        
        ot= WM_operatortype_append_macro("NODE_OT_duplicate_move", "Duplicate", OPTYPE_UNDO|OPTYPE_REGISTER);
        WM_operatortype_macro_define(ot, "NODE_OT_duplicate");
        WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
 
+       /* modified operator call for duplicating with input links */
+       ot= WM_operatortype_append_macro("NODE_OT_duplicate_move_keep_inputs", "Duplicate", OPTYPE_UNDO|OPTYPE_REGISTER);
+       mot = WM_operatortype_macro_define(ot, "NODE_OT_duplicate");
+               RNA_boolean_set(mot->ptr, "keep_inputs", 1);
+       WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
+
        ot= WM_operatortype_append_macro("NODE_OT_select_link_viewer", "Link Viewer", OPTYPE_UNDO);
        WM_operatortype_macro_define(ot, "NODE_OT_select");
        WM_operatortype_macro_define(ot, "NODE_OT_link_viewer");
@@ -155,6 +162,8 @@ void node_keymap(struct wmKeyConfig *keyconf)
        
        WM_keymap_add_menu(keymap, "NODE_MT_add", AKEY, KM_PRESS, KM_SHIFT, 0);
        WM_keymap_add_item(keymap, "NODE_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0);
+       /* modified operator call for duplicating with input links */
+       WM_keymap_add_item(keymap, "NODE_OT_duplicate_move_keep_inputs", DKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0);
        
        WM_keymap_add_item(keymap, "NODE_OT_hide_toggle", HKEY, KM_PRESS, 0, 0);
        WM_keymap_add_item(keymap, "NODE_OT_mute_toggle", MKEY, KM_PRESS, 0, 0);
index dd9f493fd66754fe90f8a20e6bcf33222a080268..33d3f33c0635007f14071380e7ea4152fe475d10 100644 (file)
@@ -431,7 +431,8 @@ typedef struct GameData {
        /*
         * Radius of the activity bubble, in Manhattan length. Objects
         * outside the box are activity-culled. */
-       float activityBoxRadius; //it's not being used ANYWHERE !!!!!!!!!!!!!!
+       float activityBoxRadius;
+
        /*
         * bit 3: (gameengine): Activity culling is enabled.
         * bit 5: (gameengine) : enable Bullet DBVT tree for view frustrum culling
@@ -448,7 +449,8 @@ typedef struct GameData {
 
        /* stereo/dome mode */
        struct GameDome dome;
-       short stereoflag, stereomode, xsch, ysch; //xsch and ysch used for backwards compat.
+       short stereoflag, stereomode;
+       short pad2, pad3;
        float eyeseparation, pad1;
 } GameData;
 
index dd66e49fdec1ad2f228aafb8776d1cc191055ee3..61e65585dd4fa4d9688c10d73a4971be48c3c406 100644 (file)
@@ -483,7 +483,7 @@ static PointerRNA rna_Object_active_vertex_group_get(PointerRNA *ptr)
 static int rna_Object_active_vertex_group_index_get(PointerRNA *ptr)
 {
        Object *ob= (Object*)ptr->id.data;
-       return MAX2(ob->actdef-1, 0);
+       return ob->actdef-1;
 }
 
 static void rna_Object_active_vertex_group_index_set(PointerRNA *ptr, int value)
index b33935b7bedeba1dc3531ddfcaa332714934bb79..9018fd8c71a41025491ea07dbde566b192b568ad 100644 (file)
@@ -45,6 +45,8 @@
 
 // #include "ED_mesh.h"
 
+#include "BLI_math.h"
+
 #ifdef RNA_RUNTIME
 
 #include "BKE_main.h"
@@ -64,8 +66,6 @@
 #include "BKE_mball.h"
 #include "BKE_modifier.h"
 
-#include "BLI_math.h"
-
 #include "DNA_mesh_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_meshdata_types.h"
@@ -415,7 +415,7 @@ void rna_Object_ray_cast(Object *ob, ReportList *reports, float ray_start[3], fl
        *index= -1;
 }
 
-void rna_Object_closest_point_on_mesh(Object *ob, ReportList *reports, float point_co[3], float n_location[3], float n_normal[3], int *index)
+void rna_Object_closest_point_on_mesh(Object *ob, ReportList *reports, float point_co[3], float max_dist, float n_location[3], float n_normal[3], int *index)
 {
        BVHTreeFromMesh treeData= {NULL};
        
@@ -435,7 +435,7 @@ void rna_Object_closest_point_on_mesh(Object *ob, ReportList *reports, float poi
                BVHTreeNearest nearest;
 
                nearest.index = -1;
-               nearest.dist = FLT_MAX;
+               nearest.dist = max_dist * max_dist;
 
                if(BLI_bvhtree_find_nearest(treeData.tree, point_co, &nearest, treeData.nearest_callback, &treeData) != -1) {
                        copy_v3_v3(n_location, nearest.co);
@@ -541,9 +541,10 @@ void RNA_api_object(StructRNA *srna)
        RNA_def_function_ui_description(func, "Find the nearest point on the object.");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
 
-       /* ray start and end */
+       /* location of point for test and max distance */
        parm= RNA_def_float_vector(func, "point", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4);
        RNA_def_property_flag(parm, PROP_REQUIRED);
+       parm= RNA_def_float(func, "max_dist", sqrt(FLT_MAX), 0.0, FLT_MAX, "", "", 0.0, FLT_MAX);
 
        /* return location and normal */
        parm= RNA_def_float_vector(func, "location", 3, NULL, -FLT_MAX, FLT_MAX, "Location", "The location on the object closest to the point", -1e4, 1e4);
@@ -553,7 +554,7 @@ void RNA_api_object(StructRNA *srna)
        RNA_def_property_flag(parm, PROP_THICK_WRAP);
        RNA_def_function_output(func, parm);
 
-       parm= RNA_def_int(func, "index", 0, 0, 0, "", "The face index, -1 when no intersection is found.", 0, 0);
+       parm= RNA_def_int(func, "index", 0, 0, 0, "", "The face index, -1 when no closest point is found.", 0, 0);
        RNA_def_function_output(func, parm);
 
        /* View */
index b9b5c8a064a1796749445e3b1750e3fc4018d562..5e6f377acf19e2ac53ca251e7eae391ad03ed306 100644 (file)
@@ -52,6 +52,6 @@ void modifier_vgroup_cache(struct ModifierData *md, float (*vertexCos)[3]);
 void validate_layer_name(const struct CustomData *data, int type, char *name, char *outname);
 struct DerivedMesh *get_cddm(struct Object *ob, struct EditMesh *em, struct DerivedMesh *dm, float (*vertexCos)[3]);
 struct DerivedMesh *get_dm(struct Object *ob, struct EditMesh *em, struct DerivedMesh *dm, float (*vertexCos)[3], int orco);
-void modifier_get_vgroup(struct Object *ob, DerivedMesh *dm, const char *name, struct MDeformVert **dvert, int *defgrp_index);
+void modifier_get_vgroup(struct Object *ob, struct DerivedMesh *dm, const char *name, struct MDeformVert **dvert, int *defgrp_index);
 
 #endif /* MOD_UTIL_H */
index cf7c64c9d5e3910910e6a1bdb0004162223912f7..190f68ce19a7cd65bc4f31bceb7a11ba95c40575 100644 (file)
@@ -83,7 +83,11 @@ void nodestack_get_vec(float *in, short type_in, bNodeStack *ns)
 void ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr)
 {
        ShaderCallData scd;
-       
+       /*
+        @note: preserve material from ShadeInput for material id, nodetree execs change it
+        fix for bug "[#28012] Mat ID messy with shader nodes"
+        */
+       Material *mat = shi->mat;
        /* convert caller data to struct */
        scd.shi= shi;
        scd.shr= shr;
@@ -92,7 +96,8 @@ void ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr)
        memset(shr, 0, sizeof(ShadeResult));
                   
        ntreeExecTree(ntree, &scd, shi->thread);        /* threads */
-       
+       // @note: set material back to preserved material
+       shi->mat = mat;
        /* better not allow negative for now */
        if(shr->combined[0]<0.0f) shr->combined[0]= 0.0f;
        if(shr->combined[1]<0.0f) shr->combined[1]= 0.0f;
index 603f9f31743a8c875d9db49a0908e91b995ca5e4..09432e0b31692efeb502d2a1af0808b0f60c4627 100644 (file)
@@ -114,7 +114,7 @@ static PyObject *Buffer_to_list_recursive(Buffer *self)
        return list;
 }
 
-/* deprecate */
+/* *DEPRECATED* 2011/7/17 bgl.Buffer.list */
 static PyObject *Buffer_list(Buffer *self, void *UNUSED(arg))
 {
        fprintf(stderr, "Warning: 'Buffer.list' deprecated, use '[:]' instead\n");
index 61fc2e483b1e910145b926e37b874719f0c0254c..6e1b9c807f389694e50bf39c3c29168603e303bd 100644 (file)
@@ -4548,7 +4548,7 @@ PyTypeObject pyrna_struct_meta_idprop_Type= {
        NULL,                       /* printfunc tp_print; */
        NULL,                                           /* getattrfunc tp_getattr; */
        NULL,                                           /* setattrfunc tp_setattr; */
-       NULL,                                           /* tp_compare */ /* DEPRECATED in python 3.0! */
+       NULL,                                           /* tp_compare */ /* deprecated in python 3.0! */
        NULL,                                           /* tp_repr */
 
        /* Method suites for standard classes */
index f0655ec497a21a51268e31ac19e5ac5bdeb5e25a..7e186765e52b5f901c45e0a24b5f51c9e5afda9b 100644 (file)
@@ -3568,10 +3568,12 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf)
 
        /* items for modal map */
        WM_modalkeymap_add_item(keymap, ESCKEY,    KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CANCEL);
-       WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_ANY, KM_ANY, 0, GESTURE_MODAL_CANCEL);
+                       /* Note: cancel only on press otherwise you cannot map this to RMB-gesture */
+       WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CANCEL);
 
        WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN);
        WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, GESTURE_MODAL_SELECT);
+       WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_RELEASE, KM_ANY, 0, GESTURE_MODAL_SELECT);
 
 #if 0 // Durian guys like this
        WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_SHIFT, 0, GESTURE_MODAL_BEGIN);
index 3a96322eca46f9515ad36f6c60b133d0b7eb0b6f..c8d4e76639220c796f114b4c2b34c94257ca4a80 100644 (file)
@@ -1976,8 +1976,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
                        frame_type = RAS_FrameSettings::e_frame_scale;
                }
                
-               aspect_width = blenderscene->gm.xsch;
-               aspect_height = blenderscene->gm.ysch;
+               aspect_width = blenderscene->r.xsch*blenderscene->r.xasp;
+               aspect_height = blenderscene->r.ysch*blenderscene->r.yasp;
        }
        
        RAS_FrameSettings frame_settings(
diff --git a/source/tests/check_deprecated.py b/source/tests/check_deprecated.py
new file mode 100644 (file)
index 0000000..11c7ce6
--- /dev/null
@@ -0,0 +1,144 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+import os
+from os.path import splitext
+
+DEPRECATE_DAYS = 120
+
+SKIP_DIRS = ("extern",
+             "scons",
+             os.path.join("source", "tests"),  # not this dir
+             )
+
+def is_c_header(filename):
+    ext = splitext(filename)[1]
+    return (ext in (".h", ".hpp", ".hxx"))
+
+
+def is_c(filename):
+    ext = splitext(filename)[1]
+    return (ext in (".c", ".cpp", ".cxx", ".m", ".mm", ".rc"))
+
+
+def is_c_any(filename):
+    return is_c(filename) or is_c_header(filename)
+
+def is_py(filename):
+    ext = splitext(filename)[1]
+    return (ext == ".py")
+
+def is_source_any(filename):
+    return is_c_any(filename) or is_py(filename)
+
+def source_list(path, filename_check=None):
+    for dirpath, dirnames, filenames in os.walk(path):
+
+        # skip '.svn'
+        if dirpath.startswith("."):
+            continue
+
+        for filename in filenames:
+            if filename_check is None or filename_check(filename):
+                yield os.path.join(dirpath, filename)
+
+
+def deprecations():
+    """
+    Searches out source code for lines like
+
+    /* *DEPRECATED* 2011/7/17 bgl.Buffer.list info text */
+
+    Or...
+    
+    # *DEPRECATED* 2010/12/22 some.py.func more info */
+
+    """
+    import datetime
+    SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.normpath(os.path.join(os.path.dirname(__file__), "..", ".."))))
+
+    SKIP_DIRS_ABS = [os.path.join(SOURCE_DIR, p) for p in SKIP_DIRS]
+
+    deprecations_ls = []
+
+    scan_tot = 0
+
+    print("scanning in %r for '*DEPRECATED* YYYY/MM/DD info'" % SOURCE_DIR)
+
+    for fn in source_list(SOURCE_DIR, is_source_any):
+        # print(fn)
+        skip = False
+        for p in SKIP_DIRS_ABS:
+            if fn.startswith(p):
+                skip = True
+                break
+        if skip:
+            continue
+
+        file = open(fn, 'r', encoding="utf8")
+        for i, l in enumerate(file):
+            # logic for deprecation warnings
+            if '*DEPRECATED*' in l:
+                try:
+                    l = l.strip()
+                    data = l.split('*DEPRECATED*', 1)[-1].strip().strip()
+                    data = [w.strip() for w in data.split('/', 2)]
+                    data[-1], info = data[-1].split(' ', 1)
+                    info = info.split("*/", 1)[0]
+                    if len(data) != 3:
+                        print("    poorly formatting line:\n"
+                              "    %r:%d\n"
+                              "    %s"%
+                              (fn, i + 1, l)
+                              )
+                    else:
+                        data = datetime.datetime(*tuple([int(w) for w in data]))
+                        
+                        deprecations_ls.append((data, (fn, i + 1), info))
+                except:
+                    print("Error file - %r:%d" % (fn, i + 1))
+                    import traceback
+                    traceback.print_exc()
+
+        scan_tot += 1
+
+    print("    scanned %d files" % scan_tot)
+
+    return deprecations_ls
+
+def main():
+    import datetime
+    now = datetime.datetime.now()\
+    
+    deps = deprecations()
+
+    print("\nAll deprecations...")
+    for data, fileinfo, info in deps:
+        days_old = (now - data).days
+        if days_old > DEPRECATE_DAYS:
+            info = "*** REMOVE! *** " + info
+        print("   %r, days-old(%.2d), %s:%d - %s" % (data, days_old, fileinfo[0], fileinfo[1], info))
+    if deps:
+        print("\ndone!")
+    else:
+        print("\nnone found!")
+
+if __name__ == '__main__':
+    main()