svn merge -r 37212:37306 https://svn.blender.org/svnroot/bf-blender/trunk/blender
authorBenoit Bolsee <benoit.bolsee@online.be>
Tue, 7 Jun 2011 21:20:25 +0000 (21:20 +0000)
committerBenoit Bolsee <benoit.bolsee@online.be>
Tue, 7 Jun 2011 21:20:25 +0000 (21:20 +0000)
96 files changed:
GNUmakefile
build_files/scons/config/win32-vc-config.py
release/scripts/startup/bl_operators/presets.py
release/scripts/startup/bl_operators/wm.py
release/scripts/startup/bl_ui/properties_data_mesh.py
release/scripts/startup/bl_ui/properties_object_constraint.py
release/scripts/startup/bl_ui/properties_render.py
release/scripts/startup/bl_ui/space_text.py
source/blender/blenkernel/BKE_brush.h
source/blender/blenkernel/BKE_deform.h
source/blender/blenkernel/BKE_multires.h
source/blender/blenkernel/intern/brush.c
source/blender/blenkernel/intern/customdata.c
source/blender/blenkernel/intern/deform.c
source/blender/blenkernel/intern/multires.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/sequencer.c
source/blender/blenlib/BLI_math_geom.h
source/blender/blenlib/BLI_math_vector.h
source/blender/blenlib/BLI_utildefines.h
source/blender/blenlib/intern/math_geom.c
source/blender/blenlib/intern/math_vector_inline.c
source/blender/blenlib/intern/path_util.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/animation/anim_channels_edit.c
source/blender/editors/animation/anim_markers.c
source/blender/editors/animation/anim_ops.c
source/blender/editors/datafiles/startup.blend.c
source/blender/editors/include/ED_mesh.h
source/blender/editors/include/ED_screen.h
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_draw.c
source/blender/editors/interface/interface_intern.h
source/blender/editors/interface/interface_layout.c
source/blender/editors/interface/interface_widgets.c
source/blender/editors/interface/resources.c
source/blender/editors/interface/view2d_ops.c
source/blender/editors/mesh/editmesh_loop.c
source/blender/editors/object/object_bake.c
source/blender/editors/object/object_shapekey.c
source/blender/editors/object/object_vgroup.c
source/blender/editors/render/render_view.c
source/blender/editors/screen/area.c
source/blender/editors/screen/screen_edit.c
source/blender/editors/screen/screen_ops.c
source/blender/editors/sculpt_paint/paint_image.c
source/blender/editors/sculpt_paint/paint_intern.h
source/blender/editors/sculpt_paint/paint_stroke.c
source/blender/editors/sculpt_paint/paint_vertex.c
source/blender/editors/sculpt_paint/sculpt.c
source/blender/editors/space_action/action_select.c
source/blender/editors/space_file/file_ops.c
source/blender/editors/space_file/filesel.c
source/blender/editors/space_graph/graph_select.c
source/blender/editors/space_image/image_ops.c
source/blender/editors/space_info/info_report.c
source/blender/editors/space_logic/logic_buttons.c
source/blender/editors/space_nla/nla_select.c
source/blender/editors/space_node/node_edit.c
source/blender/editors/space_node/node_select.c
source/blender/editors/space_outliner/outliner.c
source/blender/editors/space_sequencer/sequencer_draw.c
source/blender/editors/space_sequencer/sequencer_edit.c
source/blender/editors/space_sequencer/sequencer_select.c
source/blender/editors/space_view3d/view3d_edit.c
source/blender/editors/space_view3d/view3d_select.c
source/blender/editors/transform/transform.c
source/blender/editors/transform/transform_conversions.c
source/blender/editors/util/undo.c
source/blender/editors/uvedit/uvedit_ops.c
source/blender/gpu/intern/gpu_draw.c
source/blender/imbuf/IMB_imbuf.h
source/blender/imbuf/intern/divers.c
source/blender/imbuf/intern/filter.c
source/blender/makesdna/DNA_lattice_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/makesdna/DNA_sequence_types.h
source/blender/makesrna/RNA_access.h
source/blender/makesrna/RNA_define.h
source/blender/makesrna/RNA_types.h
source/blender/makesrna/intern/rna_access.c
source/blender/makesrna/intern/rna_define.c
source/blender/makesrna/intern/rna_internal_types.h
source/blender/makesrna/intern/rna_rna.c
source/blender/makesrna/intern/rna_scene.c
source/blender/makesrna/intern/rna_wm.c
source/blender/nodes/intern/CMP_nodes/CMP_math.c
source/blender/python/intern/bpy_props.c
source/blender/python/intern/bpy_rna.c
source/blender/python/intern/bpy_rna.h
source/blender/render/intern/source/rendercore.c
source/blender/render/intern/source/volumetric.c
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/WM_types.h
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_operators.c

index 008dfe77eae9fa80e572cf4ce5b36111070ae4b0..47073bf573488650ccea7d84641e3658c0afe8f9 100644 (file)
@@ -64,21 +64,19 @@ endif
 
 # Build Blender
 all:
-       @echo 
+       @echo
        @echo Configuring Blender ...
 
        if test ! -f $(BUILD_DIR)/CMakeCache.txt ; then \
-               mkdir -p $(BUILD_DIR) ; \
-               cd $(BUILD_DIR) ; \
-               cmake $(BLENDER_DIR) -DCMAKE_BUILD_TYPE:STRING=$(BUILD_TYPE) ; \
+               cmake -H$(BLENDER_DIR) -B$(BUILD_DIR) -DCMAKE_BUILD_TYPE:STRING=$(BUILD_TYPE) ; \
        fi
 
-       @echo 
+       @echo
        @echo Building Blender ...
-       cd $(BUILD_DIR) ; make -s -j $(NPROCS) install
-       @echo 
+       make -C $(BUILD_DIR) -s -j $(NPROCS) install
+       @echo
        @echo run blender from "$(BUILD_DIR)/bin/blender"
-       @echo 
+       @echo
 
 debug: all
        # pass
@@ -91,7 +89,7 @@ package_pacman:
        cd build_files/package_spec/pacman ; MAKEFLAGS="-j$(NPROCS)" makepkg --asroot
 
 package_archive:
-       cd $(BUILD_DIR) ; make -s package_archive
+       make -C $(BUILD_DIR) -s package_archive
        @echo archive in "$(BUILD_DIR)/release"
 
 # forward build targets
@@ -109,6 +107,6 @@ test_cmake:
        @echo "written: test_cmake_consistency.log"
 
 clean:
-       cd $(BUILD_DIR) ; make clean
+       make -C $(BUILD_DIR) clean
 
 .PHONY: all
index 65076be85edfae6fdeda8f1e0e9a996deaef16f2..a0dade8bdf67a84ad7c470a9bcc213f668c5a0f4 100644 (file)
@@ -35,7 +35,7 @@ BF_LIBSAMPLERATE_LIBPATH = '${BF_LIBSAMPLERATE}/lib'
 
 WITH_BF_JACK = False
 BF_JACK = LIBDIR + '/jack'
-BF_JACK_INC = '${BF_JACK}/include'
+BF_JACK_INC = '${BF_JACK}/include ${BF_FFMPEG}/include/msvc'
 BF_JACK_LIB = 'libjack'
 BF_JACK_LIBPATH = '${BF_JACK}/lib'
 
index 493c51ad2379ae2f170da9f399adc82ab0cc383f..2175d7528a460db1293f9c6c27d23c100fb358e6 100644 (file)
@@ -326,7 +326,7 @@ class AddPresetOperator(AddPresetBase, bpy.types.Operator):
 
         ret = []
         for prop_id, prop in operator_rna.properties.items():
-            if (not prop.is_hidden) and prop_id not in properties_blacklist:
+            if (not (prop.is_hidden or prop.is_skip_save)) and prop_id not in properties_blacklist:
                 ret.append("op.%s" % prop_id)
 
         return ret
index 3f4a061c4ac4c39d1b90716b2f3718d9458d0b71..fcc30ecbb4b4a18f585da8755a49cccb7b08c0a4 100644 (file)
@@ -106,7 +106,7 @@ class WM_OT_context_set_boolean(bpy.types.Operator):
     '''Set a context value.'''
     bl_idname = "wm.context_set_boolean"
     bl_label = "Context Set Boolean"
-    bl_options = {'UNDO'}
+    bl_options = {'UNDO', 'INTERNAL'}
 
     data_path = rna_path_prop
     value = BoolProperty(name="Value",
@@ -119,7 +119,7 @@ class WM_OT_context_set_int(bpy.types.Operator):  # same as enum
     '''Set a context value.'''
     bl_idname = "wm.context_set_int"
     bl_label = "Context Set"
-    bl_options = {'UNDO'}
+    bl_options = {'UNDO', 'INTERNAL'}
 
     data_path = rna_path_prop
     value = IntProperty(name="Value", description="Assign value", default=0)
@@ -132,7 +132,7 @@ class WM_OT_context_scale_int(bpy.types.Operator):
     '''Scale an int context value.'''
     bl_idname = "wm.context_scale_int"
     bl_label = "Context Set"
-    bl_options = {'UNDO'}
+    bl_options = {'UNDO', 'INTERNAL'}
 
     data_path = rna_path_prop
     value = FloatProperty(name="Value", description="Assign value", default=1.0)
@@ -168,7 +168,7 @@ class WM_OT_context_set_float(bpy.types.Operator):  # same as enum
     '''Set a context value.'''
     bl_idname = "wm.context_set_float"
     bl_label = "Context Set Float"
-    bl_options = {'UNDO'}
+    bl_options = {'UNDO', 'INTERNAL'}
 
     data_path = rna_path_prop
     value = FloatProperty(name="Value",
@@ -182,7 +182,7 @@ class WM_OT_context_set_string(bpy.types.Operator):  # same as enum
     '''Set a context value.'''
     bl_idname = "wm.context_set_string"
     bl_label = "Context Set String"
-    bl_options = {'UNDO'}
+    bl_options = {'UNDO', 'INTERNAL'}
 
     data_path = rna_path_prop
     value = StringProperty(name="Value",
@@ -195,7 +195,7 @@ class WM_OT_context_set_enum(bpy.types.Operator):
     '''Set a context value.'''
     bl_idname = "wm.context_set_enum"
     bl_label = "Context Set Enum"
-    bl_options = {'UNDO'}
+    bl_options = {'UNDO', 'INTERNAL'}
 
     data_path = rna_path_prop
     value = StringProperty(name="Value",
@@ -209,7 +209,7 @@ class WM_OT_context_set_value(bpy.types.Operator):
     '''Set a context value.'''
     bl_idname = "wm.context_set_value"
     bl_label = "Context Set Value"
-    bl_options = {'UNDO'}
+    bl_options = {'UNDO', 'INTERNAL'}
 
     data_path = rna_path_prop
     value = StringProperty(name="Value",
@@ -227,7 +227,7 @@ class WM_OT_context_toggle(bpy.types.Operator):
     '''Toggle a context value.'''
     bl_idname = "wm.context_toggle"
     bl_label = "Context Toggle"
-    bl_options = {'UNDO'}
+    bl_options = {'UNDO', 'INTERNAL'}
 
     data_path = rna_path_prop
 
@@ -246,7 +246,7 @@ class WM_OT_context_toggle_enum(bpy.types.Operator):
     '''Toggle a context value.'''
     bl_idname = "wm.context_toggle_enum"
     bl_label = "Context Toggle Values"
-    bl_options = {'UNDO'}
+    bl_options = {'UNDO', 'INTERNAL'}
 
     data_path = rna_path_prop
     value_1 = StringProperty(name="Value", \
@@ -273,7 +273,7 @@ class WM_OT_context_cycle_int(bpy.types.Operator):
     '''vertex keys, groups' etc.'''
     bl_idname = "wm.context_cycle_int"
     bl_label = "Context Int Cycle"
-    bl_options = {'UNDO'}
+    bl_options = {'UNDO', 'INTERNAL'}
 
     data_path = rna_path_prop
     reverse = rna_reverse_prop
@@ -307,7 +307,7 @@ class WM_OT_context_cycle_enum(bpy.types.Operator):
     '''Toggle a context value.'''
     bl_idname = "wm.context_cycle_enum"
     bl_label = "Context Enum Cycle"
-    bl_options = {'UNDO'}
+    bl_options = {'UNDO', 'INTERNAL'}
 
     data_path = rna_path_prop
     reverse = rna_reverse_prop
@@ -360,7 +360,7 @@ class WM_OT_context_cycle_array(bpy.types.Operator):
     Useful for cycling the active mesh edit mode.'''
     bl_idname = "wm.context_cycle_array"
     bl_label = "Context Array Cycle"
-    bl_options = {'UNDO'}
+    bl_options = {'UNDO', 'INTERNAL'}
 
     data_path = rna_path_prop
     reverse = rna_reverse_prop
@@ -406,7 +406,7 @@ class WM_MT_context_menu_enum(bpy.types.Menu):
 class WM_OT_context_menu_enum(bpy.types.Operator):
     bl_idname = "wm.context_menu_enum"
     bl_label = "Context Enum Menu"
-    bl_options = {'UNDO'}
+    bl_options = {'UNDO', 'INTERNAL'}
     data_path = rna_path_prop
 
     def execute(self, context):
@@ -420,7 +420,7 @@ class WM_OT_context_set_id(bpy.types.Operator):
     '''Toggle a context value.'''
     bl_idname = "wm.context_set_id"
     bl_label = "Set Library ID"
-    bl_options = {'UNDO'}
+    bl_options = {'UNDO', 'INTERNAL'}
 
     data_path = rna_path_prop
     value = StringProperty(name="Value",
@@ -462,6 +462,7 @@ class WM_OT_context_modal_mouse(bpy.types.Operator):
     '''Adjust arbitrary values with mouse input'''
     bl_idname = "wm.context_modal_mouse"
     bl_label = "Context Modal Mouse"
+    bl_options = {'INTERNAL'}
 
     data_path_iter = StringProperty(description="The data path relative to the context, must point to an iterable.")
     data_path_item = StringProperty(description="The data path from each iterable to the value (int or float)")
index 1f75b5059a55078952d53bc02c6f4a030edc816f..e2c8841317793c2ef9aa706d81fe2ffe96bc91ba 100644 (file)
@@ -99,8 +99,9 @@ class DATA_PT_normals(MeshButtonsPanel, bpy.types.Panel):
         split.prop(mesh, "show_double_sided")
 
 
-class DATA_PT_settings(MeshButtonsPanel, bpy.types.Panel):
-    bl_label = "Settings"
+class DATA_PT_texture_space(MeshButtonsPanel, bpy.types.Panel):
+    bl_label = "Texture Space"
+    bl_options = {'DEFAULT_CLOSED'}
     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
 
     def draw(self, context):
@@ -109,11 +110,13 @@ class DATA_PT_settings(MeshButtonsPanel, bpy.types.Panel):
         mesh = context.mesh
 
         layout.prop(mesh, "texture_mesh")
+
+        layout.separator()
+
         layout.prop(mesh, "use_auto_texspace")
-        
         row = layout.row()
-        row.column().prop(mesh, "texspace_location")
-        row.column().prop(mesh, "texspace_size")
+        row.column().prop(mesh, "texspace_location", text="Location")
+        row.column().prop(mesh, "texspace_size", text="Size")
 
 class DATA_PT_vertex_groups(MeshButtonsPanel, bpy.types.Panel):
     bl_label = "Vertex Groups"
index 7c2fe76fe1481a9d86b155afcf3e85cb0096308c..03823ad7345ca68c2e88a4f8da343c30e9ac90d6 100644 (file)
@@ -655,17 +655,19 @@ class ConstraintButtonsPanel():
         row = col.row()
         row.label(text="Source to Destination Mapping:")
 
+               # note: chr(187) is the ASCII arrow ( >> ). Blender Text Editor can't
+               # open it. Thus we are using the hardcoded value instead.
         row = col.row()
         row.prop(con, "map_to_x_from", expand=False, text="")
-        row.label(text=" -> X")
+        row.label(text=" %s    X" % chr(187))
 
         row = col.row()
         row.prop(con, "map_to_y_from", expand=False, text="")
-        row.label(text=" -> Y")
+        row.label(text=" %s    Y" % chr(187))
 
         row = col.row()
         row.prop(con, "map_to_z_from", expand=False, text="")
-        row.label(text=" -> Z")
+        row.label(text=" %s    Z" % chr(187))
 
         split = layout.split()
 
index a3b10702fa71f78bc469a9aa18f70849476c3dae..4e1c1b343633783dde70c8275124b0b5d9eaf0a2 100644 (file)
@@ -172,8 +172,130 @@ class RENDER_PT_layers(RenderButtonsPanel, bpy.types.Panel):
         row.prop(rl, "exclude_refraction", text="")
 
 
+class RENDER_PT_dimensions(RenderButtonsPanel, bpy.types.Panel):
+    bl_label = "Dimensions"
+    COMPAT_ENGINES = {'BLENDER_RENDER'}
+
+    def draw(self, context):
+        layout = self.layout
+
+        scene = context.scene
+        rd = scene.render
+
+        row = layout.row(align=True)
+        row.menu("RENDER_MT_presets", text=bpy.types.RENDER_MT_presets.bl_label)
+        row.operator("render.preset_add", text="", icon="ZOOMIN")
+        row.operator("render.preset_add", text="", icon="ZOOMOUT").remove_active = True
+
+        split = layout.split()
+
+        col = split.column()
+        sub = col.column(align=True)
+        sub.label(text="Resolution:")
+        sub.prop(rd, "resolution_x", text="X")
+        sub.prop(rd, "resolution_y", text="Y")
+        sub.prop(rd, "resolution_percentage", text="")
+
+        sub.label(text="Aspect Ratio:")
+        sub.prop(rd, "pixel_aspect_x", text="X")
+        sub.prop(rd, "pixel_aspect_y", text="Y")
+
+        row = col.row()
+        row.prop(rd, "use_border", text="Border")
+        sub = row.row()
+        sub.active = rd.use_border
+        sub.prop(rd, "use_crop_to_border", text="Crop")
+
+        col = split.column()
+        sub = col.column(align=True)
+        sub.label(text="Frame Range:")
+        sub.prop(scene, "frame_start", text="Start")
+        sub.prop(scene, "frame_end", text="End")
+        sub.prop(scene, "frame_step", text="Step")
+
+        sub.label(text="Frame Rate:")
+        if rd.fps_base == 1:
+            fps_rate = round(rd.fps / rd.fps_base)
+        else:
+            fps_rate = round(rd.fps / rd.fps_base, 2)
+
+        # TODO: Change the following to iterate over existing presets
+        custom_framerate = (fps_rate not in {23.98, 24, 25, 29.97, 30, 50, 59.94, 60})
+
+        if custom_framerate == True:
+            fps_label_text = "Custom (" + str(fps_rate) + " fps)"
+        else:
+            fps_label_text = str(fps_rate) + " fps"
+
+        sub.menu("RENDER_MT_framerate_presets", text=fps_label_text)
+
+        if custom_framerate or (bpy.types.RENDER_MT_framerate_presets.bl_label == "Custom"):
+            sub.prop(rd, "fps")
+            sub.prop(rd, "fps_base", text="/")
+        subrow = sub.row(align=True)
+        subrow.label(text="Time Remapping:")
+        subrow = sub.row(align=True)
+        subrow.prop(rd, "frame_map_old", text="Old")
+        subrow.prop(rd, "frame_map_new", text="New")
+
+
+class RENDER_PT_antialiasing(RenderButtonsPanel, bpy.types.Panel):
+    bl_label = "Anti-Aliasing"
+    COMPAT_ENGINES = {'BLENDER_RENDER'}
+
+    def draw_header(self, context):
+        rd = context.scene.render
+
+        self.layout.prop(rd, "use_antialiasing", text="")
+
+    def draw(self, context):
+        layout = self.layout
+
+        rd = context.scene.render
+        layout.active = rd.use_antialiasing
+
+        split = layout.split()
+
+        col = split.column()
+        col.row().prop(rd, "antialiasing_samples", expand=True)
+        sub = col.row()
+        sub.enabled = not rd.use_border
+        sub.prop(rd, "use_full_sample")
+
+        col = split.column()
+        col.prop(rd, "pixel_filter_type", text="")
+        col.prop(rd, "filter_size", text="Size")
+
+
+class RENDER_PT_motion_blur(RenderButtonsPanel, bpy.types.Panel):
+    bl_label = "Sampled Motion Blur"
+    bl_options = {'DEFAULT_CLOSED'}
+    COMPAT_ENGINES = {'BLENDER_RENDER'}
+
+    @classmethod
+    def poll(cls, context):
+        rd = context.scene.render
+        return not rd.use_full_sample and (rd.engine in cls.COMPAT_ENGINES)
+
+    def draw_header(self, context):
+        rd = context.scene.render
+
+        self.layout.prop(rd, "use_motion_blur", text="")
+
+    def draw(self, context):
+        layout = self.layout
+
+        rd = context.scene.render
+        layout.active = rd.use_motion_blur
+
+        row = layout.row()
+        row.prop(rd, "motion_blur_samples")
+        row.prop(rd, "motion_blur_shutter")
+
+
 class RENDER_PT_shading(RenderButtonsPanel, bpy.types.Panel):
     bl_label = "Shading"
+    bl_options = {'DEFAULT_CLOSED'}
     COMPAT_ENGINES = {'BLENDER_RENDER'}
 
     def draw(self, context):
@@ -276,6 +398,51 @@ class RENDER_PT_post_processing(RenderButtonsPanel, bpy.types.Panel):
         sub.prop(rd, "edge_color", text="")
 
 
+class RENDER_PT_stamp(RenderButtonsPanel, bpy.types.Panel):
+    bl_label = "Stamp"
+    bl_options = {'DEFAULT_CLOSED'}
+    COMPAT_ENGINES = {'BLENDER_RENDER'}
+
+    def draw_header(self, context):
+        rd = context.scene.render
+
+        self.layout.prop(rd, "use_stamp", text="")
+
+    def draw(self, context):
+        layout = self.layout
+
+        rd = context.scene.render
+
+        layout.active = rd.use_stamp
+
+        split = layout.split()
+
+        col = split.column()
+        col.prop(rd, "use_stamp_time", text="Time")
+        col.prop(rd, "use_stamp_date", text="Date")
+        col.prop(rd, "use_stamp_render_time", text="RenderTime")
+        col.prop(rd, "use_stamp_frame", text="Frame")
+        col.prop(rd, "use_stamp_scene", text="Scene")
+        col.prop(rd, "use_stamp_camera", text="Camera")
+        col.prop(rd, "use_stamp_lens", text="Lens")
+        col.prop(rd, "use_stamp_filename", text="Filename")
+        col.prop(rd, "use_stamp_marker", text="Marker")
+        col.prop(rd, "use_stamp_sequencer_strip", text="Seq. Strip")
+
+        col = split.column()
+        col.active = rd.use_stamp
+        col.prop(rd, "stamp_foreground", slider=True)
+        col.prop(rd, "stamp_background", slider=True)
+        col.separator()
+        col.prop(rd, "stamp_font_size", text="Font Size")
+
+        row = layout.split(percentage=0.2)
+        row.prop(rd, "use_stamp_note", text="Note")
+        sub = row.row()
+        sub.active = rd.use_stamp_note
+        sub.prop(rd, "stamp_note_text", text="")
+
+
 class RENDER_PT_output(RenderButtonsPanel, bpy.types.Panel):
     bl_label = "Output"
     COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -433,172 +600,6 @@ class RENDER_PT_encoding(RenderButtonsPanel, bpy.types.Panel):
         split.prop(rd, "ffmpeg_audio_volume", slider=True)
 
 
-class RENDER_PT_antialiasing(RenderButtonsPanel, bpy.types.Panel):
-    bl_label = "Anti-Aliasing"
-    COMPAT_ENGINES = {'BLENDER_RENDER'}
-
-    def draw_header(self, context):
-        rd = context.scene.render
-
-        self.layout.prop(rd, "use_antialiasing", text="")
-
-    def draw(self, context):
-        layout = self.layout
-
-        rd = context.scene.render
-        layout.active = rd.use_antialiasing
-
-        split = layout.split()
-
-        col = split.column()
-        col.row().prop(rd, "antialiasing_samples", expand=True)
-        sub = col.row()
-        sub.enabled = not rd.use_border
-        sub.prop(rd, "use_full_sample")
-
-        col = split.column()
-        col.prop(rd, "pixel_filter_type", text="")
-        col.prop(rd, "filter_size", text="Size")
-
-
-class RENDER_PT_motion_blur(RenderButtonsPanel, bpy.types.Panel):
-    bl_label = "Sampled Motion Blur"
-    bl_options = {'DEFAULT_CLOSED'}
-    COMPAT_ENGINES = {'BLENDER_RENDER'}
-
-    @classmethod
-    def poll(cls, context):
-        rd = context.scene.render
-        return not rd.use_full_sample and (rd.engine in cls.COMPAT_ENGINES)
-
-    def draw_header(self, context):
-        rd = context.scene.render
-
-        self.layout.prop(rd, "use_motion_blur", text="")
-
-    def draw(self, context):
-        layout = self.layout
-
-        rd = context.scene.render
-        layout.active = rd.use_motion_blur
-
-        row = layout.row()
-        row.prop(rd, "motion_blur_samples")
-        row.prop(rd, "motion_blur_shutter")
-
-
-class RENDER_PT_dimensions(RenderButtonsPanel, bpy.types.Panel):
-    bl_label = "Dimensions"
-    COMPAT_ENGINES = {'BLENDER_RENDER'}
-
-    def draw(self, context):
-        layout = self.layout
-
-        scene = context.scene
-        rd = scene.render
-
-        row = layout.row(align=True)
-        row.menu("RENDER_MT_presets", text=bpy.types.RENDER_MT_presets.bl_label)
-        row.operator("render.preset_add", text="", icon="ZOOMIN")
-        row.operator("render.preset_add", text="", icon="ZOOMOUT").remove_active = True
-
-        split = layout.split()
-
-        col = split.column()
-        sub = col.column(align=True)
-        sub.label(text="Resolution:")
-        sub.prop(rd, "resolution_x", text="X")
-        sub.prop(rd, "resolution_y", text="Y")
-        sub.prop(rd, "resolution_percentage", text="")
-
-        sub.label(text="Aspect Ratio:")
-        sub.prop(rd, "pixel_aspect_x", text="X")
-        sub.prop(rd, "pixel_aspect_y", text="Y")
-
-        row = col.row()
-        row.prop(rd, "use_border", text="Border")
-        sub = row.row()
-        sub.active = rd.use_border
-        sub.prop(rd, "use_crop_to_border", text="Crop")
-
-        col = split.column()
-        sub = col.column(align=True)
-        sub.label(text="Frame Range:")
-        sub.prop(scene, "frame_start", text="Start")
-        sub.prop(scene, "frame_end", text="End")
-        sub.prop(scene, "frame_step", text="Step")
-
-        sub.label(text="Frame Rate:")
-        if rd.fps_base == 1:
-            fps_rate = round(rd.fps / rd.fps_base)
-        else:
-            fps_rate = round(rd.fps / rd.fps_base, 2)
-
-        # TODO: Change the following to iterate over existing presets
-        custom_framerate = (fps_rate not in {23.98, 24, 25, 29.97, 30, 50, 59.94, 60})
-
-        if custom_framerate == True:
-            fps_label_text = "Custom (" + str(fps_rate) + " fps)"
-        else:
-            fps_label_text = str(fps_rate) + " fps"
-
-        sub.menu("RENDER_MT_framerate_presets", text=fps_label_text)
-
-        if custom_framerate or (bpy.types.RENDER_MT_framerate_presets.bl_label == "Custom"):
-            sub.prop(rd, "fps")
-            sub.prop(rd, "fps_base", text="/")
-        subrow = sub.row(align=True)
-        subrow.label(text="Time Remapping:")
-        subrow = sub.row(align=True)
-        subrow.prop(rd, "frame_map_old", text="Old")
-        subrow.prop(rd, "frame_map_new", text="New")
-
-
-class RENDER_PT_stamp(RenderButtonsPanel, bpy.types.Panel):
-    bl_label = "Stamp"
-    bl_options = {'DEFAULT_CLOSED'}
-    COMPAT_ENGINES = {'BLENDER_RENDER'}
-
-    def draw_header(self, context):
-        rd = context.scene.render
-
-        self.layout.prop(rd, "use_stamp", text="")
-
-    def draw(self, context):
-        layout = self.layout
-
-        rd = context.scene.render
-
-        layout.active = rd.use_stamp
-
-        split = layout.split()
-
-        col = split.column()
-        col.prop(rd, "use_stamp_time", text="Time")
-        col.prop(rd, "use_stamp_date", text="Date")
-        col.prop(rd, "use_stamp_render_time", text="RenderTime")
-        col.prop(rd, "use_stamp_frame", text="Frame")
-        col.prop(rd, "use_stamp_scene", text="Scene")
-        col.prop(rd, "use_stamp_camera", text="Camera")
-        col.prop(rd, "use_stamp_lens", text="Lens")
-        col.prop(rd, "use_stamp_filename", text="Filename")
-        col.prop(rd, "use_stamp_marker", text="Marker")
-        col.prop(rd, "use_stamp_sequencer_strip", text="Seq. Strip")
-
-        col = split.column()
-        col.active = rd.use_stamp
-        col.prop(rd, "stamp_foreground", slider=True)
-        col.prop(rd, "stamp_background", slider=True)
-        col.separator()
-        col.prop(rd, "stamp_font_size", text="Font Size")
-
-        row = layout.split(percentage=0.2)
-        row.prop(rd, "use_stamp_note", text="Note")
-        sub = row.row()
-        sub.active = rd.use_stamp_note
-        sub.prop(rd, "stamp_note_text", text="")
-
-
 class RENDER_PT_bake(RenderButtonsPanel, bpy.types.Panel):
     bl_label = "Bake"
     bl_options = {'DEFAULT_CLOSED'}
@@ -613,29 +614,42 @@ class RENDER_PT_bake(RenderButtonsPanel, bpy.types.Panel):
 
         layout.prop(rd, "bake_type")
 
-        if rd.bake_type == 'NORMALS':
-            layout.prop(rd, "bake_normal_space")
-        elif rd.bake_type in {'DISPLACEMENT', 'AO'}:
-            layout.prop(rd, "use_bake_normalize")
+        multires_bake = False
+        if rd.bake_type in ['NORMALS', 'DISPLACEMENT']:
+            layout.prop(rd, 'use_bake_multires')
+            multires_bake = rd.use_bake_multires
 
-        # col.prop(rd, "bake_aa_mode")
-        # col.prop(rd, "use_bake_antialiasing")
+        if not multires_bake:
+            if rd.bake_type == 'NORMALS':
+                layout.prop(rd, "bake_normal_space")
+            elif rd.bake_type in {'DISPLACEMENT', 'AO'}:
+                layout.prop(rd, "use_bake_normalize")
 
-        layout.separator()
+            # col.prop(rd, "bake_aa_mode")
+            # col.prop(rd, "use_bake_antialiasing")
 
-        split = layout.split()
+            layout.separator()
 
-        col = split.column()
-        col.prop(rd, "use_bake_clear")
-        col.prop(rd, "bake_margin")
-        col.prop(rd, "bake_quad_split", text="Split")
+            split = layout.split()
+
+            col = split.column()
+            col.prop(rd, "use_bake_clear")
+            col.prop(rd, "bake_margin")
+            col.prop(rd, "bake_quad_split", text="Split")
+
+            col = split.column()
+            col.prop(rd, "use_bake_selected_to_active")
+            sub = col.column()
+            sub.active = rd.use_bake_selected_to_active
+            sub.prop(rd, "bake_distance")
+            sub.prop(rd, "bake_bias")
+        else:
+            if rd.bake_type == 'DISPLACEMENT':
+                layout.prop(rd, "use_bake_lores_mesh")
+
+            layout.prop(rd, "use_bake_clear")
+            layout.prop(rd, "bake_margin")
 
-        col = split.column()
-        col.prop(rd, "use_bake_selected_to_active")
-        sub = col.column()
-        sub.active = rd.use_bake_selected_to_active
-        sub.prop(rd, "bake_distance")
-        sub.prop(rd, "bake_bias")
 
 if __name__ == "__main__":  # only for live edit.
     bpy.utils.register_module(__name__)
index 5b07e8dc37f8f7a6834eb5eaa71d4783539b3bb4..0fc8d937f6683b05b9a067a84fcb21786bf80878 100644 (file)
@@ -42,7 +42,7 @@ class TEXT_HT_header(bpy.types.Header):
 
         if text and text.is_modified:
             row = layout.row()
-            # row.color(redalert)
+            row.alert = True
             row.operator("text.resolve_conflict", text="", icon='HELP')
 
         layout.template_ID(st, "text", new="text.new", unlink="text.unlink")
index ad736cd07bf47c81a79623bd5597ac89f9d6b9da..ebb9714cd1b7af2792f35d7d007e9152f2fa258d 100644 (file)
@@ -71,7 +71,7 @@ float brush_curve_strength(struct Brush *br, float p, const float len); /* used
 /* sampling */
 void brush_sample_tex(struct Brush *brush, float *xy, float *rgba, const int thread);
 void brush_imbuf_new(struct Brush *brush, short flt, short texfalloff, int size,
-       struct ImBuf **imbuf);
+       struct ImBuf **imbuf, int use_color_correction);
 
 /* painting */
 struct BrushPainter;
@@ -82,7 +82,7 @@ BrushPainter *brush_painter_new(struct Brush *brush);
 void brush_painter_require_imbuf(BrushPainter *painter, short flt,
        short texonly, int size);
 int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos,
-       double time, float pressure, void *user);
+       double time, float pressure, void *user, int use_color_correction);
 void brush_painter_break_stroke(BrushPainter *painter);
 void brush_painter_free(BrushPainter *painter);
 
index a9ac201beda64c0a5b174e21040b9699df9483af..64cea9295736d999a5cc531352fa7bfa314c74bf 100644 (file)
@@ -59,9 +59,9 @@ float  defvert_array_find_weight_safe(const struct MDeformVert *dvert, int index
 
 void defvert_copy(struct MDeformVert *dvert_r, const struct MDeformVert *dvert);
 void defvert_sync(struct MDeformVert *dvert_r, const struct MDeformVert *dvert, int use_verify);
-void defvert_sync_mapped(struct MDeformVert *dvert_r, const struct MDeformVert *dvert, int *flip_map, int use_verify);
+void defvert_sync_mapped(struct MDeformVert *dvert_r, const struct MDeformVert *dvert, const int *flip_map, int use_verify);
 void defvert_remap (struct MDeformVert *dvert, int *map);
-void defvert_flip(struct MDeformVert *dvert, int *flip_map);
+void defvert_flip(struct MDeformVert *dvert, const int *flip_map);
 void defvert_normalize(struct MDeformVert *dvert);
 
 /* utility function, note that 32 chars is the maximum string length since its only
index ea34ff4aa0789050e4f1b15aad4752ea7fd182a6..ba23b2d79c084d7e54f230d14b8cc7fc7dbf6179 100644 (file)
@@ -91,6 +91,7 @@ void multires_topology_changed(struct Scene *scene, struct Object *ob);
 void old_mdisps_bilinear(float out[3], float (*disps)[3], const int st, float u, float v);
 void mdisp_rot_crn_to_face(const int S, const int corners, const int face_side, const float x, const float y, float *u, float *v);
 int mdisp_rot_face_to_crn(const int corners, const int face_side, const float u, const float v, float *x, float *y);
+int mdisp_rot_face_to_quad_crn(const int corners, const int face_side, const float u, const float v, float *x, float *y);
 void mdisp_apply_weight(const int S, const int corners, int x, int y, const int face_side, float crn_weight[4][2], float *u_r, float *v_r);
 void mdisp_flip_disp(const int S, const int corners, const float axis_x[2], const float axis_y[2], float disp[3]);
 void mdisp_join_tris(struct MDisps *dst, struct MDisps *tri1, struct MDisps *tri2);
index 25b60fef6ddc77ee8f1855c4024f24887483aafd..a4ceb62ab55dcbf2247afc76b88d0a16c9879b39 100644 (file)
@@ -521,7 +521,7 @@ void brush_sample_tex(Brush *brush, float *xy, float *rgba, const int thread)
 }
 
 
-void brush_imbuf_new(Brush *brush, short flt, short texfall, int bufsize, ImBuf **outbuf)
+void brush_imbuf_new(Brush *brush, short flt, short texfall, int bufsize, ImBuf **outbuf, int use_color_correction)
 {
        ImBuf *ibuf;
        float xy[2], dist, rgba[4], *dstf;
@@ -529,7 +529,8 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int bufsize, ImBuf
        const int radius= brush_size(brush);
        char *dst, crgb[3];
        const float alpha= brush_alpha(brush);
-
+       float brush_rgb[3];
+    
        imbflag= (flt)? IB_rectfloat: IB_rect;
        xoff = -bufsize/2.0f + 0.5f;
        yoff = -bufsize/2.0f + 0.5f;
@@ -541,6 +542,11 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int bufsize, ImBuf
                ibuf= IMB_allocImBuf(bufsize, bufsize, 32, imbflag);
 
        if (flt) {
+               copy_v3_v3(brush_rgb, brush->rgb);
+               if(use_color_correction){
+                       srgb_to_linearrgb_v3_v3(brush_rgb, brush_rgb);
+               }
+
                for (y=0; y < ibuf->y; y++) {
                        dstf = ibuf->rect_float + y*rowbytes;
 
@@ -551,7 +557,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int bufsize, ImBuf
                                if (texfall == 0) {
                                        dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
 
-                                       VECCOPY(dstf, brush->rgb);
+                                       VECCOPY(dstf, brush_rgb);
                                        dstf[3]= alpha*brush_curve_strength_clamp(brush, dist, radius);
                                }
                                else if (texfall == 1) {
@@ -561,10 +567,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int bufsize, ImBuf
                                        dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
 
                                        brush_sample_tex(brush, xy, rgba, 0);
-
-                                       dstf[0] = rgba[0]*brush->rgb[0];
-                                       dstf[1] = rgba[1]*brush->rgb[1];
-                                       dstf[2] = rgba[2]*brush->rgb[2];
+                                       mul_v3_v3v3(dstf, rgba, brush_rgb);
                                        dstf[3] = rgba[3]*alpha*brush_curve_strength_clamp(brush, dist, radius);
                                }
                        }
@@ -862,7 +865,7 @@ static void brush_painter_fixed_tex_partial_update(BrushPainter *painter, float
                brush_painter_do_partial(painter, NULL, x1, y2, x2, ibuf->y, 0, 0, pos);
 }
 
-static void brush_painter_refresh_cache(BrushPainter *painter, float *pos)
+static void brush_painter_refresh_cache(BrushPainter *painter, float *pos, int use_color_correction)
 {
        Brush *brush= painter->brush;
        BrushPainterCache *cache= &painter->cache;
@@ -889,11 +892,11 @@ static void brush_painter_refresh_cache(BrushPainter *painter, float *pos)
                size= (cache->size)? cache->size: diameter;
 
                if (brush->flag & BRUSH_FIXED_TEX) {
-                       brush_imbuf_new(brush, flt, 3, size, &cache->maskibuf);
+                       brush_imbuf_new(brush, flt, 3, size, &cache->maskibuf, use_color_correction);
                        brush_painter_fixed_tex_partial_update(painter, pos);
                }
                else
-                       brush_imbuf_new(brush, flt, 2, size, &cache->ibuf);
+                       brush_imbuf_new(brush, flt, 2, size, &cache->ibuf, use_color_correction);
 
                cache->lastsize= diameter;
                cache->lastalpha= alpha;
@@ -952,7 +955,7 @@ void brush_jitter_pos(Brush *brush, float *pos, float *jitterpos)
        }
 }
 
-int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, double time, float pressure, void *user)
+int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, double time, float pressure, void *user, int use_color_correction)
 {
        Brush *brush= painter->brush;
        int totpaintops= 0;
@@ -970,7 +973,7 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl
 
                brush_apply_pressure(painter, brush, pressure);
                if (painter->cache.enabled)
-                       brush_painter_refresh_cache(painter, pos);
+                       brush_painter_refresh_cache(painter, pos, use_color_correction);
                totpaintops += func(user, painter->cache.ibuf, pos, pos);
                
                painter->lasttime= time;
@@ -1043,7 +1046,7 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl
                                brush_jitter_pos(brush, paintpos, finalpos);
 
                                if (painter->cache.enabled)
-                                       brush_painter_refresh_cache(painter, finalpos);
+                                       brush_painter_refresh_cache(painter, finalpos, use_color_correction);
 
                                totpaintops +=
                                        func(user, painter->cache.ibuf, painter->lastpaintpos, finalpos);
@@ -1057,7 +1060,7 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl
                        brush_jitter_pos(brush, pos, finalpos);
 
                        if (painter->cache.enabled)
-                               brush_painter_refresh_cache(painter, finalpos);
+                               brush_painter_refresh_cache(painter, finalpos, use_color_correction);
 
                        totpaintops += func(user, painter->cache.ibuf, pos, finalpos);
 
@@ -1085,7 +1088,7 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl
                                brush_jitter_pos(brush, pos, finalpos);
 
                                if (painter->cache.enabled)
-                                       brush_painter_refresh_cache(painter, finalpos);
+                                       brush_painter_refresh_cache(painter, finalpos, use_color_correction);
 
                                totpaintops +=
                                        func(user, painter->cache.ibuf, painter->lastmousepos, finalpos);
index bffb4c3852a9c95a78a5bbe3ef5e7591f382123c..57a7c917fa35218e945a7e9d1d352b7a45762bcc 100644 (file)
@@ -540,7 +540,7 @@ static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
                                float face_u, face_v, crn_u, crn_v;
 
                                mdisp_apply_weight(S, dst_corners, x, y, st, crn_weight, &face_u, &face_v);
-                               crn = mdisp_rot_face_to_crn(src_corners, st, face_u, face_v, &crn_u, &crn_v);
+                               crn = mdisp_rot_face_to_quad_crn(src_corners, st, face_u, face_v, &crn_u, &crn_v);
 
                                old_mdisps_bilinear((*out), &s->disps[crn*side*side], side, crn_u, crn_v);
                                mdisp_flip_disp(crn, dst_corners, axis_x, axis_y, *out);
index 0696653d2e4c2c065168153d1fc283fa7b649ef5..11a0a5884eec7f3fd57c80b65b32c705cf1c91cf 100644 (file)
@@ -121,7 +121,7 @@ void defvert_sync (MDeformVert *dvert_r, const MDeformVert *dvert, int use_verif
 }
 
 /* be sure all flip_map values are valid */
-void defvert_sync_mapped (MDeformVert *dvert_r, const MDeformVert *dvert, int *flip_map, int use_verify)
+void defvert_sync_mapped (MDeformVert *dvert_r, const MDeformVert *dvert, const int *flip_map, int use_verify)
 {
        if(dvert->totweight && dvert_r->totweight) {
                int i;
@@ -170,7 +170,7 @@ void defvert_normalize (MDeformVert *dvert)
        }
 }
 
-void defvert_flip (MDeformVert *dvert, int *flip_map)
+void defvert_flip (MDeformVert *dvert, const int *flip_map)
 {
        MDeformWeight *dw;
        int i;
index 13ab89200db1deac766e1b95fa3e94bfa3df1d64..5802bb2b697ef06977ce10340fa44b0dbb99068d 100644 (file)
@@ -1997,11 +1997,67 @@ void mdisp_rot_crn_to_face(const int S, const int corners, const int face_side,
        }
 }
 
+/* Find per-corner coordinate with given per-face UV coord */
 int mdisp_rot_face_to_crn(const int corners, const int face_side, const float u, const float v, float *x, float *y)
 {
        const float offset = face_side*0.5f - 0.5f;
        int S = 0;
 
+       if (corners == 4) {
+               if(u <= offset && v <= offset) S = 0;
+               else if(u > offset  && v <= offset) S = 1;
+               else if(u > offset  && v > offset) S = 2;
+               else if(u <= offset && v >= offset)  S = 3;
+
+               if(S == 0) {
+                       *y = offset - u;
+                       *x = offset - v;
+               } else if(S == 1) {
+                       *x = u - offset;
+                       *y = offset - v;
+               } else if(S == 2) {
+                       *y = u - offset;
+                       *x = v - offset;
+               } else if(S == 3) {
+                       *x= offset - u;
+                       *y = v - offset;
+               }
+       } else {
+               int grid_size = offset;
+               float w = (face_side - 1) - u - v;
+               float W1, W2;
+
+               if (u >= v && u >= w) {S = 0; W1= w; W2= v;}
+               else if (v >= u && v >= w) {S = 1; W1 = u; W2 = w;}
+               else {S = 2; W1 = v; W2 = u;}
+
+               W1 /= (face_side-1);
+               W2 /= (face_side-1);
+
+               *x = (1-(2*W1)/(1-W2)) * grid_size;
+               *y = (1-(2*W2)/(1-W1)) * grid_size;
+       }
+
+       return S;
+}
+
+/* Find per-corner coordinate with given per-face UV coord
+   Practically as the previous funciton but it assumes a bit different coordinate system for triangles
+   which is optimized for MDISP layer interpolation:
+
+   v
+   ^
+   |      /|
+   |    /  |
+   |  /    |
+   |/______|___> u
+
+ */
+int mdisp_rot_face_to_quad_crn(const int corners, const int face_side, const float u, const float v, float *x, float *y)
+{
+       const float offset = face_side*0.5f - 0.5f;
+       int S = 0;
+
        if (corners == 4) {
                if(u <= offset && v <= offset) S = 0;
                else if(u > offset  && v <= offset) S = 1;
@@ -2148,7 +2204,7 @@ void mdisp_join_tris(MDisps *dst, MDisps *tri1, MDisps *tri2)
                                        face_v = st - 1 - face_v;
                                } else src = tri1;
 
-                               crn = mdisp_rot_face_to_crn(3, st, face_u, face_v, &crn_u, &crn_v);
+                               crn = mdisp_rot_face_to_quad_crn(3, st, face_u, face_v, &crn_u, &crn_v);
 
                                old_mdisps_bilinear((*out), &src->disps[crn*side*side], side, crn_u, crn_v);
                                (*out)[0] = 0;
index 90c5ac149a13ab8b229fb02f785f80f13c422ef7..189f2735aa8405330bc78ccdb71321a30c6bf2be 100644 (file)
@@ -2388,24 +2388,42 @@ void object_set_dimensions(Object *ob, const float *value)
 void minmax_object(Object *ob, float *min, float *max)
 {
        BoundBox bb;
-       Mesh *me;
-       Curve *cu;
        float vec[3];
        int a;
+       short change= FALSE;
        
        switch(ob->type) {
-               
        case OB_CURVE:
        case OB_FONT:
        case OB_SURF:
-               cu= ob->data;
-               
-               if(cu->bb==NULL) tex_space_curve(cu);
-               bb= *(cu->bb);
-               
-               for(a=0; a<8; a++) {
-                       mul_m4_v3(ob->obmat, bb.vec[a]);
-                       DO_MINMAX(bb.vec[a], min, max);
+               {
+                       Curve *cu= ob->data;
+
+                       if(cu->bb==NULL) tex_space_curve(cu);
+                       bb= *(cu->bb);
+
+                       for(a=0; a<8; a++) {
+                               mul_m4_v3(ob->obmat, bb.vec[a]);
+                               DO_MINMAX(bb.vec[a], min, max);
+                       }
+                       change= TRUE;
+               }
+               break;
+       case OB_LATTICE:
+               {
+                       Lattice *lt= ob->data;
+                       BPoint *bp= lt->def;
+                       int u, v, w;
+
+                       for(w=0; w<lt->pntsw; w++) {
+                               for(v=0; v<lt->pntsv; v++) {
+                                       for(u=0; u<lt->pntsu; u++, bp++) {
+                                               mul_v3_m4v3(vec, ob->obmat, bp->vec);
+                                               DO_MINMAX(vec, min, max);
+                                       }
+                               }
+                       }
+                       change= TRUE;
                }
                break;
        case OB_ARMATURE:
@@ -2417,25 +2435,27 @@ void minmax_object(Object *ob, float *min, float *max)
                                mul_v3_m4v3(vec, ob->obmat, pchan->pose_tail);
                                DO_MINMAX(vec, min, max);
                        }
-                       break;
+                       change= TRUE;
                }
-               /* no break, get_mesh will give NULL and it passes on to default */
+               break;
        case OB_MESH:
-               me= get_mesh(ob);
-               
-               if(me) {
-                       bb = *mesh_get_bb(ob);
-                       
-                       for(a=0; a<8; a++) {
-                               mul_m4_v3(ob->obmat, bb.vec[a]);
-                               DO_MINMAX(bb.vec[a], min, max);
+               {
+                       Mesh *me= get_mesh(ob);
+
+                       if(me) {
+                               bb = *mesh_get_bb(ob);
+
+                               for(a=0; a<8; a++) {
+                                       mul_m4_v3(ob->obmat, bb.vec[a]);
+                                       DO_MINMAX(bb.vec[a], min, max);
+                               }
+                               change= TRUE;
                        }
                }
-               if(min[0] < max[0] ) break;
-               
-               /* else here no break!!!, mesh can be zero sized */
-               
-       default:
+               break;
+       }
+
+       if(change == FALSE) {
                DO_MINMAX(ob->obmat[3], min, max);
 
                copy_v3_v3(vec, ob->obmat[3]);
@@ -2445,7 +2465,6 @@ void minmax_object(Object *ob, float *min, float *max)
                copy_v3_v3(vec, ob->obmat[3]);
                sub_v3_v3(vec, ob->size);
                DO_MINMAX(vec, min, max);
-               break;
        }
 }
 
index b94782f9a25c0c78b4cffe2447d02e4bef3e9bf2..b82ac69fc9e068166411a0932990fafcc1c15300 100644 (file)
@@ -594,7 +594,12 @@ void calc_sequence(Scene *scene, Sequence *seq)
                                seq->start= seq->enddisp;
                                seq->enddisp = seq->startdisp;
                                seq->startdisp= seq->start;
+                               seq->flag |= SEQ_INVALID_EFFECT;
                        }
+                       else {
+                               seq->flag &= ~SEQ_INVALID_EFFECT;
+                       }
+
                        seq->len= seq->enddisp - seq->startdisp;
                }
                else {
index 634634f02e5e366125fee10d5d370260eece1464..b34b9c4b70f27d99ba887e21ecb689a206da421e 100644 (file)
@@ -162,6 +162,9 @@ void barycentric_transform(float pt_tar[3], float const pt_src[3],
 void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3[2],
        const float co[2], float w[3]);
 
+void resolve_tri_uv(float uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2]);
+void resolve_quad_uv(float uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2]);
+
 /***************************** View & Projection *****************************/
 
 void lookat_m4(float mat[4][4], float vx, float vy, 
index 5f26bff0ad994db2e6d16c953ddce3618f155a77..decfa22c3e6529d4f6bc9e420687516678afd5e9 100644 (file)
@@ -58,6 +58,8 @@ MINLINE void swap_v4_v4(float a[4], float b[4]);
 
 /********************************* Arithmetic ********************************/
 
+MINLINE void add_v3_fl(float r[3], float f);
+MINLINE void add_v4_fl(float r[4], float f);
 MINLINE void add_v2_v2(float r[2], const float a[2]);
 MINLINE void add_v2_v2v2(float r[2], const float a[2], const float b[2]);
 MINLINE void add_v3_v3(float r[3], const float a[3]);
index a376d04841254608687b740486b7160a512247fd..9af55601ff7fcbd4632c73ec2bbb80c607df59a5 100644 (file)
 
 #define FTOCHAR(val) ((val)<=0.0f)? 0 : (((val)>(1.0f-0.5f/255.0f))? 255 : (char)((255.0f*(val))+0.5f))
 #define FTOUSHORT(val) ((val >= 1.0f-0.5f/65535)? 65535: (val <= 0.0f)? 0: (unsigned short)(val*65535.0f + 0.5f))
+#define F3TOCHAR3(v2,v1) (v1)[0]=FTOCHAR((v2[0])); (v1)[1]=FTOCHAR((v2[1])); (v1)[2]=FTOCHAR((v2[2]))
+#define F3TOCHAR4(v2,v1) { (v1)[0]=FTOCHAR((v2[0])); (v1)[1]=FTOCHAR((v2[1])); (v1)[2]=FTOCHAR((v2[2])); \
+                                               (v1)[3]=FTOCHAR((v2[3])); (v1)[3] = 255; }
+#define F4TOCHAR4(v2,v1) { (v1)[0]=FTOCHAR((v2[0])); (v1)[1]=FTOCHAR((v2[1])); (v1)[2]=FTOCHAR((v2[2])); \
+                                               (v1)[3]=FTOCHAR((v2[3])); (v1)[3]=FTOCHAR((v2[3])); }
+
 
 #define VECCOPY(v1,v2)          {*(v1)= *(v2); *(v1+1)= *(v2+1); *(v1+2)= *(v2+2);}
 #define VECCOPY2D(v1,v2)          {*(v1)= *(v2); *(v1+1)= *(v2+1);}
index 5979a24c807af73649f1ae54283b0e876a829311..96ed788a49fa8ab363df59403ae774061ae20291 100644 (file)
@@ -1809,6 +1809,80 @@ void interp_cubic_v3(float x[3], float v[3], const float x1[3], const float v1[3
        v[2]= 3*a[2]*t2 + 2*b[2]*t + v1[2];
 }
 
+/* unfortunately internal calculations have to be done at double precision to achieve correct/stable results. */
+
+#define IS_ZERO(x) ((x>(-DBL_EPSILON) && x<DBL_EPSILON) ? 1 : 0)
+
+/* Barycentric reverse  */
+void resolve_tri_uv(float uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2])
+{
+       /* find UV such that
+          t= u*t0 + v*t1 + (1-u-v)*t2
+          u*(t0-t2) + v*(t1-t2)= t-t2 */
+       const double a= st0[0]-st2[0], b= st1[0]-st2[0];
+       const double c= st0[1]-st2[1], d= st1[1]-st2[1];
+       const double det= a*d - c*b;
+
+       if(IS_ZERO(det)==0)     {  /* det should never be zero since the determinant is the signed ST area of the triangle. */
+               const double x[]= {st[0]-st2[0], st[1]-st2[1]};
+
+               uv[0]= (float)((d*x[0] - b*x[1])/det);
+               uv[1]= (float)(((-c)*x[0] + a*x[1])/det);
+       } else zero_v2(uv);
+}
+
+/* bilinear reverse */
+void resolve_quad_uv(float uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2])
+{
+       const double signed_area= (st0[0]*st1[1] - st0[1]*st1[0]) + (st1[0]*st2[1] - st1[1]*st2[0]) +
+                              (st2[0]*st3[1] - st2[1]*st3[0]) + (st3[0]*st0[1] - st3[1]*st0[0]);
+
+       /* X is 2D cross product (determinant)
+          A= (p0-p) X (p0-p3)*/
+       const double a= (st0[0]-st[0])*(st0[1]-st3[1]) - (st0[1]-st[1])*(st0[0]-st3[0]);
+
+       /* B= ( (p0-p) X (p1-p2) + (p1-p) X (p0-p3) ) / 2 */
+       const double b= 0.5 * ( ((st0[0]-st[0])*(st1[1]-st2[1]) - (st0[1]-st[1])*(st1[0]-st2[0])) +
+                                                        ((st1[0]-st[0])*(st0[1]-st3[1]) - (st1[1]-st[1])*(st0[0]-st3[0])) );
+
+       /* C = (p1-p) X (p1-p2) */
+       const double fC= (st1[0]-st[0])*(st1[1]-st2[1]) - (st1[1]-st[1])*(st1[0]-st2[0]);
+       const double denom= a - 2*b + fC;
+
+       // clear outputs
+       zero_v2(uv);
+
+       if(IS_ZERO(denom)!=0) {
+               const double fDen= a-fC;
+               if(IS_ZERO(fDen)==0)
+                       uv[0]= (float)(a / fDen);
+       } else {
+               const double desc_sq= b*b - a*fC;
+               const double desc= sqrt(desc_sq<0.0?0.0:desc_sq);
+               const double s= signed_area>0 ? (-1.0) : 1.0;
+
+               uv[0]= (float)(( (a-b) + s * desc ) / denom);
+       }
+
+       /* find UV such that
+         fST = (1-u)(1-v)*ST0 + u*(1-v)*ST1 + u*v*ST2 + (1-u)*v*ST3 */
+       {
+               const double denom_s= (1-uv[0])*(st0[0]-st3[0]) + uv[0]*(st1[0]-st2[0]);
+               const double denom_t= (1-uv[0])*(st0[1]-st3[1]) + uv[0]*(st1[1]-st2[1]);
+               int i= 0; double denom= denom_s;
+
+               if(fabs(denom_s)<fabs(denom_t)) {
+                       i= 1;
+                       denom=denom_t;
+               }
+
+               if(IS_ZERO(denom)==0)
+                       uv[1]= (float) (( (1-uv[0])*(st0[i]-st[i]) + uv[0]*(st1[i]-st[i]) ) / denom);
+       }
+}
+
+#undef IS_ZERO
+
 /***************************** View & Projection *****************************/
 
 void orthographic_m4(float matrix[][4], const float left, const float right, const float bottom, const float top, const float nearClip, const float farClip)
index 9f6a8afe2d5792088ac4f7b76178c949de1bb49a..e2b7c7703563c2736a66204af1414294504f63a7 100644 (file)
@@ -102,6 +102,21 @@ MINLINE void swap_v4_v4(float a[4], float b[4])
 
 /********************************* Arithmetic ********************************/
 
+MINLINE void add_v3_fl(float r[3], float f)
+{
+       r[0] += f;
+       r[1] += f;
+       r[2] += f;
+}
+
+MINLINE void add_v4_fl(float r[4], float f)
+{
+       r[0] += f;
+       r[1] += f;
+       r[2] += f;
+       r[3] += f;
+}
+
 MINLINE void add_v2_v2(float *r, const float *a)
 {
        r[0] += a[0];
index 6106dca2633c113c4ee1d2f9478afe2c932de3b8..af87707fb90084237881ceb02785a4ab7f377f7e 100644 (file)
@@ -154,9 +154,7 @@ int BLI_split_name_num(char *left, int *nr, const char *name, const char delim)
 {
        int a;
 
-       /* could use '0', but this would mean the first
-        * duplicate would become FooBar.000 */
-       *nr= 1;
+       *nr= 0;
        a= strlen(name);
        memcpy(left, name, (a + 1) * sizeof(char));
 
@@ -218,13 +216,13 @@ int BLI_uniquename_cb(int (*unique_check)(void *, const char *), void *arg, cons
                int             number;
                int             len= BLI_split_name_num(left, &number, name, delim);
                do {
-                       int newlen= BLI_snprintf(tempname, name_len, "%s%c%03d", left, delim, number);
+                       int newlen= BLI_snprintf(tempname, name_len, "%s%c%03d", left, delim, ++number);
                        if(newlen >= name_len) {
                                len -= ((newlen + 1) - name_len);
                                if(len < 0) len= number= 0;
                                left[len]= '\0';
                        }
-               } while(number++, unique_check(arg, tempname));
+               } while(unique_check(arg, tempname));
 
                BLI_strncpy(name, tempname, name_len);
                
index 384c2782d36be5f727ba02e5e6b2d91bd7244967..53d4ceec4e1f3c77ac038f7cb738835b5df68144 100644 (file)
@@ -1723,7 +1723,6 @@ static void lib_link_fcurves(FileData *fd, ID *id, ListBase *list)
 static void direct_link_fmodifiers(FileData *fd, ListBase *list)
 {
        FModifier *fcm;
-       int a;
        
        for (fcm= list->first; fcm; fcm= fcm->next) {
                /* relink general data */
@@ -1739,6 +1738,7 @@ static void direct_link_fmodifiers(FileData *fd, ListBase *list)
                                data->coefficients= newdataadr(fd, data->coefficients);
 
                                if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
+                                       unsigned int a;
                                        for(a = 0; a < data->arraysize; a++)
                                                SWITCH_INT(data->coefficients[a]);
                                }
index f755df799867fc30b1ea37303c72f33dd4111fb8..9145cc2b79d9ea4f4bc9e00b8d02b05b35beb5d7 100644 (file)
@@ -1881,6 +1881,7 @@ static void ANIM_OT_channels_select_border(wmOperatorType *ot)
        ot->invoke= WM_border_select_invoke;
        ot->exec= animchannels_borderselect_exec;
        ot->modal= WM_border_select_modal;
+       ot->cancel= WM_border_select_cancel;
        
        ot->poll= animedit_poll_channels_nla_tweakmode_off;
        
index c802ba621f1a8e1888db5a9059cc6b0a55f8af02..c6e5542703407af87d80379411aa231b081872c2 100644 (file)
@@ -717,7 +717,7 @@ static void ed_marker_move_apply(wmOperator *op)
 }
 
 /* only for modal */
-static void ed_marker_move_cancel(bContext *C, wmOperator *op)
+static int ed_marker_move_cancel(bContext *C, wmOperator *op)
 {
        RNA_int_set(op->ptr, "frames", 0);
        ed_marker_move_apply(op);
@@ -725,6 +725,8 @@ static void ed_marker_move_cancel(bContext *C, wmOperator *op)
        
        WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL);
        WM_event_add_notifier(C, NC_ANIMATION|ND_MARKERS, NULL);
+
+       return OPERATOR_CANCELLED;
 }
 
 
@@ -886,6 +888,7 @@ static void MARKER_OT_move(wmOperatorType *ot)
        ot->invoke= ed_marker_move_invoke_wrapper;
        ot->modal= ed_marker_move_modal;
        ot->poll= ed_markers_poll_selected_markers;
+       ot->cancel= ed_marker_move_cancel;
        
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER;
@@ -980,6 +983,7 @@ static void MARKER_OT_duplicate(wmOperatorType *ot)
        ot->invoke= ed_marker_duplicate_invoke_wrapper;
        ot->modal= ed_marker_move_modal;
        ot->poll= ed_markers_poll_selected_markers;
+       ot->cancel= ed_marker_move_cancel;
        
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -1185,6 +1189,7 @@ static void MARKER_OT_select_border(wmOperatorType *ot)
        ot->exec= ed_marker_border_select_exec;
        ot->invoke= ed_marker_select_border_invoke_wrapper;
        ot->modal= WM_border_select_modal;
+       ot->cancel= WM_border_select_cancel;
        
        ot->poll= ed_markers_poll_markers_exist;
        
index 93d99c59a0e2a0c482fb22913b9c8feb6f1eb1a0..0e0bf275d8fe299beeecce017a74e31eca0db968 100644 (file)
@@ -224,6 +224,7 @@ static void ANIM_OT_previewrange_set(wmOperatorType *ot)
        ot->invoke= WM_border_select_invoke;
        ot->exec= previewrange_define_exec;
        ot->modal= WM_border_select_modal;
+       ot->cancel= WM_border_select_cancel;
        
        ot->poll= ED_operator_animview_active;
        
index 6900f458a2b1c6f3616cb8b5a835270b73e251cb..1121eb5a299e6f6987765b32027496d325736859 100644 (file)
@@ -8854,8 +8854,8 @@ char datatoc_startup_blend[]= {
   0,  0,  0,  0,  0,  0,  0,255,255,255,255,255,114,114,114,255,  0,  0,  0,255,  0,  0,  0,255,255,255,255,255,114,114,114,255,
   0,  0,  0,255,  0,  0,  0,255,255,255,255,255,165,165,165,255,  0,  0,  0,255,  0,  0,  0,255,255,255,255,255,165,165,165,127,
   0,  0,  0,255,  0,  0,  0,255,255,255,255,255,160,160,160,100,127,112,112,100,  0,  0,  0,  0, 64, 64, 64,255,  0,  0,  0,255,
-241, 88,  0,255,  0,  0,  0, 40,255,140, 25,255,  8, 48,  8,255, 85,187, 85,255,255,255,255,255,  0,  0,  0,255,255,133,  0,255,
-  0,  0,  0,255,255,160,  0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255,204,  0,153,255,  0,  0,  0, 18,255,133,  0, 60,
+241, 88,  0,255,  0,  0,  0, 40,255,170, 64,255,  8, 48,  8,255, 85,187, 85,255,255,255,255,255,  0,  0,  0,255,255,133,  0,255,
+  0,  0,  0,255,255,160,  0,255,219, 37, 18,255,32, 255,255,255, 75, 75, 75,255,204,  0,153,255,  0,  0,  0, 18,255,133,  0, 60,
 255,133,  0,255, 32,  0,  0,255,  0, 32,  0,255,  0,  0,128,255,  0,  0,  0,  0, 34,221,221,255, 35, 97,221,255,200,200,200,255,
  80,200,255, 80,  0,  0,  0,  0,  0,  0,  0,  0, 96,192, 64,255,144,144,  0,255,128, 48, 96,255,219, 37, 18,255,240,255, 64,255,
 240,144,160,255,255,255,255,255,  0,  0,  0,255,144,144,  0,255, 64,144, 48,255,128, 48, 96,255,  0,  0,  0,255,240,255, 64,255,
index 5c4dfc6ba3d9bbe93892c915353a0f51f8bfff44..8bb77ad43a04710418d8bb964a593ecf5f7f9dbe 100644 (file)
@@ -206,10 +206,10 @@ struct bDeformGroup               *ED_vgroup_add(struct Object *ob);
 struct bDeformGroup            *ED_vgroup_add_name(struct Object *ob, const char *name);
 void                                   ED_vgroup_delete(struct Object *ob, struct bDeformGroup *defgroup);
 void                                   ED_vgroup_select_by_name(struct Object *ob, const char *name);
-void                                   ED_vgroup_data_create(struct ID *id);
+int                                            ED_vgroup_data_create(struct ID *id);
 int                                            ED_vgroup_give_array(struct ID *id, struct MDeformVert **dvert_arr, int *dvert_tot);
 int                                            ED_vgroup_copy_array(struct Object *ob, struct Object *ob_from);
-void                                   ED_vgroup_mirror(struct Object *ob, int mirror_weights, int flip_vgroups);
+void                                   ED_vgroup_mirror(struct Object *ob, const short mirror_weights, const short flip_vgroups);
 
 int                                            ED_vgroup_object_is_edit_mode(struct Object *ob);
 
index 6e396a1021b232a3a6c27463a146b82efbb0b9ba..f2ef4e16852b4454a8e7fa73fa38b54ecdd3a23f 100644 (file)
@@ -107,7 +107,7 @@ void        ED_screen_set_subwinactive(struct bContext *C, struct wmEvent *event);
 void   ED_screen_exit(struct bContext *C, struct wmWindow *window, struct bScreen *screen);
 void   ED_screen_animation_timer(struct bContext *C, int redraws, int refresh, int sync, int enable);
 void   ED_screen_animation_timer_update(struct bScreen *screen, int redraws, int refresh);
-int            ED_screen_full_newspace(struct bContext *C, ScrArea *sa, int type);
+ScrArea *ED_screen_full_newspace(struct bContext *C, ScrArea *sa, int type);
 void   ED_screen_full_prevspace(struct bContext *C, ScrArea *sa);
 void   ED_screen_full_restore(struct bContext *C, ScrArea *sa);
 struct ScrArea *ED_screen_full_toggle(struct bContext *C, struct wmWindow *win, struct ScrArea *sa);
index c431af9fd8e1530ca7dc47c3ad08b06c68b105df..a21122698d9252ea2f43be84ff0b6ae9476c5b81 100644 (file)
@@ -449,6 +449,45 @@ void uiCenteredBoundsBlock(uiBlock *block, int addval)
 
 /* link line drawing is not part of buttons or theme.. so we stick with it here */
 
+static int ui_but_float_precision(uiBut *but, double value)
+{
+       int prec;
+
+       /* first check if prec is 0 and fallback to a simple default */
+       if((prec= (int)but->a2) == 0) {
+               prec= (but->hardmax < 10.001f) ? 3 : 2;
+       }
+
+       /* check on the number of decimal places neede to display
+        * the number, this is so 0.00001 is not displayed as 0.00,
+        * _but_, this is only for small values si 10.0001 will not get
+        * the same treatment */
+       if(value != 0.0 && (value= ABS(value)) < 0.1) {
+               double prec_d= -(log10(value));
+               double prec_d_floor = floor(prec_d + FLT_EPSILON);
+               int test_prec= (int)prec_d_floor;
+
+               /* this check is so 0.00016 from isnt rounded to 0.0001 */
+               if(prec_d - prec_d_floor > FLT_EPSILON) { /* not ending with a .0~001 */
+                       /* check if a second decimal place is needed 0.00015 for eg. */
+                       if(double_round(value, test_prec + 1) - double_round(value, test_prec + 2) != 0.0) {
+                               test_prec += 2;
+                       }
+                       else {
+                               test_prec += 1;
+                       }
+               }
+
+               if(test_prec > prec && test_prec <= 7) {
+                       prec= test_prec;
+               }
+       }
+
+       CLAMP(prec, 1, 7);
+
+       return prec;
+}
+
 static void ui_draw_linkline(uiLinkLine *line)
 {
        rcti rect;
@@ -1530,10 +1569,7 @@ void ui_get_but_string(uiBut *but, char *str, int maxlen)
                                ui_get_but_string_unit(but, str, maxlen, value, 0);
                        }
                        else {
-                               int prec= (int)but->a2;
-                               if(prec==0) prec= 3;
-                               else CLAMP(prec, 1, 7);
-
+                               const int prec= ui_but_float_precision(but, value);
                                BLI_snprintf(str, maxlen, "%.*f", prec, value);
                        }
                }
@@ -2009,10 +2045,7 @@ void ui_check_but(uiBut *but)
                                BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%s", but->str, new_str);
                        }
                        else {
-                               int prec= (int)but->a2;
-                               if(prec==0) prec= (but->hardmax < 10.001f) ? 3 : 2;
-                               else CLAMP(prec, 1, 7);
-
+                               const int prec= ui_but_float_precision(but, value);
                                BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%.*f", but->str, prec, value);
                        }
                }
@@ -2030,11 +2063,9 @@ void ui_check_but(uiBut *but)
 
        case LABEL:
                if(ui_is_but_float(but)) {
-                       int prec= (int)but->a2;
+                       int prec;
                        value= ui_get_but_val(but);
-                       if(prec==0) prec= 3;
-                       else CLAMP(prec, 1, 7);
-
+                       prec= ui_but_float_precision(but, value);
                        BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%.*f", but->str, prec, value);
                }
                else {
index 710d4d58825d6b2b740f592361d3a2689d0eaa61..c7f11116834f91f0150d605f796e1192ba2c103d 100644 (file)
@@ -1120,7 +1120,7 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *rect)
        ColorBand *coba;
        CBData *cbd;
        float x1, y1, sizex, sizey;
-       float dx, v3[2], v1[2], v2[2], v1a[2], v2a[2];
+       float v3[2], v1[2], v2[2], v1a[2], v2a[2];
        int a;
        float pos, colf[4]= {0,0,0,0}; /* initialize incase the colorband isnt valid */
                
@@ -1131,18 +1131,17 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *rect)
        y1= rect->ymin;
        sizex= rect->xmax-x1;
        sizey= rect->ymax-y1;
-       
+
        /* first background, to show tranparency */
-       dx= sizex/12.0f;
-       v1[0]= x1;
-       for(a=0; a<12; a++) {
-               if(a & 1) glColor3f(0.3, 0.3, 0.3); else glColor3f(0.8, 0.8, 0.8);
-               glRectf(v1[0], y1, v1[0]+dx, y1+0.5f*sizey);
-               if(a & 1) glColor3f(0.8, 0.8, 0.8); else glColor3f(0.3, 0.3, 0.3);
-               glRectf(v1[0], y1+0.5f*sizey, v1[0]+dx, y1+sizey);
-               v1[0]+= dx;
-       }
-       
+
+       glColor4ub(UI_TRANSP_DARK, UI_TRANSP_DARK, UI_TRANSP_DARK, 255);
+       glRectf(x1, y1, x1+sizex, y1+sizey);
+       glEnable(GL_POLYGON_STIPPLE);
+       glColor4ub(UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, 255);
+       glPolygonStipple(checker_stipple_sml);
+       glRectf(x1, y1, x1+sizex, y1+sizey);
+       glDisable(GL_POLYGON_STIPPLE);
+
        glShadeModel(GL_FLAT);
        glEnable(GL_BLEND);
        
index 3f3665aae389c2020e3dfb087e45d20c4a2e0f64..8475090b468618eb2409bbcc6f03444bee0636b5 100644 (file)
@@ -486,6 +486,11 @@ void ui_widget_color_init(struct ThemeUI *tui);
 void ui_draw_menu_item(struct uiFontStyle *fstyle, rcti *rect, const char *name, int iconid, int state);
 void ui_draw_preview_item(struct uiFontStyle *fstyle, rcti *rect, const char *name, int iconid, int state);
 
+extern unsigned char checker_stipple_sml[];
+/* used for transp checkers */
+#define UI_TRANSP_DARK 100
+#define UI_TRANSP_LIGHT 160
+
 /* interface_style.c */
 void uiStyleInit(void);
 
index b68634acd1e46616b494f75e14272753de6f49a7..55c1488291bac10007a72a2b52ac617531e1fb21 100644 (file)
@@ -651,6 +651,9 @@ PointerRNA uiItemFullO(uiLayout *layout, const char *opname, const char *name, i
        if (flag & UI_ITEM_R_NO_BG)
                uiBlockSetEmboss(block, UI_EMBOSS);
 
+       if(layout->redalert)
+               uiButSetFlag(but, UI_BUT_REDALERT);
+
        /* assign properties */
        if(properties || (flag & UI_ITEM_O_RETURN_PROPS)) {
                PointerRNA *opptr= uiButGetOperatorPtrRNA(but);
index f767a432cd09c1ef035a4687368e23a3833e825c..41bb12e44336695ea33db4b128bb9143155fb27f 100644 (file)
@@ -159,6 +159,18 @@ static float check_tria_vert[6][2]= {
 static int check_tria_face[4][3]= {
 {3, 2, 4}, {3, 4, 5}, {1, 0, 3}, {0, 2, 3}};
 
+GLubyte checker_stipple_sml[32*32/8] =
+{
+       255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \
+       255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \
+       0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \
+       0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \
+       255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \
+       255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \
+       0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \
+       0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \
+};
+
 /* ************************************************* */
 
 void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3)
@@ -614,22 +626,10 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
        if(wtb->inner) {
                if(wcol->shaded==0) {
                        if (wcol->alpha_check) {
-                               GLubyte checker_stipple_sml[32*32/8] =
-                               {
-                                       255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \
-                                       255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \
-                                       0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \
-                                       0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \
-                                       255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \
-                                       255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \
-                                       0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \
-                                       0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \
-                               };
-
                                float x_mid= 0.0f; /* used for dumb clamping of values */
 
                                /* dark checkers */
-                               glColor4ub(100, 100, 100, 255);
+                               glColor4ub(UI_TRANSP_DARK, UI_TRANSP_DARK, UI_TRANSP_DARK, 255);
                                glBegin(GL_POLYGON);
                                for(a=0; a<wtb->totvert; a++) {
                                        glVertex2fv(wtb->inner_v[a]);
@@ -638,7 +638,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
 
                                /* light checkers */
                                glEnable(GL_POLYGON_STIPPLE);
-                               glColor4ub(160, 160, 160, 255);
+                               glColor4ub(UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, 255);
                                glPolygonStipple(checker_stipple_sml);
                                glBegin(GL_POLYGON);
                                for(a=0; a<wtb->totvert; a++) {
index 6d4d88da270ca0013f89829b685a70c849383beb..6527e0140b83da92bd7a9f815680ec3a7c550c28 100644 (file)
@@ -585,7 +585,7 @@ void ui_theme_init_default(void)
        SETCOL(btheme->tv3d.wire,       0x0, 0x0, 0x0, 255);
        SETCOL(btheme->tv3d.lamp,       0, 0, 0, 40);
        SETCOL(btheme->tv3d.select, 241, 88, 0, 255);
-       SETCOL(btheme->tv3d.active, 255, 140, 25, 255);
+       SETCOL(btheme->tv3d.active, 255, 170, 64, 255);
        SETCOL(btheme->tv3d.group,      8, 48, 8, 255);
        SETCOL(btheme->tv3d.group_active, 85, 187, 85, 255);
        SETCOL(btheme->tv3d.transform, 0xff, 0xff, 0xff, 255);
@@ -604,7 +604,7 @@ void ui_theme_init_default(void)
        SETCOL(btheme->tv3d.face_dot, 255, 133, 0, 255);
        SETCOL(btheme->tv3d.editmesh_active, 255, 255, 255, 128);
        SETCOLF(btheme->tv3d.edge_crease, 0.8, 0, 0.6, 1.0);
-       SETCOL(btheme->tv3d.edge_sharp, 255, 32, 32, 255);
+       SETCOL(btheme->tv3d.edge_sharp, 0, 255, 255, 255);
        SETCOL(btheme->tv3d.header_text, 0, 0, 0, 255);
        SETCOL(btheme->tv3d.header_text_hi, 255, 255, 255, 255);
        SETCOL(btheme->tv3d.button_text, 0, 0, 0, 255);
index f7bff168a33334f64caf9d4a70f7235879ed3805..434334258af2052fcd86e8cfbc2af46f5c76a42e 100644 (file)
@@ -876,6 +876,13 @@ static void view_zoomdrag_exit(bContext *C, wmOperator *op)
        }
 } 
 
+static int view_zoomdrag_cancel(bContext *C, wmOperator *op)
+{
+       view_zoomdrag_exit(C, op);
+
+       return OPERATOR_CANCELLED;
+}
+
 /* for 'redo' only, with no user input */
 static int view_zoomdrag_exec(bContext *C, wmOperator *op)
 {
@@ -1065,6 +1072,7 @@ static void VIEW2D_OT_zoom(wmOperatorType *ot)
        ot->exec= view_zoomdrag_exec;
        ot->invoke= view_zoomdrag_invoke;
        ot->modal= view_zoomdrag_modal;
+       ot->cancel= view_zoomdrag_cancel;
        
        ot->poll= view_zoom_poll;
        
@@ -1165,6 +1173,7 @@ static void VIEW2D_OT_zoom_border(wmOperatorType *ot)
        ot->invoke= WM_border_select_invoke;
        ot->exec= view_borderzoom_exec;
        ot->modal= WM_border_select_modal;
+       ot->cancel= WM_border_select_cancel;
        
        ot->poll= view_zoom_poll;
        
@@ -1352,7 +1361,14 @@ static void scroller_activate_exit(bContext *C, wmOperator *op)
                
                ED_region_tag_redraw(CTX_wm_region(C));
        }
-} 
+}
+
+static int scroller_activate_cancel(bContext *C, wmOperator *op)
+{
+       scroller_activate_exit(C, op);
+
+       return OPERATOR_CANCELLED;
+}
 
 /* apply transform to view (i.e. adjust 'cur' rect) */
 static void scroller_activate_apply(bContext *C, wmOperator *op)
@@ -1561,6 +1577,8 @@ static void VIEW2D_OT_scroller_activate(wmOperatorType *ot)
        /* api callbacks */
        ot->invoke= scroller_activate_invoke;
        ot->modal= scroller_activate_modal;
+       ot->cancel= scroller_activate_cancel;
+
        ot->poll= view2d_poll;
 }
 
index d7e59e0a68f1bc76fcba19e45962ffb5163c6a16..32971ca77ed7b5a662ae67d483a6f3ff3ab8169d 100644 (file)
@@ -716,6 +716,7 @@ void MESH_OT_knife_cut(wmOperatorType *ot)
        ot->invoke= WM_gesture_lines_invoke;
        ot->modal= WM_gesture_lines_modal;
        ot->exec= knife_cut_exec;
+       ot->cancel= WM_gesture_lines_cancel;
        
        ot->poll= EM_view3d_poll;
        
index b513bab3924f4edac875f9f2635201c014d477c0..565c5810cff82c284d7d1cc3e084f90b31914d97 100644 (file)
@@ -22,7 +22,8 @@
  *
  * The Original Code is: all of this file.
  *
- * Contributor(s): none yet.
+ * Contributor(s): Morten Mikkelsen,
+ *                 Sergey Sharybin
  *
  * ***** END GPL LICENSE BLOCK *****
  */
 #include "DNA_screen_types.h"
 #include "DNA_space_types.h"
 #include "DNA_world_types.h"
+#include "DNA_object_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
 
 #include "BLI_blenlib.h"
 #include "BLI_threads.h"
 #include "BLI_utildefines.h"
+#include "BLI_math.h"
+#include "BLI_math_geom.h"
 
 #include "BKE_blender.h"
 #include "BKE_context.h"
 #include "BKE_main.h"
 #include "BKE_multires.h"
 #include "BKE_report.h"
+#include "BKE_cdderivedmesh.h"
+#include "BKE_modifier.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_subsurf.h"
 
 #include "RE_pipeline.h"
 #include "RE_shader_ext.h"
 
 #include "object_intern.h"
 
+/* ****************** multires BAKING ********************** */
+
+/* holder of per-object data needed for bake job
+   needed to make job totally thread-safe */
+typedef struct MultiresBakerJobData {
+       struct MultiresBakerJobData *next, *prev;
+       DerivedMesh *lores_dm, *hires_dm;
+       int simple, lvl, tot_lvl;
+} MultiresBakerJobData;
+
+/* data passing to multires-baker job */
+typedef struct {
+       ListBase data;
+       int bake_clear, bake_filter;
+       short mode, use_lores_mesh;
+} MultiresBakeJob;
+
+/* data passing to multires baker */
+typedef struct {
+       DerivedMesh *lores_dm, *hires_dm;
+       int simple, lvl, tot_lvl, bake_filter;
+       short mode, use_lores_mesh;
+
+       int tot_obj, tot_image;
+       ListBase image;
+
+       int baked_objects, baked_faces;
+
+       short *stop;
+       short *do_update;
+       float *progress;
+} MultiresBakeRender;
+
+typedef void (*MPassKnownData)(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
+                               const int face_index, const int lvl, const float st[2],
+                               float tangmat[3][3], const int x, const int y);
+
+typedef void* (*MInitBakeData)(MultiresBakeRender *bkr, Image* ima);
+typedef void (*MApplyBakeData)(void *bake_data);
+typedef void (*MFreeBakeData)(void *bake_data);
+
+typedef struct {
+       MVert *mvert;
+       MFace *mface;
+       MTFace *mtface;
+       float *pvtangent;
+       float *precomputed_normals;
+       int w, h;
+       int face_index;
+       int i0, i1, i2;
+       DerivedMesh *lores_dm, *hires_dm;
+       int lvl;
+       void *bake_data;
+       MPassKnownData pass_data;
+} MResolvePixelData;
+
+typedef void (*MFlushPixel)(const MResolvePixelData *data, const int x, const int y);
+
+typedef struct {
+       int w, h;
+       char *texels;
+       const MResolvePixelData *data;
+       MFlushPixel flush_pixel;
+} MBakeRast;
+
+typedef struct {
+       float *heights;
+       float height_min, height_max;
+       Image *ima;
+       DerivedMesh *ssdm;
+} MHeightBakeData;
+
+static void multiresbake_get_normal(const MResolvePixelData *data, float norm[], const int face_num, const int vert_index)
+{
+       unsigned int indices[]= {data->mface[face_num].v1, data->mface[face_num].v2,
+                             data->mface[face_num].v3, data->mface[face_num].v4};
+       const int smoothnormal= (data->mface[face_num].flag & ME_SMOOTH);
+
+       if(!smoothnormal)  { /* flat */
+               if(data->precomputed_normals) {
+                       copy_v3_v3(norm, &data->precomputed_normals[3*face_num]);
+               } else {
+                       float nor[3];
+                       float *p0, *p1, *p2;
+                       const int iGetNrVerts= data->mface[face_num].v4!=0 ? 4 : 3;
+
+                       p0= data->mvert[indices[0]].co;
+                       p1= data->mvert[indices[1]].co;
+                       p2= data->mvert[indices[2]].co;
+
+                       if(iGetNrVerts==4) {
+                               float *p3= data->mvert[indices[3]].co;
+                               normal_quad_v3(nor, p0, p1, p2, p3);
+                       } else {
+                               normal_tri_v3(nor, p0, p1, p2);
+                       }
+
+                       copy_v3_v3(norm, nor);
+               }
+       } else {
+               short *no= data->mvert[indices[vert_index]].no;
+
+               normal_short_to_float_v3(norm, no);
+               normalize_v3(norm);
+       }
+}
+
+static void init_bake_rast(MBakeRast *bake_rast, const ImBuf *ibuf, const MResolvePixelData *data, MFlushPixel flush_pixel)
+{
+       memset(bake_rast, 0, sizeof(MBakeRast));
+
+       bake_rast->texels = ibuf->userdata;
+       bake_rast->w= ibuf->x;
+       bake_rast->h= ibuf->y;
+       bake_rast->data= data;
+       bake_rast->flush_pixel= flush_pixel;
+}
+
+static void flush_pixel(const MResolvePixelData *data, const int x, const int y)
+{
+       float st[2]= {(x+0.5f)/data->w, (y+0.5f)/data->h};
+       float *st0, *st1, *st2;
+       float *tang0, *tang1, *tang2;
+       float no0[3], no1[3], no2[3];
+       float fUV[2], from_tang[3][3], to_tang[3][3];
+       float u, v, w, sign;
+       int r;
+
+       const int i0= data->i0;
+       const int i1= data->i1;
+       const int i2= data->i2;
+
+       st0= data->mtface[data->face_index].uv[i0];
+       st1= data->mtface[data->face_index].uv[i1];
+       st2= data->mtface[data->face_index].uv[i2];
+
+       tang0= data->pvtangent + data->face_index*16 + i0*4;
+       tang1= data->pvtangent + data->face_index*16 + i1*4;
+       tang2= data->pvtangent + data->face_index*16 + i2*4;
+
+       multiresbake_get_normal(data, no0, data->face_index, i0);       /* can optimize these 3 into one call */
+       multiresbake_get_normal(data, no1, data->face_index, i1);
+       multiresbake_get_normal(data, no2, data->face_index, i2);
+
+       resolve_tri_uv(fUV, st, st0, st1, st2);
+
+       u= fUV[0];
+       v= fUV[1];
+       w= 1-u-v;
+
+       /* the sign is the same at all face vertices for any non degenerate face.
+          Just in case we clamp the interpolated value though. */
+       sign= (tang0[3]*u + tang1[3]*v + tang2[3]*w)<0 ? (-1.0f) : 1.0f;
+
+       /* this sequence of math is designed specifically as is with great care
+          to be compatible with our shader. Please don't change without good reason. */
+       for(r= 0; r<3; r++) {
+               from_tang[0][r]= tang0[r]*u + tang1[r]*v + tang2[r]*w;
+               from_tang[2][r]= no0[r]*u + no1[r]*v + no2[r]*w;
+       }
+
+       cross_v3_v3v3(from_tang[1], from_tang[2], from_tang[0]);  /* B = sign * cross(N, T)  */
+       mul_v3_fl(from_tang[1], sign);
+       invert_m3_m3(to_tang, from_tang);
+       /* sequence end */
+
+       data->pass_data(data->lores_dm, data->hires_dm, data->bake_data,
+                       data->face_index, data->lvl, st, to_tang, x, y);
+}
+
+static void set_rast_triangle(const MBakeRast *bake_rast, const int x, const int y)
+{
+       const int w= bake_rast->w;
+       const int h= bake_rast->h;
+
+       if(x>=0 && x<w && y>=0 && y<h) {
+               if((bake_rast->texels[y*w+x])==0) {
+                       flush_pixel(bake_rast->data, x, y);
+                       bake_rast->texels[y*w+x]= FILTER_MASK_USED;
+               }
+       }
+}
+
+static void rasterize_half(const MBakeRast *bake_rast,
+                           const float s0_s, const float t0_s, const float s1_s, const float t1_s,
+                           const float s0_l, const float t0_l, const float s1_l, const float t1_l,
+                           const int y0_in, const int y1_in, const int is_mid_right)
+{
+       const int s_stable= fabsf(t1_s-t0_s)>FLT_EPSILON ? 1 : 0;
+       const int l_stable= fabsf(t1_l-t0_l)>FLT_EPSILON ? 1 : 0;
+       const int w= bake_rast->w;
+       const int h= bake_rast->h;
+       int y, y0, y1;
+
+       if(y1_in<=0 || y0_in>=h)
+               return;
+
+       y0= y0_in<0 ? 0 : y0_in;
+       y1= y1_in>=h ? h : y1_in;
+
+       for(y= y0; y<y1; y++) {
+               /*-b(x-x0) + a(y-y0) = 0 */
+               int iXl, iXr, x;
+               float x_l= s_stable!=0 ? (s0_s + (((s1_s-s0_s)*(y-t0_s))/(t1_s-t0_s))) : s0_s;
+               float x_r= l_stable!=0 ? (s0_l + (((s1_l-s0_l)*(y-t0_l))/(t1_l-t0_l))) : s0_l;
+
+               if(is_mid_right!=0)
+                       SWAP(float, x_l, x_r);
+
+               iXl= (int)ceilf(x_l);
+               iXr= (int)ceilf(x_r);
+
+               if(iXr>0 && iXl<w) {
+                       iXl= iXl<0?0:iXl;
+                       iXr= iXr>=w?w:iXr;
+
+                       for(x= iXl; x<iXr; x++)
+                               set_rast_triangle(bake_rast, x, y);
+               }
+       }
+}
+
+static void bake_rasterize(const MBakeRast *bake_rast, const float st0_in[2], const float st1_in[2], const float st2_in[2])
+{
+       const int w= bake_rast->w;
+       const int h= bake_rast->h;
+       float slo= st0_in[0]*w - 0.5f;
+       float tlo= st0_in[1]*h - 0.5f;
+       float smi= st1_in[0]*w - 0.5f;
+       float tmi= st1_in[1]*h - 0.5f;
+       float shi= st2_in[0]*w - 0.5f;
+       float thi= st2_in[1]*h - 0.5f;
+       int is_mid_right= 0, ylo, yhi, yhi_beg;
+
+       /* skip degenerates */
+       if((slo==smi && tlo==tmi) || (slo==shi && tlo==thi) || (smi==shi && tmi==thi))
+               return;
+
+       /* sort by T */
+       if(tlo>tmi && tlo>thi) {
+               SWAP(float, shi, slo);
+               SWAP(float, thi, tlo);
+       } else if(tmi>thi) {
+               SWAP(float, shi, smi);
+               SWAP(float, thi, tmi);
+       }
+
+       if(tlo>tmi) {
+               SWAP(float, slo, smi);
+               SWAP(float, tlo, tmi);
+       }
+
+       /* check if mid point is to the left or to the right of the lo-hi edge */
+       is_mid_right= (-(shi-slo)*(tmi-thi) + (thi-tlo)*(smi-shi))>0 ? 1 : 0;
+       ylo= (int) ceilf(tlo);
+       yhi_beg= (int) ceilf(tmi);
+       yhi= (int) ceilf(thi);
+
+       /*if(fTmi>ceilf(fTlo))*/
+       rasterize_half(bake_rast, slo, tlo, smi, tmi, slo, tlo, shi, thi, ylo, yhi_beg, is_mid_right);
+       rasterize_half(bake_rast, smi, tmi, shi, thi, slo, tlo, shi, thi, yhi_beg, yhi, is_mid_right);
+}
+
+static int multiresbake_test_break(MultiresBakeRender *bkr)
+{
+       if(!bkr->stop) {
+               /* this means baker is executed outside from job system */
+               return 0;
+       }
+
+       return G.afbreek;
+}
+
+static void do_multires_bake(MultiresBakeRender *bkr, Image* ima, MPassKnownData passKnownData,
+                             MInitBakeData initBakeData, MApplyBakeData applyBakeData, MFreeBakeData freeBakeData)
+{
+       DerivedMesh *dm= bkr->lores_dm;
+       ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+       const int lvl= bkr->lvl;
+       const int tot_face= dm->getNumFaces(dm);
+       MVert *mvert= dm->getVertArray(dm);
+       MFace *mface= dm->getFaceArray(dm);
+       MTFace *mtface= dm->getFaceDataArray(dm, CD_MTFACE);
+       float *pvtangent= NULL;
+
+       if(CustomData_get_layer_index(&dm->faceData, CD_TANGENT) == -1)
+               DM_add_tangent_layer(dm);
+
+       pvtangent= DM_get_face_data_layer(dm, CD_TANGENT);
+
+       if(tot_face > 0) {  /* sanity check */
+               int f= 0;
+               MBakeRast bake_rast;
+               MResolvePixelData data={NULL};
+
+               data.mface= mface;
+               data.mvert= mvert;
+               data.mtface= mtface;
+               data.pvtangent= pvtangent;
+               data.precomputed_normals= dm->getFaceDataArray(dm, CD_NORMAL);  /* don't strictly need this */
+               data.w= ibuf->x;
+               data.h= ibuf->y;
+               data.lores_dm= dm;
+               data.hires_dm= bkr->hires_dm;
+               data.lvl= lvl;
+               data.pass_data= passKnownData;
+
+               if(initBakeData)
+                       data.bake_data= initBakeData(bkr, ima);
+
+               init_bake_rast(&bake_rast, ibuf, &data, flush_pixel);
+
+               for(f= 0; f<tot_face; f++) {
+                       MTFace *mtfate= &mtface[f];
+                       int verts[3][2], nr_tris, t;
+
+                       if(multiresbake_test_break(bkr))
+                               break;
+
+                       if(mtfate->tpage!=ima)
+                               continue;
+
+                       data.face_index= f;
+
+                       /* might support other forms of diagonal splits later on such as
+                          split by shortest diagonal.*/
+                       verts[0][0]=0;
+                       verts[1][0]=1;
+                       verts[2][0]=2;
+
+                       verts[0][1]=0;
+                       verts[1][1]=2;
+                       verts[2][1]=3;
+
+                       nr_tris= mface[f].v4!=0 ? 2 : 1;
+                       for(t= 0; t<nr_tris; t++) {
+                               data.i0= verts[0][t];
+                               data.i1= verts[1][t];
+                               data.i2 =verts[2][t];
+
+                               bake_rasterize(&bake_rast, mtfate->uv[data.i0], mtfate->uv[data.i1], mtfate->uv[data.i2]);
+                       }
+
+                       bkr->baked_faces++;
+
+                       if(bkr->do_update)
+                               *bkr->do_update= 1;
+
+                       if(bkr->progress)
+                               *bkr->progress= ((float)bkr->baked_objects + (float)bkr->baked_faces / tot_face) / bkr->tot_obj;
+               }
+
+               if(applyBakeData)
+                       applyBakeData(data.bake_data);
+
+               if(freeBakeData)
+                       freeBakeData(data.bake_data);
+       }
+}
+
+static void interp_bilinear_quad_data(float data[4][3], float u, float v, float res[3])
+{
+       float vec[3];
+
+       copy_v3_v3(res, data[0]);
+       mul_v3_fl(res, (1-u)*(1-v));
+       copy_v3_v3(vec, data[1]);
+       mul_v3_fl(vec, u*(1-v)); add_v3_v3(res, vec);
+       copy_v3_v3(vec, data[2]);
+       mul_v3_fl(vec, u*v); add_v3_v3(res, vec);
+       copy_v3_v3(vec, data[3]);
+       mul_v3_fl(vec, (1-u)*v); add_v3_v3(res, vec);
+}
+
+static void interp_barycentric_tri_data(float data[3][3], float u, float v, float res[3])
+{
+       float vec[3];
+
+       copy_v3_v3(res, data[0]);
+       mul_v3_fl(res, u);
+       copy_v3_v3(vec, data[1]);
+       mul_v3_fl(vec, v); add_v3_v3(res, vec);
+       copy_v3_v3(vec, data[2]);
+       mul_v3_fl(vec, 1.0f-u-v); add_v3_v3(res, vec);
+}
+
+/* mode = 0: interpolate normals,
+   mode = 1: interpolate coord */
+static void interp_bilinear_grid(DMGridData *grid, int grid_size, float crn_x, float crn_y, int mode, float res[3])
+{
+       int x0, x1, y0, y1;
+       float u, v;
+       float data[4][3];
+
+       x0= (int) crn_x;
+       x1= x0>=(grid_size-1) ? (grid_size-1) : (x0+1);
+
+       y0= (int) crn_y;
+       y1= y0>=(grid_size-1) ? (grid_size-1) : (y0+1);
+
+       u= crn_x-x0;
+       v= crn_y-y0;
+
+       if(mode == 0) {
+               copy_v3_v3(data[0], grid[y0 * grid_size + x0].no);
+               copy_v3_v3(data[1], grid[y0 * grid_size + x1].no);
+               copy_v3_v3(data[2], grid[y1 * grid_size + x1].no);
+               copy_v3_v3(data[3], grid[y1 * grid_size + x0].no);
+       } else {
+               copy_v3_v3(data[0], grid[y0 * grid_size + x0].co);
+               copy_v3_v3(data[1], grid[y0 * grid_size + x1].co);
+               copy_v3_v3(data[2], grid[y1 * grid_size + x1].co);
+               copy_v3_v3(data[3], grid[y1 * grid_size + x0].co);
+       }
+
+       interp_bilinear_quad_data(data, u, v, res);
+}
+
+static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm,  const int lvl, const int face_index, const float u, const float v, float co[3], float n[3])
+{
+       MFace mface;
+       DMGridData **grid_data;
+       float crn_x, crn_y;
+       int grid_size, S, face_side;
+       int *grid_offset, g_index;
+
+       lodm->getFace(lodm, face_index, &mface);
+
+       grid_size= hidm->getGridSize(hidm);
+       grid_data= hidm->getGridData(hidm);
+       grid_offset= hidm->getGridOffset(hidm);
+
+       face_side= (grid_size<<1)-1;
+
+       if(lvl==0) {
+               g_index= grid_offset[face_index];
+               S= mdisp_rot_face_to_crn(mface.v4 ? 4 : 3, face_side, u*(face_side-1), v*(face_side-1), &crn_x, &crn_y);
+       } else {
+               const int *index= lodm->getFaceDataArray(lodm, CD_ORIGINDEX);
+               int side= (1 << (lvl-1)) + 1;
+               int grid_index= index[face_index];
+               int loc_offs= face_index % (1<<(2*lvl));
+               int cell_index= loc_offs % ((side-1)*(side-1));
+               int cell_side= grid_size / (side-1);
+               int row= cell_index / (side-1);
+               int col= cell_index % (side-1);
+
+               S= face_index / (1<<(2*(lvl-1))) - grid_offset[grid_index];
+               g_index= grid_offset[grid_index];
+
+               crn_y= (row * cell_side) + u * cell_side;
+               crn_x= (col * cell_side) + v * cell_side;
+       }
+
+       CLAMP(crn_x, 0.0f, grid_size);
+       CLAMP(crn_y, 0.0f, grid_size);
+
+       if(n != NULL)
+               interp_bilinear_grid(grid_data[g_index + S], grid_size, crn_x, crn_y, 0, n);
+
+       if(co != NULL)
+               interp_bilinear_grid(grid_data[g_index + S], grid_size, crn_x, crn_y, 1, co);
+}
+
+/* mode = 0: interpolate normals,
+   mode = 1: interpolate coord */
+static void interp_bilinear_mface(DerivedMesh *dm, MFace *mface, const float u, const float v, const int mode, float res[3])
+{
+       float data[4][3];
+
+       if(mode == 0) {
+               dm->getVertNo(dm, mface->v1, data[0]);
+               dm->getVertNo(dm, mface->v2, data[1]);
+               dm->getVertNo(dm, mface->v3, data[2]);
+               dm->getVertNo(dm, mface->v4, data[3]);
+       } else {
+               dm->getVertCo(dm, mface->v1, data[0]);
+               dm->getVertCo(dm, mface->v2, data[1]);
+               dm->getVertCo(dm, mface->v3, data[2]);
+               dm->getVertCo(dm, mface->v4, data[3]);
+       }
+
+       interp_bilinear_quad_data(data, u, v, res);
+}
+
+/* mode = 0: interpolate normals,
+   mode = 1: interpolate coord */
+static void interp_barycentric_mface(DerivedMesh *dm, MFace *mface, const float u, const float v, const int mode, float res[3])
+{
+       float data[3][3];
+
+       if(mode == 0) {
+               dm->getVertNo(dm, mface->v1, data[0]);
+               dm->getVertNo(dm, mface->v2, data[1]);
+               dm->getVertNo(dm, mface->v3, data[2]);
+       } else {
+               dm->getVertCo(dm, mface->v1, data[0]);
+               dm->getVertCo(dm, mface->v2, data[1]);
+               dm->getVertCo(dm, mface->v3, data[2]);
+       }
+
+       interp_barycentric_tri_data(data, u, v, res);
+}
+
+static void *init_heights_data(MultiresBakeRender *bkr, Image* ima)
+{
+       MHeightBakeData *height_data;
+       ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+
+       height_data= MEM_callocN(sizeof(MHeightBakeData), "MultiresBake heightData");
+
+       height_data->ima= ima;
+       height_data->heights= MEM_callocN(sizeof(float)*ibuf->x*ibuf->y, "MultiresBake heights");
+       height_data->height_max= -FLT_MAX;
+       height_data->height_min= FLT_MAX;
+
+       if(!bkr->use_lores_mesh) {
+               SubsurfModifierData smd= {{NULL}};
+               int ss_lvl= bkr->tot_lvl - bkr->lvl;
+
+               CLAMP(ss_lvl, 0, 6);
+
+               smd.levels= smd.renderLevels= ss_lvl;
+               smd.flags|= eSubsurfModifierFlag_SubsurfUv;
+
+               if(bkr->simple)
+                       smd.subdivType= ME_SIMPLE_SUBSURF;
+
+               height_data->ssdm= subsurf_make_derived_from_derived(bkr->lores_dm, &smd, 0, NULL, 0, 0, 0);
+       }
+
+       return (void*)height_data;
+}
+
+static void apply_heights_data(void *bake_data)
+{
+       MHeightBakeData *height_data= (MHeightBakeData*)bake_data;
+       ImBuf *ibuf= BKE_image_get_ibuf(height_data->ima, NULL);
+       int x, y, i;
+       float height, *heights= height_data->heights;
+       float min= height_data->height_min, max= height_data->height_max;
+
+       for(x= 0; x<ibuf->x; x++) {
+               for(y =0; y<ibuf->y; y++) {
+                       i= ibuf->x*y + x;
+
+                       if(((char*)ibuf->userdata)[i] != FILTER_MASK_USED)
+                               continue;
+
+                       if(ibuf->rect_float) {
+                               float *rrgbf= ibuf->rect_float + i*4;
+
+                               if(max-min > 1e-5) height= (heights[i]-min)/(max-min);
+                               else height= 0;
+
+                               rrgbf[0]=rrgbf[1]=rrgbf[2]= height;
+                       } else {
+                               char *rrgb= (char*)ibuf->rect + i*4;
+
+                               if(max-min > 1e-5) height= (heights[i]-min)/(max-min);
+                               else height= 0;
+
+                               rrgb[0]=rrgb[1]=rrgb[2]= FTOCHAR(height);
+                       }
+               }
+       }
+
+       ibuf->userflags= IB_RECT_INVALID;
+}
+
+static void free_heights_data(void *bake_data)
+{
+       MHeightBakeData *height_data= (MHeightBakeData*)bake_data;
+
+       if(height_data->ssdm)
+               height_data->ssdm->release(height_data->ssdm);
+
+       MEM_freeN(height_data->heights);
+       MEM_freeN(height_data);
+}
+
+/* MultiresBake callback for heights baking
+   general idea:
+     - find coord of point with specified UV in hi-res mesh (let's call it p1)
+     - find coord of point and normal with specified UV in lo-res mesh (or subdivided lo-res
+       mesh to make texture smoother) let's call this point p0 and n.
+     - height wound be dot(n, p1-p0) */
+static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
+                                   const int face_index, const int lvl, const float st[2],
+                                   float UNUSED(tangmat[3][3]), const int x, const int y)
+{
+       MTFace *mtface= CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
+       MFace mface;
+       Image *ima= mtface[face_index].tpage;
+       ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+       MHeightBakeData *height_data= (MHeightBakeData*)bake_data;
+       float uv[2], *st0, *st1, *st2, *st3;
+       int pixel= ibuf->x*y + x;
+       float vec[3], p0[3], p1[3], n[3], len;
+
+       lores_dm->getFace(lores_dm, face_index, &mface);
+
+       st0= mtface[face_index].uv[0];
+       st1= mtface[face_index].uv[1];
+       st2= mtface[face_index].uv[2];
+
+       if(mface.v4) {
+               st3= mtface[face_index].uv[3];
+               resolve_quad_uv(uv, st, st0, st1, st2, st3);
+       } else
+               resolve_tri_uv(uv, st, st0, st1, st2);
+
+       CLAMP(uv[0], 0.0f, 1.0f);
+       CLAMP(uv[1], 0.0f, 1.0f);
+
+       get_ccgdm_data(lores_dm, hires_dm, lvl, face_index, uv[0], uv[1], p1, 0);
+
+       if(height_data->ssdm) {
+               //get_ccgdm_data_ss(lores_dm, height_data->ssdm, lvl, face_index, uv[0], uv[1], p0, n);
+               get_ccgdm_data(lores_dm, height_data->ssdm, 0, face_index, uv[0], uv[1], p0, n);
+       } else {
+               MFace mface;
+               lores_dm->getFace(lores_dm, face_index, &mface);
+
+               if(mface.v4) {
+                       interp_bilinear_mface(lores_dm, &mface, uv[0], uv[1], 1, p0);
+                       interp_bilinear_mface(lores_dm, &mface, uv[0], uv[1], 0, n);
+               } else {
+                       interp_barycentric_mface(lores_dm, &mface, uv[0], uv[1], 1, p0);
+                       interp_barycentric_mface(lores_dm, &mface, uv[0], uv[1], 0, n);
+               }
+       }
+
+       sub_v3_v3v3(vec, p1, p0);
+       //len= len_v3(vec);
+       len= dot_v3v3(n, vec);
+
+       height_data->heights[pixel]= len;
+       if(len<height_data->height_min) height_data->height_min= len;
+       if(len>height_data->height_max) height_data->height_max= len;
+
+       if(ibuf->rect_float) {
+               float *rrgbf= ibuf->rect_float + pixel*4;
+               rrgbf[3]= 1.0f;
+
+               ibuf->userflags= IB_RECT_INVALID;
+       } else {
+               char *rrgb= (char*)ibuf->rect + pixel*4;
+               rrgb[3]= 255;
+       }
+}
+
+/* MultiresBake callback for normals' baking
+   general idea:
+     - find coord and normal of point with specified UV in hi-res mesh
+     - multiply it by tangmat
+     - vector in color space would be norm(vec) /2 + (0.5, 0.5, 0.5) */
+static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *UNUSED(bake_data),
+                                   const int face_index, const int lvl, const float st[2],
+                                   float tangmat[3][3], const int x, const int y)
+{
+       MTFace *mtface= CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
+       MFace mface;
+       Image *ima= mtface[face_index].tpage;
+       ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+       float uv[2], *st0, *st1, *st2, *st3;
+       int pixel= ibuf->x*y + x;
+       float n[3], vec[3], tmp[3]= {0.5, 0.5, 0.5};
+
+       lores_dm->getFace(lores_dm, face_index, &mface);
+
+       st0= mtface[face_index].uv[0];
+       st1= mtface[face_index].uv[1];
+       st2= mtface[face_index].uv[2];
+
+       if(mface.v4) {
+               st3= mtface[face_index].uv[3];
+               resolve_quad_uv(uv, st, st0, st1, st2, st3);
+       } else
+               resolve_tri_uv(uv, st, st0, st1, st2);
+
+       CLAMP(uv[0], 0.0f, 1.0f);
+       CLAMP(uv[1], 0.0f, 1.0f);
+
+       get_ccgdm_data(lores_dm, hires_dm, lvl, face_index, uv[0], uv[1], NULL, n);
+
+       mul_v3_m3v3(vec, tangmat, n);
+       normalize_v3(vec);
+       mul_v3_fl(vec, 0.5);
+       add_v3_v3(vec, tmp);
+
+       if(ibuf->rect_float) {
+               float *rrgbf= ibuf->rect_float + pixel*4;
+               rrgbf[0]= vec[0];
+               rrgbf[1]= vec[1];
+               rrgbf[2]= vec[2];
+               rrgbf[3]= 1.0f;
+
+               ibuf->userflags= IB_RECT_INVALID;
+       } else {
+               char *rrgb= (char*)ibuf->rect + pixel*4;
+               rrgb[0]= FTOCHAR(vec[0]);
+               rrgb[1]= FTOCHAR(vec[1]);
+               rrgb[2]= FTOCHAR(vec[2]);
+               rrgb[3]= 255;
+       }
+}
+
+static void count_images(MultiresBakeRender *bkr)
+{
+       int a, totface;
+       DerivedMesh *dm= bkr->lores_dm;
+       MTFace *mtface= CustomData_get_layer(&dm->faceData, CD_MTFACE);
+
+       bkr->image.first= bkr->image.last= NULL;
+       bkr->tot_image= 0;
+
+       totface= dm->getNumFaces(dm);
+
+       for(a= 0; a<totface; a++)
+               mtface[a].tpage->id.flag&= ~LIB_DOIT;
+
+       for(a= 0; a<totface; a++) {
+               Image *ima= mtface[a].tpage;
+               if((ima->id.flag&LIB_DOIT)==0) {
+                       LinkData *data= BLI_genericNodeN(ima);
+                       BLI_addtail(&bkr->image, data);
+                       bkr->tot_image++;
+                       ima->id.flag|= LIB_DOIT;
+               }
+       }
+
+       for(a= 0; a<totface; a++)
+               mtface[a].tpage->id.flag&= ~LIB_DOIT;
+}
+
+static void bake_images(MultiresBakeRender *bkr)
+{
+       LinkData *link;
+
+       for(link= bkr->image.first; link; link= link->next) {
+               Image *ima= (Image*)link->data;
+               ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+
+               if(ibuf->x>0 && ibuf->y>0) {
+                       ibuf->userdata= MEM_callocN(ibuf->y*ibuf->x, "MultiresBake imbuf mask");
+
+                       switch(bkr->mode) {
+                               case RE_BAKE_NORMALS:
+                                       do_multires_bake(bkr, ima, apply_tangmat_callback, NULL, NULL, NULL);
+                                       break;
+                               case RE_BAKE_DISPLACEMENT:
+                                       do_multires_bake(bkr, ima, apply_heights_callback, init_heights_data,
+                                                        apply_heights_data, free_heights_data);
+                                       break;
+                       }
+               }
+
+               ima->id.flag|= LIB_DOIT;
+       }
+}
+
+static void finish_images(MultiresBakeRender *bkr)
+{
+       LinkData *link;
+
+       for(link= bkr->image.first; link; link= link->next) {
+               Image *ima= (Image*)link->data;
+               int i;
+               ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+
+               if(ibuf->x<=0 || ibuf->y<=0)
+                       continue;
+
+               /* Margin */
+               if(bkr->bake_filter) {
+                       char *temprect;
+
+                       /* extend the mask +2 pixels from the image,
+                        * this is so colors dont blend in from outside */
+
+                       for(i=0; i<bkr->bake_filter; i++)
+                               IMB_mask_filter_extend((char *)ibuf->userdata, ibuf->x, ibuf->y);
+
+                       temprect = MEM_dupallocN(ibuf->userdata);
+
+                       /* expand twice to clear this many pixels, so they blend back in */
+                       IMB_mask_filter_extend(temprect, ibuf->x, ibuf->y);
+                       IMB_mask_filter_extend(temprect, ibuf->x, ibuf->y);
+
+                       /* clear all pixels in the margin */
+                       IMB_mask_clear(ibuf, temprect, FILTER_MASK_MARGIN);
+                       MEM_freeN(temprect);
+
+                       for(i= 0; i<bkr->bake_filter; i++)
+                               IMB_filter_extend(ibuf, (char *)ibuf->userdata);
+               }
+
+               ibuf->userflags|= IB_BITMAPDIRTY;
+               if(ibuf->mipmap[0]) {
+                       ibuf->userflags|= IB_MIPMAP_INVALID;
+                       imb_freemipmapImBuf(ibuf);
+               }
+
+               if(ibuf->userdata) {
+                       MEM_freeN(ibuf->userdata);
+                       ibuf->userdata= NULL;
+               }
+       }
+}
+
+static void multiresbake_start(MultiresBakeRender *bkr)
+{
+       count_images(bkr);
+       bake_images(bkr);
+       finish_images(bkr);
+}
+
+static int multiresbake_check(bContext *C, wmOperator *op) {
+       Scene *scene= CTX_data_scene(C);
+       Object *ob;
+       Mesh *me;
+       MultiresModifierData *mmd;
+       int ok= 1, a;
+
+       CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
+               ob= base->object;
+
+               if(ob->type != OB_MESH) {
+                       BKE_report(op->reports, RPT_ERROR, "Basking of multires data only works with active object which is a mesh");
+
+                       ok= 0;
+                       break;
+               }
+
+               me= (Mesh*)ob->data;
+               mmd= get_multires_modifier(scene, ob, 0);
+
+               /* Multi-resolution should be and be last in the stack */
+               if(ok && mmd) {
+                       ModifierData *md;
+
+                       ok= mmd->totlvl>0;
+
+                       for(md = (ModifierData*)mmd->modifier.next; md && ok; md = md->next) {
+                               if (modifier_isEnabled(scene, md, eModifierMode_Realtime)) {
+                                       ok= 0;
+                               }
+                       }
+               } else ok= 0;
+
+               if(!ok) {
+                       BKE_report(op->reports, RPT_ERROR, "Multires data baking requires multi-resolution object");
+
+                       break;
+               }
+
+               if(!me->mtface) {
+                       BKE_report(op->reports, RPT_ERROR, "Mesh should be unwrapped before multires data baking");
+
+                       ok= 0;
+               } else {
+                       a= me->totface;
+                       while (ok && a--) {
+                               Image *ima= me->mtface[a].tpage;
+
+                               if(!ima) {
+                                       BKE_report(op->reports, RPT_ERROR, "You should have active texture to use multires baker");
+
+                                       ok= 0;
+                               } else {
+                                       ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+
+                                       if(!ibuf) {
+                                               BKE_report(op->reports, RPT_ERROR, "Baking should happend to image with image buffer");
+
+                                               ok= 0;
+                                       } else {
+                                               if(ibuf->rect==NULL && ibuf->rect_float==NULL)
+                                                       ok= 0;
+
+                                               if(ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4))
+                                                       ok= 0;
+
+                                               if(!ok)
+                                                       BKE_report(op->reports, RPT_ERROR, "Baking to unsupported image type");
+                                       }
+                               }
+                       }
+               }
+
+               if(!ok)
+                       break;
+       }
+       CTX_DATA_END;
+
+       return ok;
+}
+
+static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *lvl)
+{
+       DerivedMesh *dm;
+       MultiresModifierData *mmd= get_multires_modifier(scene, ob, 0);
+       Mesh *me= (Mesh*)ob->data;
+
+       *lvl= mmd->lvl;
+
+       if(mmd->lvl==0) {
+               DerivedMesh *tmp_dm= CDDM_from_mesh(me, ob);
+               dm= CDDM_copy(tmp_dm);
+               tmp_dm->release(tmp_dm);
+       } else {
+               MultiresModifierData tmp_mmd= *mmd;
+               DerivedMesh *cddm= CDDM_from_mesh(me, ob);
+
+               tmp_mmd.lvl= mmd->lvl;
+               dm= multires_dm_create_from_derived(&tmp_mmd, 1, cddm, ob, 0, 0);
+               cddm->release(cddm);
+       }
+
+       return dm;
+}
+
+static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *lvl, int *simple)
+{
+       Mesh *me= (Mesh*)ob->data;
+       MultiresModifierData *mmd= get_multires_modifier(scene, ob, 0);
+       MultiresModifierData tmp_mmd= *mmd;
+       DerivedMesh *cddm= CDDM_from_mesh(me, ob);
+       DerivedMesh *dm;
+
+       *lvl= mmd->totlvl;
+       *simple= mmd->simple;
+
+       tmp_mmd.lvl= mmd->totlvl;
+       dm= multires_dm_create_from_derived(&tmp_mmd, 1, cddm, ob, 0, 0);
+       cddm->release(cddm);
+
+       return dm;
+}
+
+static void clear_images(MTFace *mtface, int totface)
+{
+       int a;
+       float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f};
+
+       for(a= 0; a<totface; a++)
+               mtface[a].tpage->id.flag&= ~LIB_DOIT;
+
+       for(a= 0; a<totface; a++) {
+               Image *ima= mtface[a].tpage;
+
+               if((ima->id.flag&LIB_DOIT)==0) {
+                       ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+
+                       IMB_rectfill(ibuf, vec);
+                       ima->id.flag|= LIB_DOIT;
+               }
+       }
+
+       for(a= 0; a<totface; a++)
+               mtface[a].tpage->id.flag&= ~LIB_DOIT;
+}
+
+static int multiresbake_image_exec_locked(bContext *C, wmOperator *op)
+{
+       Object *ob;
+       Scene *scene= CTX_data_scene(C);
+
+       if(!multiresbake_check(C, op))
+               return OPERATOR_CANCELLED;
+
+       if(scene->r.bake_flag&R_BAKE_CLEAR) {  /* clear images */
+               CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
+                       Mesh *me;
+
+                       ob= base->object;
+                       me= (Mesh*)ob->data;
+
+                       clear_images(me->mtface, me->totface);
+               }
+               CTX_DATA_END;
+       }
+
+       CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
+               MultiresBakeRender bkr= {0};
+
+               ob= base->object;
+
+               /* copy data stored in job descriptor */
+               bkr.bake_filter= scene->r.bake_filter;
+               bkr.mode= scene->r.bake_mode;
+               bkr.use_lores_mesh= scene->r.bake_flag&R_BAKE_LORES_MESH;
+
+               /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
+               bkr.lores_dm= multiresbake_create_loresdm(scene, ob, &bkr.lvl);
+               bkr.hires_dm= multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple);
+
+               multiresbake_start(&bkr);
+
+               BLI_freelistN(&bkr.image);
+
+               bkr.lores_dm->release(bkr.lores_dm);
+               bkr.hires_dm->release(bkr.hires_dm);
+       }
+       CTX_DATA_END;
+
+       return OPERATOR_FINISHED;
+}
+
+/* Multiresbake adopted for job-system executing */
+static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj)
+{
+       Scene *scene= CTX_data_scene(C);
+       Object *ob;
+
+       /* backup scene settings, so their changing in UI would take no effect on baker */
+       bkj->bake_filter= scene->r.bake_filter;
+       bkj->mode= scene->r.bake_mode;
+       bkj->use_lores_mesh= scene->r.bake_flag&R_BAKE_LORES_MESH;
+       bkj->bake_clear= scene->r.bake_flag&R_BAKE_CLEAR;
+
+       CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
+               MultiresBakerJobData *data;
+               ob= base->object;
+
+               data= MEM_callocN(sizeof(MultiresBakerJobData), "multiresBaker derivedMesh_data");
+               data->lores_dm = multiresbake_create_loresdm(scene, ob, &data->lvl);
+               data->hires_dm = multiresbake_create_hiresdm(scene, ob, &data->tot_lvl, &data->simple);
+               BLI_addtail(&bkj->data, data);
+       }
+       CTX_DATA_END;
+}
+
+static void multiresbake_startjob(void *bkv, short *stop, short *do_update, float *progress)
+{
+       MultiresBakerJobData *data;
+       MultiresBakeJob *bkj= bkv;
+       int baked_objects= 0, tot_obj;
+
+       tot_obj= BLI_countlist(&bkj->data);
+
+       if(bkj->bake_clear) {  /* clear images */
+               for(data= bkj->data.first; data; data= data->next) {
+                       DerivedMesh *dm= data->lores_dm;
+                       MTFace *mtface= CustomData_get_layer(&dm->faceData, CD_MTFACE);
+
+                       clear_images(mtface, dm->getNumFaces(dm));
+               }
+       }
+
+       for(data= bkj->data.first; data; data= data->next) {
+               MultiresBakeRender bkr= {0};
+
+               /* copy data stored in job descriptor */
+               bkr.bake_filter= bkj->bake_filter;
+               bkr.mode= bkj->mode;
+               bkr.use_lores_mesh= bkj->use_lores_mesh;
+
+               /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
+               bkr.lores_dm= data->lores_dm;
+               bkr.hires_dm= data->hires_dm;
+               bkr.tot_lvl= data->tot_lvl;
+               bkr.lvl= data->lvl;
+               bkr.simple= data->simple;
+
+               /* needed for proper progress bar */
+               bkr.tot_obj= tot_obj;
+               bkr.baked_objects= baked_objects;
+
+               bkr.stop= stop;
+               bkr.do_update= do_update;
+               bkr.progress= progress;
+
+               multiresbake_start(&bkr);
+
+               BLI_freelistN(&bkr.image);
+
+               baked_objects++;
+       }
+}
+
+static void multiresbake_freejob(void *bkv)
+{
+       MultiresBakeJob *bkj= bkv;
+       MultiresBakerJobData *data, *next;
+
+       data= bkj->data.first;
+       while (data) {
+               next= data->next;
+               data->lores_dm->release(data->lores_dm);
+               data->hires_dm->release(data->hires_dm);
+               MEM_freeN(data);
+               data= next;
+       }
+
+       MEM_freeN(bkj);
+}
+
+static int multiresbake_image_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       MultiresBakeJob *bkr;
+       wmJob *steve;
+
+       if(!multiresbake_check(C, op))
+               return OPERATOR_CANCELLED;
+
+       bkr= MEM_callocN(sizeof(MultiresBakeJob), "MultiresBakeJob data");
+       init_multiresbake_job(C, bkr);
+
+       /* setup job */
+       steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Multires Bake", WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY|WM_JOB_PROGRESS);
+       WM_jobs_customdata(steve, bkr, multiresbake_freejob);
+       WM_jobs_timer(steve, 0.2, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */
+       WM_jobs_callbacks(steve, multiresbake_startjob, NULL, NULL, NULL);
+
+       G.afbreek= 0;
+
+       WM_jobs_start(CTX_wm_manager(C), steve);
+       WM_cursor_wait(0);
+
+       /* add modal handler for ESC */
+       WM_event_add_modal_handler(C, op);
+
+       return OPERATOR_RUNNING_MODAL;
+}
+
 /* ****************** render BAKING ********************** */
 
 /* threaded break test */
@@ -147,9 +1285,6 @@ static void init_bake_internal(BakeRender *bkr, bContext *C)
 {
        Scene *scene= CTX_data_scene(C);
 
-       /* flush multires changes (for sculpt) */
-       multires_force_render_update(CTX_data_active_object(C));
-
        /* get editmode results */
        ED_object_exit_editmode(C, 0);  /* 0 = does not exit editmode */
 
@@ -273,43 +1408,59 @@ static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), wmEven
        return OPERATOR_PASS_THROUGH;
 }
 
+static int is_multires_bake(Scene *scene)
+{
+       if ( ELEM(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT))
+               return scene->r.bake_flag & R_BAKE_MULTIRES;
+
+       return 0;
+}
+
 static int objects_bake_render_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(_event))
 {
        Scene *scene= CTX_data_scene(C);
+       int result= OPERATOR_CANCELLED;
 
-       /* only one render job at a time */
-       if(WM_jobs_test(CTX_wm_manager(C), scene))
-               return OPERATOR_CANCELLED;
-       
-       if(test_bake_internal(C, op->reports)==0) {
-               return OPERATOR_CANCELLED;
-       }
-       else {
-               BakeRender *bkr= MEM_callocN(sizeof(BakeRender), "render bake");
-               wmJob *steve;
+       if(is_multires_bake(scene)) {
+               result= multiresbake_image_exec(C, op);
+       } else {
+               /* only one render job at a time */
+               if(WM_jobs_test(CTX_wm_manager(C), scene))
+                       return OPERATOR_CANCELLED;
+
+               if(test_bake_internal(C, op->reports)==0) {
+                       return OPERATOR_CANCELLED;
+               }
+               else {
+                       BakeRender *bkr= MEM_callocN(sizeof(BakeRender), "render bake");
+                       wmJob *steve;
 
-               init_bake_internal(bkr, C);
-               bkr->reports= op->reports;
+                       init_bake_internal(bkr, C);
+                       bkr->reports= op->reports;
 
-               /* setup job */
-               steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Texture Bake", WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY|WM_JOB_PROGRESS);
-               WM_jobs_customdata(steve, bkr, bake_freejob);
-               WM_jobs_timer(steve, 0.2, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */
-               WM_jobs_callbacks(steve, bake_startjob, NULL, bake_update, NULL);
+                       /* setup job */
+                       steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Texture Bake", WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY|WM_JOB_PROGRESS);
+                       WM_jobs_customdata(steve, bkr, bake_freejob);
+                       WM_jobs_timer(steve, 0.2, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */
+                       WM_jobs_callbacks(steve, bake_startjob, NULL, bake_update, NULL);
 
-               G.afbreek= 0;
-               G.rendering = 1;
+                       G.afbreek= 0;
+                       G.rendering = 1;
 
-               WM_jobs_start(CTX_wm_manager(C), steve);
+                       WM_jobs_start(CTX_wm_manager(C), steve);
 
-               WM_cursor_wait(0);
-               WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, scene);
+                       WM_cursor_wait(0);
 
-               /* add modal handler for ESC */
-               WM_event_add_modal_handler(C, op);
+                       /* add modal handler for ESC */
+                       WM_event_add_modal_handler(C, op);
+               }
+
+               result= OPERATOR_RUNNING_MODAL;
        }
 
-       return OPERATOR_RUNNING_MODAL;
+       WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, scene);
+
+       return result;
 }
 
 
@@ -317,46 +1468,53 @@ static int bake_image_exec(bContext *C, wmOperator *op)
 {
        Main *bmain= CTX_data_main(C);
        Scene *scene= CTX_data_scene(C);
+       int result= OPERATOR_CANCELLED;
 
+       if(is_multires_bake(scene)) {
+               result= multiresbake_image_exec_locked(C, op);
+       } else  {
+               if(test_bake_internal(C, op->reports)==0) {
+                       return OPERATOR_CANCELLED;
+               }
+               else {
+                       ListBase threads;
+                       BakeRender bkr= {NULL};
 
-       if(test_bake_internal(C, op->reports)==0) {
-               return OPERATOR_CANCELLED;
-       }
-       else {
-               ListBase threads;
-               BakeRender bkr= {NULL};
+                       init_bake_internal(&bkr, C);
+                       bkr.reports= op->reports;
 
-               init_bake_internal(&bkr, C);
-               bkr.reports= op->reports;
+                       RE_test_break_cb(bkr.re, NULL, thread_break);
+                       G.afbreek= 0;   /* blender_test_break uses this global */
 
-               RE_test_break_cb(bkr.re, NULL, thread_break);
-               G.afbreek= 0;   /* blender_test_break uses this global */
+                       RE_Database_Baking(bkr.re, bmain, scene, scene->lay, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE)? OBACT: NULL);
 
-               RE_Database_Baking(bkr.re, bmain, scene, scene->lay, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE)? OBACT: NULL);
+                       /* baking itself is threaded, cannot use test_break in threads  */
+                       BLI_init_threads(&threads, do_bake_render, 1);
+                       bkr.ready= 0;
+                       BLI_insert_thread(&threads, &bkr);
 
-               /* baking itself is threaded, cannot use test_break in threads  */
-               BLI_init_threads(&threads, do_bake_render, 1);
-               bkr.ready= 0;
-               BLI_insert_thread(&threads, &bkr);
+                       while(bkr.ready==0) {
+                               PIL_sleep_ms(50);
+                               if(bkr.ready)
+                                       break;
 
-               while(bkr.ready==0) {
-                       PIL_sleep_ms(50);
-                       if(bkr.ready)
-                               break;
+                               /* used to redraw in 2.4x but this is just for exec in 2.5 */
+                               if (!G.background)
+                                       blender_test_break();
+                       }
+                       BLI_end_threads(&threads);
 
-                       /* used to redraw in 2.4x but this is just for exec in 2.5 */
-                       if (!G.background)
-                               blender_test_break();
-               }
-               BLI_end_threads(&threads);
+                       if(bkr.tot==0) BKE_report(op->reports, RPT_ERROR, "No valid images found to bake to");
 
-               if(bkr.tot==0) BKE_report(op->reports, RPT_ERROR, "No valid images found to bake to");
+                       finish_bake_internal(&bkr);
 
-               finish_bake_internal(&bkr);
+                       result= OPERATOR_FINISHED;
+               }
        }
 
        WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, scene);
-       return OPERATOR_FINISHED;
+
+       return result;
 }
 
 void OBJECT_OT_bake_image(wmOperatorType *ot)
index 7c59278dcf5ec66fcf464a68500e1c39877c7ada..fd2e7fd7c998540b2056159573a3ccbf18341afb 100644 (file)
@@ -203,9 +203,9 @@ static int object_shape_key_mirror(bContext *C, Object *ob)
                                                fp1= ((float *)kb->data) + i1*3;
                                                fp2= ((float *)kb->data) + i2*3;
 
-                                               VECCOPY(tvec,   fp1);
-                                               VECCOPY(fp1,    fp2);
-                                               VECCOPY(fp2,    tvec);
+                                               copy_v3_v3(tvec,        fp1);
+                                               copy_v3_v3(fp1, fp2);
+                                               copy_v3_v3(fp2, tvec);
 
                                                /* flip x axis */
                                                fp1[0] = -fp1[0];
@@ -217,7 +217,46 @@ static int object_shape_key_mirror(bContext *C, Object *ob)
 
                        mesh_octree_table(ob, NULL, NULL, 'e');
                }
-               /* todo, other types? */
+               else if (ob->type == OB_LATTICE) {
+                       Lattice *lt= ob->data;
+                       int i1, i2;
+                       float *fp1, *fp2;
+                       int u, v, w;
+                       /* half but found up odd value */
+                       const int pntsu_half = (((lt->pntsu / 2) + (lt->pntsu % 2))) ;
+
+                       /* currently editmode isnt supported by mesh so
+                        * ignore here for now too */
+
+                       /* if(lt->editlatt) lt= lt->editlatt->latt; */
+
+                       for(w=0; w<lt->pntsw; w++) {
+                               for(v=0; v<lt->pntsv; v++) {
+                                       for(u=0; u<pntsu_half; u++) {
+                                               int u_inv= (lt->pntsu - 1) - u;
+                                               float tvec[3];
+                                               if(u == u_inv) {
+                                                       i1= LT_INDEX(lt, u, v, w);
+                                                       fp1= ((float *)kb->data) + i1*3;
+                                                       fp1[0]= -fp1[0];
+                                               }
+                                               else {
+                                                       i1= LT_INDEX(lt, u, v, w);
+                                                       i2= LT_INDEX(lt, u_inv, v, w);
+
+                                                       fp1= ((float *)kb->data) + i1*3;
+                                                       fp2= ((float *)kb->data) + i2*3;
+
+                                                       copy_v3_v3(tvec, fp1);
+                                                       copy_v3_v3(fp1, fp2);
+                                                       copy_v3_v3(fp2, tvec);
+                                                       fp1[0]= -fp1[0];
+                                                       fp2[0]= -fp2[0];
+                                               }
+                                       }
+                               }
+                       }
+               }
 
                MEM_freeN(tag_elem);
        }
index 43448198ae153eaec46c7127ab60a73bf1601ea5..52ba9460818d26c0aec13f36172afcb6aacf36f7 100644 (file)
@@ -77,6 +77,7 @@
 static void vgroup_remap_update_users(Object *ob, int *map);
 static void vgroup_delete_edit_mode(Object *ob, bDeformGroup *defgroup);
 static void vgroup_delete_object_mode(Object *ob, bDeformGroup *dg);
+static void vgroup_delete_all(Object *ob);
 
 static Lattice *vgroup_edit_lattice(Object *ob)
 {
@@ -138,22 +139,30 @@ void ED_vgroup_delete(Object *ob, bDeformGroup *defgroup)
                vgroup_delete_object_mode(ob, dg);
 }
 
-void ED_vgroup_data_create(ID *id)
+int ED_vgroup_data_create(ID *id)
 {
        /* create deform verts */
 
        if(GS(id->name)==ID_ME) {
                Mesh *me= (Mesh *)id;
                me->dvert= CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, me->totvert);
+               return TRUE;
        }
        else if(GS(id->name)==ID_LT) {
                Lattice *lt= (Lattice *)id;
                lt->dvert= MEM_callocN(sizeof(MDeformVert)*lt->pntsu*lt->pntsv*lt->pntsw, "lattice deformVert");
+               return TRUE;
+       }
+       else {
+               return FALSE;
        }
 }
 
 static int ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_tot)
 {
+       *dvert_tot = 0;
+       *dvert_arr = NULL;
+
        if(id) {
                switch(GS(id->name)) {
                        case ID_ME:
@@ -166,8 +175,6 @@ static int ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_to
                                        int i;
 
                                        if (!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) {
-                                               *dvert_tot = 0;
-                                               *dvert_arr = NULL;
                                                return 0;
                                        }
 
@@ -195,8 +202,9 @@ static int ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_to
 
                                        return 1;
                                }
-                               else
+                               else {
                                        return 0;
+                               }
                        }
                        case ID_LT:
                        {
@@ -222,8 +230,6 @@ static int ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_to
                }
        }
 
-       *dvert_arr= NULL;
-       *dvert_tot= 0;
        return 0;
 }
 
@@ -265,13 +271,24 @@ int ED_vgroup_copy_array(Object *ob, Object *ob_from)
        int i;
        int totdef_from= BLI_countlist(&ob_from->defbase);
        int totdef= BLI_countlist(&ob->defbase);
+       short new_vgroup= FALSE;
 
        ED_vgroup_give_parray(ob_from->data, &dvert_array_from, &dvert_tot_from);
        ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot);
 
+       if((dvert_array == NULL) && (dvert_array_from != NULL) && ED_vgroup_data_create(ob->data)) {
+               ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot);
+               new_vgroup= TRUE;
+       }
+
        if(ob==ob_from || dvert_tot==0 || (dvert_tot != dvert_tot_from) || dvert_array_from==NULL || dvert_array==NULL) {
                if (dvert_array) MEM_freeN(dvert_array);
                if (dvert_array_from) MEM_freeN(dvert_array_from);
+
+               if(new_vgroup == TRUE) {
+                       /* free the newly added vgroup since it wasn't compatible */
+                       vgroup_delete_all(ob);
+               }
                return 0;
        }
 
@@ -1015,55 +1032,75 @@ static void vgroup_clean_all(Object *ob, float eul, int keep_single)
        if (dvert_array) MEM_freeN(dvert_array);
 }
 
-void ED_vgroup_mirror(Object *ob, int mirror_weights, int flip_vgroups)
+
+static void dvert_mirror_op(MDeformVert *dvert, MDeformVert *dvert_mirr,
+                            const char sel, const char sel_mirr,
+                            const int *flip_map,
+                            const short mirror_weights, const short flip_vgroups)
+{
+       BLI_assert(sel || sel_mirr);
+
+       if(sel_mirr && sel) {
+               /* swap */
+               if(mirror_weights)
+                       SWAP(MDeformVert, *dvert, *dvert_mirr);
+               if(flip_vgroups) {
+                       defvert_flip(dvert, flip_map);
+                       defvert_flip(dvert_mirr, flip_map);
+               }
+       }
+       else {
+               /* dvert should always be the target */
+               if(sel_mirr) {
+                       SWAP(MDeformVert *, dvert, dvert_mirr);
+               }
+
+               if(mirror_weights)
+                       defvert_copy(dvert, dvert_mirr);
+               if(flip_vgroups) {
+                       defvert_flip(dvert, flip_map);
+               }
+       }
+}
+
+void ED_vgroup_mirror(Object *ob, const short mirror_weights, const short flip_vgroups)
 {
+#define VGROUP_MIRR_OP dvert_mirror_op(dvert, dvert_mirr, sel, sel_mirr, flip_map, mirror_weights, flip_vgroups)
+
        EditVert *eve, *eve_mirr;
        MDeformVert *dvert, *dvert_mirr;
+       short sel, sel_mirr;
        int     *flip_map;
 
        if(mirror_weights==0 && flip_vgroups==0)
                return;
 
+       flip_map= defgroup_flip_map(ob, 0);
+
        /* only the active group */
        if(ob->type == OB_MESH) {
                Mesh *me= ob->data;
                EditMesh *em = BKE_mesh_get_editmesh(me);
 
-               EM_cache_x_mirror_vert(ob, em);
 
-               if(!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT))
+               if(!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) {
+                       MEM_freeN(flip_map);
                        return;
+               }
 
-               flip_map= defgroup_flip_map(ob, 0);
+               EM_cache_x_mirror_vert(ob, em);
 
                /* Go through the list of editverts and assign them */
                for(eve=em->verts.first; eve; eve=eve->next){
                        if((eve_mirr=eve->tmp.v)) {
-                               if((eve_mirr->f & SELECT || eve->f & SELECT) && (eve != eve_mirr)) {
+                               sel= eve->f & SELECT;
+                               sel_mirr= eve_mirr->f & SELECT;
+
+                               if((sel || sel_mirr) && (eve != eve_mirr)) {
                                        dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
                                        dvert_mirr= CustomData_em_get(&em->vdata, eve_mirr->data, CD_MDEFORMVERT);
                                        if(dvert && dvert_mirr) {
-                                               if(eve_mirr->f & SELECT && eve->f & SELECT) {
-                                                       /* swap */
-                                                       if(mirror_weights)
-                                                               SWAP(MDeformVert, *dvert, *dvert_mirr);
-                                                       if(flip_vgroups) {
-                                                               defvert_flip(dvert, flip_map);
-                                                               defvert_flip(dvert_mirr, flip_map);
-                                                       }
-                                               }
-                                               else {
-                                                       /* dvert should always be the target */
-                                                       if(eve_mirr->f & SELECT) {
-                                                               SWAP(MDeformVert *, dvert, dvert_mirr);
-                                                       }
-
-                                                       if(mirror_weights)
-                                                               defvert_copy(dvert, dvert_mirr);
-                                                       if(flip_vgroups) {
-                                                               defvert_flip(dvert, flip_map);
-                                                       }
-                                               }
+                                               VGROUP_MIRR_OP;
                                        }
                                }
 
@@ -1071,10 +1108,58 @@ void ED_vgroup_mirror(Object *ob, int mirror_weights, int flip_vgroups)
                        }
                }
 
-               MEM_freeN(flip_map);
-
                BKE_mesh_end_editmesh(me, em);
        }
+       else if (ob->type == OB_LATTICE) {
+               Lattice *lt= ob->data;
+               int i1, i2;
+               int u, v, w;
+               int pntsu_half;
+               /* half but found up odd value */
+
+               if(lt->editlatt) lt= lt->editlatt->latt;
+
+               if(lt->pntsu == 1 || lt->dvert == NULL) {
+                       MEM_freeN(flip_map);
+                       return;
+               }
+
+               /* unlike editmesh we know that by only looping over the first hald of
+                * the 'u' indicies it will cover all points except the middle which is
+                * ok in this case */
+               pntsu_half= lt->pntsu / 2;
+
+               for(w=0; w<lt->pntsw; w++) {
+                       for(v=0; v<lt->pntsv; v++) {
+                               for(u=0; u<pntsu_half; u++) {
+                                       int u_inv= (lt->pntsu - 1) - u;
+                                       if(u != u_inv) {
+                                               BPoint *bp, *bp_mirr;
+
+                                               i1= LT_INDEX(lt, u, v, w);
+                                               i2= LT_INDEX(lt, u_inv, v, w);
+
+                                               bp= &lt->def[i1];
+                                               bp_mirr= &lt->def[i2];
+
+                                               sel= bp->f1 & SELECT;
+                                               sel_mirr= bp_mirr->f1 & SELECT;
+
+                                               if(sel || sel_mirr) {
+                                                       dvert= &lt->dvert[i1];
+                                                       dvert_mirr= &lt->dvert[i2];
+
+                                                       VGROUP_MIRR_OP;
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       MEM_freeN(flip_map);
+
+#undef VGROUP_MIRR_OP
 }
 
 static void vgroup_remap_update_users(Object *ob, int *map)
@@ -1920,17 +2005,25 @@ void OBJECT_OT_vertex_group_copy_to_linked(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
-static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *UNUSED(op))
+static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op)
 {
        Object *obact= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+       int change= 0;
+       int fail= 0;
 
        CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects)
        {
-               if(obact != ob)
-                       ED_vgroup_copy_array(ob, obact);
+               if(obact != ob) {
+                       if(ED_vgroup_copy_array(ob, obact)) change++;
+                       else                                fail++;
+               }
        }
        CTX_DATA_END;
 
+       if((change == 0 && fail == 0) || fail) {
+               BKE_reportf(op->reports, RPT_ERROR, "Copy to VGroups to Selected warning done %d, failed %d, object data must have matching indicies", change, fail);
+       }
+
        return OPERATOR_FINISHED;
 }
 
index 64a4d47cddc92d8cf56af09b4b20b7fd82e6ac3e..9dfcde6ed0db9ba170ca46ca5762deef71dd6450 100644 (file)
@@ -184,8 +184,7 @@ void render_view_open(bContext *C, int mx, int my)
                        area_was_image = 1;
 
                /* this function returns with changed context */
-               ED_screen_full_newspace(C, CTX_wm_area(C), SPACE_IMAGE);
-               sa= CTX_wm_area(C);
+               sa= ED_screen_full_newspace(C, CTX_wm_area(C), SPACE_IMAGE);
        }
 
        if(!sa) {
index 828699e85cecebb5928f70c039aba2407f279234..4d531e78ec0815f46e4555fe0be2e279ca5521de 100644 (file)
@@ -1138,7 +1138,7 @@ void ED_area_newspace(bContext *C, ScrArea *sa, int type)
                /* tell WM to refresh, cursor types etc */
                WM_event_add_mousemove(C);
                                
-               /*send space change notifyer*/
+               /*send space change notifier*/
                WM_event_add_notifier(C, NC_SPACE|ND_SPACE_CHANGED, sa);
                
                ED_area_tag_refresh(sa);
@@ -1165,7 +1165,7 @@ void ED_area_prevspace(bContext *C, ScrArea *sa)
        }
        ED_area_tag_redraw(sa);
 
-       /*send space change notifyer*/
+       /*send space change notifier*/
        WM_event_add_notifier(C, NC_SPACE|ND_SPACE_CHANGED, sa);
 }
 
@@ -1213,7 +1213,7 @@ static void spacefunc(struct bContext *C, void *UNUSED(arg1), void *UNUSED(arg2)
        ED_area_newspace(C, CTX_wm_area(C), CTX_wm_area(C)->butspacetype);
        ED_area_tag_redraw(CTX_wm_area(C));
 
-       /*send space change notifyer*/
+       /*send space change notifier*/
        WM_event_add_notifier(C, NC_SPACE|ND_SPACE_CHANGED, CTX_wm_area(C));
 }
 
index eb41dcd147beb8e94b073953ac528259c04bdc23..721ce82335191ee5ead55307c178aa0d85643aa5 100644 (file)
@@ -1513,7 +1513,7 @@ void ED_screen_delete_scene(bContext *C, Scene *scene)
        unlink_scene(bmain, scene, newscene);
 }
 
-int ED_screen_full_newspace(bContext *C, ScrArea *sa, int type)
+ScrArea *ED_screen_full_newspace(bContext *C, ScrArea *sa, int type)
 {
        wmWindow *win= CTX_wm_window(C);
        bScreen *screen= CTX_wm_screen(C);
@@ -1538,7 +1538,7 @@ int ED_screen_full_newspace(bContext *C, ScrArea *sa, int type)
        
        ED_area_newspace(C, newsa, type);
        
-       return 1;
+       return newsa;
 }
 
 void ED_screen_full_prevspace(bContext *C, ScrArea *sa)
index 9e840e755786fccb9959ef503365c68bd98215bb..f016fb6822aae06b48afe295cf20ea099839450c 100644 (file)
@@ -627,6 +627,13 @@ static int actionzone_modal(bContext *C, wmOperator *op, wmEvent *event)
        return OPERATOR_RUNNING_MODAL;
 }
 
+static int actionzone_cancel(bContext *UNUSED(C), wmOperator *op)
+{
+       actionzone_exit(op);
+
+       return OPERATOR_CANCELLED;
+}
+
 static void SCREEN_OT_actionzone(wmOperatorType *ot)
 {
        /* identifiers */
@@ -637,6 +644,7 @@ static void SCREEN_OT_actionzone(wmOperatorType *ot)
        ot->invoke= actionzone_invoke;
        ot->modal= actionzone_modal;
        ot->poll= actionzone_area_poll;
+       ot->cancel= actionzone_cancel;
        
        ot->flag= OPTYPE_BLOCKING;
        
@@ -759,6 +767,7 @@ static void SCREEN_OT_area_swap(wmOperatorType *ot)
        ot->invoke= area_swap_invoke;
        ot->modal= area_swap_modal;
        ot->poll= ED_operator_areaactive;
+       ot->cancel= area_swap_cancel;
        
        ot->flag= OPTYPE_BLOCKING;
 }
@@ -1494,6 +1503,7 @@ static void SCREEN_OT_area_split(wmOperatorType *ot)
        ot->exec= area_split_exec;
        ot->invoke= area_split_invoke;
        ot->modal= area_split_modal;
+       ot->cancel= area_split_cancel;
        
        ot->poll= screen_active_editable;
        ot->flag= OPTYPE_BLOCKING;
@@ -1693,6 +1703,13 @@ static int region_scale_modal(bContext *C, wmOperator *op, wmEvent *event)
        return OPERATOR_RUNNING_MODAL;
 }
 
+int region_scale_cancel(bContext *UNUSED(C), wmOperator *op)
+{
+       MEM_freeN(op->customdata);
+       op->customdata = NULL;
+
+       return OPERATOR_CANCELLED;
+}
 
 static void SCREEN_OT_region_scale(wmOperatorType *ot)
 {
@@ -1703,6 +1720,7 @@ static void SCREEN_OT_region_scale(wmOperatorType *ot)
        
        ot->invoke= region_scale_invoke;
        ot->modal= region_scale_modal;
+       ot->cancel= region_scale_cancel;
        
        ot->poll= ED_operator_areaactive;
        
@@ -2257,8 +2275,9 @@ static void SCREEN_OT_area_join(wmOperatorType *ot)
        ot->invoke= area_join_invoke;
        ot->modal= area_join_modal;
        ot->poll= screen_active_editable;
+       ot->cancel= area_join_cancel;
        
-       ot->flag= OPTYPE_BLOCKING;
+       ot->flag= OPTYPE_BLOCKING|OPTYPE_INTERNAL;
        
        /* rna */
        RNA_def_int(ot->srna, "min_x", -100, INT_MIN, INT_MAX, "X 1", "", INT_MIN, INT_MAX);
@@ -3053,6 +3072,7 @@ static void SCREEN_OT_border_select(wmOperatorType *ot)
        ot->exec= border_select_do;
        ot->invoke= WM_border_select_invoke;
        ot->modal= WM_border_select_modal;
+       ot->cancel= WM_border_select_cancel;
        
        ot->poll= ED_operator_areaactive;
        
index db0d2314ad06580b9a0c242f6712896b93278237..cae5c14aa9753f78313ceeb8704053a062ee7de7 100644 (file)
@@ -3692,14 +3692,26 @@ static void do_projectpaint_draw(ProjPaintState *ps, ProjPixel *projPixel, float
        }
 }
 
-static void do_projectpaint_draw_f(ProjPaintState *ps, ProjPixel *projPixel, float *rgba, float alpha, float mask) {
+static void do_projectpaint_draw_f(ProjPaintState *ps, ProjPixel *projPixel, float *rgba, float alpha, float mask, int use_color_correction) {
        if (ps->is_texbrush) {
-               rgba[0] *= ps->brush->rgb[0];
-               rgba[1] *= ps->brush->rgb[1];
-               rgba[2] *= ps->brush->rgb[2];
+               /* rgba already holds a texture result here from higher level function */
+               float rgba_br[3];
+               if(use_color_correction){
+                       srgb_to_linearrgb_v3_v3(rgba_br, ps->brush->rgb);
+                       mul_v3_v3(rgba, rgba_br);
+               }
+               else{
+                       mul_v3_v3(rgba, ps->brush->rgb);
+               }
        }
        else {
-               VECCOPY(rgba, ps->brush->rgb);
+               if(use_color_correction){
+                       srgb_to_linearrgb_v3_v3(rgba, ps->brush->rgb);
+               }
+               else {
+                       VECCOPY(rgba, ps->brush->rgb);
+               }
+               rgba[3] = 1.0;
        }
        
        if (ps->is_airbrush==0 && mask < 1.0f) {
@@ -3736,6 +3748,7 @@ static void *do_projectpaint_thread(void *ph_v)
        float falloff;
        int bucket_index;
        int is_floatbuf = 0;
+       int use_color_correction = 0;
        const short tool =  ps->tool;
        rctf bucket_bounds;
        
@@ -3841,6 +3854,7 @@ static void *do_projectpaint_thread(void *ph_v)
 
                                                                last_projIma->touch = 1;
                                                                is_floatbuf = last_projIma->ibuf->rect_float ? 1 : 0;
+                                                               use_color_correction = (last_projIma->ibuf->profile == IB_PROFILE_LINEAR_RGB) ? 1 : 0;
                                                        }
 
                                                        last_partial_redraw_cell = last_projIma->partRedrawRect + projPixel->bb_cell_index;
@@ -3871,7 +3885,7 @@ static void *do_projectpaint_thread(void *ph_v)
                                                                else                            do_projectpaint_smear(ps, projPixel, alpha, mask, smearArena, &smearPixels, co);
                                                                break;
                                                        default:
-                                                               if (is_floatbuf)        do_projectpaint_draw_f(ps, projPixel, rgba, alpha, mask);
+                                                               if (is_floatbuf)        do_projectpaint_draw_f(ps, projPixel, rgba, alpha, mask, use_color_correction);
                                                                else                            do_projectpaint_draw(ps, projPixel, rgba, alpha, mask);
                                                                break;
                                                        }
@@ -3987,7 +4001,7 @@ static int project_paint_sub_stroke(ProjPaintState *ps, BrushPainter *painter, c
        // we may want to use this later 
        // brush_painter_require_imbuf(painter, ((ibuf->rect_float)? 1: 0), 0, 0);
        
-       if (brush_painter_paint(painter, project_paint_op, pos, time, pressure, ps)) {
+       if (brush_painter_paint(painter, project_paint_op, pos, time, pressure, ps, 0)) {
                return 1;
        }
        else return 0;
@@ -4058,7 +4072,6 @@ static void imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w,
 static void imapaint_image_update(SpaceImage *sima, Image *image, ImBuf *ibuf, short texpaint)
 {
        if(ibuf->rect_float)
-               /* TODO - should just update a portion from imapaintpartial! */
                ibuf->userflags |= IB_RECT_INVALID; /* force recreate of char rect */
        
        if(ibuf->mipmap[0])
@@ -4255,8 +4268,8 @@ static ImBuf *imapaint_lift_clone(ImBuf *ibuf, ImBuf *ibufb, int *pos)
 
 static void imapaint_convert_brushco(ImBuf *ibufb, float *pos, int *ipos)
 {
-       ipos[0]= (int)(pos[0] - ibufb->x/2);
-       ipos[1]= (int)(pos[1] - ibufb->y/2);
+       ipos[0]= (int)floorf((pos[0] - ibufb->x/2) + 1.0f);
+       ipos[1]= (int)floorf((pos[1] - ibufb->y/2) + 1.0f);
 }
 
 /* dosnt run for projection painting
@@ -4409,7 +4422,7 @@ static int imapaint_paint_sub_stroke(ImagePaintState *s, BrushPainter *painter,
 
        brush_painter_require_imbuf(painter, ((ibuf->rect_float)? 1: 0), 0, 0);
 
-       if (brush_painter_paint(painter, imapaint_paint_op, pos, time, pressure, s)) {
+       if (brush_painter_paint(painter, imapaint_paint_op, pos, time, pressure, s, ibuf->profile == IB_PROFILE_LINEAR_RGB)) {
                if (update)
                        imapaint_image_update(s->sima, image, ibuf, texpaint);
                return 1;
@@ -4863,12 +4876,7 @@ static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event)
        PointerRNA itemptr;
        float pressure, mousef[2];
        double time;
-       int tablet, mouse[2];
-
-       // XXX +1 matches brush location better but
-       // still not exact, find out why and fix ..
-       mouse[0]= event->mval[0] + 1;
-       mouse[1]= event->mval[1] + 1;
+       int tablet;
 
        time= PIL_check_seconds_timer();
 
@@ -4888,8 +4896,8 @@ static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event)
                pressure= pop->prev_pressure ? pop->prev_pressure : 1.0f;
 
        if(pop->first) {
-               pop->prevmouse[0]= mouse[0];
-               pop->prevmouse[1]= mouse[1];
+               pop->prevmouse[0]= event->mval[0];
+               pop->prevmouse[1]= event->mval[1];
                pop->starttime= time;
 
                /* special exception here for too high pressure values on first touch in
@@ -4908,8 +4916,8 @@ static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event)
        /* fill in stroke */
        RNA_collection_add(op->ptr, "stroke", &itemptr);
 
-       mousef[0] = (float)(mouse[0]);
-       mousef[1] = (float)(mouse[1]);
+       mousef[0] = (float)(event->mval[0]);
+       mousef[1] = (float)(event->mval[1]);
        RNA_float_set_array(&itemptr, "mouse", mousef);
        RNA_float_set(&itemptr, "time", (float)(time - pop->starttime));
        RNA_float_set(&itemptr, "pressure", pressure);
@@ -5012,31 +5020,45 @@ static int get_imapaint_zoom(bContext *C, float *zoomx, float *zoomy)
 
 static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata))
 {
+#define PX_SIZE_FADE_MAX 12.0f
+#define PX_SIZE_FADE_MIN 4.0f
+
        Brush *brush= image_paint_brush(C);
        Paint *paint= paint_get_active(CTX_data_scene(C));
 
-       if(paint && brush) {
+       if(paint && brush && paint->flags & PAINT_SHOW_BRUSH) {
                float zoomx, zoomy;
+               const float size= (float)brush_size(brush);
+               const short use_zoom= get_imapaint_zoom(C, &zoomx, &zoomy);
+               const float pixel_size= MAX2(size * zoomx, size * zoomy);
+               float alpha= 0.5f;
 
-               if(!(paint->flags & PAINT_SHOW_BRUSH))
+               /* fade out the brush (cheap trick to work around brush interfearing with sampling [#])*/
+               if(pixel_size < PX_SIZE_FADE_MIN) {
                        return;
+               }
+               else if (pixel_size < PX_SIZE_FADE_MAX) {
+                       alpha *= (pixel_size - PX_SIZE_FADE_MIN) / (PX_SIZE_FADE_MAX - PX_SIZE_FADE_MIN);
+               }
 
                glPushMatrix();
 
                glTranslatef((float)x, (float)y, 0.0f);
 
-               if(get_imapaint_zoom(C, &zoomx, &zoomy))
+               if(use_zoom)
                        glScalef(zoomx, zoomy, 1.0f);
 
-               glColor4f(brush->add_col[0], brush->add_col[1], brush->add_col[2], 0.5f);
+               glColor4f(brush->add_col[0], brush->add_col[1], brush->add_col[2], alpha);
                glEnable( GL_LINE_SMOOTH );
                glEnable(GL_BLEND);
-               glutil_draw_lined_arc(0, (float)(M_PI*2.0), (float)brush_size(brush), 40);
+               glutil_draw_lined_arc(0, (float)(M_PI*2.0), size, 40);
                glDisable(GL_BLEND);
                glDisable( GL_LINE_SMOOTH );
 
                glPopMatrix();
        }
+#undef PX_SIZE_FADE_MAX
+#undef PX_SIZE_FADE_MIN
 }
 
 static void toggle_paint_cursor(bContext *C, int enable)
index bb877e4b1ee854309fff1b818be0f6fd7ca04bbf..5a0ee19d6c935d1588d70d6e36be5bbe94b2fab7 100644 (file)
@@ -65,6 +65,7 @@ int paint_space_stroke_enabled(struct Brush *br);
 
 int paint_stroke_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
 int paint_stroke_exec(struct bContext *C, struct wmOperator *op);
+int paint_stroke_cancel(struct bContext *C, struct wmOperator *op);
 struct ViewContext *paint_stroke_view_context(struct PaintStroke *stroke);
 void *paint_stroke_mode_data(struct PaintStroke *stroke);
 void paint_stroke_set_mode_data(struct PaintStroke *stroke, void *mode_data);
index 58c3446673c969c63b1bb52eca235bb8de7be484..7ddf5dff000b62c375eab6f396111edc1d771057 100644 (file)
@@ -916,6 +916,19 @@ int paint_stroke_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
+int paint_stroke_cancel(bContext *C, wmOperator *op)
+{
+       PaintStroke *stroke = op->customdata;
+
+       if(stroke->done)
+               stroke->done(C, stroke);
+
+       MEM_freeN(stroke);
+       op->customdata = NULL;
+
+       return OPERATOR_CANCELLED;
+}
+
 ViewContext *paint_stroke_view_context(PaintStroke *stroke)
 {
        return &stroke->vc;
index c35b742eb9eaa247fcad2fb88094ff89987be228..3da19ba7346ebe37c74946fe846bdf20c99e8133 100644 (file)
@@ -1600,6 +1600,13 @@ static int wpaint_invoke(bContext *C, wmOperator *op, wmEvent *event)
        return OPERATOR_RUNNING_MODAL;
 }
 
+static int wpaint_cancel(bContext *C, wmOperator *op)
+{
+       paint_stroke_cancel(C, op);
+
+       return OPERATOR_CANCELLED;
+}
+
 void PAINT_OT_weight_paint(wmOperatorType *ot)
 {
        
@@ -1612,6 +1619,7 @@ void PAINT_OT_weight_paint(wmOperatorType *ot)
        ot->modal= paint_stroke_modal;
        /* ot->exec= vpaint_exec; <-- needs stroke property */
        ot->poll= weight_paint_poll;
+       ot->cancel= wpaint_cancel;
        
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
@@ -1892,6 +1900,13 @@ static int vpaint_invoke(bContext *C, wmOperator *op, wmEvent *event)
        return OPERATOR_RUNNING_MODAL;
 }
 
+static int vpaint_cancel(bContext *C, wmOperator *op)
+{
+       paint_stroke_cancel(C, op);
+
+       return OPERATOR_CANCELLED;
+}
+
 void PAINT_OT_vertex_paint(wmOperatorType *ot)
 {
        /* identifiers */
@@ -1903,6 +1918,7 @@ void PAINT_OT_vertex_paint(wmOperatorType *ot)
        ot->modal= paint_stroke_modal;
        /* ot->exec= vpaint_exec; <-- needs stroke property */
        ot->poll= vertex_paint_poll;
+       ot->cancel= vpaint_cancel;
        
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
index 20e747020670bb5b44ed6d0749d9e4ed621def0f..cab8c522a89d11c47603abd6e10ea919552eeca5 100644 (file)
@@ -3559,6 +3559,24 @@ static int sculpt_brush_stroke_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
+static int sculpt_brush_stroke_cacel(bContext *C, wmOperator *op)
+{
+       Object *ob= CTX_data_active_object(C);
+       SculptSession *ss = ob->sculpt;
+       Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+
+       paint_stroke_cancel(C, op);
+
+       if(ss->cache) {
+               sculpt_cache_free(ss->cache);
+               ss->cache = NULL;
+       }
+
+       sculpt_brush_exit_tex(sd);
+
+       return OPERATOR_CANCELLED;
+}
+
 static void SCULPT_OT_brush_stroke(wmOperatorType *ot)
 {
        static EnumPropertyItem stroke_mode_items[] = {
@@ -3577,6 +3595,7 @@ static void SCULPT_OT_brush_stroke(wmOperatorType *ot)
        ot->modal= paint_stroke_modal;
        ot->exec= sculpt_brush_stroke_exec;
        ot->poll= sculpt_poll;
+       ot->cancel= sculpt_brush_stroke_cacel;
 
        /* flags (sculpt does own undo? (ton) */
        ot->flag= OPTYPE_BLOCKING;
index be8547afa234375c5429e3de0445e686e598116f..4d0043913abe72ba606170282dcebe8609171e60 100644 (file)
@@ -332,6 +332,7 @@ void ACTION_OT_select_border(wmOperatorType *ot)
        ot->invoke= WM_border_select_invoke;
        ot->exec= actkeys_borderselect_exec;
        ot->modal= WM_border_select_modal;
+       ot->cancel= WM_border_select_cancel;
        
        ot->poll= ED_operator_action_active;
        
index 9662b4b401fea1c161985f7aed09e6d846dbd288..a5d516a14175fac69e3708c8aa633f248af3feaf 100644 (file)
@@ -301,6 +301,7 @@ void FILE_OT_select_border(wmOperatorType *ot)
        ot->exec= file_border_select_exec;
        ot->modal= file_border_select_modal;
        ot->poll= ED_operator_file_active;
+       ot->cancel= WM_border_select_cancel;
 
        /* rna */
        WM_operator_properties_gesture_border(ot, 0);
index 793267bfa8ca6e2aba2098d43d3bc277b8d854fa..45193a38ef5de0d6ec5a3343911102d3dd745a6d 100644 (file)
@@ -403,12 +403,10 @@ float file_font_pointsize(void)
        uiStyleFontSet(&style->widget);
        s = BLF_height(style->widget.uifont_id, tmp);
        return style->widget.points;
-#elif 0
+#else
        uiStyle *style= U.uistyles.first;
        uiStyleFontSet(&style->widget);
-       return style->widget.points;
-#else
-       return UI_UNIT_Y * 0.6666f;
+       return style->widget.points * UI_DPI_FAC;
 #endif
 }
 
index 76883027df1b9ddb4796c3437dcb9883d77f25a6..cb799b85d3a68c24e4eb80ce17dd1d809e566cc4 100644 (file)
@@ -344,6 +344,7 @@ void GRAPH_OT_select_border(wmOperatorType *ot)
        ot->invoke= WM_border_select_invoke;
        ot->exec= graphkeys_borderselect_exec;
        ot->modal= WM_border_select_modal;
+       ot->cancel= WM_border_select_cancel;
        
        ot->poll= graphop_visible_keyframes_poll;
        
index f48daa39c594297b743bb7ce63ac8b85356b6c03..10b8cb238aa2217a22445c2c49545c42f6f4ef51 100644 (file)
@@ -1925,6 +1925,7 @@ void IMAGE_OT_sample_line(wmOperatorType *ot)
        ot->modal= WM_gesture_straightline_modal;
        ot->exec= sample_line_exec;
        ot->poll= space_image_main_area_poll;
+       ot->cancel= WM_gesture_straightline_cancel;
        
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
index 937b683e880e4354d94969774a152466a5fbaa38..c8bda43422789f9fbbf282cb5284327675310e61 100644 (file)
@@ -302,6 +302,7 @@ void INFO_OT_select_border(wmOperatorType *ot)
        ot->invoke= WM_border_select_invoke;
        ot->exec= borderselect_exec;
        ot->modal= WM_border_select_modal;
+       ot->cancel= WM_border_select_cancel;
 
        ot->poll= ED_operator_info_active;
 
index e894fd9cff5b3ef1700a78f060a2054b5c48a59f..16e916928a91e9f96d16df0f3daeb11ee53b5e78 100644 (file)
@@ -206,6 +206,7 @@ void LOGIC_OT_links_cut(wmOperatorType *ot)
        ot->invoke= WM_gesture_lines_invoke;
        ot->modal= WM_gesture_lines_modal;
        ot->exec= cut_links_exec;
+       ot->cancel= WM_gesture_lines_cancel;
        
        ot->poll= ED_operator_logic_active;
        
index 0f0a4c0ad4c5d0ff1288f2df4d410b8db4fc31dc..8ef63b9a83dadbfa2a8680feb7da4beffd081f0e 100644 (file)
@@ -333,6 +333,7 @@ void NLA_OT_select_border(wmOperatorType *ot)
        ot->invoke= WM_border_select_invoke;
        ot->exec= nlaedit_borderselect_exec;
        ot->modal= WM_border_select_modal;
+       ot->cancel= WM_border_select_cancel;
        
        ot->poll= nlaop_poll_tweakmode_off;
        
index d967e2240e68c4038a0a3a281bdafb411fa3738e..99f2ea99efca9eb5a9442c009265be1c90365da8 100644 (file)
@@ -1086,6 +1086,13 @@ static int snode_bg_viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event)
        return OPERATOR_RUNNING_MODAL;
 }
 
+static int snode_bg_viewmove_cancel(bContext *UNUSED(C), wmOperator *op)
+{
+       MEM_freeN(op->customdata);
+       op->customdata= NULL;
+
+       return OPERATOR_CANCELLED;
+}
 
 void NODE_OT_backimage_move(wmOperatorType *ot)
 {
@@ -1098,6 +1105,7 @@ void NODE_OT_backimage_move(wmOperatorType *ot)
        ot->invoke= snode_bg_viewmove_invoke;
        ot->modal= snode_bg_viewmove_modal;
        ot->poll= composite_node_active;
+       ot->cancel= snode_bg_viewmove_cancel;
        
        /* flags */
        ot->flag= OPTYPE_BLOCKING;
@@ -1384,6 +1392,14 @@ static int node_resize_invoke(bContext *C, wmOperator *op, wmEvent *event)
        return OPERATOR_CANCELLED|OPERATOR_PASS_THROUGH;
 }
 
+static int node_resize_cancel(bContext *UNUSED(C), wmOperator *op)
+{
+       MEM_freeN(op->customdata);
+       op->customdata= NULL;
+
+       return OPERATOR_CANCELLED;
+}
+
 void NODE_OT_resize(wmOperatorType *ot)
 {
        /* identifiers */
@@ -1394,6 +1410,7 @@ void NODE_OT_resize(wmOperatorType *ot)
        ot->invoke= node_resize_invoke;
        ot->modal= node_resize_modal;
        ot->poll= ED_operator_node_active;
+       ot->cancel= node_resize_cancel;
        
        /* flags */
        ot->flag= OPTYPE_BLOCKING;
@@ -2279,6 +2296,18 @@ static int node_link_invoke(bContext *C, wmOperator *op, wmEvent *event)
        }
 }
 
+static int node_link_cancel(bContext *C, wmOperator *op)
+{
+       SpaceNode *snode= CTX_wm_space_node(C);
+       bNodeLinkDrag *nldrag= op->customdata;
+
+       nodeRemLink(snode->edittree, nldrag->link);
+       BLI_remlink(&snode->linkdrag, nldrag);
+       MEM_freeN(nldrag);
+
+       return OPERATOR_CANCELLED;
+}
+
 void NODE_OT_link(wmOperatorType *ot)
 {
        /* identifiers */
@@ -2290,6 +2319,7 @@ void NODE_OT_link(wmOperatorType *ot)
        ot->modal= node_link_modal;
 //     ot->exec= node_link_exec;
        ot->poll= ED_operator_node_active;
+       ot->cancel= node_link_cancel;
        
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
@@ -2402,6 +2432,7 @@ void NODE_OT_links_cut(wmOperatorType *ot)
        ot->invoke= WM_gesture_lines_invoke;
        ot->modal= WM_gesture_lines_modal;
        ot->exec= cut_links_exec;
+       ot->cancel= WM_gesture_lines_cancel;
        
        ot->poll= ED_operator_node_active;
        
index a1ef75f3976a65600c00304a54d5b1ae35a6a58a..1abcaccc939d25cbafef30caeb6a31bc1db4582c 100644 (file)
@@ -215,6 +215,7 @@ void NODE_OT_select_border(wmOperatorType *ot)
        ot->invoke= node_border_select_invoke;
        ot->exec= node_borderselect_exec;
        ot->modal= WM_border_select_modal;
+       ot->cancel= WM_border_select_cancel;
        
        ot->poll= ED_operator_node_active;
        
index 037b1db56d63db63853d3fc1944a9f09b73bee69..43e46d485eeca23ad5f3c73d714ac40cdbbaa91c 100644 (file)
 #include "outliner_intern.h"
 
 
-
-#define OL_H   19
-#define OL_X   18
-
 #define OL_Y_OFFSET    2
 
-#define OL_TOG_RESTRICT_VIEWX  54
-#define OL_TOG_RESTRICT_SELECTX        36
-#define OL_TOG_RESTRICT_RENDERX        18
+#define OL_TOG_RESTRICT_VIEWX  (UI_UNIT_X*3)
+#define OL_TOG_RESTRICT_SELECTX        (UI_UNIT_X*2)
+#define OL_TOG_RESTRICT_RENDERX        UI_UNIT_X
 
 #define OL_TOGW OL_TOG_RESTRICT_VIEWX
 
-#define OL_RNA_COLX                    300
-#define OL_RNA_COL_SIZEX       150
-#define OL_RNA_COL_SPACEX      50
+#define OL_RNA_COLX                    (UI_UNIT_X*15)
+#define OL_RNA_COL_SIZEX       (UI_UNIT_X*7.5)
+#define OL_RNA_COL_SPACEX      (UI_UNIT_X*2.5)
 
 #define TS_CHUNK       128
 
@@ -260,7 +256,7 @@ static void outliner_height(SpaceOops *soops, ListBase *lb, int *h)
                TreeStoreElem *tselem= TREESTORE(te);
                if((tselem->flag & TSE_CLOSED)==0) 
                        outliner_height(soops, &te->subtree, h);
-               (*h) += OL_H;
+               (*h) += UI_UNIT_Y;
                te= te->next;
        }
 }
@@ -297,7 +293,7 @@ static void outliner_rna_width(SpaceOops *soops, ListBase *lb, int *w, int start
                        *w = startx+100;
 
                if((tselem->flag & TSE_CLOSED)==0)
-                       outliner_rna_width(soops, &te->subtree, w, startx+OL_X);
+                       outliner_rna_width(soops, &te->subtree, w, startx+UI_UNIT_X);
                te= te->next;
        }
 }
@@ -2485,13 +2481,13 @@ static int tree_element_type_active(bContext *C, Scene *scene, SpaceOops *soops,
 static int do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops, TreeElement *te, int extend, const float mval[2])
 {
        
-       if(mval[1]>te->ys && mval[1]<te->ys+OL_H) {
+       if(mval[1]>te->ys && mval[1]<te->ys+UI_UNIT_Y) {
                TreeStoreElem *tselem= TREESTORE(te);
                int openclose= 0;
 
                /* open close icon */
                if((te->flag & TE_ICONROW)==0) {                                // hidden icon, no open/close
-                       if( mval[0]>te->xs && mval[0]<te->xs+OL_X) 
+                       if( mval[0]>te->xs && mval[0]<te->xs+UI_UNIT_X) 
                                openclose= 1;
                }
 
@@ -2510,7 +2506,7 @@ static int do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, Spa
                        return 1;
                }
                /* name and first icon */
-               else if(mval[0]>te->xs+OL_X && mval[0]<te->xend) {
+               else if(mval[0]>te->xs+UI_UNIT_X && mval[0]<te->xend) {
                        
                        /* always makes active object */
                        if(tselem->type!=TSE_SEQUENCE && tselem->type!=TSE_SEQ_STRIP && tselem->type!=TSE_SEQUENCE_DUP)
@@ -2597,7 +2593,7 @@ static int outliner_item_activate(bContext *C, wmOperator *op, wmEvent *event)
                int row;
                
                /* get row number - 100 here is just a dummy value since we don't need the column */
-               UI_view2d_listview_view_to_cell(&ar->v2d, 1000, OL_H, 0.0f, OL_Y_OFFSET, 
+               UI_view2d_listview_view_to_cell(&ar->v2d, 1000, UI_UNIT_Y, 0.0f, OL_Y_OFFSET, 
                                                fmval[0], fmval[1], NULL, &row);
                
                /* select relevant row */
@@ -2631,7 +2627,7 @@ void OUTLINER_OT_item_activate(wmOperatorType *ot)
 static int do_outliner_item_openclose(bContext *C, SpaceOops *soops, TreeElement *te, int all, const float mval[2])
 {
        
-       if(mval[1]>te->ys && mval[1]<te->ys+OL_H) {
+       if(mval[1]>te->ys && mval[1]<te->ys+UI_UNIT_Y) {
                TreeStoreElem *tselem= TREESTORE(te);
 
                /* all below close/open? */
@@ -2696,11 +2692,11 @@ void OUTLINER_OT_item_openclose(wmOperatorType *ot)
 static int do_outliner_item_rename(bContext *C, ARegion *ar, SpaceOops *soops, TreeElement *te, const float mval[2])
 {
        
-       if(mval[1]>te->ys && mval[1]<te->ys+OL_H) {
+       if(mval[1]>te->ys && mval[1]<te->ys+UI_UNIT_Y) {
                TreeStoreElem *tselem= TREESTORE(te);
                
                /* name and first icon */
-               if(mval[0]>te->xs+OL_X && mval[0]<te->xend) {
+               if(mval[0]>te->xs+UI_UNIT_X && mval[0]<te->xend) {
                        
                        /* can't rename rna datablocks entries */
                        if(ELEM3(tselem->type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM))
@@ -2861,12 +2857,12 @@ static void outliner_set_coordinates_element(SpaceOops *soops, TreeElement *te,
        /* store coord and continue, we need coordinates for elements outside view too */
        te->xs= (float)startx;
        te->ys= (float)(*starty);
-       *starty-= OL_H;
+       *starty-= UI_UNIT_Y;
        
        if((tselem->flag & TSE_CLOSED)==0) {
                TreeElement *ten;
                for(ten= te->subtree.first; ten; ten= ten->next) {
-                       outliner_set_coordinates_element(soops, ten, startx+OL_X, starty);
+                       outliner_set_coordinates_element(soops, ten, startx+UI_UNIT_X, starty);
                }
        }
        
@@ -2876,7 +2872,7 @@ static void outliner_set_coordinates_element(SpaceOops *soops, TreeElement *te,
 static void outliner_set_coordinates(ARegion *ar, SpaceOops *soops)
 {
        TreeElement *te;
-       int starty= (int)(ar->v2d.tot.ymax)-OL_H;
+       int starty= (int)(ar->v2d.tot.ymax)-UI_UNIT_Y;
        int startx= 0;
        
        for(te= soops->tree.first; te; te= te->next) {
@@ -3731,7 +3727,7 @@ void OUTLINER_OT_data_operation(wmOperatorType *ot)
 static int do_outliner_operation_event(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops, TreeElement *te, wmEvent *event, const float mval[2])
 {
        
-       if(mval[1]>te->ys && mval[1]<te->ys+OL_H) {
+       if(mval[1]>te->ys && mval[1]<te->ys+UI_UNIT_Y) {
                int scenelevel=0, objectlevel=0, idlevel=0, datalevel=0;
                TreeStoreElem *tselem= TREESTORE(te);
                
@@ -4309,7 +4305,10 @@ static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon)
        if(arg->x >= arg->xmax) 
                UI_icon_draw(arg->x, arg->y, icon);
        else {
-               uiBut *but= uiDefIconBut(arg->block, LABEL, 0, icon, arg->x-4, arg->y, ICON_DEFAULT_WIDTH, ICON_DEFAULT_WIDTH, NULL, 0.0, 0.0, 1.0, arg->alpha, (arg->id && arg->id->lib) ? arg->id->lib->name : "");
+               /* XXX investigate: button placement of icons is way different than UI_icon_draw? */
+               float ufac= UI_UNIT_X/20.0f;
+               uiBut *but= uiDefIconBut(arg->block, LABEL, 0, icon, arg->x-3.0f*ufac, arg->y, UI_UNIT_X-4.0f*ufac, UI_UNIT_Y-4.0f*ufac, NULL, 0.0, 0.0, 1.0, arg->alpha, (arg->id && arg->id->lib) ? arg->id->lib->name : "");
+               
                if(arg->id)
                        uiButSetDragID(but, arg->id);
        }
@@ -4572,7 +4571,7 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa
        for(te= lb->first; te; te= te->next) {
                
                /* exit drawing early */
-               if((*offsx) - OL_X > xmax)
+               if((*offsx) - UI_UNIT_X > xmax)
                        break;
 
                tselem= TREESTORE(te);
@@ -4589,19 +4588,21 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa
                        else active= tree_element_type_active(NULL, scene, soops, te, tselem, 0);
                        
                        if(active) {
+                               float ufac= UI_UNIT_X/20.0f;
+
                                uiSetRoundBox(15);
                                glColor4ub(255, 255, 255, 100);
-                               uiRoundBox( (float)*offsx-0.5f, (float)ys-1.0f, (float)*offsx+OL_H-3.0f, (float)ys+OL_H-3.0f, OL_H/2.0f-2.0f);
+                               uiRoundBox( (float)*offsx-0.5f*ufac, (float)ys-1.0f*ufac, (float)*offsx+UI_UNIT_Y-3.0f*ufac, (float)ys+UI_UNIT_Y-3.0f*ufac, UI_UNIT_Y/2.0f-2.0f*ufac);
                                glEnable(GL_BLEND); /* roundbox disables */
                        }
                        
                        tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, 0.5f);
                        te->xs= (float)*offsx;
                        te->ys= (float)ys;
-                       te->xend= (short)*offsx+OL_X;
+                       te->xend= (short)*offsx+UI_UNIT_X;
                        te->flag |= TE_ICONROW; // for click
                        
-                       (*offsx) += OL_X;
+                       (*offsx) += UI_UNIT_X;
                }
                
                /* this tree element always has same amount of branches, so dont draw */
@@ -4621,7 +4622,7 @@ static void outliner_set_coord_tree_element(SpaceOops *soops, TreeElement *te, i
        te->ys= (float)(*starty);
        
        for(ten= te->subtree.first; ten; ten= ten->next) {
-               outliner_set_coord_tree_element(soops, ten, startx+OL_X, starty);
+               outliner_set_coord_tree_element(soops, ten, startx+UI_UNIT_X, starty);
        }       
 }
 
@@ -4630,16 +4631,17 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
 {
        TreeElement *ten;
        TreeStoreElem *tselem;
+       float ufac= UI_UNIT_X/20.0f;
        int offsx= 0, active=0; // active=1 active obj, else active data
        
        tselem= TREESTORE(te);
 
-       if(*starty+2*OL_H >= ar->v2d.cur.ymin && *starty<= ar->v2d.cur.ymax) {
+       if(*starty+2*UI_UNIT_Y >= ar->v2d.cur.ymin && *starty<= ar->v2d.cur.ymax) {
                int xmax= ar->v2d.cur.xmax;
                
                /* icons can be ui buts, we dont want it to overlap with restrict */
                if((soops->flag & SO_HIDE_RESTRICTCOLS)==0)
-                       xmax-= OL_TOGW+ICON_DEFAULT_WIDTH;
+                       xmax-= OL_TOGW+UI_UNIT_X;
                
                glEnable(GL_BLEND);
 
@@ -4708,7 +4710,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
                /* active circle */
                if(active) {
                        uiSetRoundBox(15);
-                       uiRoundBox( (float)startx+OL_H-1.5f, (float)*starty+2.0f, (float)startx+2.0f*OL_H-4.0f, (float)*starty+OL_H-1.0f, OL_H/2.0f-2.0f);
+                       uiRoundBox( (float)startx+UI_UNIT_Y-1.5f*ufac, (float)*starty+2.0f*ufac, (float)startx+2.0f*UI_UNIT_Y-4.0f*ufac, (float)*starty+UI_UNIT_Y-1.0f*ufac, UI_UNIT_Y/2.0f-2.0f*ufac);
                        glEnable(GL_BLEND);     /* roundbox disables it */
                        
                        te->flag |= TE_ACTIVE; // for lookup in display hierarchies
@@ -4720,35 +4722,35 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
                        if(tselem->type==0 && ELEM(te->idcode, ID_OB, ID_SCE))
                                icon_x = startx;
                        else
-                               icon_x = startx+5;
+                               icon_x = startx+5*ufac;
 
                                // icons a bit higher
                        if(tselem->flag & TSE_CLOSED) 
-                               UI_icon_draw((float)icon_x, (float)*starty+2, ICON_DISCLOSURE_TRI_RIGHT);
+                               UI_icon_draw((float)icon_x, (float)*starty+2*ufac, ICON_DISCLOSURE_TRI_RIGHT);
                        else
-                               UI_icon_draw((float)icon_x, (float)*starty+2, ICON_DISCLOSURE_TRI_DOWN);
+                               UI_icon_draw((float)icon_x, (float)*starty+2*ufac, ICON_DISCLOSURE_TRI_DOWN);
                }
-               offsx+= OL_X;
+               offsx+= UI_UNIT_X;
                
                /* datatype icon */
                
                if(!(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM))) {
                        // icons a bit higher
-                       tselem_draw_icon(block, xmax, (float)startx+offsx, (float)*starty+2, tselem, te, 1.0f);
+                       tselem_draw_icon(block, xmax, (float)startx+offsx, (float)*starty+2*ufac, tselem, te, 1.0f);
                        
-                       offsx+= OL_X;
+                       offsx+= UI_UNIT_X;
                }
                else
-                       offsx+= 2;
+                       offsx+= 2*ufac;
                
                if(tselem->type==0 && tselem->id->lib) {
                        glPixelTransferf(GL_ALPHA_SCALE, 0.5f);
                        if(tselem->id->flag & LIB_INDIRECT)
-                               UI_icon_draw((float)startx+offsx, (float)*starty+2, ICON_LIBRARY_DATA_INDIRECT);
+                               UI_icon_draw((float)startx+offsx, (float)*starty+2*ufac, ICON_LIBRARY_DATA_INDIRECT);
                        else
-                               UI_icon_draw((float)startx+offsx, (float)*starty+2, ICON_LIBRARY_DATA_DIRECT);
+                               UI_icon_draw((float)startx+offsx, (float)*starty+2*ufac, ICON_LIBRARY_DATA_DIRECT);
                        glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
-                       offsx+= OL_X;
+                       offsx+= UI_UNIT_X;
                }               
                glDisable(GL_BLEND);
 
@@ -4757,9 +4759,9 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
                else if(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) UI_ThemeColorBlend(TH_BACK, TH_TEXT, 0.75f);
                else UI_ThemeColor(TH_TEXT);
                
-               UI_DrawString(startx+offsx, *starty+5, te->name);
+               UI_DrawString(startx+offsx, *starty+5*ufac, te->name);
                
-               offsx+= (int)(OL_X + UI_GetStringWidth(te->name));
+               offsx+= (int)(UI_UNIT_X + UI_GetStringWidth(te->name));
                
                /* closed item, we draw the icons, not when it's a scene, or master-server list though */
                if(tselem->flag & TSE_CLOSED) {
@@ -4770,7 +4772,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
                                        
                                        // divider
                                        UI_ThemeColorShade(TH_BACK, -40);
-                                       glRecti(tempx -10, *starty+4, tempx -8, *starty+OL_H-4);
+                                       glRecti(tempx -10, *starty+4, tempx -8, *starty+UI_UNIT_Y-4);
 
                                        glEnable(GL_BLEND);
                                        glPixelTransferf(GL_ALPHA_SCALE, 0.5);
@@ -4789,16 +4791,16 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
        te->xend= startx+offsx;
                
        if((tselem->flag & TSE_CLOSED)==0) {
-               *starty-= OL_H;
+               *starty-= UI_UNIT_Y;
                
                for(ten= te->subtree.first; ten; ten= ten->next)
-                       outliner_draw_tree_element(C, block, scene, ar, soops, ten, startx+OL_X, starty);
+                       outliner_draw_tree_element(C, block, scene, ar, soops, ten, startx+UI_UNIT_X, starty);
        }       
        else {
                for(ten= te->subtree.first; ten; ten= ten->next)
                        outliner_set_coord_tree_element(soops, te, startx, starty);
 
-               *starty-= OL_H;
+               *starty-= UI_UNIT_Y;
        }
 }
 
@@ -4817,12 +4819,12 @@ static void outliner_draw_hierarchy(SpaceOops *soops, ListBase *lb, int startx,
                
                /* horizontal line? */
                if(tselem->type==0 && (te->idcode==ID_OB || te->idcode==ID_SCE))
-                       glRecti(startx, *starty, startx+OL_X, *starty-1);
+                       glRecti(startx, *starty, startx+UI_UNIT_X, *starty-1);
                        
-               *starty-= OL_H;
+               *starty-= UI_UNIT_Y;
                
                if((tselem->flag & TSE_CLOSED)==0)
-                       outliner_draw_hierarchy(soops, &te->subtree, startx+OL_X, starty);
+                       outliner_draw_hierarchy(soops, &te->subtree, startx+UI_UNIT_X, starty);
        }
        
        /* vertical line */
@@ -4831,7 +4833,7 @@ static void outliner_draw_hierarchy(SpaceOops *soops, ListBase *lb, int startx,
                tselem= TREESTORE(te);
                if(tselem->type==0 && te->idcode==ID_OB) {
                        
-                       glRecti(startx, y1+OL_H, startx+1, y2);
+                       glRecti(startx, y1+UI_UNIT_Y, startx+1, y2);
                }
        }
 }
@@ -4847,13 +4849,13 @@ static void outliner_draw_struct_marks(ARegion *ar, SpaceOops *soops, ListBase *
                /* selection status */
                if((tselem->flag & TSE_CLOSED)==0)
                        if(tselem->type == TSE_RNA_STRUCT)
-                               glRecti(0, *starty+1, (int)ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, *starty+OL_H-1);
+                               glRecti(0, *starty+1, (int)ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, *starty+UI_UNIT_Y-1);
 
-               *starty-= OL_H;
+               *starty-= UI_UNIT_Y;
                if((tselem->flag & TSE_CLOSED)==0) {
                        outliner_draw_struct_marks(ar, soops, &te->subtree, starty);
                        if(tselem->type == TSE_RNA_STRUCT)
-                               fdrawline(0, (float)*starty+OL_H, ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, (float)*starty+OL_H);
+                               fdrawline(0, (float)*starty+UI_UNIT_Y, ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, (float)*starty+UI_UNIT_Y);
                }
        }
 }
@@ -4868,9 +4870,9 @@ static void outliner_draw_selection(ARegion *ar, SpaceOops *soops, ListBase *lb,
                
                /* selection status */
                if(tselem->flag & TSE_SELECTED) {
-                       glRecti(0, *starty+1, (int)ar->v2d.cur.xmax, *starty+OL_H-1);
+                       glRecti(0, *starty+1, (int)ar->v2d.cur.xmax, *starty+UI_UNIT_Y-1);
                }
-               *starty-= OL_H;
+               *starty-= UI_UNIT_Y;
                if((tselem->flag & TSE_CLOSED)==0) outliner_draw_selection(ar, soops, &te->subtree, starty);
        }
 }
@@ -4888,24 +4890,24 @@ static void outliner_draw_tree(bContext *C, uiBlock *block, Scene *scene, ARegio
                /* struct marks */
                UI_ThemeColorShadeAlpha(TH_BACK, -15, -200);
                //UI_ThemeColorShade(TH_BACK, -20);
-               starty= (int)ar->v2d.tot.ymax-OL_H-OL_Y_OFFSET;
+               starty= (int)ar->v2d.tot.ymax-UI_UNIT_Y-OL_Y_OFFSET;
                outliner_draw_struct_marks(ar, soops, &soops->tree, &starty);
        }
        
        /* always draw selection fill before hierarchy */
        UI_GetThemeColor3fv(TH_BACK, col);
        glColor3f(col[0]+0.06f, col[1]+0.08f, col[2]+0.10f);
-       starty= (int)ar->v2d.tot.ymax-OL_H-OL_Y_OFFSET;
+       starty= (int)ar->v2d.tot.ymax-UI_UNIT_Y-OL_Y_OFFSET;
        outliner_draw_selection(ar, soops, &soops->tree, &starty);
        
        // grey hierarchy lines
        UI_ThemeColorBlend(TH_BACK, TH_TEXT, 0.2f);
-       starty= (int)ar->v2d.tot.ymax-OL_H/2-OL_Y_OFFSET;
+       starty= (int)ar->v2d.tot.ymax-UI_UNIT_Y/2-OL_Y_OFFSET;
        startx= 6;
        outliner_draw_hierarchy(soops, &soops->tree, startx, &starty);
        
        // items themselves
-       starty= (int)ar->v2d.tot.ymax-OL_H-OL_Y_OFFSET;
+       starty= (int)ar->v2d.tot.ymax-UI_UNIT_Y-OL_Y_OFFSET;
        startx= 0;
        for(te= soops->tree.first; te; te= te->next) {
                outliner_draw_tree_element(C, block, scene, ar, soops, te, startx, &starty);
@@ -4919,11 +4921,11 @@ static void outliner_back(ARegion *ar)
        
        UI_ThemeColorShade(TH_BACK, 6);
        ystart= (int)ar->v2d.tot.ymax;
-       ystart= OL_H*(ystart/(OL_H))-OL_Y_OFFSET;
+       ystart= UI_UNIT_Y*(ystart/(UI_UNIT_Y))-OL_Y_OFFSET;
        
-       while(ystart+2*OL_H > ar->v2d.cur.ymin) {
-               glRecti(0, ystart, (int)ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, ystart+OL_H);
-               ystart-= 2*OL_H;
+       while(ystart+2*UI_UNIT_Y > ar->v2d.cur.ymin) {
+               glRecti(0, ystart, (int)ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, ystart+UI_UNIT_Y);
+               ystart-= 2*UI_UNIT_Y;
        }
 }
 
@@ -4937,11 +4939,11 @@ static void outliner_draw_restrictcols(ARegion *ar)
        
        UI_ThemeColorShade(TH_BACK, 6);
        ystart= (int)ar->v2d.tot.ymax;
-       ystart= OL_H*(ystart/(OL_H))-OL_Y_OFFSET;
+       ystart= UI_UNIT_Y*(ystart/(UI_UNIT_Y))-OL_Y_OFFSET;
        
-       while(ystart+2*OL_H > ar->v2d.cur.ymin) {
-               glRecti((int)ar->v2d.cur.xmax-OL_TOGW, ystart, (int)ar->v2d.cur.xmax, ystart+OL_H);
-               ystart-= 2*OL_H;
+       while(ystart+2*UI_UNIT_Y > ar->v2d.cur.ymin) {
+               glRecti((int)ar->v2d.cur.xmax-OL_TOGW, ystart, (int)ar->v2d.cur.xmax, ystart+UI_UNIT_Y);
+               ystart-= 2*UI_UNIT_Y;
        }
        
        UI_ThemeColorShadeAlpha(TH_BACK, -15, -200);
@@ -5225,7 +5227,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
 
        for(te= lb->first; te; te= te->next) {
                tselem= TREESTORE(te);
-               if(te->ys+2*OL_H >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {   
+               if(te->ys+2*UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {      
                        /* objects have toggle-able restriction flags */
                        if(tselem->type==0 && te->idcode==ID_OB) {
                                PointerRNA ptr;
@@ -5235,17 +5237,17 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
                                
                                uiBlockSetEmboss(block, UI_EMBOSSN);
                                bt= uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_VIEW_OFF,
-                                                         (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, 17, OL_H-1,
+                                                         (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1,
                                                          &ptr, "hide", -1, 0, 0, -1, -1, NULL);
                                uiButSetFunc(bt, restrictbutton_view_cb, scene, ob);
                                
                                bt= uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_SELECT_OFF,
-                                                                 (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, 17, OL_H-1,
+                                                                 (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1,
                                                                  &ptr, "hide_select", -1, 0, 0, -1, -1, NULL);
                                uiButSetFunc(bt, restrictbutton_sel_cb, scene, ob);
                                
                                bt= uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_RENDER_OFF,
-                                                                 (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, 17, OL_H-1,
+                                                                 (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1,
                                                                  &ptr, "hide_render", -1, 0, 0, -1, -1, NULL);
                                uiButSetFunc(bt, restrictbutton_rend_cb, scene, ob);
                                
@@ -5259,15 +5261,15 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
                                uiBlockSetEmboss(block, UI_EMBOSSN);
 
                                restrict_bool= group_restrict_flag(gr, OB_RESTRICT_VIEW);
-                               bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, 17, OL_H-1, NULL, 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
+                               bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, NULL, 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
                                uiButSetFunc(bt, restrictbutton_gr_restrict_view, scene, gr);
 
                                restrict_bool= group_restrict_flag(gr, OB_RESTRICT_SELECT);
-                               bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, 17, OL_H-1, NULL, 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
+                               bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, NULL, 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
                                uiButSetFunc(bt, restrictbutton_gr_restrict_select, scene, gr);
 
                                restrict_bool= group_restrict_flag(gr, OB_RESTRICT_RENDER);
-                               bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, 17, OL_H-1, NULL, 0, 0, 0, 0, "Restrict/Allow renderability");
+                               bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, NULL, 0, 0, 0, 0, "Restrict/Allow renderability");
                                uiButSetFunc(bt, restrictbutton_gr_restrict_render, scene, gr);
 
                                uiBlockSetEmboss(block, UI_EMBOSS);
@@ -5277,7 +5279,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
                                uiBlockSetEmboss(block, UI_EMBOSSN);
                                
                                bt= uiDefIconButBitI(block, ICONTOGN, SCE_LAY_DISABLE, 0, ICON_CHECKBOX_HLT-1, 
-                                                                        (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, 17, OL_H-1, te->directdata, 0, 0, 0, 0, "Render this RenderLayer");
+                                                                        (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, te->directdata, 0, 0, 0, 0, "Render this RenderLayer");
                                uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
                                
                                uiBlockSetEmboss(block, UI_EMBOSS);
@@ -5290,13 +5292,13 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
                                
                                
                                bt= uiDefIconButBitI(block, ICONTOG, passflag, 0, ICON_CHECKBOX_HLT-1, 
-                                                                        (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, 17, OL_H-1, layflag, 0, 0, 0, 0, "Render this Pass");
+                                                                        (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, layflag, 0, 0, 0, 0, "Render this Pass");
                                uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
                                
                                layflag++;      /* is lay_xor */
                                if(ELEM8(passflag, SCE_PASS_SPEC, SCE_PASS_SHADOW, SCE_PASS_AO, SCE_PASS_REFLECT, SCE_PASS_REFRACT, SCE_PASS_INDIRECT, SCE_PASS_EMIT, SCE_PASS_ENVIRONMENT))
                                        bt= uiDefIconButBitI(block, TOG, passflag, 0, (*layflag & passflag)?ICON_DOT:ICON_BLANK1, 
-                                                                        (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, 17, OL_H-1, layflag, 0, 0, 0, 0, "Exclude this Pass from Combined");
+                                                                        (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, layflag, 0, 0, 0, 0, "Exclude this Pass from Combined");
                                uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
                                
                                uiBlockSetEmboss(block, UI_EMBOSS);
@@ -5307,11 +5309,11 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
                                
                                uiBlockSetEmboss(block, UI_EMBOSSN);
                                bt= uiDefIconButBitI(block, ICONTOGN, eModifierMode_Realtime, 0, ICON_RESTRICT_VIEW_OFF, 
-                                               (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, 17, OL_H-1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
+                                               (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
                                uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob);
                                
                                bt= uiDefIconButBitI(block, ICONTOGN, eModifierMode_Render, 0, ICON_RESTRICT_RENDER_OFF, 
-                                               (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, 17, OL_H-1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow renderability");
+                                               (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow renderability");
                                uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob);
                        }
                        else if(tselem->type==TSE_POSE_CHANNEL)  {
@@ -5320,11 +5322,11 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
                                
                                uiBlockSetEmboss(block, UI_EMBOSSN);
                                bt= uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_P, 0, ICON_RESTRICT_VIEW_OFF, 
-                                               (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, 17, OL_H-1, &(bone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
+                                               (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(bone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
                                uiButSetFunc(bt, restrictbutton_bone_cb, NULL, bone);
                                
                                bt= uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF, 
-                                               (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, 17, OL_H-1, &(bone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
+                                               (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(bone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
                                uiButSetFunc(bt, restrictbutton_bone_cb, NULL, NULL);
                        }
                        else if(tselem->type==TSE_EBONE)  {
@@ -5332,11 +5334,11 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
                                
                                uiBlockSetEmboss(block, UI_EMBOSSN);
                                bt= uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_A, 0, ICON_RESTRICT_VIEW_OFF, 
-                                               (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, 17, OL_H-1, &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
+                                               (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
                                uiButSetFunc(bt, restrictbutton_ebone_cb, NULL, ebone);
                                
                                bt= uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF, 
-                                               (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, 17, OL_H-1, &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
+                                               (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
                                uiButSetFunc(bt, restrictbutton_ebone_cb, NULL, NULL);
                        }
                }
@@ -5377,19 +5379,19 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa
 
        for(te= lb->first; te; te= te->next) {
                tselem= TREESTORE(te);
-               if(te->ys+2*OL_H >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {   
+               if(te->ys+2*UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {      
                        if(tselem->type == TSE_RNA_PROPERTY) {
                                ptr= &te->rnaptr;
                                prop= te->directdata;
                                
                                if(!(RNA_property_type(prop) == PROP_POINTER && (tselem->flag & TSE_CLOSED)==0))
-                                       uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, OL_H-1);
+                                       uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, UI_UNIT_Y-1);
                        }
                        else if(tselem->type == TSE_RNA_ARRAY_ELEM) {
                                ptr= &te->rnaptr;
                                prop= te->directdata;
                                
-                               uiDefAutoButR(block, ptr, prop, te->index, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, OL_H-1);
+                               uiDefAutoButR(block, ptr, prop, te->index, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, UI_UNIT_Y-1);
                        }
                }
                
@@ -5444,7 +5446,7 @@ static uiBlock *operator_search_menu(bContext *C, ARegion *ar, void *arg_kmi)
        /* fake button, it holds space for search items */
        uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
        
-       but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, 150, 19, 0, 0, "");
+       but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, 150, UI_UNIT_Y, 0, 0, "");
        uiButSetSearchFunc(but, operator_search_cb, arg_kmi, operator_call_cb, ot);
        
        uiBoundsBlock(block, 6);
@@ -5583,11 +5585,11 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo
        
        for(te= lb->first; te; te= te->next) {
                tselem= TREESTORE(te);
-               if(te->ys+2*OL_H >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
+               if(te->ys+2*UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
                        uiBut *but;
                        const char *str;
                        int xstart= 240;
-                       int butw1= 20; /* operator */
+                       int butw1= UI_UNIT_X; /* operator */
                        int butw2= 90; /* event type, menus */
                        int butw3= 43; /* modifiers */
 
@@ -5597,7 +5599,7 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo
                                /* modal map? */
                                if(kmi->propvalue);
                                else {
-                                       uiDefBlockBut(block, operator_search_menu, kmi, "", xstart, (int)te->ys+1, butw1, OL_H-1, "Assign new Operator");
+                                       uiDefBlockBut(block, operator_search_menu, kmi, "", xstart, (int)te->ys+1, butw1, UI_UNIT_Y-1, "Assign new Operator");
                                }
                                xstart+= butw1+10;
                                
@@ -5605,43 +5607,43 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo
                                kmi->maptype= keymap_menu_type(kmi->type);
                                
                                str= keymap_type_menu();
-                               but= uiDefButS(block, MENU, 0, str,     xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->maptype, 0, 0, 0, 0, "Event type");
+                               but= uiDefButS(block, MENU, 0, str,     xstart, (int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->maptype, 0, 0, 0, 0, "Event type");
                                uiButSetFunc(but, keymap_type_cb, kmi, NULL);
                                xstart+= butw2+5;
                                
                                /* edit actual event */
                                switch(kmi->maptype) {
                                        case OL_KM_KEYBOARD:
-                                               uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->type, "Key code");
+                                               uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->type, "Key code");
                                                xstart+= butw2+5;
                                                break;
                                        case OL_KM_MOUSE:
                                                str= keymap_mouse_menu();
-                                               uiDefButS(block, MENU, 0, str, xstart,(int)te->ys+1, butw2, OL_H-1, &kmi->type, 0, 0, 0, 0,  "Mouse button");   
+                                               uiDefButS(block, MENU, 0, str, xstart,(int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->type, 0, 0, 0, 0,  "Mouse button");      
                                                xstart+= butw2+5;
                                                break;
                                        case OL_KM_TWEAK:
                                                str= keymap_tweak_menu();
-                                               uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->type, 0, 0, 0, 0,  "Tweak gesture"); 
+                                               uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->type, 0, 0, 0, 0,  "Tweak gesture");    
                                                xstart+= butw2+5;
                                                str= keymap_tweak_dir_menu();
-                                               uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->val, 0, 0, 0, 0,  "Tweak gesture direction");        
+                                               uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->val, 0, 0, 0, 0,  "Tweak gesture direction");   
                                                xstart+= butw2+5;
                                                break;
                                }
                                
                                /* modifiers */
-                               uiDefButS(block, OPTION, 0, "Shift",    xstart, (int)te->ys+1, butw3+5, OL_H-1, &kmi->shift, 0, 0, 0, 0, "Modifier"); xstart+= butw3+5;
-                               uiDefButS(block, OPTION, 0, "Ctrl",     xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->ctrl, 0, 0, 0, 0, "Modifier"); xstart+= butw3;
-                               uiDefButS(block, OPTION, 0, "Alt",      xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->alt, 0, 0, 0, 0, "Modifier"); xstart+= butw3;
-                               uiDefButS(block, OPTION, 0, "OS",       xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->oskey, 0, 0, 0, 0, "Modifier"); xstart+= butw3;
+                               uiDefButS(block, OPTION, 0, "Shift",    xstart, (int)te->ys+1, butw3+5, UI_UNIT_Y-1, &kmi->shift, 0, 0, 0, 0, "Modifier"); xstart+= butw3+5;
+                               uiDefButS(block, OPTION, 0, "Ctrl",     xstart, (int)te->ys+1, butw3, UI_UNIT_Y-1, &kmi->ctrl, 0, 0, 0, 0, "Modifier"); xstart+= butw3;
+                               uiDefButS(block, OPTION, 0, "Alt",      xstart, (int)te->ys+1, butw3, UI_UNIT_Y-1, &kmi->alt, 0, 0, 0, 0, "Modifier"); xstart+= butw3;
+                               uiDefButS(block, OPTION, 0, "OS",       xstart, (int)te->ys+1, butw3, UI_UNIT_Y-1, &kmi->oskey, 0, 0, 0, 0, "Modifier"); xstart+= butw3;
                                xstart+= 5;
-                               uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->keymodifier, "Key Modifier code");
+                               uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys+1, butw3, UI_UNIT_Y-1, &kmi->keymodifier, "Key Modifier code");
                                xstart+= butw3+5;
                                
                                /* rna property */
                                if(kmi->ptr && kmi->ptr->data) {
-                                       uiDefBut(block, LABEL, 0, "(RNA property)",     xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->oskey, 0, 0, 0, 0, ""); xstart+= butw2;
+                                       uiDefBut(block, LABEL, 0, "(RNA property)",     xstart, (int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->oskey, 0, 0, 0, 0, ""); xstart+= butw2;
                                }
 
                                (void)xstart;
@@ -5662,7 +5664,7 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Spa
        
        for(te= lb->first; te; te= te->next) {
                tselem= TREESTORE(te);
-               if(te->ys+2*OL_H >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
+               if(te->ys+2*UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
                        
                        if(tselem->flag & TSE_TEXTBUT) {
                                
@@ -5679,10 +5681,10 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Spa
 
                                dx= (int)UI_GetStringWidth(te->name);
                                if(dx<100) dx= 100;
-                               spx=te->xs+2*OL_X-4;
+                               spx=te->xs+2*UI_UNIT_X-4;
                                if(spx+dx+10>ar->v2d.cur.xmax) dx = ar->v2d.cur.xmax-spx-10;
 
-                               bt= uiDefBut(block, TEX, OL_NAMEBUTTON, "", spx, (int)te->ys, dx+10, OL_H-1, (void *)te->name, 1.0, (float)len, 0, 0, "");
+                               bt= uiDefBut(block, TEX, OL_NAMEBUTTON, "", spx, (int)te->ys, dx+10, UI_UNIT_Y-1, (void *)te->name, 1.0, (float)len, 0, 0, "");
                                uiButSetRenameFunc(bt, namebutton_cb, tselem);
                                
                                /* returns false if button got removed */
@@ -5716,7 +5718,7 @@ void draw_outliner(const bContext *C)
                 *                               (OL_RNA_COL_X), whichever is wider...
                 *      - column 2 is fixed at OL_RNA_COL_SIZEX
                 *
-                *  (*) XXX max width for now is a fixed factor of OL_X*(max_indention+100)
+                *  (*) XXX max width for now is a fixed factor of UI_UNIT_X*(max_indention+100)
                 */
                 
                /* get actual width of column 1 */
index f351d52db07f11e916962365504b1ee74e341ecb..119c5da309ee892e43100814017f9227566292c4 100644 (file)
@@ -550,15 +550,17 @@ static void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, floa
        glShadeModel(GL_SMOOTH);
        glBegin(GL_QUADS);
        
-       if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -50);
+       if(seq->flag & SEQ_INVALID_EFFECT) { col[0]= 255; col[1]= 0; col[2]= 255; }
+       else if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -50);
        else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 0);
        
        glColor3ubv(col);
        
        glVertex2f(x1,y1);
        glVertex2f(x2,y1);
-       
-       if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 5);
+
+       if(seq->flag & SEQ_INVALID_EFFECT) { col[0]= 255; col[1]= 0; col[2]= 255; }
+       else if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 5);
        else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -5);
 
        glColor3ubv((GLubyte *)col);
index 71ed7928bc8d7780211a26d67719c5181b8b1586..6900271deea91fbf4de8eebec3389ec3d6284b94 100644 (file)
@@ -2817,6 +2817,7 @@ void SEQUENCER_OT_view_ghost_border(wmOperatorType *ot)
        ot->exec= view_ghost_border_exec;
        ot->modal= WM_border_select_modal;
        ot->poll= sequencer_view_poll;
+       ot->cancel= WM_border_select_cancel;
 
        /* flags */
        ot->flag= 0;
index 8b4bfb2e04243e77c13eb6c9e348f6f7ee821a6b..8d5f372f55e8b81c062d6630b8f62e03f27335c9 100644 (file)
@@ -871,6 +871,7 @@ void SEQUENCER_OT_select_border(wmOperatorType *ot)
        ot->invoke= WM_border_select_invoke;
        ot->exec= sequencer_borderselect_exec;
        ot->modal= WM_border_select_modal;
+       ot->cancel= WM_border_select_cancel;
        
        ot->poll= ED_operator_sequencer_active;
        
index 31aae28dd614ad37c4749493054d5cb883668fa1..9ff73767b4c4753cd6d5aa89f7661ab69d43dcbd 100644 (file)
@@ -904,6 +904,13 @@ static int view3d_camera_active_poll(bContext *C)
        return 0;
 }
 
+static int viewrotate_cancel(bContext *C, wmOperator *op)
+{
+       viewops_data_free(C, op);
+
+       return OPERATOR_CANCELLED;
+}
+
 void VIEW3D_OT_rotate(wmOperatorType *ot)
 {
 
@@ -916,6 +923,7 @@ void VIEW3D_OT_rotate(wmOperatorType *ot)
        ot->invoke= viewrotate_invoke;
        ot->modal= viewrotate_modal;
        ot->poll= ED_operator_region_view3d_active;
+       ot->cancel= viewrotate_cancel;
 
        /* flags */
        ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER;
@@ -1058,6 +1066,13 @@ static int viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event)
        }
 }
 
+static int viewmove_cancel(bContext *C, wmOperator *op)
+{
+       viewops_data_free(C, op);
+
+       return OPERATOR_CANCELLED;
+}
+
 void VIEW3D_OT_move(wmOperatorType *ot)
 {
 
@@ -1070,6 +1085,7 @@ void VIEW3D_OT_move(wmOperatorType *ot)
        ot->invoke= viewmove_invoke;
        ot->modal= viewmove_modal;
        ot->poll= ED_operator_view3d_active;
+       ot->cancel= viewmove_cancel;
 
        /* flags */
        ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER;
@@ -1414,6 +1430,12 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
        return OPERATOR_FINISHED;
 }
 
+static int viewzoom_cancel(bContext *C, wmOperator *op)
+{
+       viewops_data_free(C, op);
+
+       return OPERATOR_CANCELLED;
+}
 
 void VIEW3D_OT_zoom(wmOperatorType *ot)
 {
@@ -1427,6 +1449,7 @@ void VIEW3D_OT_zoom(wmOperatorType *ot)
        ot->exec= viewzoom_exec;
        ot->modal= viewzoom_modal;
        ot->poll= ED_operator_region_view3d_active;
+       ot->cancel= viewzoom_cancel;
 
        /* flags */
        ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER;
@@ -1641,6 +1664,13 @@ static int viewdolly_poll(bContext *C)
        return 0;
 }
 
+static int viewdolly_cancel(bContext *C, wmOperator *op)
+{
+       viewops_data_free(C, op);
+
+       return OPERATOR_CANCELLED;
+}
+
 void VIEW3D_OT_dolly(wmOperatorType *ot)
 {
        /* identifiers */
@@ -1653,6 +1683,7 @@ void VIEW3D_OT_dolly(wmOperatorType *ot)
        ot->exec= viewdolly_exec;
        ot->modal= viewdolly_modal;
        ot->poll= viewdolly_poll;
+       ot->cancel= viewdolly_cancel;
 
        /* flags */
        ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER;
@@ -2046,6 +2077,7 @@ void VIEW3D_OT_render_border(wmOperatorType *ot)
        ot->invoke= WM_border_select_invoke;
        ot->exec= render_border_exec;
        ot->modal= WM_border_select_modal;
+       ot->cancel= WM_border_select_cancel;
 
        ot->poll= view3d_camera_active_poll;
 
@@ -2201,6 +2233,7 @@ void VIEW3D_OT_zoom_border(wmOperatorType *ot)
        ot->invoke= view3d_zoom_border_invoke;
        ot->exec= view3d_zoom_border_exec;
        ot->modal= WM_border_select_modal;
+       ot->cancel= WM_border_select_cancel;
 
        ot->poll= ED_operator_region_view3d_active;
 
@@ -2839,6 +2872,7 @@ void VIEW3D_OT_clip_border(wmOperatorType *ot)
        ot->invoke= view3d_clipping_invoke;
        ot->exec= view3d_clipping_exec;
        ot->modal= WM_border_select_modal;
+       ot->cancel= WM_border_select_cancel;
 
        ot->poll= ED_operator_region_view3d_active;
 
index fb3c0a63b7d976824433b1f490322a5b7e07bdd3..6391db7ae5e830012a3ade0a288f642af48380b9 100644 (file)
@@ -875,6 +875,7 @@ void VIEW3D_OT_select_lasso(wmOperatorType *ot)
        ot->modal= WM_gesture_lasso_modal;
        ot->exec= view3d_lasso_select_exec;
        ot->poll= view3d_selectable_data;
+       ot->cancel= WM_gesture_lasso_cancel;
        
        /* flags */
        ot->flag= OPTYPE_UNDO;
@@ -1829,6 +1830,7 @@ void VIEW3D_OT_select_border(wmOperatorType *ot)
        ot->exec= view3d_borderselect_exec;
        ot->modal= WM_border_select_modal;
        ot->poll= view3d_selectable_data;
+       ot->cancel= WM_border_select_cancel;
        
        /* flags */
        ot->flag= OPTYPE_UNDO;
@@ -2308,6 +2310,7 @@ void VIEW3D_OT_select_circle(wmOperatorType *ot)
        ot->modal= WM_gesture_circle_modal;
        ot->exec= view3d_circle_select_exec;
        ot->poll= view3d_selectable_data;
+       ot->cancel= WM_gesture_circle_cancel;
        
        /* flags */
        ot->flag= OPTYPE_UNDO;
index 27ca345e132b1aa9efdc894d671519aab174ab47..181fb0f0aac2b4a508d43c89b3317318209b2ac5 100644 (file)
@@ -4858,8 +4858,8 @@ void initEdgeSlide(TransInfo *t)
        t->idx_max = 0;
        t->num.idx_max = 0;
        t->snap[0] = 0.0f;
-       t->snap[1] = (float)((5.0/180)*M_PI);
-       t->snap[2] = t->snap[1] * 0.2f;
+       t->snap[1] = 0.1f;
+       t->snap[2] = t->snap[1] * 0.1f;
 
        t->num.increment = t->snap[1];
 
@@ -4985,6 +4985,9 @@ int EdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
 
        snapGrid(t, &final);
 
+       /* only do this so out of range values are not displayed */
+       CLAMP(final, -1.0f, 1.0f);
+
        if (hasNumInput(&t->num)) {
                char c[20];
 
@@ -4992,10 +4995,10 @@ int EdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
 
                outputNumInput(&(t->num), c);
 
-               sprintf(str, "Edge Slide Percent: %s", &c[0]);
+               sprintf(str, "Edge Slide: %s", &c[0]);
        }
        else {
-               sprintf(str, "Edge Slide Percent: %.2f", final);
+               sprintf(str, "Edge Slide: %.2f", final);
        }
 
        CLAMP(final, -1.0f, 1.0f);
index c7699f7249cf287803d51948e040b0d1fce31874..68aa27a7b629c56b550b917aa34ea1e69c94ae77 100644 (file)
@@ -4016,6 +4016,7 @@ static void freeSeqData(TransInfo *t)
                                }
 
                                if(overlap) {
+                                       int has_effect= 0;
                                        for(seq= seqbasep->first; seq; seq= seq->next)
                                                seq->tmp= NULL;
 
@@ -4024,12 +4025,47 @@ static void freeSeqData(TransInfo *t)
                                        for(a=0; a<t->total; a++, td++) {
                                                seq= ((TransDataSeq *)td->extra)->seq;
                                                if ((seq != seq_prev)) {
-                                                       /* Tag seq with a non zero value, used by shuffle_seq_time to identify the ones to shuffle */
-                                                       seq->tmp= (void*)1;
+                                                       /* check effects strips, we cant change their time */
+                                                       if((seq->type & SEQ_EFFECT) && seq->seq1) {
+                                                               has_effect= TRUE;
+                                                       }
+                                                       else {
+                                                               /* Tag seq with a non zero value, used by shuffle_seq_time to identify the ones to shuffle */
+                                                               seq->tmp= (void*)1;
+                                                       }
                                                }
                                        }
 
                                        shuffle_seq_time(seqbasep, t->scene);
+
+                                       if(has_effect) {
+                                               /* update effects strips based on strips just moved in time */
+                                               td= t->data;
+                                               seq_prev= NULL;
+                                               for(a=0; a<t->total; a++, td++) {
+                                                       seq= ((TransDataSeq *)td->extra)->seq;
+                                                       if ((seq != seq_prev)) {
+                                                               if((seq->type & SEQ_EFFECT) && seq->seq1) {
+                                                                       calc_sequence(t->scene, seq);
+                                                               }
+                                                       }
+                                               }
+
+                                               /* now if any effects _still_ overlap, we need to move them up */
+                                               td= t->data;
+                                               seq_prev= NULL;
+                                               for(a=0; a<t->total; a++, td++) {
+                                                       seq= ((TransDataSeq *)td->extra)->seq;
+                                                       if ((seq != seq_prev)) {
+                                                               if((seq->type & SEQ_EFFECT) && seq->seq1) {
+                                                                       if(seq_test_overlap(seqbasep, seq)) {
+                                                                               shuffle_seq(seqbasep, seq, t->scene);
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                               /* done with effects */
+                                       }
                                }
                        }
 #endif
index 692a19a7198c4120774bb20081d11be23b3257e4..24a868891de1bce54d0d0d10f0d947040690c796 100644 (file)
@@ -307,6 +307,8 @@ void ED_OT_undo_push(wmOperatorType *ot)
        /* api callbacks */
        ot->exec= ed_undo_push_exec;
 
+       ot->flag= OPTYPE_INTERNAL;
+
        RNA_def_string(ot->srna, "message", "Add an undo step *function may be moved*", MAXUNDONAME, "Undo Message", "");
 }
 
index 66b1e7d412bb7fc04baadf3d6c6b8bd0d945ddce..c09f8cff02d6990014bf8ad7e645f4d9f4e032ba 100644 (file)
@@ -2221,6 +2221,7 @@ static void UV_OT_select_border(wmOperatorType *ot)
        ot->exec= border_select_exec;
        ot->modal= WM_border_select_modal;
        ot->poll= ED_operator_image_active;     /* requires space image */;
+       ot->cancel= WM_border_select_cancel;
        
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -2310,6 +2311,7 @@ static void UV_OT_circle_select(wmOperatorType *ot)
        ot->modal= WM_gesture_circle_modal;
        ot->exec= circle_select_exec;
        ot->poll= ED_operator_image_active;     /* requires space image */;
+       ot->cancel= WM_gesture_circle_cancel;
        
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
index 0e7df43bd344ee9fd342b56d19623dd395dbd04e..7dfbc52819ef3c8749e8efcea5e914e3c711cc29 100644 (file)
@@ -687,9 +687,25 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h, int mipmap)
                glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skip_pixels);
                glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skip_rows);
 
-               if ((ibuf->rect==NULL) && ibuf->rect_float)
-                       IMB_rect_from_float(ibuf);
-
+               if (ibuf->rect_float){
+                       /*This case needs a whole new buffer*/
+                       if(ibuf->rect==NULL) {
+                               IMB_rect_from_float(ibuf);
+                       }
+                       else {
+                               /* Do partial drawing. 'buffer' holds only the changed part. Needed for color corrected result */
+                               float *buffer = (float *)MEM_mallocN(w*h*sizeof(float)*4, "temp_texpaint_float_buf");
+                               IMB_partial_rect_from_float(ibuf, buffer, x, y, w, h);
+                               glBindTexture(GL_TEXTURE_2D, ima->bindcode);
+                               glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
+                                       GL_FLOAT, buffer);
+                               MEM_freeN(buffer);
+                               if(ima->tpageflag & IMA_MIPMAP_COMPLETE)
+                                       ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
+                               return;
+                       }
+               }
+               
                glBindTexture(GL_TEXTURE_2D, ima->bindcode);
 
                glPixelStorei(GL_UNPACK_ROW_LENGTH, ibuf->x);
index 21249c9e8f72804e0d9e7dfeae0d91d8b61e34dc..5d61452e149e3bb875df726fb9768ced20038c3f 100644 (file)
@@ -243,8 +243,15 @@ void IMB_free_anim(struct anim *anim);
  *
  * @attention Defined in filter.c
  */
+
+#define FILTER_MASK_NULL               0
+#define FILTER_MASK_MARGIN             1
+#define FILTER_MASK_USED               2
+
 void IMB_filter(struct ImBuf *ibuf);
 void IMB_filterN(struct ImBuf *out, struct ImBuf *in);
+void IMB_mask_filter_extend(char *mask, int width, int height);
+void IMB_mask_clear(struct ImBuf *ibuf, char *mask, int val);
 void IMB_filter_extend(struct ImBuf *ibuf, char *mask);
 void IMB_makemipmap(struct ImBuf *ibuf, int use_filter);
 void IMB_remakemipmap(struct ImBuf *ibuf, int use_filter);
@@ -320,7 +327,12 @@ int imb_get_anim_type(const char *name);
  */
 void IMB_de_interlace(struct ImBuf *ibuf);
 void IMB_interlace(struct ImBuf *ibuf);
+
+/* create char buffer, color corrected if necessary, for ImBufs that lack one */ 
 void IMB_rect_from_float(struct ImBuf *ibuf);
+/* create char buffer for part of the image, color corrected if necessary,
+   Changed part will be stored in buffer. This is expected to be used for texture painting updates */ 
+void IMB_partial_rect_from_float(struct ImBuf *ibuf, float *buffer, int x, int y, int w, int h);
 void IMB_float_from_rect(struct ImBuf *ibuf);
 void IMB_float_from_rect_simple(struct ImBuf *ibuf); /* no profile conversion */
 /* note, check that the conversion exists, only some are supported */
index 6b35d7df397fa31caa696bf0007976fc6ce1d82c..90ee2692cf0323417dbf2af08fbdd8ed7ad87277 100644 (file)
@@ -197,6 +197,135 @@ void IMB_rect_from_float(struct ImBuf *ibuf)
        ibuf->userflags &= ~IB_RECT_INVALID;
 }
 
+
+/* converts from linear float to sRGB byte for part of the texture, buffer will hold the changed part */
+void IMB_partial_rect_from_float(struct ImBuf *ibuf,float *buffer, int x, int y, int w, int h)
+{
+       /* indices to source and destination image pixels */
+       float *srcFloatPxl;
+       unsigned char *dstBytePxl;
+       /* buffer index will fill buffer */
+       float *bufferIndex;
+
+       /* convenience pointers to start of image buffers */
+       float *init_srcFloatPxl = (float *)ibuf->rect_float;
+       unsigned char *init_dstBytePxl = (unsigned char *) ibuf->rect;
+
+       /* Dithering factor */
+       float dither= ibuf->dither / 255.0f;
+       /* respective attributes of image */
+       short profile= ibuf->profile;
+       int channels= ibuf->channels;
+       
+       int i, j;
+       
+       /*
+               if called -only- from GPU_paint_update_image this test will never fail
+               but leaving it here for better or worse
+       */
+       if(init_srcFloatPxl==NULL || (buffer == NULL)){
+               return;
+       }
+       if(init_dstBytePxl==NULL) {
+               imb_addrectImBuf(ibuf);
+               init_dstBytePxl = (unsigned char *) ibuf->rect;
+       }
+       if(channels==1) {
+                       for (j = 0; j < h; j++){
+                               bufferIndex = buffer + w*j*4;
+                               dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+                               srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x);
+                               for(i = 0;  i < w; i++, dstBytePxl+=4, srcFloatPxl++, bufferIndex+=4) {
+                                       dstBytePxl[1]= dstBytePxl[2]= dstBytePxl[3]= dstBytePxl[0] = FTOCHAR(srcFloatPxl[0]);
+                                       bufferIndex[0] = bufferIndex[1] = bufferIndex[2] = bufferIndex[3] = srcFloatPxl[0];
+                               }
+                       }
+       }
+       else if (profile == IB_PROFILE_LINEAR_RGB) {
+               if(channels == 3) {
+                       for (j = 0; j < h; j++){
+                               bufferIndex = buffer + w*j*4;
+                               dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+                               srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*3;
+                               for(i = 0;  i < w; i++, dstBytePxl+=4, srcFloatPxl+=3, bufferIndex += 4) {
+                                       linearrgb_to_srgb_v3_v3(bufferIndex, srcFloatPxl);
+                                       F3TOCHAR4(bufferIndex, dstBytePxl);
+                                       bufferIndex[3]= 1.0;
+                               }
+                       }
+               }
+               else if (channels == 4) {
+                       if (dither != 0.f) {
+                               for (j = 0; j < h; j++){
+                                       bufferIndex = buffer + w*j*4;
+                                       dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+                                       srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4;
+                                       for(i = 0;  i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) {
+                                               const float d = (BLI_frand()-0.5f)*dither;
+                                               linearrgb_to_srgb_v3_v3(bufferIndex, srcFloatPxl);
+                                               bufferIndex[3] = srcFloatPxl[3];
+                                               add_v4_fl(bufferIndex, d);
+                                               F4TOCHAR4(bufferIndex, dstBytePxl);
+                                       }
+                               }
+                       } else {
+                               for (j = 0; j < h; j++){
+                                       bufferIndex = buffer + w*j*4;
+                                       dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+                                       srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4;
+                                       for(i = 0;  i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) {
+                                               linearrgb_to_srgb_v3_v3(bufferIndex, srcFloatPxl);
+                                               bufferIndex[3]= srcFloatPxl[3];
+                                               F4TOCHAR4(bufferIndex, dstBytePxl);
+                                       }
+                               }
+                       }
+               }
+       }
+       else if(ELEM(profile, IB_PROFILE_NONE, IB_PROFILE_SRGB)) {
+               if(channels==3) {
+                       for (j = 0; j < h; j++){
+                               bufferIndex = buffer + w*j*4;
+                               dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+                               srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*3;
+                               for(i = 0;  i < w; i++, dstBytePxl+=4, srcFloatPxl+=3, bufferIndex+=4) {
+                                       copy_v3_v3(bufferIndex, srcFloatPxl);
+                                       F3TOCHAR4(bufferIndex, dstBytePxl);
+                                       bufferIndex[3] = 1.0;
+                               }
+                       }
+               }
+               else {
+                       if (dither != 0.f) {
+                               for (j = 0; j < h; j++){
+                                       bufferIndex = buffer + w*j*4;
+                                       dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+                                       srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4;
+                                       for(i = 0;  i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) {
+                                               const float d = (BLI_frand()-0.5f)*dither;
+                                               copy_v4_v4(bufferIndex, srcFloatPxl);
+                                               add_v4_fl(bufferIndex,d);
+                                               F4TOCHAR4(bufferIndex, dstBytePxl);
+                                       }
+                               }
+                       } else {
+                               for (j = 0; j < h; j++){
+                                       bufferIndex = buffer + w*j*4;
+                                       dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+                                       srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4;
+                                       for(i = 0;  i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) {
+                                               copy_v4_v4(bufferIndex, srcFloatPxl);
+                                               F4TOCHAR4(bufferIndex, dstBytePxl);
+                                       }
+                               }
+                       }
+               }
+       }
+       /* ensure user flag is reset */
+       ibuf->userflags &= ~IB_RECT_INVALID;
+}
+
 static void imb_float_from_rect_nonlinear(struct ImBuf *ibuf, float *fbuf)
 {
        float *tof = fbuf;
index 16fb1fdf4aa982cd39702ae636c0111c57250150..d12360e5a7ead984f9436ec12f621018d9bdd6e6 100644 (file)
@@ -262,6 +262,70 @@ void IMB_filter(struct ImBuf *ibuf)
        imb_filterx(ibuf);
 }
 
+void IMB_mask_filter_extend(char *mask, int width, int height)
+{
+       char *row1, *row2, *row3;
+       int rowlen, x, y;
+       char *temprect;
+
+       rowlen= width;
+
+       /* make a copy, to prevent flooding */
+       temprect= MEM_dupallocN(mask);
+
+       for(y=1; y<=height; y++) {
+               /* setup rows */
+               row1= (char *)(temprect + (y-2)*rowlen);
+               row2= row1 + rowlen;
+               row3= row2 + rowlen;
+               if(y==1)
+                       row1= row2;
+               else if(y==height)
+                       row3= row2;
+
+               for(x=0; x<rowlen; x++) {
+                       if (mask[((y-1)*rowlen)+x]==0) {
+                               if (*row1 || *row2 || *row3 || *(row1+1) || *(row3+1) ) {
+                                       mask[((y-1)*rowlen)+x] = FILTER_MASK_MARGIN;
+                               } else if((x!=rowlen-1) && (*(row1+2) || *(row2+2) || *(row3+2)) ) {
+                                       mask[((y-1)*rowlen)+x] = FILTER_MASK_MARGIN;
+                               }
+                       }
+
+                       if(x!=0) {
+                               row1++; row2++; row3++;
+                       }
+               }
+       }
+
+       MEM_freeN(temprect);
+}
+
+void IMB_mask_clear(ImBuf *ibuf, char *mask, int val)
+{
+       int x,y;
+       if (ibuf->rect_float) {
+               for(x=0; x<ibuf->x; x++) {
+                       for(y=0; y<ibuf->y; y++) {
+                               if (mask[ibuf->x*y + x] == val) {
+                                       float *col= ibuf->rect_float + 4*(ibuf->x*y + x);
+                                       col[0] = col[1] = col[2] = col[3] = 0.0f;
+                               }
+                       }
+               }
+       } else {
+               /* char buffer */
+               for(x=0; x<ibuf->x; x++) {
+                       for(y=0; y<ibuf->y; y++) {
+                               if (mask[ibuf->x*y + x] == val) {
+                                       char *col= (char *)(ibuf->rect + ibuf->x*y + x);
+                                       col[0] = col[1] = col[2] = col[3] = 0;
+                               }
+                       }
+               }
+       }
+}
+
 #define EXTEND_PIXEL(color, w) if((color)[3]) {r+= w*(color)[0]; g+= w*(color)[1]; b+= w*(color)[2]; a+= w*(color)[3]; tot+=w;}
 
 /* if alpha is zero, it checks surrounding pixels and averages color. sets new alphas to 1.0
index 662ef9e8a453d4e8b58f95b1e21b3213f5b1547c..a9e745b81487f2f87b382e43ffa026936a643744 100644 (file)
@@ -83,5 +83,7 @@ typedef struct Lattice {
 
 #define LT_DS_EXPAND   4
 
+#define LT_INDEX(lt, u, v, w) ((w) * ((lt)->pntsu * (lt)->pntsv) + ((v) * (lt)->pntsu) + (u))
+
 #endif
 
index fb9b4f01b97ca160a860af872e63479c51fa82ef..ccc306e777b4276680ce8c5d8326a538579bba0e 100644 (file)
@@ -1036,13 +1036,14 @@ typedef struct Scene {
 #define R_JPEG2K_CINE_PRESET   256
 #define R_JPEG2K_CINE_48FPS            512
 
-
 /* bake_mode: same as RE_BAKE_xxx defines */
 /* bake_flag: */
 #define R_BAKE_CLEAR           1
 #define R_BAKE_OSA                     2
 #define R_BAKE_TO_ACTIVE       4
 #define R_BAKE_NORMALIZE       8
+#define R_BAKE_MULTIRES                16
+#define R_BAKE_LORES_MESH      32
 
 /* bake_normal_space */
 #define R_BAKE_SPACE_CAMERA     0
index f89cc9d518a27b3ad7c5ca9a93692f4028ebef9a..3e7654bcf47d000eda88493ea273eb3a447a74c5 100644 (file)
@@ -253,27 +253,30 @@ typedef struct SpeedControlVars {
 #define SEQ_NAME_MAXSTR                        24
 
 /* seq->flag */
-#define SEQ_LEFTSEL                            2
-#define SEQ_RIGHTSEL                   4
-#define SEQ_OVERLAP                            8
-#define SEQ_FILTERY                            16
-#define SEQ_MUTE                               32
-#define SEQ_MAKE_PREMUL                        64
-#define SEQ_REVERSE_FRAMES             128
-#define SEQ_IPO_FRAME_LOCKED   256
-#define SEQ_EFFECT_NOT_LOADED  512
-#define SEQ_FLAG_DELETE                        1024
-#define SEQ_FLIPX                              2048
-#define SEQ_FLIPY                              4096
-#define SEQ_MAKE_FLOAT                         8192
-#define SEQ_LOCK                               16384
-#define SEQ_USE_PROXY                           32768
-#define SEQ_USE_TRANSFORM                       65536
-#define SEQ_USE_CROP                           131072
-#define SEQ_USE_COLOR_BALANCE                  262144
-#define SEQ_USE_PROXY_CUSTOM_DIR               524288
-#define SEQ_USE_PROXY_CUSTOM_FILE             2097152
-#define SEQ_USE_EFFECT_DEFAULT_FADE           4194304
+#define SEQ_LEFTSEL                 (1<<1)
+#define SEQ_RIGHTSEL                (1<<2)
+#define SEQ_OVERLAP                 (1<<3)
+#define SEQ_FILTERY                 (1<<4)
+#define SEQ_MUTE                    (1<<5)
+#define SEQ_MAKE_PREMUL             (1<<6)
+#define SEQ_REVERSE_FRAMES          (1<<7)
+#define SEQ_IPO_FRAME_LOCKED        (1<<8)
+#define SEQ_EFFECT_NOT_LOADED       (1<<9)
+#define SEQ_FLAG_DELETE             (1<<10)
+#define SEQ_FLIPX                   (1<<11)
+#define SEQ_FLIPY                   (1<<12)
+#define SEQ_MAKE_FLOAT              (1<<13)
+#define SEQ_LOCK                    (1<<14)
+#define SEQ_USE_PROXY               (1<<15)
+#define SEQ_USE_TRANSFORM           (1<<16)
+#define SEQ_USE_CROP                (1<<17)
+#define SEQ_USE_COLOR_BALANCE       (1<<18)
+#define SEQ_USE_PROXY_CUSTOM_DIR    (1<<19)
+
+#define SEQ_USE_PROXY_CUSTOM_FILE   (1<<21)
+#define SEQ_USE_EFFECT_DEFAULT_FADE (1<<22)
+
+#define SEQ_INVALID_EFFECT          (1<<31)
 
 /* convenience define for all selection flags */
 #define SEQ_ALLSEL     (SELECT+SEQ_LEFTSEL+SEQ_RIGHTSEL)
index e0feba3f2fd4a49f698678dc88d22fe07cc218e9..ca19a86e42cd231c16d51542d6d5470a6df254a4 100644 (file)
@@ -650,6 +650,7 @@ PropertyType RNA_property_type(PropertyRNA *prop);
 PropertySubType RNA_property_subtype(PropertyRNA *prop);
 PropertyUnit RNA_property_unit(PropertyRNA *prop);
 int RNA_property_flag(PropertyRNA *prop);
+void *RNA_property_py_data_get(PropertyRNA *prop);
 
 int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop);
 int RNA_property_array_check(PointerRNA *ptr, PropertyRNA *prop);
index b076393ef3de6acde86944d079440c76a9456db6..ac2a89161d96824e272075372a848f71bf8f86e2 100644 (file)
@@ -163,6 +163,8 @@ void RNA_def_property_update(PropertyRNA *prop, int noteflag, const char *update
 void RNA_def_property_editable_func(PropertyRNA *prop, const char *editable);
 void RNA_def_property_editable_array_func(PropertyRNA *prop, const char *editable);
 
+void RNA_def_property_update_runtime(PropertyRNA *prop, void *func);
+
 void RNA_def_property_dynamic_array_funcs(PropertyRNA *prop, const char *getlength);
 void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const char *set);
 void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range);
@@ -172,6 +174,7 @@ void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const cha
 void RNA_def_property_pointer_funcs(PropertyRNA *prop, const char *get, const char *set, const char *typef, const char *poll);
 void RNA_def_property_collection_funcs(PropertyRNA *prop, const char *begin, const char *next, const char *end, const char *get, const char *length, const char *lookupint, const char *lookupstring);
 void RNA_def_property_srna(PropertyRNA *prop, const char *type);
+void RNA_def_py_data(PropertyRNA *prop, void *py_data);
 
 /* Function */
 
index b3f2ae01c9955ac9a39c205f353bb8e97fa79cba..ec213d6a496cbbe13b5e975a662d5ba5a5f96f28 100644 (file)
@@