Merging r43501 through r43720 form trunk into soc-2011-tomato
authorSergey Sharybin <sergey.vfx@gmail.com>
Thu, 26 Jan 2012 12:12:20 +0000 (12:12 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Thu, 26 Jan 2012 12:12:20 +0000 (12:12 +0000)
321 files changed:
build_files/cmake/cmake_static_check_cppcheck.py
build_files/scons/tools/Blender.py
doc/python_api/examples/bge.constraints.py
doc/python_api/examples/bge.texture.1.py
doc/python_api/examples/bge.texture.py
doc/python_api/rst/bge.constraints.rst
doc/python_api/rst/bge.render.rst
doc/python_api/rst/bge.texture.rst
doc/python_api/rst/bge.types.rst
extern/libmv/third_party/glog/src/config.h
extern/libmv/third_party/glog/src/config_linux.h
intern/boolop/SConscript
intern/boolop/intern/BOP_CarveInterface.cpp
intern/cycles/app/cycles_xml.cpp
intern/cycles/blender/addon/properties.py
intern/cycles/blender/addon/ui.py
intern/cycles/blender/blender_object.cpp
intern/cycles/blender/blender_session.cpp
intern/cycles/blender/blender_shader.cpp
intern/cycles/blender/blender_sync.h
intern/cycles/device/device_cpu.cpp
intern/cycles/kernel/CMakeLists.txt
intern/cycles/kernel/kernel.cl
intern/cycles/kernel/kernel.cpp
intern/cycles/kernel/kernel.cu
intern/cycles/kernel/kernel.h
intern/cycles/kernel/kernel_accumulate.h [new file with mode: 0644]
intern/cycles/kernel/kernel_compat_cpu.h
intern/cycles/kernel/kernel_compat_cuda.h
intern/cycles/kernel/kernel_differential.h
intern/cycles/kernel/kernel_displace.h
intern/cycles/kernel/kernel_emission.h
intern/cycles/kernel/kernel_film.h
intern/cycles/kernel/kernel_light.h
intern/cycles/kernel/kernel_montecarlo.h
intern/cycles/kernel/kernel_object.h
intern/cycles/kernel/kernel_optimized.cpp
intern/cycles/kernel/kernel_passes.h [new file with mode: 0644]
intern/cycles/kernel/kernel_path.h
intern/cycles/kernel/kernel_random.h
intern/cycles/kernel/kernel_shader.h
intern/cycles/kernel/kernel_textures.h
intern/cycles/kernel/kernel_types.h
intern/cycles/kernel/osl/nodes/CMakeLists.txt
intern/cycles/kernel/osl/nodes/node_brightness.osl [new file with mode: 0644]
intern/cycles/kernel/svm/svm.h
intern/cycles/kernel/svm/svm_brightness.h [new file with mode: 0644]
intern/cycles/kernel/svm/svm_image.h
intern/cycles/kernel/svm/svm_types.h
intern/cycles/render/buffers.cpp
intern/cycles/render/buffers.h
intern/cycles/render/film.cpp
intern/cycles/render/film.h
intern/cycles/render/light.cpp
intern/cycles/render/light.h
intern/cycles/render/mesh_displace.cpp
intern/cycles/render/nodes.cpp
intern/cycles/render/nodes.h
intern/cycles/render/object.cpp
intern/cycles/render/object.h
intern/cycles/render/scene.h
intern/cycles/render/shader.cpp
intern/cycles/render/shader.h
intern/ffmpeg/ffmpeg_compat.h
intern/ghost/GHOST_ISystem.h
intern/ghost/intern/GHOST_NDOFManager.cpp
intern/ghost/intern/GHOST_NDOFManager.h
intern/ghost/intern/GHOST_System.cpp
intern/ghost/intern/GHOST_System.h
intern/ghost/intern/GHOST_SystemX11.cpp
release/scripts/presets/keyconfig/maya.py
release/scripts/startup/bl_ui/properties_data_modifier.py
release/scripts/startup/bl_ui/properties_particle.py
release/scripts/startup/bl_ui/properties_physics_cloth.py
release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py
release/scripts/startup/bl_ui/properties_physics_fluid.py
release/scripts/startup/bl_ui/space_clip.py
release/scripts/startup/bl_ui/space_image.py
release/scripts/startup/bl_ui/space_logic.py
release/scripts/startup/bl_ui/space_node.py
release/scripts/startup/bl_ui/space_view3d_toolbar.py
source/blender/avi/intern/endian.c
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/BKE_armature.h
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/BKE_global.h
source/blender/blenkernel/BKE_image.h
source/blender/blenkernel/BKE_main.h
source/blender/blenkernel/BKE_modifier.h
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/BKE_tracking.h
source/blender/blenkernel/BKE_utildefines.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/armature.c
source/blender/blenkernel/intern/brush.c
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/dynamicpaint.c
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/image_gen.c
source/blender/blenkernel/intern/implicit.c
source/blender/blenkernel/intern/key.c
source/blender/blenkernel/intern/mesh.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/movieclip.c
source/blender/blenkernel/intern/nla.c
source/blender/blenkernel/intern/node.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/sequencer.c
source/blender/blenkernel/intern/smoke.c
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/blenkernel/intern/text.c
source/blender/blenkernel/intern/tracking.c
source/blender/blenlib/BLI_array.h
source/blender/blenlib/BLI_math_color.h
source/blender/blenlib/BLI_math_geom.h
source/blender/blenlib/BLI_math_vector.h
source/blender/blenlib/intern/BLI_ghash.c
source/blender/blenlib/intern/BLI_kdtree.c
source/blender/blenlib/intern/boxpack2d.c
source/blender/blenlib/intern/math_color.c
source/blender/blenlib/intern/math_color_inline.c
source/blender/blenlib/intern/math_geom.c
source/blender/blenlib/intern/math_rotation.c
source/blender/blenlib/intern/math_vector.c
source/blender/blenlib/intern/math_vector_inline.c
source/blender/blenlib/intern/noise.c
source/blender/blenloader/BLO_readfile.h
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/blenpluginapi/iff.h
source/blender/editors/animation/anim_channels_defines.c
source/blender/editors/armature/editarmature.c
source/blender/editors/armature/editarmature_retarget.c
source/blender/editors/armature/poselib.c
source/blender/editors/armature/reeb.c
source/blender/editors/curve/editcurve.c
source/blender/editors/curve/editfont.c
source/blender/editors/include/ED_image.h
source/blender/editors/include/ED_mesh.h
source/blender/editors/include/ED_object.h
source/blender/editors/include/UI_interface.h
source/blender/editors/include/UI_interface_icons.h
source/blender/editors/include/UI_resources.h
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_draw.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/interface_icons.c
source/blender/editors/interface/interface_intern.h
source/blender/editors/interface/interface_layout.c
source/blender/editors/interface/interface_panel.c
source/blender/editors/interface/interface_regions.c
source/blender/editors/interface/interface_templates.c
source/blender/editors/interface/interface_widgets.c
source/blender/editors/interface/resources.c
source/blender/editors/interface/view2d.c
source/blender/editors/mesh/mesh_data.c
source/blender/editors/mesh/mesh_ops.c
source/blender/editors/object/object_add.c
source/blender/editors/object/object_bake.c
source/blender/editors/object/object_modifier.c
source/blender/editors/object/object_relations.c
source/blender/editors/object/object_vgroup.c
source/blender/editors/physics/physics_fluid.c
source/blender/editors/render/render_shading.c
source/blender/editors/screen/screendump.c
source/blender/editors/sculpt_paint/CMakeLists.txt
source/blender/editors/sculpt_paint/paint_cursor.c [new file with mode: 0644]
source/blender/editors/sculpt_paint/paint_intern.h
source/blender/editors/sculpt_paint/paint_ops.c
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/sculpt_paint/sculpt_intern.h
source/blender/editors/sculpt_paint/sculpt_uv.c
source/blender/editors/sound/sound_ops.c
source/blender/editors/space_buttons/buttons_context.c
source/blender/editors/space_buttons/buttons_ops.c
source/blender/editors/space_clip/clip_draw.c
source/blender/editors/space_clip/clip_graph_draw.c
source/blender/editors/space_clip/clip_graph_ops.c
source/blender/editors/space_clip/clip_intern.h
source/blender/editors/space_clip/clip_ops.c
source/blender/editors/space_clip/space_clip.c
source/blender/editors/space_clip/tracking_ops.c
source/blender/editors/space_file/filelist.c
source/blender/editors/space_file/filesel.c
source/blender/editors/space_graph/graph_edit.c
source/blender/editors/space_image/image_draw.c
source/blender/editors/space_image/image_ops.c
source/blender/editors/space_info/info_ops.c
source/blender/editors/space_node/drawnode.c
source/blender/editors/space_node/node_edit.c
source/blender/editors/space_node/node_templates.c
source/blender/editors/space_node/space_node.c
source/blender/editors/space_outliner/outliner_draw.c
source/blender/editors/space_outliner/outliner_edit.c
source/blender/editors/space_outliner/outliner_intern.h
source/blender/editors/space_outliner/outliner_ops.c
source/blender/editors/space_outliner/outliner_select.c
source/blender/editors/space_outliner/space_outliner.c
source/blender/editors/space_script/script_edit.c
source/blender/editors/space_sequencer/sequencer_add.c
source/blender/editors/space_sequencer/sequencer_draw.c
source/blender/editors/space_sequencer/sequencer_edit.c
source/blender/editors/space_text/text_ops.c
source/blender/editors/space_time/space_time.c
source/blender/editors/space_view3d/drawarmature.c
source/blender/editors/space_view3d/drawmesh.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/drawvolume.c
source/blender/editors/space_view3d/space_view3d.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/editors/space_view3d/view3d_edit.c
source/blender/editors/space_view3d/view3d_fly.c
source/blender/editors/space_view3d/view3d_header.c
source/blender/editors/space_view3d/view3d_intern.h
source/blender/editors/space_view3d/view3d_select.c
source/blender/editors/space_view3d/view3d_view.c
source/blender/editors/util/ed_util.c
source/blender/editors/uvedit/uvedit_ops.c
source/blender/editors/uvedit/uvedit_smart_stitch.c
source/blender/editors/uvedit/uvedit_unwrap_ops.c
source/blender/imbuf/IMB_imbuf_types.h
source/blender/imbuf/intern/IMB_anim.h
source/blender/imbuf/intern/IMB_indexer.h
source/blender/imbuf/intern/divers.c
source/blender/makesdna/DNA_ID.h
source/blender/makesdna/DNA_brush_types.h
source/blender/makesdna/DNA_cloth_types.h
source/blender/makesdna/DNA_customdata_types.h
source/blender/makesdna/DNA_dynamicpaint_types.h
source/blender/makesdna/DNA_fileglobal_types.h
source/blender/makesdna/DNA_image_types.h
source/blender/makesdna/DNA_modifier_types.h
source/blender/makesdna/DNA_movieclip_types.h
source/blender/makesdna/DNA_node_types.h
source/blender/makesdna/DNA_object_fluidsim.h
source/blender/makesdna/DNA_object_force.h
source/blender/makesdna/DNA_scene_types.h
source/blender/makesdna/DNA_sequence_types.h
source/blender/makesdna/DNA_smoke_types.h
source/blender/makesdna/DNA_sound_types.h
source/blender/makesdna/DNA_space_types.h
source/blender/makesdna/DNA_texture_types.h
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesdna/DNA_vfont_types.h
source/blender/makesrna/intern/SConscript
source/blender/makesrna/intern/rna_access.c
source/blender/makesrna/intern/rna_cloth.c
source/blender/makesrna/intern/rna_controller.c
source/blender/makesrna/intern/rna_fluidsim.c
source/blender/makesrna/intern/rna_mesh.c
source/blender/makesrna/intern/rna_modifier.c
source/blender/makesrna/intern/rna_nodetree.c
source/blender/makesrna/intern/rna_nodetree_types.h
source/blender/makesrna/intern/rna_object_api.c
source/blender/makesrna/intern/rna_render.c
source/blender/makesrna/intern/rna_scene.c
source/blender/makesrna/intern/rna_scene_api.c
source/blender/makesrna/intern/rna_sculpt_paint.c
source/blender/makesrna/intern/rna_sensor.c
source/blender/makesrna/intern/rna_space.c
source/blender/makesrna/intern/rna_tracking.c
source/blender/makesrna/intern/rna_userdef.c
source/blender/modifiers/intern/MOD_boolean_util.c
source/blender/modifiers/intern/MOD_build.c
source/blender/modifiers/intern/MOD_dynamicpaint.c
source/blender/modifiers/intern/MOD_fluidsim_util.c
source/blender/modifiers/intern/MOD_solidify.c
source/blender/modifiers/intern/MOD_weightvgedit.c
source/blender/modifiers/intern/MOD_weightvgmix.c
source/blender/modifiers/intern/MOD_weightvgproximity.c
source/blender/nodes/CMakeLists.txt
source/blender/nodes/NOD_shader.h
source/blender/nodes/NOD_socket.h
source/blender/nodes/composite/node_composite_tree.c
source/blender/nodes/composite/nodes/node_composite_image.c
source/blender/nodes/intern/node_common.c
source/blender/nodes/intern/node_socket.c
source/blender/nodes/shader/nodes/node_shader_brightness.c [new file with mode: 0644]
source/blender/nodes/shader/nodes/node_shader_gamma.c
source/blender/python/intern/bpy_props.c
source/blender/python/intern/bpy_rna.c
source/blender/python/mathutils/mathutils_Matrix.c
source/blender/quicktime/quicktime_export.h
source/blender/render/extern/include/RE_shader_ext.h
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/imagetexture.c
source/blender/render/intern/source/occlusion.c
source/blender/render/intern/source/pixelshading.c
source/blender/render/intern/source/rayshade.c
source/blender/render/intern/source/render_result.c
source/blender/render/intern/source/render_texture.c
source/blender/render/intern/source/rendercore.c
source/blender/render/intern/source/shadbuf.c
source/blender/render/intern/source/shadeinput.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_operators.c
source/blenderplayer/bad_level_call_stubs/stubs.c
source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp
source/gameengine/BlenderRoutines/KX_BlenderCanvas.h
source/gameengine/Converter/BL_ActionActuator.cpp
source/gameengine/Converter/KX_ConvertActuators.cpp
source/gameengine/GameLogic/SCA_PythonKeyboard.cpp
source/gameengine/GameLogic/SCA_PythonKeyboard.h
source/gameengine/GameLogic/SCA_PythonMouse.cpp
source/gameengine/GameLogic/SCA_PythonMouse.h
source/gameengine/GamePlayer/common/GPC_Canvas.h
source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp
source/gameengine/GamePlayer/ghost/GPG_Canvas.h
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_GameObject.h
source/gameengine/Ketsji/KX_PythonInit.cpp
source/gameengine/Rasterizer/RAS_ICanvas.h
source/gameengine/VideoTexture/blendVideoTex.cpp
source/tests/bl_mesh_modifiers.py

index 8720cb83054c8be369c64abdfd6321c83e03873d..6c13f3a079a12826d46a01a86468be393b71ef45 100644 (file)
@@ -37,7 +37,8 @@ CHECKER_BIN = "cppcheck"
 CHECKER_ARGS = [
     # not sure why this is needed, but it is.
     "-I" + os.path.join(project_source_info.SOURCE_DIR, "extern", "glew", "include"),
-
+       "--suppress=*:%s/extern/glew/include/GL/glew.h:241" % project_source_info.SOURCE_DIR,
+    # "--max-configs=1",  # speeds up execution
     #  "--check-config", # when includes are missing
     #  "--enable=all",  # if you want sixty hundred pedantic suggestions
     ]
index e9195fe207de47abf5d3dc466a4d6e87c7ed70a9..f8d9eb8b3e1902124ff653afb9c95584d146bed8 100644 (file)
@@ -272,7 +272,7 @@ def setup_syslibs(lenv):
         syslibs += Split(lenv['BF_PTHREADS_LIB'])
     if lenv['WITH_BF_COLLADA']:
         syslibs.append(lenv['BF_PCRE_LIB'])
-        if lenv['BF_DEBUG']:
+        if lenv['BF_DEBUG'] and (lenv['OURPLATFORM'] != 'linux'):
             syslibs += [colladalib+'_d' for colladalib in Split(lenv['BF_OPENCOLLADA_LIB'])]
         else:
             syslibs += Split(lenv['BF_OPENCOLLADA_LIB'])
index de2f7e0a39daf5ab23586fb1727fa201481a034a..e76fc3dd13b9190c36019ec44fa42b2adf52c49c 100644 (file)
@@ -1,6 +1,6 @@
 """
 Basic Physics Constraint
-++++++++++++++++++++++
+++++++++++++++++++++++++
 Example of how to create a hinge Physics Constraint between two objects.
 """
 from bge import logic
index 918ffc9772d66e9a8ae33d09841588c424651b5a..fba369739f7e30897d466015772e07722e78909c 100644 (file)
@@ -1,6 +1,6 @@
 """
-Texture replacement
-++++++++++++++++++++++
+Texture Replacement
++++++++++++++++++++
 Example of how to replace a texture in game with an external image.
 createTexture() and removeTexture() are to be called from a module Python
 Controller.
index 70e4d6d9377f42d281d2fa2ab0f178940ca099c1..1ba0b99fc27a05fda78557e8d85fba175fbd52b5 100644 (file)
@@ -1,6 +1,6 @@
 """
 Basic Video Playback
-++++++++++++++++++++++
+++++++++++++++++++++
 Example of how to replace a texture in game with a video. It needs to run everyframe
 """
 import bge
index da0a358dfed472e6cd6944a06aa8807e9a14df26..83f2a6b4950febcaaf36fa80279302e7f1140dec 100644 (file)
@@ -5,6 +5,11 @@ Physics Constraints (bge.constraints)
 .. module:: bge.constraints
 
 .. literalinclude:: ../examples/bge.constraints.py
+   :language: rest
+   :lines: 2-4
+
+.. literalinclude:: ../examples/bge.constraints.py
+   :lines: 6-
 
 .. function:: createConstraint(physicsid, physicsid2, constrainttype, [pivotX, pivotY, pivotZ, [axisX, axisY, axisZ, [flag]]]])
 
index eeb50a833ffbd2577b8b141146041f3108450e72..ddc05ac1d8c425127bf5415337206ccdb822fd38 100644 (file)
@@ -77,6 +77,14 @@ Functions
    
    :rtype: integer
 
+.. function:: setWindowSize(width, height)
+
+   Set the width and height of the window (in pixels). This also works for fullscreen applications.
+   
+   :type width: integer
+   :type height: integer
+
+
 .. function:: makeScreenshot(filename)
 
    Writes a screenshot to the given filename.
index 0abefcbea82e4d66ddcbb736e61eb163ee0068ba..07d83f66bd4de077a03fbcc66f89cbb1a6008f24 100644 (file)
@@ -37,8 +37,18 @@ When the texture object is deleted, the new texture is deleted and the old textu
 .. module:: bge.texture
 
 .. literalinclude:: ../examples/bge.texture.py
+   :language: rest
+   :lines: 2-4
+
+.. literalinclude:: ../examples/bge.texture.py
+   :lines: 6-
+
+.. literalinclude:: ../examples/bge.texture.1.py
+   :language: rest
+   :lines: 2-6
 
 .. literalinclude:: ../examples/bge.texture.1.py
+   :lines: 8-
 
 .. class:: VideoFFmpeg(file [, capture=-1, rate=25.0, width=0, height=0])
 
index f97c95babc9a958fe518eac8a1d40a12bb687ff8..735ad037175a73ef91034b2e84c26add95c2b082 100644 (file)
@@ -66,6 +66,12 @@ Game Types (bge.types)
 
       :type: dictionary {:ref:`keycode<keyboard-keys>`::ref:`status<input-status>`, ...}
 
+   .. attribute:: active_events
+
+      A dictionary containing the status of only the active keyboard events or keys. (read-only).
+
+      :type: dictionary {:ref:`keycode<keyboard-keys>`::ref:`status<input-status>`, ...}
+
 .. class:: SCA_PythonMouse(PyObjectPlus)
 
    The current mouse.
@@ -75,6 +81,12 @@ Game Types (bge.types)
       a dictionary containing the status of each mouse event. (read-only).
 
       :type: dictionary {:ref:`keycode<mouse-keys>`::ref:`status<input-status>`, ...}
+
+   .. attribute:: active_events
+
+      a dictionary containing the status of only the active mouse events. (read-only).
+
+      :type: dictionary {:ref:`keycode<mouse-keys>`::ref:`status<input-status>`, ...}
       
    .. attribute:: position
 
@@ -942,7 +954,7 @@ Game Types (bge.types)
 
       .. deprecated:: use :data:`localPosition` and :data:`worldPosition`.
 
-      :type: :class:`mathurils.Vector`
+      :type: :class:`mathutils.Vector`
 
    .. attribute:: orientation
 
@@ -980,7 +992,7 @@ Game Types (bge.types)
 
    .. attribute:: worldScale
 
-      The object's world scaling factor. Read-only. [sx, sy, sz]
+      The object's world scaling factor. [sx, sy, sz]
 
       :type: :class:`mathutils.Vector`
 
@@ -995,6 +1007,18 @@ Game Types (bge.types)
       The object's world position. [x, y, z]
 
       :type: :class:`mathutils.Vector`
+
+   .. attribute:: localTransform
+
+      The object's local space transform matrix. 4x4 Matrix.
+
+      :type: :class:`mathutils.Matrix`
+
+   .. attribute:: worldTransform
+
+      The object's world space transform matrix. 4x4 Matrix.
+
+      :type: :class:`mathutils.Matrix`
          
    .. attribute:: localLinearVelocity
       
index 49c0d8905b0cc6ea37102211019f376e7a98fd5b..102bf9e4034d29ba8569ff5a2b8a29b8e503495b 100644 (file)
@@ -2,14 +2,14 @@
 /* src/config.h.in.  Generated from configure.ac by autoheader.  */
 
 /* Namespace for Google classes */
-#ifdef __APPLE__
+#if defined(__APPLE__)
  #include "config_mac.h"
-#elif __FreeBSD__
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
  #include "config_freebsd.h"
-#elif __MINGW32__
+#elif defined(__MINGW32__)
  #include "windows/config.h"
-#elif __GNUC__
+#elif defined(__linux__)
  #include "config_linux.h"
-#elif _MSC_VER
+#elif defined(_MSC_VER)
  #include "windows/config.h"
 #endif
index ffd4e778de6eaeece0be56ed905545f059ac99c4..faf032949bb49e9c991037162cc1cd84a9e0e684 100644 (file)
 /* How to access the PC from a struct ucontext */
 #if defined(_M_X64) || defined(__amd64__) || defined(__x86_64__)
   #define PC_FROM_UCONTEXT uc_mcontext.gregs[REG_RIP]
-#else
+#elif defined(_M_IX86) || defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)
   #define PC_FROM_UCONTEXT uc_mcontext.gregs[REG_EIP]
+#else
+  #undef PC_FROM_UCONTEXT
 #endif
 
 /* Define to necessary symbol if this constant uses a non-standard name on
index 0efed532cb90326d40290969fa4166316deb103c..1c8c912614dd6e1f2dda14d68e8a9cb639a43c72 100644 (file)
@@ -8,6 +8,7 @@ incs += ' ../../source/blender/blenlib'
 defs = []
 
 if not env['WITH_BF_CARVE']:
+    import os
     sources = env.Glob('intern/*.cpp')
     sources.remove('intern' + os.sep + 'BOP_CarveInterface.cpp')
 else:
index 4db4fdd819d89339895cf1154f2cdf7c13f5d112..274d9cac0cf2bbd495df29374d6096d50c7106dd 100644 (file)
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * The Original Code is Copyright (C) 2010 by the Blender Foundation.
  * All rights reserved.
  *
  * The Original Code is: all of this file.
  *
- * Contributor(s): none yet.
+ * Contributor(s): Ken Hughes,
+ *                 Sergey Sharybin.
  *
  * ***** END GPL LICENSE BLOCK *****
  */
@@ -36,6 +37,9 @@
 #include <carve/interpolator.hpp>
 #include <carve/rescale.hpp>
 
+#include <iostream>
+
+using namespace carve::mesh;
 typedef unsigned int uint;
 
 #define MAX(x,y) ((x)>(y)?(x):(y))
@@ -61,10 +65,161 @@ static int isFacePlanar(CSG_IFace &face, std::vector<carve::geom3d::Vector> &ver
        return 1;
 }
 
-static carve::mesh::MeshSet<3> *Carve_addMesh(CSG_FaceIteratorDescriptor& face_it,
-                                              CSG_VertexIteratorDescriptor& vertex_it,
-                                              carve::interpolate::FaceAttr<uint> &oface_num,
-                                              uint &num_origfaces )
+static MeshSet<3> *Carve_meshSetFromMeshes(std::vector<MeshSet<3>::mesh_t*> &meshes)
+{
+       std::vector<MeshSet<3>::mesh_t*> new_meshes;
+
+       std::vector<MeshSet<3>::mesh_t*>::iterator it = meshes.begin();
+       for(; it!=meshes.end(); it++) {
+               MeshSet<3>::mesh_t *mesh = *it;
+               MeshSet<3>::mesh_t *new_mesh = new MeshSet<3>::mesh_t(mesh->faces);
+
+               new_meshes.push_back(new_mesh);
+       }
+
+       return new MeshSet<3>(new_meshes);
+}
+
+static void Carve_getIntersectedOperandMeshes(std::vector<MeshSet<3>::mesh_t*> &meshes,
+                                              std::vector<MeshSet<3>::aabb_t> &precomputedAABB,
+                                              MeshSet<3>::aabb_t &otherAABB,
+                                              std::vector<MeshSet<3>::mesh_t*> &operandMeshes)
+{
+       std::vector<MeshSet<3>::mesh_t*>::iterator it = meshes.begin();
+       std::vector<MeshSet<3>::aabb_t>::iterator aabb_it = precomputedAABB.begin();
+       std::vector<MeshSet<3>::aabb_t> usedAABB;
+
+       while(it != meshes.end()) {
+               MeshSet<3>::mesh_t *mesh = *it;
+               MeshSet<3>::aabb_t aabb = mesh->getAABB();
+               bool isIntersect = false;
+
+               std::vector<MeshSet<3>::aabb_t>::iterator used_it = usedAABB.begin();
+               for(; used_it!=usedAABB.end(); used_it++) {
+                       MeshSet<3>::aabb_t usedAABB = *used_it;
+
+                       if(usedAABB.intersects(aabb) && usedAABB.intersects(otherAABB)) {
+                               isIntersect = true;
+                               break;
+                       }
+               }
+
+               if(!isIntersect) {
+                       operandMeshes.push_back(mesh);
+                       usedAABB.push_back(aabb);
+
+                       it = meshes.erase(it);
+                       aabb_it = precomputedAABB.erase(aabb_it);
+               }
+               else {
+                       it++;
+                       aabb_it++;
+               }
+       }
+}
+
+static MeshSet<3> *Carve_getIntersectedOperand(std::vector<MeshSet<3>::mesh_t*> &meshes,
+                                               std::vector<MeshSet<3>::aabb_t> &precomputedAABB,
+                                               MeshSet<3>::aabb_t &otherAABB)
+{
+       std::vector<MeshSet<3>::mesh_t*> operandMeshes;
+       Carve_getIntersectedOperandMeshes(meshes, precomputedAABB, otherAABB, operandMeshes);
+
+       return Carve_meshSetFromMeshes(operandMeshes);
+}
+
+static MeshSet<3> *Carve_unionIntersectingMeshes(MeshSet<3> *poly,
+                                                 std::vector<MeshSet<3>::aabb_t> &precomputedAABB,
+                                                 MeshSet<3>::aabb_t &otherAABB,
+                                                 carve::interpolate::FaceAttr<uint> &oface_num)
+{
+       if(poly->meshes.size()<=1)
+               return poly;
+
+       carve::csg::CSG csg;
+
+       oface_num.installHooks(csg);
+       csg.hooks.registerHook(new carve::csg::CarveTriangulator, carve::csg::CSG::Hooks::PROCESS_OUTPUT_FACE_BIT);
+
+       std::vector<MeshSet<3>::mesh_t*> orig_meshes =
+                       std::vector<MeshSet<3>::mesh_t*>(poly->meshes.begin(), poly->meshes.end());
+
+       MeshSet<3> *left = Carve_getIntersectedOperand(orig_meshes, precomputedAABB, otherAABB);
+
+       while(orig_meshes.size()) {
+               MeshSet<3> *right = Carve_getIntersectedOperand(orig_meshes, precomputedAABB, otherAABB);
+
+               try {
+                       MeshSet<3> *result = csg.compute(left, right, carve::csg::CSG::UNION, NULL, carve::csg::CSG::CLASSIFY_EDGE);
+
+                       delete left;
+                       delete right;
+
+                       left = result;
+               }
+               catch(carve::exception e) {
+                       std::cerr << "CSG failed, exception " << e.str() << std::endl;
+
+                       delete right;
+               }
+               catch(...) {
+                       delete left;
+                       delete right;
+
+                       throw "Unknown error in Carve library";
+               }
+       }
+
+       return left;
+}
+
+static MeshSet<3>::aabb_t Carve_computeAABB(MeshSet<3> *poly,
+                                            std::vector<MeshSet<3>::aabb_t> &precomputedAABB)
+{
+       MeshSet<3>::aabb_t overallAABB;
+       std::vector<MeshSet<3>::mesh_t*>::iterator it = poly->meshes.begin();
+
+       for(; it!=poly->meshes.end(); it++) {
+               MeshSet<3>::aabb_t aabb;
+               MeshSet<3>::mesh_t *mesh = *it;
+
+               aabb = mesh->getAABB();
+               precomputedAABB.push_back(aabb);
+
+               overallAABB.unionAABB(aabb);
+       }
+
+       return overallAABB;
+}
+
+static void Carve_prepareOperands(MeshSet<3> **left_r, MeshSet<3> **right_r,
+                                  carve::interpolate::FaceAttr<uint> &oface_num)
+{
+       MeshSet<3> *left, *right;
+
+       std::vector<MeshSet<3>::aabb_t> left_precomputedAABB;
+       std::vector<MeshSet<3>::aabb_t> right_precomputedAABB;
+
+       MeshSet<3>::aabb_t leftAABB = Carve_computeAABB(*left_r, left_precomputedAABB);
+       MeshSet<3>::aabb_t rightAABB = Carve_computeAABB(*right_r, right_precomputedAABB);
+
+       left = Carve_unionIntersectingMeshes(*left_r, left_precomputedAABB, rightAABB, oface_num);
+       right = Carve_unionIntersectingMeshes(*right_r, right_precomputedAABB, leftAABB, oface_num);
+
+       if(left != *left_r)
+               delete *left_r;
+
+       if(right != *right_r)
+               delete *right_r;
+
+       *left_r = left;
+       *right_r = right;
+}
+
+static MeshSet<3> *Carve_addMesh(CSG_FaceIteratorDescriptor &face_it,
+                                 CSG_VertexIteratorDescriptor &vertex_it,
+                                 carve::interpolate::FaceAttr<uint> &oface_num,
+                                 uint &num_origfaces)
 {
        CSG_IVertex vertex;
        std::vector<carve::geom3d::Vector> vertices;
@@ -126,12 +281,12 @@ static carve::mesh::MeshSet<3> *Carve_addMesh(CSG_FaceIteratorDescriptor& face_i
                }
        }
 
-       carve::mesh::MeshSet<3> *poly = new carve::mesh::MeshSet<3> (vertices, numfaces, f);
+       MeshSet<3> *poly = new MeshSet<3> (vertices, numfaces, f);
 
        uint i;
-       carve::mesh::MeshSet<3>::face_iter face_iter = poly->faceBegin();
+       MeshSet<3>::face_iter face_iter = poly->faceBegin();
        for (i = 0; face_iter != poly->faceEnd(); ++face_iter, ++i) {
-               carve::mesh::MeshSet<3>::face_t *face = *face_iter;
+               MeshSet<3>::face_t *face = *face_iter;
                oface_num.setAttribute(face, forig[i]);
        }
 
@@ -139,8 +294,8 @@ static carve::mesh::MeshSet<3> *Carve_addMesh(CSG_FaceIteratorDescriptor& face_i
 }
 
 // check whether two faces share an edge, and if so merge them
-static uint quadMerge(std::map<carve::mesh::MeshSet<3>::vertex_t*, uint> *vertexToIndex_map,
-                      carve::mesh::MeshSet<3>::face_t *f1, carve::mesh::MeshSet<3>::face_t *f2,
+static uint quadMerge(std::map<MeshSet<3>::vertex_t*, uint> *vertexToIndex_map,
+                      MeshSet<3>::face_t *f1, MeshSet<3>::face_t *f2,
                       uint v, uint quad[4])
 {
        uint current, n1, p1, n2, p2;
@@ -188,23 +343,23 @@ static uint quadMerge(std::map<carve::mesh::MeshSet<3>::vertex_t*, uint> *vertex
        return 0;
 }
 
-static BSP_CSGMesh* Carve_exportMesh(carve::mesh::MeshSet<3>* &poly, carve::interpolate::FaceAttr<uint> &oface_num,
+static BSP_CSGMesh *Carve_exportMesh(MeshSet<3>* &poly, carve::interpolate::FaceAttr<uint> &oface_num,
                                      uint num_origfaces)
 {
        uint i;
-       BSP_CSGMeshoutputMesh = BSP_CSGMesh::New();
+       BSP_CSGMesh *outputMesh = BSP_CSGMesh::New();
 
        if (outputMesh == NULL)
                return NULL;
 
-       std::vector<BSP_MVertex>vertices = new std::vector<BSP_MVertex>;
+       std::vector<BSP_MVertex> *vertices = new std::vector<BSP_MVertex>;
 
        outputMesh->SetVertices(vertices);
 
-       std::map<carve::mesh::MeshSet<3>::vertex_t*, uint> vertexToIndex_map;
-       std::vector<carve::mesh::MeshSet<3>::vertex_t>::iterator it = poly->vertex_storage.begin();
+       std::map<MeshSet<3>::vertex_t*, uint> vertexToIndex_map;
+       std::vector<MeshSet<3>::vertex_t>::iterator it = poly->vertex_storage.begin();
        for (i = 0; it != poly->vertex_storage.end(); ++i, ++it) {
-               carve::mesh::MeshSet<3>::vertex_t *vertex = &(*it);
+               MeshSet<3>::vertex_t *vertex = &(*it);
                vertexToIndex_map[vertex] = i;
        }
 
@@ -217,13 +372,13 @@ static BSP_CSGMesh* Carve_exportMesh(carve::mesh::MeshSet<3>* &poly, carve::inte
        }
 
        // build vectors of faces for each original face and each vertex 
-       std::vector< std::vector<uint> > vi(poly->vertex_storage.size());
-       std::vector< std::vector<uint> > ofaces(num_origfaces);
-       carve::mesh::MeshSet<3>::face_iter face_iter = poly->faceBegin();
+       std::vector<std::vector<uint> > vi(poly->vertex_storage.size());
+       std::vector<std::vector<uint> > ofaces(num_origfaces);
+       MeshSet<3>::face_iter face_iter = poly->faceBegin();
        for (i = 0; face_iter != poly->faceEnd(); ++face_iter, ++i) {
-               carve::mesh::MeshSet<3>::face_t *f = *face_iter;
+               MeshSet<3>::face_t *f = *face_iter;
                ofaces[oface_num.getAttribute(f)].push_back(i);
-               carve::mesh::MeshSet<3>::face_t::edge_iter_t edge_iter = f->begin();
+               MeshSet<3>::face_t::edge_iter_t edge_iter = f->begin();
                for (; edge_iter != f->end(); ++edge_iter) {
                        int index = vertexToIndex_map[edge_iter->vert];
                        vi[index].push_back(i);
@@ -242,7 +397,7 @@ static BSP_CSGMesh* Carve_exportMesh(carve::mesh::MeshSet<3>* &poly, carve::inte
                        uint findex = fl.back();
                        fl.pop_back();
 
-                       carve::mesh::MeshSet<3>::face_t *f = *(poly->faceBegin() + findex);
+                       MeshSet<3>::face_t *f = *(poly->faceBegin() + findex);
 
                        // add all information except vertices to the output mesh
                        outputMesh->FaceSet().push_back(BSP_MFace());
@@ -256,7 +411,7 @@ static BSP_CSGMesh* Carve_exportMesh(carve::mesh::MeshSet<3>* &poly, carve::inte
                        // the original face
                        uint result = 0;
 
-                       carve::mesh::MeshSet<3>::face_t::edge_iter_t edge_iter = f->begin();
+                       MeshSet<3>::face_t::edge_iter_t edge_iter = f->begin();
                        for (; edge_iter != f->end(); ++edge_iter) {
                                int v = vertexToIndex_map[edge_iter->vert];
                                for (uint pos2=0; !result && pos2 < vi[v].size();pos2++) {
@@ -266,7 +421,7 @@ static BSP_CSGMesh* Carve_exportMesh(carve::mesh::MeshSet<3>* &poly, carve::inte
                                        if (findex == otherf)
                                                continue;
 
-                                       carve::mesh::MeshSet<3>::face_t *f2 = *(poly->faceBegin() + otherf);
+                                       MeshSet<3>::face_t *f2 = *(poly->faceBegin() + otherf);
 
                                        // if other face doesn't have the same original face,
                                        // ignore it also
@@ -302,7 +457,7 @@ static BSP_CSGMesh* Carve_exportMesh(carve::mesh::MeshSet<3>* &poly, carve::inte
                                outFace.m_verts.push_back(quadverts[2]);
                                outFace.m_verts.push_back(quadverts[3]);
                        } else {
-                               carve::mesh::MeshSet<3>::face_t::edge_iter_t edge_iter = f->begin();
+                               MeshSet<3>::face_t::edge_iter_t edge_iter = f->begin();
                                for (; edge_iter != f->end(); ++edge_iter) {
                                        //int index = ofacevert_num.getAttribute(f, edge_iter.idx());
                                        int index = vertexToIndex_map[edge_iter->vert];
@@ -337,7 +492,7 @@ BoolOpState BOP_performBooleanOperation(BoolOpType                    opType,
                                         CSG_VertexIteratorDescriptor  obBVertices)
 {
        carve::csg::CSG::OP op;
-       carve::mesh::MeshSet<3> *left, *right, *output;
+       MeshSet<3> *left, *right, *output;
        carve::csg::CSG csg;
        carve::geom3d::Vector min, max;
        carve::interpolate::FaceAttr<uint> oface_num;
@@ -360,6 +515,8 @@ BoolOpState BOP_performBooleanOperation(BoolOpType                    opType,
        left = Carve_addMesh(obAFaces, obAVertices, oface_num, num_origfaces );
        right = Carve_addMesh(obBFaces, obBVertices, oface_num, num_origfaces );
 
+       Carve_prepareOperands(&left, &right, oface_num);
+
        min.x = max.x = left->vertex_storage[0].v.x;
        min.y = max.y = left->vertex_storage[0].v.y;
        min.z = max.z = left->vertex_storage[0].v.z;
@@ -390,13 +547,29 @@ BoolOpState BOP_performBooleanOperation(BoolOpType                    opType,
        csg.hooks.registerHook(new carve::csg::CarveTriangulator, carve::csg::CSG::Hooks::PROCESS_OUTPUT_FACE_BIT);
 
        oface_num.installHooks(csg);
-       output = csg.compute( left, right, op, NULL, carve::csg::CSG::CLASSIFY_EDGE);
+
+       try {
+               output = csg.compute(left, right, op, NULL, carve::csg::CSG::CLASSIFY_EDGE);
+       }
+       catch(carve::exception e) {
+               std::cerr << "CSG failed, exception " << e.str() << std::endl;
+       }
+       catch(...) {
+               delete left;
+               delete right;
+
+               throw "Unknown error in Carve library";
+       }
+
        delete left;
        delete right;
 
+       if(!output)
+               return BOP_ERROR;
+
        output->transform(rev_r);
 
-       *outputMesh = Carve_exportMesh( output, oface_num, num_origfaces);
+       *outputMesh = Carve_exportMesh(output, oface_num, num_origfaces);
        delete output;
 
        return BOP_OK;
index af52520d87c37980ebd786eec76cb736815b2106..5e4b3da071dcf67b9ef21bd754eebbc86474886a 100644 (file)
@@ -462,6 +462,9 @@ static void xml_read_shader_graph(const XMLReadState& state, Shader *shader, pug
                else if(string_iequals(node.name(), "gamma")) {
                        snode = new GammaNode();
                }
+               else if(string_iequals(node.name(), "brightness")) {
+                       snode = new BrightContrastNode();
+               }
                else if(string_iequals(node.name(), "combine_rgb")) {
                        snode = new CombineRGBNode();
                }
index 0a3cffd5071a46ec227fe4739129c33939398236..7e7e83b4f69b99f2e6247e5b1b81d58581780f97 100644 (file)
@@ -33,78 +33,189 @@ from . import enums
 class CyclesRenderSettings(bpy.types.PropertyGroup):
     @classmethod
     def register(cls):
-        bpy.types.Scene.cycles = PointerProperty(type=cls, name="Cycles Render Settings", description="Cycles render settings")
-
-        cls.device = EnumProperty(name="Device", description="Device to use for rendering",
-            items=enums.devices, default="CPU")
-
-        cls.feature_set = EnumProperty(name="Feature Set", description="Feature set to use for rendering",
-            items=enums.feature_set, default="SUPPORTED")
-
-        cls.shading_system = EnumProperty(name="Shading System", description="Shading system to use for rendering",
-            items=enums.shading_systems, default="GPU_COMPATIBLE")
-
-        cls.samples = IntProperty(name="Samples", description="Number of samples to render for each pixel",
-            default=10, min=1, max=2147483647)
-        cls.preview_samples = IntProperty(name="Preview Samples", description="Number of samples to render in the viewport, unlimited if 0",
-            default=10, min=0, max=2147483647)
-        cls.preview_pause = BoolProperty(name="Pause Preview", description="Pause all viewport preview renders",
-            default=False)
-
-        cls.no_caustics = BoolProperty(name="No Caustics", description="Leave out caustics, resulting in a darker image with less noise",
-            default=False)
-        cls.blur_caustics = FloatProperty(name="Blur Caustics", description="Blur caustics to reduce noise",
-            default=0.0, min=0.0, max=1.0)
-
-        cls.min_bounces = IntProperty(name="Min Bounces", description="Minimum number of bounces, setting this lower than the maximum enables probalistic path termination (faster but noisier)",
-            default=3, min=0, max=1024)
-        cls.max_bounces = IntProperty(name="Max Bounces", description="Total maximum number of bounces",
-            default=8, min=0, max=1024)
-
-        cls.diffuse_bounces = IntProperty(name="Diffuse Bounces", description="Maximum number of diffuse reflection bounces, bounded by total maximum",
-            default=128, min=0, max=1024)
-        cls.glossy_bounces = IntProperty(name="Glossy Bounces", description="Maximum number of glossy reflection bounces, bounded by total maximum",
-            default=128, min=0, max=1024)
-        cls.transmission_bounces = IntProperty(name="Transmission Bounces", description="Maximum number of transmission bounces, bounded by total maximum",
-            default=128, min=0, max=1024)
-
-        cls.transparent_min_bounces = IntProperty(name="Transparent Min Bounces", description="Minimum number of transparent bounces, setting this lower than the maximum enables probalistic path termination (faster but noisier)",
-            default=8, min=0, max=1024)
-        cls.transparent_max_bounces = IntProperty(name="Transparent Max Bounces", description="Maximum number of transparent bounces",
-            default=8, min=0, max=1024)
-        cls.use_transparent_shadows = BoolProperty(name="Transparent Shadows", description="Use transparency of surfaces for rendering shadows",
-            default=True)
-
-        cls.film_exposure = FloatProperty(name="Exposure", description="Image brightness scale",
-            default=1.0, min=0.0, max=10.0)
-        cls.film_transparent = BoolProperty(name="Transparent", description="World background is transparent",
-            default=False)
-
-        cls.filter_type = EnumProperty(name="Filter Type", description="Pixel filter type",
-            items=enums.filter_types, default="GAUSSIAN")
-        cls.filter_width = FloatProperty(name="Filter Width", description="Pixel filter width",
-            default=1.5, min=0.01, max=10.0)
-
-        cls.seed = IntProperty(name="Seed", description="Seed value for integrator to get different noise patterns",
-            default=0, min=0, max=2147483647)
-
-        cls.debug_tile_size = IntProperty(name="Tile Size", description="",
-            default=1024, min=1, max=4096)
-        cls.debug_min_size = IntProperty(name="Min Size", description="",
-            default=64, min=1, max=4096)
-        cls.debug_reset_timeout = FloatProperty(name="Reset timeout", description="",
-            default=0.1, min=0.01, max=10.0)
-        cls.debug_cancel_timeout = FloatProperty(name="Cancel timeout", description="",
-            default=0.1, min=0.01, max=10.0)
-        cls.debug_text_timeout = FloatProperty(name="Text timeout", description="",
-            default=1.0, min=0.01, max=10.0)
-
-        cls.debug_bvh_type = EnumProperty(name="Viewport BVH Type", description="Choose between faster updates, or faster render",
-            items=enums.bvh_types, default="DYNAMIC_BVH")
-        cls.debug_use_spatial_splits = BoolProperty(name="Use Spatial Splits", description="Use BVH spatial splits: longer builder time, faster render",
-            default=False)
-        cls.use_cache = BoolProperty(name="Cache BVH", description="Cache last built BVH to disk for faster re-render if no geometry changed",
-            default=False)
+        bpy.types.Scene.cycles = PointerProperty(
+                name="Cycles Render Settings",
+                description="Cycles render settings",
+                type=cls,
+                )
+        cls.device = EnumProperty(
+                name="Device",
+                description="Device to use for rendering",
+                items=enums.devices,
+                default='CPU',
+                )
+        cls.feature_set = EnumProperty(
+                name="Feature Set",
+                description="Feature set to use for rendering",
+                items=enums.feature_set,
+                default='SUPPORTED',
+                )
+        cls.shading_system = EnumProperty(
+                name="Shading System",
+                description="Shading system to use for rendering",
+                items=enums.shading_systems,
+                default='GPU_COMPATIBLE',
+                )
+
+        cls.samples = IntProperty(
+                name="Samples",
+                description="Number of samples to render for each pixel",
+                min=1, max=2147483647,
+                default=10,
+                )
+        cls.preview_samples = IntProperty(
+                name="Preview Samples",
+                description="Number of samples to render in the viewport, unlimited if 0",
+                min=0, max=2147483647,
+                default=10,
+                )
+        cls.preview_pause = BoolProperty(
+                name="Pause Preview",
+                description="Pause all viewport preview renders",
+                default=False,
+                )
+
+        cls.no_caustics = BoolProperty(
+                name="No Caustics",
+                description="Leave out caustics, resulting in a darker image with less noise",
+                default=False,
+                )
+        cls.blur_caustics = FloatProperty(
+                name="Blur Caustics",
+                description="Blur caustics to reduce noise",
+                min=0.0, max=1.0,
+                default=0.0,
+                )
+
+        cls.min_bounces = IntProperty(
+                name="Min Bounces",
+                description="Minimum number of bounces, setting this lower than the maximum enables probalistic path termination (faster but noisier)",
+                min=0, max=1024,
+                default=3,
+                )
+        cls.max_bounces = IntProperty(
+                name="Max Bounces",
+                description="Total maximum number of bounces",
+                min=0, max=1024,
+                default=8,
+                )
+
+        cls.diffuse_bounces = IntProperty(
+                name="Diffuse Bounces",
+                description="Maximum number of diffuse reflection bounces, bounded by total maximum",
+                min=0, max=1024,
+                default=128,
+                )
+        cls.glossy_bounces = IntProperty(
+                name="Glossy Bounces",
+                description="Maximum number of glossy reflection bounces, bounded by total maximum",
+                min=0, max=1024,
+                default=128,
+                )
+        cls.transmission_bounces = IntProperty(
+                name="Transmission Bounces",
+                description="Maximum number of transmission bounces, bounded by total maximum",
+                min=0, max=1024,
+                default=128,
+                )
+
+        cls.transparent_min_bounces = IntProperty(
+                name="Transparent Min Bounces",
+                description="Minimum number of transparent bounces, setting this lower than the maximum enables probalistic path termination (faster but noisier)",
+                min=0, max=1024,
+                default=8,
+                )
+        cls.transparent_max_bounces = IntProperty(
+                name="Transparent Max Bounces",
+                description="Maximum number of transparent bounces",
+                min=0, max=1024,
+                default=8,
+                )
+        cls.use_transparent_shadows = BoolProperty(
+                name="Transparent Shadows",
+                description="Use transparency of surfaces for rendering shadows",
+                default=True,
+                )
+
+        cls.film_exposure = FloatProperty(
+                name="Exposure",
+                description="Image brightness scale",
+                min=0.0, max=10.0,
+                default=1.0,
+                )
+        cls.film_transparent = BoolProperty(
+                name="Transparent",
+                description="World background is transparent",
+                default=False,
+                )
+
+        cls.filter_type = EnumProperty(
+                name="Filter Type",
+                description="Pixel filter type",
+                items=enums.filter_types,
+                default='GAUSSIAN',
+                )
+        cls.filter_width = FloatProperty(
+                name="Filter Width",
+                description="Pixel filter width",
+                min=0.01, max=10.0,
+                default=1.5,
+                )
+
+        cls.seed = IntProperty(
+                name="Seed",
+                description="Seed value for integrator to get different noise patterns",
+                min=0, max=2147483647,
+                default=0,
+                )
+
+        cls.debug_tile_size = IntProperty(
+                name="Tile Size",
+                description="",
+                min=1, max=4096,
+                default=1024,
+                )
+        cls.debug_min_size = IntProperty(
+                name="Min Size",
+                description="",
+                min=1, max=4096,
+                default=64,
+                )
+        cls.debug_reset_timeout = FloatProperty(
+                name="Reset timeout",
+                description="",
+                min=0.01, max=10.0,
+                default=0.1,
+                )
+        cls.debug_cancel_timeout = FloatProperty(
+                name="Cancel timeout",
+                description="",
+                min=0.01, max=10.0,
+                default=0.1,
+                )
+        cls.debug_text_timeout = FloatProperty(
+                name="Text timeout",
+                description="",
+                min=0.01, max=10.0,
+                default=1.0,
+                )
+
+        cls.debug_bvh_type = EnumProperty(
+                name="Viewport BVH Type",
+                description="Choose between faster updates, or faster render",
+                items=enums.bvh_types,
+                default='DYNAMIC_BVH',
+                )
+        cls.debug_use_spatial_splits = BoolProperty(
+                name="Use Spatial Splits",
+                description="Use BVH spatial splits: longer builder time, faster render",
+                default=False,
+                )
+        cls.use_cache = BoolProperty(
+                name="Cache BVH",
+                description="Cache last built BVH to disk for faster re-render if no geometry changed",
+                default=False,
+                )
 
     @classmethod
     def unregister(cls):
@@ -114,14 +225,31 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
 class CyclesCameraSettings(bpy.types.PropertyGroup):
     @classmethod
     def register(cls):
-        bpy.types.Camera.cycles = PointerProperty(type=cls, name="Cycles Camera Settings", description="Cycles camera settings")
-
-        cls.aperture_size = FloatProperty(name="Aperture Size", description="Radius of the aperture for depth of field",
-            default=0.0, min=0.0, max=10.0)
-        cls.aperture_blades = IntProperty(name="Aperture Blades", description="Number of blades in aperture for polygonal bokeh (at least 3)",
-            default=0, min=0, max=100)
-        cls.aperture_rotation = FloatProperty(name="Aperture Rotation", description="Rotation of blades in aperture",
-            default=0, soft_min=-math.pi, soft_max=math.pi, subtype='ANGLE')
+        bpy.types.Camera.cycles = PointerProperty(
+                name="Cycles Camera Settings",
+                description="Cycles camera settings",
+                type=cls,
+                )
+
+        cls.aperture_size = FloatProperty(
+                name="Aperture Size",
+                description="Radius of the aperture for depth of field",
+                min=0.0, max=10.0,
+                default=0.0,
+                )
+        cls.aperture_blades = IntProperty(
+                name="Aperture Blades",
+                description="Number of blades in aperture for polygonal bokeh (at least 3)",
+                min=0, max=100,
+                default=0,
+                )
+        cls.aperture_rotation = FloatProperty(
+                name="Aperture Rotation",
+                description="Rotation of blades in aperture",
+                soft_min=-math.pi, soft_max=math.pi,
+                subtype='ANGLE',
+                default=0,
+                )
 
     @classmethod
     def unregister(cls):
@@ -131,9 +259,21 @@ class CyclesCameraSettings(bpy.types.PropertyGroup):
 class CyclesMaterialSettings(bpy.types.PropertyGroup):
     @classmethod
     def register(cls):
-        bpy.types.Material.cycles = PointerProperty(type=cls, name="Cycles Material Settings", description="Cycles material settings")
-        cls.sample_as_light = BoolProperty(name="Sample as Lamp", description="Use direct light sampling for this material, disabling may reduce overall noise for large objects that emit little light compared to other light sources", default=True)
-        cls.homogeneous_volume = BoolProperty(name="Homogeneous Volume", description="When using volume rendering, assume volume has the same density everywhere, for faster rendering", default=False)
+        bpy.types.Material.cycles = PointerProperty(
+                name="Cycles Material Settings",
+                description="Cycles material settings",
+                type=cls,
+                )
+        cls.sample_as_light = BoolProperty(
+                name="Sample as Lamp",
+                description="Use direct light sampling for this material, disabling may reduce overall noise for large objects that emit little light compared to other light sources",
+                default=True,
+                )
+        cls.homogeneous_volume = BoolProperty(
+                name="Homogeneous Volume",
+                description="When using volume rendering, assume volume has the same density everywhere, for faster rendering",
+                default=False,
+                )
 
     @classmethod
     def unregister(cls):
@@ -143,8 +283,16 @@ class CyclesMaterialSettings(bpy.types.PropertyGroup):
 class CyclesLampSettings(bpy.types.PropertyGroup):
     @classmethod
     def register(cls):
-        bpy.types.Lamp.cycles = PointerProperty(type=cls, name="Cycles Lamp Settings", description="Cycles lamp settings")
-        cls.cast_shadow = BoolProperty(name="Cast Shadow", description="Lamp casts shadows", default=True)
+        bpy.types.Lamp.cycles = PointerProperty(
+                name="Cycles Lamp Settings",
+                description="Cycles lamp settings",
+                type=cls,
+                )
+        cls.cast_shadow = BoolProperty(
+                name="Cast Shadow",
+                description="Lamp casts shadows",
+                default=True,
+                )
 
     @classmethod
     def unregister(cls):
@@ -154,7 +302,22 @@ class CyclesLampSettings(bpy.types.PropertyGroup):
 class CyclesWorldSettings(bpy.types.PropertyGroup):
     @classmethod
     def register(cls):
-        bpy.types.World.cycles = PointerProperty(type=cls, name="Cycles World Settings", description="Cycles world settings")
+        bpy.types.World.cycles = PointerProperty(
+                name="Cycles World Settings",
+                description="Cycles world settings",
+                type=cls,
+                )
+        cls.sample_as_light = BoolProperty(
+                name="Sample as Lamp",
+                description="Use direct light sampling for the environment, enabling for non-solid colors is recommended",
+                default=False,
+                )
+        cls.sample_map_resolution = IntProperty(
+                name="Map Resolution",
+                description="Importance map size is resolution x resolution; higher values potentially produce less noise, at the cost of memory and speed",
+                min=4, max=8096,
+                default=256,
+                )
 
     @classmethod
     def unregister(cls):
@@ -164,13 +327,37 @@ class CyclesWorldSettings(bpy.types.PropertyGroup):
 class CyclesVisibilitySettings(bpy.types.PropertyGroup):
     @classmethod
     def register(cls):
-        bpy.types.Object.cycles_visibility = PointerProperty(type=cls, name="Cycles Visibility Settings", description="Cycles visibility settings")
-
-        cls.camera = BoolProperty(name="Camera", description="Object visibility for camera rays", default=True)
-        cls.diffuse = BoolProperty(name="Diffuse", description="Object visibility for diffuse reflection rays", default=True)
-        cls.glossy = BoolProperty(name="Glossy", description="Object visibility for glossy reflection rays", default=True)
-        cls.transmission = BoolProperty(name="Transmission", description="Object visibility for transmission rays", default=True)
-        cls.shadow = BoolProperty(name="Shadow", description="Object visibility for shadow rays", default=True)
+        bpy.types.Object.cycles_visibility = PointerProperty(
+                name="Cycles Visibility Settings",
+                description="Cycles visibility settings",
+                type=cls,
+                )
+
+        cls.camera = BoolProperty(
+                name="Camera",
+                description="Object visibility for camera rays",
+                default=True,
+                )
+        cls.diffuse = BoolProperty(
+                name="Diffuse",
+                description="Object visibility for diffuse reflection rays",
+                default=True,
+                )
+        cls.glossy = BoolProperty(
+                name="Glossy",
+                description="Object visibility for glossy reflection rays",
+                default=True,
+                )
+        cls.transmission = BoolProperty(
+                name="Transmission",
+                description="Object visibility for transmission rays",
+                default=True,
+                )
+        cls.shadow = BoolProperty(
+                name="Shadow",
+                description="Object visibility for shadow rays",
+                default=True,
+                )
 
     @classmethod
     def unregister(cls):
@@ -180,15 +367,39 @@ class CyclesVisibilitySettings(bpy.types.PropertyGroup):
 class CyclesMeshSettings(bpy.types.PropertyGroup):
     @classmethod
     def register(cls):
-        bpy.types.Mesh.cycles = PointerProperty(type=cls, name="Cycles Mesh Settings", description="Cycles mesh settings")
-        bpy.types.Curve.cycles = PointerProperty(type=cls, name="Cycles Mesh Settings", description="Cycles mesh settings")
-        bpy.types.MetaBall.cycles = PointerProperty(type=cls, name="Cycles Mesh Settings", description="Cycles mesh settings")
-
-        cls.displacement_method = EnumProperty(name="Displacement Method", description="Method to use for the displacement",
-            items=enums.displacement_methods, default="BUMP")
-        cls.use_subdivision = BoolProperty(name="Use Subdivision", description="Subdivide mesh for rendering",
-            default=False)
-        cls.dicing_rate = FloatProperty(name="Dicing Rate", description="", default=1.0, min=0.001, max=1000.0)
+        bpy.types.Mesh.cycles = PointerProperty(
+                name="Cycles Mesh Settings",
+                description="Cycles mesh settings",
+                type=cls,
+                )
+        bpy.types.Curve.cycles = PointerProperty(
+                name="Cycles Mesh Settings",
+                description="Cycles mesh settings",
+                type=cls,
+                )
+        bpy.types.MetaBall.cycles = PointerProperty(
+                name="Cycles Mesh Settings",
+                description="Cycles mesh settings",
+                type=cls,
+                )
+
+        cls.displacement_method = EnumProperty(
+                name="Displacement Method",
+                description="Method to use for the displacement",
+                items=enums.displacement_methods,
+                default='BUMP',
+                )
+        cls.use_subdivision = BoolProperty(
+                name="Use Subdivision",
+                description="Subdivide mesh for rendering",
+                default=False,
+                )
+        cls.dicing_rate = FloatProperty(
+                name="Dicing Rate",
+                description="",
+                min=0.001, max=1000.0,
+                default=1.0,
+                )
 
     @classmethod
     def unregister(cls):
index 70f38fa7e8ccc97235143c4c674a655c4f092c48..6353bf37a15b94473040f45e9844a20d2c67e86a 100644 (file)
@@ -183,6 +183,38 @@ class CyclesRender_PT_layers(CyclesButtonsPanel, Panel):
 
         layout.separator()
 
+        split = layout.split()
+
+        col = split.column()
+        col.label(text="Passes:")
+        col.prop(rl, "use_pass_combined")
+        col.prop(rl, "use_pass_z")
+        col.prop(rl, "use_pass_normal")
+        col.prop(rl, "use_pass_object_index")
+        col.prop(rl, "use_pass_material_index")
+        col.prop(rl, "use_pass_emit")
+        col.prop(rl, "use_pass_environment")
+
+        col = split.column()
+        col.label()
+        col.label(text="Diffuse:")
+        row = col.row(align=True)
+        row.prop(rl, "use_pass_diffuse_direct", text="Direct", toggle=True)
+        row.prop(rl, "use_pass_diffuse_indirect", text="Indirect", toggle=True)
+        row.prop(rl, "use_pass_diffuse_color", text="Color", toggle=True)
+        col.label(text="Glossy:")
+        row = col.row(align=True)
+        row.prop(rl, "use_pass_glossy_direct", text="Direct", toggle=True)
+        row.prop(rl, "use_pass_glossy_indirect", text="Indirect", toggle=True)
+        row.prop(rl, "use_pass_glossy_color", text="Color", toggle=True)
+        col.label(text="Transmission:")
+        row = col.row(align=True)
+        row.prop(rl, "use_pass_transmission_direct", text="Direct", toggle=True)
+        row.prop(rl, "use_pass_transmission_indirect", text="Indirect", toggle=True)
+        row.prop(rl, "use_pass_transmission_color", text="Color", toggle=True)
+
+        layout.separator()
+
         rl = rd.layers[0]
         layout.prop(rl, "material_override", text="Material")
 
@@ -241,7 +273,7 @@ class CyclesCamera_PT_dof(CyclesButtonsPanel, Panel):
 
 
 class Cycles_PT_context_material(CyclesButtonsPanel, Panel):
-    bl_label = "Surface"
+    bl_label = ""
     bl_context = "material"
     bl_options = {'HIDE_HEADER'}
 
@@ -337,16 +369,13 @@ class CyclesObject_PT_ray_visibility(CyclesButtonsPanel, Panel):
         ob = context.object
         visibility = ob.cycles_visibility
 
-        split = layout.split()
-
-        col = split.column()
-        col.prop(visibility, "camera")
-        col.prop(visibility, "diffuse")
-        col.prop(visibility, "glossy")
-
-        col = split.column()
-        col.prop(visibility, "transmission")
-        col.prop(visibility, "shadow")
+        flow = layout.column_flow()
+        
+        flow.prop(visibility, "camera")
+        flow.prop(visibility, "diffuse")
+        flow.prop(visibility, "glossy")
+        flow.prop(visibility, "transmission")
+        flow.prop(visibility, "shadow")
 
 
 def find_node(material, nodetype):
@@ -453,10 +482,34 @@ class CyclesWorld_PT_surface(CyclesButtonsPanel, Panel):
         layout = self.layout
 
         world = context.world
+
         if not panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Surface'):
             layout.prop(world, "horizon_color", text="Color")
 
 
+class CyclesWorld_PT_settings(CyclesButtonsPanel, Panel):
+    bl_label = "Settings"
+    bl_context = "world"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    @classmethod
+    def poll(cls, context):
+        return context.world and CyclesButtonsPanel.poll(context)
+
+    def draw(self, context):
+        layout = self.layout
+
+        world = context.world
+        cworld = world.cycles
+
+        col = layout.column()
+
+        col.prop(cworld, "sample_as_light")
+        row = col.row()
+        row.active = cworld.sample_as_light
+        row.prop(cworld, "sample_map_resolution")
+
+
 class CyclesWorld_PT_volume(CyclesButtonsPanel, Panel):
     bl_label = "Volume"
     bl_context = "world"
@@ -589,14 +642,9 @@ class CyclesTexture_PT_context(CyclesButtonsPanel, Panel):
                 col.template_ID(user, "texture", new="texture.new")
 
             if tex:
-                row = split.row()
-                row.prop(tex, "use_nodes", icon="NODETREE", text="")
-                row.label()
-
-                if not tex.use_nodes:
-                    split = layout.split(percentage=0.2)
-                    split.label(text="Type:")
-                    split.prop(tex, "type", text="")
+                split = layout.split(percentage=0.2)
+                split.label(text="Type:")
+                split.prop(tex, "type", text="")
 
 
 class CyclesTexture_PT_nodes(CyclesButtonsPanel, Panel):
index 608cb33eadde8bf694ff4f587732c1e39ac6b8de..afcfcd9506342b86f617ac76b482014ebfef6006 100644 (file)
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
+#include "graph.h"
 #include "light.h"
 #include "mesh.h"
 #include "object.h"
 #include "scene.h"
+#include "nodes.h"
+#include "shader.h"
 
 #include "blender_sync.h"
 #include "blender_util.h"
@@ -152,6 +155,37 @@ void BlenderSync::sync_light(BL::Object b_parent, int b_index, BL::Object b_ob,
        light->tag_update(scene);
 }
 
+void BlenderSync::sync_background_light()
+{
+       BL::World b_world = b_scene.world();
+
+       if(b_world) {
+               PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
+               bool sample_as_light = get_boolean(cworld, "sample_as_light");
+
+               if(sample_as_light) {
+                       /* test if we need to sync */
+                       Light *light;
+                       ObjectKey key(b_world, 0, b_world);
+
+                       if(light_map.sync(&light, b_world, b_world, key) ||
+                          world_recalc ||
+                          b_world.ptr.data != world_map)
+                       {
+                               light->type = LIGHT_BACKGROUND;
+                               light->map_resolution  = get_int(cworld, "sample_map_resolution");
+                               light->shader = scene->default_background;
+
+                               light->tag_update(scene);
+                               light_map.set_recalc(b_world);
+                       }
+               }
+       }
+
+       world_map = b_world.ptr.data;
+       world_recalc = false;
+}
+
 /* Object */
 
 void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm, uint layer_flag)
@@ -180,6 +214,7 @@ void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob,
        /* object sync */
        if(object_updated || (object->mesh && object->mesh->need_update)) {
                object->name = b_ob.name().c_str();
+               object->pass_id = b_ob.pass_index();
                object->tfm = tfm;
 
                /* visibility flags for both parent */
@@ -263,6 +298,8 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d)
                }
        }
 
+       sync_background_light();
+
        /* handle removed data and modified pointers */
        if(light_map.post_sync())
                scene->light_manager->tag_update(scene);
index b052fb3e195a742b7907e310e53cfae4dad619a4..ff1c32831bb130279d51f38070286c38ad3245b3 100644 (file)
@@ -116,9 +116,68 @@ void BlenderSession::free_session()
        delete session;
 }
 
+static PassType get_pass_type(BL::RenderPass b_pass)
+{
+       switch(b_pass.type()) {
+               case BL::RenderPass::type_COMBINED:
+                       return PASS_COMBINED;
+
+               case BL::RenderPass::type_Z:
+                       return PASS_DEPTH;
+               case BL::RenderPass::type_NORMAL:
+                       return PASS_NORMAL;
+               case BL::RenderPass::type_OBJECT_INDEX:
+                       return PASS_OBJECT_ID;
+               case BL::RenderPass::type_UV:
+                       return PASS_UV;
+               case BL::RenderPass::type_MATERIAL_INDEX:
+                       return PASS_MATERIAL_ID;
+
+               case BL::RenderPass::type_DIFFUSE_DIRECT:
+                       return PASS_DIFFUSE_DIRECT;
+               case BL::RenderPass::type_GLOSSY_DIRECT:
+                       return PASS_GLOSSY_DIRECT;
+               case BL::RenderPass::type_TRANSMISSION_DIRECT:
+                       return PASS_TRANSMISSION_DIRECT;
+
+               case BL::RenderPass::type_DIFFUSE_INDIRECT:
+                       return PASS_DIFFUSE_INDIRECT;
+               case BL::RenderPass::type_GLOSSY_INDIRECT:
+                       return PASS_GLOSSY_INDIRECT;
+               case BL::RenderPass::type_TRANSMISSION_INDIRECT:
+                       return PASS_TRANSMISSION_INDIRECT;
+
+               case BL::RenderPass::type_DIFFUSE_COLOR:
+                       return PASS_DIFFUSE_COLOR;
+               case BL::RenderPass::type_GLOSSY_COLOR:
+                       return PASS_GLOSSY_COLOR;
+               case BL::RenderPass::type_TRANSMISSION_COLOR:
+                       return PASS_TRANSMISSION_COLOR;
+
+               case BL::RenderPass::type_EMIT:
+                       return PASS_EMISSION;
+               case BL::RenderPass::type_ENVIRONMENT:
+                       return PASS_BACKGROUND;
+
+               case BL::RenderPass::type_DIFFUSE:
+               case BL::RenderPass::type_SHADOW:
+               case BL::RenderPass::type_AO:
+               case BL::RenderPass::type_COLOR:
+               case BL::RenderPass::type_REFRACTION:
+               case BL::RenderPass::type_SPECULAR:
+               case BL::RenderPass::type_REFLECTION:
+               case BL::RenderPass::type_VECTOR:
+               case BL::RenderPass::type_MIST:
+                       return PASS_NONE;
+       }
+       
+       return PASS_NONE;
+}
+
 void BlenderSession::render()
 {
        /* get buffer parameters */
+       SessionParams session_params = BlenderSync::get_session_params(b_userpref, b_scene, background);
        BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height);
        int w = buffer_params.width, h = buffer_params.height;
 
@@ -143,6 +202,25 @@ void BlenderSession::render()
                /* set layer */
                b_rlay = *b_iter;
 
+               /* add passes */
+               if(session_params.device.type == DEVICE_CPU) { /* todo */
+                       BL::RenderLayer::passes_iterator b_pass_iter;
+                       
+                       for(b_rlay.passes.begin(b_pass_iter); b_pass_iter != b_rlay.passes.end(); ++b_pass_iter) {
+                               BL::RenderPass b_pass(*b_pass_iter);
+                               PassType pass_type = get_pass_type(b_pass);
+
+                               if(pass_type != PASS_NONE)
+                                       Pass::add(pass_type, buffer_params.passes);
+                       }
+               }
+
+               scene->film->passes = buffer_params.passes;
+               scene->film->need_update = true;
+
+               /* update session */
+               session->reset(buffer_params, session_params.samples);
+
                /* update scene */
                sync->sync_data(b_v3d, active);
 
@@ -165,22 +243,41 @@ void BlenderSession::write_render_result()
 {
        /* get state */
        RenderBuffers *buffers = session->buffers;
+
+       /* copy data from device */
+       if(!buffers->copy_from_device())
+               return;
+
+       BufferParams& params = buffers->params;
        float exposure = scene->film->exposure;
        double total_time, sample_time;
        int sample;
+
        session->progress.get_sample(sample, total_time, sample_time);
 
-       /* get pixels */
-       float4 *pixels = buffers->copy_from_device(exposure, sample);
+       vector<float> pixels(params.width*params.height*4);
 
-       if(!pixels)
-               return;
+       /* copy each pass */
+       BL::RenderLayer::passes_iterator b_iter;
+       
+       for(b_rlay.passes.begin(b_iter); b_iter != b_rlay.passes.end(); ++b_iter) {
+               BL::RenderPass b_pass(*b_iter);
 
-       /* write pixels */
-       rna_RenderLayer_rect_set(&b_rlay.ptr, (float*)pixels);
-       RE_engine_update_result((RenderEngine*)b_engine.ptr.data, (RenderResult*)b_rr.ptr.data);
+               /* find matching pass type */
+               PassType pass_type = get_pass_type(b_pass);
+               int components = b_pass.channels();
+
+               /* copy pixels */
+               if(buffers->get_pass(pass_type, exposure, sample, components, &pixels[0]))
+                       rna_RenderPass_rect_set(&b_pass.ptr, &pixels[0]);
+       }
 
-       delete [] pixels;
+       /* copy combined pass */
+       if(buffers->get_pass(PASS_COMBINED, exposure, sample, 4, &pixels[0]))
+               rna_RenderLayer_rect_set(&b_rlay.ptr, &pixels[0]);
+
+       /* tag result as updated */
+       RE_engine_update_result((RenderEngine*)b_engine.ptr.data, (RenderResult*)b_rr.ptr.data);
 }
 
 void BlenderSession::synchronize()
index f5ffc321476dd475ed80b52aa0a9ab48e97e1e4f..5310e35dc25b06201bb1ec755c8136f02e7d799f 100644 (file)
@@ -142,6 +142,10 @@ static ShaderNode *add_node(BL::BlendData b_data, ShaderGraph *graph, BL::Shader
                        node = new GammaNode();
                        break;
                }
+               case BL::ShaderNode::type_BRIGHTCONTRAST: {
+                       node = new BrightContrastNode();
+                       break;
+               }
                case BL::ShaderNode::type_MIX_RGB: {
                        BL::ShaderNodeMixRGB b_mix_node(b_node);
                        MixNode *mix = new MixNode();
@@ -632,6 +636,7 @@ void BlenderSync::sync_materials()
                        ShaderGraph *graph = new ShaderGraph();
 
                        shader->name = b_mat->name().c_str();
+                       shader->pass_id = b_mat->pass_index();
 
                        /* create nodes */
                        if(b_mat->use_nodes() && b_mat->node_tree()) {
@@ -700,9 +705,6 @@ void BlenderSync::sync_world()
 
        if(background->modified(prevbackground))
                background->tag_update(scene);
-
-       world_map = b_world.ptr.data;
-       world_recalc = false;
 }
 
 /* Sync Lamps */
index 7b65376bd846eb46d44d253a89e7ec2207db1810..5e76a0a0b1e858a349530504c5b4c228e7162e79 100644 (file)
@@ -80,6 +80,7 @@ private:
        Mesh *sync_mesh(BL::Object b_ob, bool object_updated);
        void sync_object(BL::Object b_parent, int b_index, BL::Object b_object, Transform& tfm, uint layer_flag);
        void sync_light(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm);
+       void sync_background_light();
 
        /* util */
        void find_shader(BL::ID id, vector<uint>& used_shaders, int default_shader);
index f4b2b7a8269373b059e5fec64fb141d673b8d1f7..2ca599f6c674c07bb30fdd8a5e227e645a54dffc 100644 (file)
@@ -162,7 +162,7 @@ public:
                if(system_cpu_support_optimized()) {
                        for(int y = task.y; y < task.y + task.h; y++) {
                                for(int x = task.x; x < task.x + task.w; x++)
-                                       kernel_cpu_optimized_path_trace(kg, (float4*)task.buffer, (unsigned int*)task.rng_state,
+                                       kernel_cpu_optimized_path_trace(kg, (float*)task.buffer, (unsigned int*)task.rng_state,
                                                task.sample, x, y, task.offset, task.stride);
 
                                if(tasks.worker_cancel())
@@ -174,7 +174,7 @@ public:
                {
                        for(int y = task.y; y < task.y + task.h; y++) {
                                for(int x = task.x; x < task.x + task.w; x++)
-                                       kernel_cpu_path_trace(kg, (float4*)task.buffer, (unsigned int*)task.rng_state,
+                                       kernel_cpu_path_trace(kg, (float*)task.buffer, (unsigned int*)task.rng_state,
                                                task.sample, x, y, task.offset, task.stride);
 
                                if(tasks.worker_cancel())
@@ -194,7 +194,7 @@ public:
                if(system_cpu_support_optimized()) {
                        for(int y = task.y; y < task.y + task.h; y++)
                                for(int x = task.x; x < task.x + task.w; x++)
-                                       kernel_cpu_optimized_tonemap(kg, (uchar4*)task.rgba, (float4*)task.buffer,
+                                       kernel_cpu_optimized_tonemap(kg, (uchar4*)task.rgba, (float*)task.buffer,
                                                task.sample, task.resolution, x, y, task.offset, task.stride);
                }
                else
@@ -202,7 +202,7 @@ public:
                {
                        for(int y = task.y; y < task.y + task.h; y++)
                                for(int x = task.x; x < task.x + task.w; x++)
-                                       kernel_cpu_tonemap(kg, (uchar4*)task.rgba, (float4*)task.buffer,
+                                       kernel_cpu_tonemap(kg, (uchar4*)task.rgba, (float*)task.buffer,
                                                task.sample, task.resolution, x, y, task.offset, task.stride);
                }
        }
@@ -217,7 +217,7 @@ public:
 #ifdef WITH_OPTIMIZED_KERNEL
                if(system_cpu_support_optimized()) {
                        for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) {
-                               kernel_cpu_optimized_shader(kg, (uint4*)task.shader_input, (float3*)task.shader_output, task.shader_eval_type, x);
+                               kernel_cpu_optimized_shader(kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x);
 
                                if(tasks.worker_cancel())
                                        break;
@@ -227,7 +227,7 @@ public:
 #endif
                {
                        for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) {
-                               kernel_cpu_shader(kg, (uint4*)task.shader_input, (float3*)task.shader_output, task.shader_eval_type, x);
+                               kernel_cpu_shader(kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x);
 
                                if(tasks.worker_cancel())
                                        break;
index a4e0c0ddb56141b52c1871a2542b1d06cf51b13e..59fe9709e61abb5e82b1941cdd36d11fddb1fc78 100644 (file)
@@ -15,6 +15,7 @@ set(SRC
 
 set(SRC_HEADERS
        kernel.h
+       kernel_accumulate.h
        kernel_bvh.h
        kernel_camera.h
        kernel_compat_cpu.h
@@ -30,6 +31,7 @@ set(SRC_HEADERS
        kernel_mbvh.h
        kernel_montecarlo.h
        kernel_object.h
+       kernel_passes.h
        kernel_path.h
        kernel_qbvh.h
        kernel_random.h
@@ -61,6 +63,7 @@ set(SRC_SVM_HEADERS
        svm/svm_displace.h
        svm/svm_fresnel.h
        svm/svm_gamma.h
+       svm/svm_brightness.h
        svm/svm_geometry.h
        svm/svm_gradient.h
        svm/svm_hsv.h
index 479cf9b2e64c692c24d1657fe04b41c1f36fa93d..f98414d4f0221fe17205ebd9a74982f86701510b 100644 (file)
@@ -28,7 +28,7 @@
 
 __kernel void kernel_ocl_path_trace(
        __constant KernelData *data,
-       __global float4 *buffer,
+       __global float *buffer,
        __global uint *rng_state,
 
 #define KERNEL_TEX(type, ttype, name) \
@@ -56,7 +56,7 @@ __kernel void kernel_ocl_path_trace(
 __kernel void kernel_ocl_tonemap(
        __constant KernelData *data,
        __global uchar4 *rgba,
-       __global float4 *buffer,
+       __global float *buffer,
 
 #define KERNEL_TEX(type, ttype, name) \
        __global type *name,
@@ -80,7 +80,7 @@ __kernel void kernel_ocl_tonemap(
                kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y, offset, stride);
 }
 
-/*__kernel void kernel_ocl_shader(__global uint4 *input, __global float3 *output, int type, int sx)
+/*__kernel void kernel_ocl_shader(__global uint4 *input, __global float *output, int type, int sx)
 {
        int x = sx + get_global_id(0);
 
index e66ddd86cd65826dbc1f2fdc28059e93eebd8814..a93f6172d28522b4d3b64340a33356d78b0ddfa4 100644 (file)
@@ -204,21 +204,21 @@ void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t
 
 /* Path Tracing */
 
-void kernel_cpu_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state, int sample, int x, int y, int offset, int stride)
+void kernel_cpu_path_trace(KernelGlobals *kg, float *buffer, unsigned int *rng_state, int sample, int x, int y, int offset, int stride)
 {
        kernel_path_trace(kg, buffer, rng_state, sample, x, y, offset, stride);
 }
 
 /* Tonemapping */
 
-void kernel_cpu_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, int sample, int resolution, int x, int y, int offset, int stride)
+void kernel_cpu_tonemap(KernelGlobals *kg, uchar4 *rgba, float *buffer, int sample, int resolution, int x, int y, int offset, int stride)
 {
        kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y, offset, stride);
 }
 
 /* Shader Evaluation */
 
-void kernel_cpu_shader(KernelGlobals *kg, uint4 *input, float3 *output, int type, int i)
+void kernel_cpu_shader(KernelGlobals *kg, uint4 *input, float4 *output, int type, int i)
 {
        kernel_shader_evaluate(kg, input, output, (ShaderEvalType)type, i);
 }
index c97aeb6754807eeb2f026eaa6d882c1116be517c..fc7992c87f0ab58a73ab6c0cd53e22a1dcea27ad 100644 (file)
@@ -26,7 +26,7 @@
 #include "kernel_path.h"
 #include "kernel_displace.h"
 
-extern "C" __global__ void kernel_cuda_path_trace(float4 *buffer, uint *rng_state, int sample, int sx, int sy, int sw, int sh, int offset, int stride)
+extern "C" __global__ void kernel_cuda_path_trace(float *buffer, uint *rng_state, int sample, int sx, int sy, int sw, int sh, int offset, int stride)
 {
        int x = sx + blockDim.x*blockIdx.x + threadIdx.x;
        int y = sy + blockDim.y*blockIdx.y + threadIdx.y;
@@ -35,7 +35,7 @@ extern "C" __global__ void kernel_cuda_path_trace(float4 *buffer, uint *rng_stat
                kernel_path_trace(NULL, buffer, rng_state, sample, x, y, offset, stride);
 }
 
-extern "C" __global__ void kernel_cuda_tonemap(uchar4 *rgba, float4 *buffer, int sample, int resolution, int sx, int sy, int sw, int sh, int offset, int stride)
+extern "C" __global__ void kernel_cuda_tonemap(uchar4 *rgba, float *buffer, int sample, int resolution, int sx, int sy, int sw, int sh, int offset, int stride)
 {
        int x = sx + blockDim.x*blockIdx.x + threadIdx.x;
        int y = sy + blockDim.y*blockIdx.y + threadIdx.y;
@@ -44,7 +44,7 @@ extern "C" __global__ void kernel_cuda_tonemap(uchar4 *rgba, float4 *buffer, int
                kernel_film_tonemap(NULL, rgba, buffer, sample, resolution, x, y, offset, stride);
 }
 
-extern "C" __global__ void kernel_cuda_shader(uint4 *input, float3 *output, int type, int sx)
+extern "C" __global__ void kernel_cuda_shader(uint4 *input, float4 *output, int type, int sx)
 {
        int x = sx + blockDim.x*blockIdx.x + threadIdx.x;
 
index 20d43c911693cf8c909f46aa411b7df6060c06d1..26c0bcd6d1a531d8b32af904d581db1e4284fe55 100644 (file)
@@ -36,19 +36,19 @@ bool kernel_osl_use(KernelGlobals *kg);
 void kernel_const_copy(KernelGlobals *kg, const char *name, void *host, size_t size);
 void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t width, size_t height);
 
-void kernel_cpu_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state,
+void kernel_cpu_path_trace(KernelGlobals *kg, float *buffer, unsigned int *rng_state,
        int sample, int x, int y, int offset, int stride);
-void kernel_cpu_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer,
+void kernel_cpu_tonemap(KernelGlobals *kg, uchar4 *rgba, float *buffer,
        int sample, int resolution, int x, int y, int offset, int stride);
-void kernel_cpu_shader(KernelGlobals *kg, uint4 *input, float3 *output,
+void kernel_cpu_shader(KernelGlobals *kg, uint4 *input, float4 *output,
        int type, int i);
 
 #ifdef WITH_OPTIMIZED_KERNEL
-void kernel_cpu_optimized_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state,
+void kernel_cpu_optimized_path_trace(KernelGlobals *kg, float *buffer, unsigned int *rng_state,
        int sample, int x, int y, int offset, int stride);
-void kernel_cpu_optimized_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer,
+void kernel_cpu_optimized_tonemap(KernelGlobals *kg, uchar4 *rgba, float *buffer,
        int sample, int resolution, int x, int y, int offset, int stride);
-void kernel_cpu_optimized_shader(KernelGlobals *kg, uint4 *input, float3 *output,
+void kernel_cpu_optimized_shader(KernelGlobals *kg, uint4 *input, float4 *output,
        int type, int i);
 #endif
 
diff --git a/intern/cycles/kernel/kernel_accumulate.h b/intern/cycles/kernel/kernel_accumulate.h
new file mode 100644 (file)
index 0000000..e71fad5
--- /dev/null
@@ -0,0 +1,283 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+CCL_NAMESPACE_BEGIN
+
+/* BSDF Eval
+ *
+ * BSDF evaluation result, split per BSDF type. This is used to accumulate
+ * render passes separately. */
+
+__device_inline void bsdf_eval_init(BsdfEval *eval, ClosureType type, float3 value, int use_light_pass)
+{
+#ifdef __PASSES__
+       eval->use_light_pass = use_light_pass;
+
+       if(eval->use_light_pass) {
+               eval->diffuse = make_float3(0.0f, 0.0f, 0.0f);
+               eval->glossy = make_float3(0.0f, 0.0f, 0.0f);
+               eval->transmission = make_float3(0.0f, 0.0f, 0.0f);
+               eval->transparent = make_float3(0.0f, 0.0f, 0.0f);
+
+               if(type == CLOSURE_BSDF_TRANSPARENT_ID)
+                       eval->transparent = value;
+               else if(CLOSURE_IS_BSDF_DIFFUSE(type))
+                       eval->diffuse = value;
+               else if(CLOSURE_IS_BSDF_GLOSSY(type))
+                       eval->glossy = value;
+               else
+                       eval->transmission = value;
+       }
+       else
+               eval->diffuse = value;
+#else
+       *eval = value;
+#endif
+}
+
+__device_inline void bsdf_eval_accum(BsdfEval *eval, ClosureType type, float3 value)
+{
+#ifdef __PASSES__
+       if(eval->use_light_pass) {
+               if(CLOSURE_IS_BSDF_DIFFUSE(type))
+                       eval->diffuse += value;
+               else if(CLOSURE_IS_BSDF_GLOSSY(type))
+                       eval->glossy += value;
+               else
+                       eval->transmission += value;
+
+               /* skipping transparent, this function is used by for eval(), will be zero then */
+       }
+       else
+               eval->diffuse += value;
+#else
+       *eval += value;
+#endif
+}
+
+__device_inline bool bsdf_eval_is_zero(BsdfEval *eval)
+{
+#ifdef __PASSES__
+       if(eval->use_light_pass) {
+               return is_zero(eval->diffuse)
+                       && is_zero(eval->glossy)
+                       && is_zero(eval->transmission)
+                       && is_zero(eval->transparent);
+       }
+       else
+               return is_zero(eval->diffuse);
+#else
+       return is_zero(*eval);
+#endif
+}
+
+__device_inline void bsdf_eval_mul(BsdfEval *eval, float3 value)
+{
+#ifdef __PASSES__
+       if(eval->use_light_pass) {
+               eval->diffuse *= value;
+               eval->glossy *= value;
+               eval->transmission *= value;
+
+               /* skipping transparent, this function is used by for eval(), will be zero then */
+       }
+       else
+               eval->diffuse *= value;
+#else
+       *eval *= value;
+#endif
+}
+
+/* Path Radiance
+ *
+ * We accumulate different render passes separately. After summing at the end
+ * to get the combined result, it should be identical. We definte directly
+ * visible as the first non-transparent hit, while indirectly visible are the
+ * bounces after that. */
+
+__device_inline void path_radiance_init(PathRadiance *L, int use_light_pass)
+{
+       /* clear all */
+#ifdef __PASSES__
+       L->use_light_pass = use_light_pass;
+
+       if(use_light_pass) {
+               L->indirect = make_float3(0.0f, 0.0f, 0.0f);
+               L->direct_throughput = make_float3(0.0f, 0.0f, 0.0f);
+               L->direct_emission = make_float3(0.0f, 0.0f, 0.0f);
+
+               L->color_diffuse = make_float3(0.0f, 0.0f, 0.0f);
+               L->color_glossy = make_float3(0.0f, 0.0f, 0.0f);
+               L->color_transmission = make_float3(0.0f, 0.0f, 0.0f);
+
+               L->direct_diffuse = make_float3(0.0f, 0.0f, 0.0f);
+               L->direct_glossy = make_float3(0.0f, 0.0f, 0.0f);
+               L->direct_transmission = make_float3(0.0f, 0.0f, 0.0f);
+
+               L->indirect_diffuse = make_float3(0.0f, 0.0f, 0.0f);
+               L->indirect_glossy = make_float3(0.0f, 0.0f, 0.0f);
+               L->indirect_transmission = make_float3(0.0f, 0.0f, 0.0f);
+
+               L->emission = make_float3(0.0f, 0.0f, 0.0f);
+               L->background = make_float3(0.0f, 0.0f, 0.0f);
+       }
+       else
+               L->emission = make_float3(0.0f, 0.0f, 0.0f);
+#else
+       *L = make_float3(0.0f, 0.0f, 0.0f);
+#endif
+}
+
+__device_inline void path_radiance_bsdf_bounce(PathRadiance *L, float3 *throughput,
+       BsdfEval *bsdf_eval, float bsdf_pdf, int bounce, int bsdf_label)
+{
+       float inverse_pdf = 1.0f/bsdf_pdf;
+
+#ifdef __PASSES__
+       if(L->use_light_pass) {
+               if(bounce == 0) {
+                       if(bsdf_label & LABEL_TRANSPARENT) {
+                               /* transparent bounce before first hit */
+                               *throughput *= bsdf_eval->transparent*inverse_pdf;
+                       }
+                       else {
+                               /* first on directly visible surface */
+                               float3 value = *throughput*inverse_pdf;
+
+                               L->indirect_diffuse = bsdf_eval->diffuse*value;
+                               L->indirect_glossy = bsdf_eval->glossy*value;
+                               L->indirect_transmission = bsdf_eval->transmission*value;
+
+                               *throughput = L->indirect_diffuse + L->indirect_glossy + L->indirect_transmission;
+                               
+                               L->direct_throughput = *throughput;
+                       }
+               }
+               else {
+                       /* indirectly visible through BSDF */
+                       float3 sum = (bsdf_eval->diffuse + bsdf_eval->glossy + bsdf_eval->transmission + bsdf_eval->transparent)*inverse_pdf;
+                       *throughput *= sum;
+               }
+       }
+       else
+               *throughput *= bsdf_eval->diffuse*inverse_pdf;
+#else
+       *throughput *= *bsdf_eval*inverse_pdf;
+#endif
+}
+
+__device_inline void path_radiance_accum_emission(PathRadiance *L, float3 throughput, float3 value, int bounce)
+{
+#ifdef __PASSES__
+       if(L->use_light_pass) {
+               if(bounce == 0)
+                       L->emission += throughput*value;
+               else if(bounce == 1)
+                       L->direct_emission += throughput*value;
+               else
+                       L->indirect += throughput*value;
+       }
+       else
+               L->emission += throughput*value;
+#else
+       *L += throughput*value;
+#endif
+}
+
+__device_inline void path_radiance_accum_light(PathRadiance *L, float3 throughput, BsdfEval *bsdf_eval, int bounce)
+{
+#ifdef __PASSES__
+       if(L->use_light_pass) {
+               if(bounce == 0) {
+                       /* directly visible lighting */
+                       L->direct_diffuse += throughput*bsdf_eval->diffuse;
+                       L->direct_glossy += throughput*bsdf_eval->glossy;
+                       L->direct_transmission += throughput*bsdf_eval->transmission;
+               }
+               else {
+                       /* indirectly visible lighting after BSDF bounce */
+                       float3 sum = bsdf_eval->diffuse + bsdf_eval->glossy + bsdf_eval->transmission;
+                       L->indirect += throughput*sum;
+               }
+       }
+       else
+               L->emission += throughput*bsdf_eval->diffuse;
+#else
+       *L += throughput*(*bsdf_eval);
+#endif
+}
+
+__device_inline void path_radiance_accum_background(PathRadiance *L, float3 throughput, float3 value, int bounce)
+{
+#ifdef __PASSES__
+       if(L->use_light_pass) {
+               if(bounce == 0)
+                       L->background += throughput*value;
+               else if(bounce == 1)
+                       L->direct_emission += throughput*value;
+               else
+                       L->indirect += throughput*value;
+       }
+       else
+               L->emission += throughput*value;
+#else
+       *L += throughput*value;
+#endif
+}
+
+__device_inline float3 safe_divide_color(float3 a, float3 b)
+{
+       float x, y, z;
+
+       x = (b.x != 0.0f)? a.x/b.x: 0.0f;
+       y = (b.y != 0.0f)? a.y/b.y: 0.0f;
+       z = (b.z != 0.0f)? a.z/b.z: 0.0f;
+
+       return make_float3(x, y, z);
+}
+
+__device_inline float3 path_radiance_sum(PathRadiance *L)
+{
+#ifdef __PASSES__
+       if(L->use_light_pass) {
+               /* this division is a bit ugly, but means we only have to keep track of
+                  only a single throughput further along the path, here we recover just
+                  the indirect parth that is not influenced by any particular BSDF type */
+               L->direct_emission = safe_divide_color(L->direct_emission, L->direct_throughput);
+               L->direct_diffuse += L->indirect_diffuse*L->direct_emission;
+               L->direct_glossy += L->indirect_glossy*L->direct_emission;
+               L->direct_transmission += L->indirect_transmission*L->direct_emission;
+
+               L->indirect = safe_divide_color(L->indirect, L->direct_throughput);
+               L->indirect_diffuse *= L->indirect;
+               L->indirect_glossy *= L->indirect;
+               L->indirect_transmission *= L->indirect;
+
+               return L->emission + L->background
+                       + L->direct_diffuse + L->direct_glossy + L->direct_transmission
+                       + L->indirect_diffuse + L->indirect_glossy + L->indirect_transmission;
+       }
+       else
+               return L->emission;
+#else
+       return *L;
+#endif
+}
+
+CCL_NAMESPACE_END
+
index 783ae5198455544c98f3ef9b7139007a7b235b01..79f894bfdace5c895a33e8b5557ebae1cab2259d 100644 (file)
@@ -141,6 +141,7 @@ template<typename T> struct texture_image  {
 };
 
 typedef texture<float4> texture_float4;
+typedef texture<float2> texture_float2;
 typedef texture<float> texture_float;
 typedef texture<uint> texture_uint;
 typedef texture<int> texture_int;
index 40129a2f68f5e7cf831771d28a10fd40a5a1d59c..cc719bfadbc87b33fab4da1947547acb9e57b6a8 100644 (file)
@@ -45,6 +45,7 @@
 /* Textures */
 
 typedef texture<float4, 1> texture_float4;
+typedef texture<float2, 1> texture_float2;
 typedef texture<float, 1> texture_float;
 typedef texture<uint, 1> texture_uint;
 typedef texture<int, 1> texture_int;
index 4e2b1ea7d139148ea188ff05bc31483c7e9df2ad..5b4290a77226fb6540e5ed9d9e5cc0a4a0429c01 100644 (file)
@@ -71,8 +71,8 @@ __device void differential_dudv(differential *du, differential *dv, float3 dPdu,
         * and the same for dudy and dvdy. the denominator is the same for both
         * solutions, so we compute it only once.
         *
-     * dP.dx = dPdu * dudx + dPdv * dvdx;
-     * dP.dy = dPdu * dudy + dPdv * dvdy; */
+        * dP.dx = dPdu * dudx + dPdv * dvdx;
+        * dP.dy = dPdu * dudy + dPdv * dvdy; */
 
        float det = (dPdu.x*dPdv.y - dPdv.x*dPdu.y);
 
index c39e5e43dbbce4baef44668af0818874fc4fe13b..73666892cf3d7e6e4722b77334ea6b859ffbdf0c 100644 (file)
@@ -18,7 +18,7 @@
 
 CCL_NAMESPACE_BEGIN
 
-__device void kernel_shader_evaluate(KernelGlobals *kg, uint4 *input, float3 *output, ShaderEvalType type, int i)
+__device void kernel_shader_evaluate(KernelGlobals *kg, uint4 *input, float4 *output, ShaderEvalType type, int i)
 {
        ShaderData sd;
        uint4 in = input[i];
@@ -62,7 +62,7 @@ __device void kernel_shader_evaluate(KernelGlobals *kg, uint4 *input, float3 *ou
        }
        
        /* write output */
-       output[i] = out;
+       output[i] = make_float4(out.x, out.y, out.z, 0.0f);
 }
 
 CCL_NAMESPACE_END
index b81db721eb3cf05695cc9599187a01d7ebff1a02..b3a5b2bfcb41da8734afd591330423485551e685 100644 (file)
@@ -25,21 +25,31 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando,
 {
        /* setup shading at emitter */
        ShaderData sd;
-
-       shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, u, v);
-       ls->Ng = sd.Ng;
-
-       /* no path flag, we're evaluating this for all closures. that's weak but
-          we'd have to do multiple evaluations otherwise */
-       shader_eval_surface(kg, &sd, rando, 0);
-       
        float3 eval;
 
-       /* evaluate emissive closure */
-       if(sd.flag & SD_EMISSION)
-               eval = shader_emissive_eval(kg, &sd);
-       else
-               eval = make_float3(0.0f, 0.0f, 0.0f);
+       if(ls->type == LIGHT_BACKGROUND) {
+               Ray ray;
+               ray.D = ls->D;
+               ray.P = ls->P;
+               ray.dP.dx = make_float3(0.0f, 0.0f, 0.0f);
+               ray.dP.dy = make_float3(0.0f, 0.0f, 0.0f);
+               shader_setup_from_background(kg, &sd, &ray);
+               eval = shader_eval_background(kg, &sd, 0);
+       }
+       else {
+               shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, u, v);
+               ls->Ng = sd.Ng;
+
+               /* no path flag, we're evaluating this for all closures. that's weak but
+                  we'd have to do multiple evaluations otherwise */
+               shader_eval_surface(kg, &sd, rando, 0);
+
+               /* evaluate emissive closure */
+               if(sd.flag & SD_EMISSION)
+                       eval = shader_emissive_eval(kg, &sd);
+               else
+                       eval = make_float3(0.0f, 0.0f, 0.0f);
+       }
 
        shader_release(kg, &sd);
 
@@ -47,52 +57,59 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando,
 }
 
 __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
-       float randt, float rando, float randu, float randv, Ray *ray, float3 *eval)
+       float randt, float rando, float randu, float randv, Ray *ray, BsdfEval *eval)
 {
        LightSample ls;
 
+       float pdf = -1.0f;
+
 #ifdef __MULTI_LIGHT__
        if(lindex != -1) {
                /* sample position on a specified light */
-               light_select(kg, lindex, randu, randv, sd->P, &ls);
+               light_select(kg, lindex, randu, randv, sd->P, &ls, &pdf);
        }
        else
 #endif
        {
                /* sample a light and position on int */
-               light_sample(kg, randt, randu, randv, sd->P, &ls);
+               light_sample(kg, randt, randu, randv, sd->P, &ls, &pdf);
        }
 
        /* compute pdf */
-       float pdf = light_sample_pdf(kg, &ls, -ls.D, ls.t);
+       if(pdf < 0.0f)
+               pdf = light_sample_pdf(kg, &ls, -ls.D, ls.t);
+
+       if(pdf == 0.0f)
+               return false;
 
        /* evaluate closure */
-       *eval = direct_emissive_eval(kg, rando, &ls, randu, randv, -ls.D);
+       float3 light_eval = direct_emissive_eval(kg, rando, &ls, randu, randv, -ls.D);
 
-       if(is_zero(*eval) || pdf == 0.0f)
+       if(is_zero(light_eval))
                return false;
 
        /* todo: use visbility flag to skip lights */
 
        /* evaluate BSDF at shading point */
        float bsdf_pdf;
-       float3 bsdf_eval = shader_bsdf_eval(kg, sd, ls.D, &bsdf_pdf);
-
-       *eval *= bsdf_eval/pdf;
 
-       if(is_zero(*eval))
-               return false;
+       shader_bsdf_eval(kg, sd, ls.D, eval, &bsdf_pdf);
 
-       if(ls.prim != ~0) {
+       if(ls.prim != ~0 || ls.type == LIGHT_BACKGROUND) {
                /* multiple importance sampling */
                float mis_weight = power_heuristic(pdf, bsdf_pdf);
-               *eval *= mis_weight;
+               light_eval *= mis_weight;
        }
        /* todo: clean up these weights */
        else if(ls.shader & SHADER_AREA_LIGHT)
-               *eval *= 0.25f; /* area lamp */
+               light_eval *= 0.25f; /* area lamp */
        else if(ls.t != FLT_MAX)
-               *eval *= 0.25f*M_1_PI_F; /* point lamp */
+               light_eval *= 0.25f*M_1_PI_F; /* point lamp */
+       
+       bsdf_eval_mul(eval, light_eval/pdf);
+
+       if(bsdf_eval_is_zero(eval))
+               return false;
 
        if(ls.shader & SHADER_CAST_SHADOW) {
                /* setup ray */
@@ -125,7 +142,8 @@ __device float3 indirect_emission(KernelGlobals *kg, ShaderData *sd, float t, in
        float3 L = shader_emissive_eval(kg, sd);
 
        if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_SAMPLE_AS_LIGHT)) {
-               /* multiple importance sampling */
+               /* multiple importance sampling, get triangle light pdf,
+                  and compute weight with respect to BSDF pdf */
                float pdf = triangle_light_pdf(kg, sd->Ng, sd->I, t);
                float mis_weight = power_heuristic(bsdf_pdf, pdf);
 
@@ -135,5 +153,34 @@ __device float3 indirect_emission(KernelGlobals *kg, ShaderData *sd, float t, in
        return L;
 }
 
+/* Indirect Background */
+
+__device float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf)
+{
+#ifdef __BACKGROUND__
+       /* evaluate background closure */
+       ShaderData sd;
+       shader_setup_from_background(kg, &sd, ray);
+       float3 L = shader_eval_background(kg, &sd, path_flag);
+       shader_release(kg, &sd);
+
+       /* check if background light exists or if we should skip pdf */
+       int res = kernel_data.integrator.pdf_background_res;
+
+       if(!(path_flag & PATH_RAY_MIS_SKIP) && res) {
+               /* multiple importance sampling, get background light pdf for ray
+                  direction, and compute weight with respect to BSDF pdf */
+               float pdf = background_light_pdf(kg, ray->D);
+               float mis_weight = power_heuristic(bsdf_pdf, pdf);
+
+               return L*mis_weight;
+       }
+
+       return L;
+#else
+       return make_float3(0.8f, 0.8f, 0.8f);
+#endif
+}
+
 CCL_NAMESPACE_END
 
index cd8acc9647abf76b5ef38b0586940b82b66f876a..d0fb5402291c1c8608317db8a3fda1d0c6f9d7f8 100644 (file)
@@ -48,15 +48,22 @@ __device uchar4 film_float_to_byte(float4 color)
        return result;
 }
 
-__device void kernel_film_tonemap(KernelGlobals *kg, __global uchar4 *rgba, __global float4 *buffer, int sample, int resolution, int x, int y, int offset, int stride)
+__device void kernel_film_tonemap(KernelGlobals *kg,
+       __global uchar4 *rgba, __global float *buffer,
+       int sample, int resolution, int x, int y, int offset, int stride)
 {
+       /* buffer offset */
        int index = offset + x + y*stride;
-       float4 irradiance = buffer[index];
 
+       rgba += index;
+       buffer += index*kernel_data.film.pass_stride;
+
+       /* map colors */
+       float4 irradiance = *(float4*)buffer;
        float4 float_result = film_map(kg, irradiance, sample);
        uchar4 byte_result = film_float_to_byte(float_result);
 
-       rgba[index] = byte_result;
+       *rgba = byte_result;
 }
 
 CCL_NAMESPACE_END
index d5d47b28d59858b2b718b38b05fdfab5f1da9e16..4c2b69c27163e7d24e2e0e14907fb808f3ea492d 100644 (file)
@@ -26,6 +26,7 @@ typedef struct LightSample {
        int object;
        int prim;
        int shader;
+       LightType type;
 } LightSample;
 
 /* Regular Light */
@@ -58,13 +59,125 @@ __device float3 area_light_sample(float3 axisu, float3 axisv, float randu, float
        return axisu*randu + axisv*randv;
 }
 
+__device float3 background_light_sample(KernelGlobals *kg, float randu, float randv, float *pdf)
+{
+       /* for the following, the CDF values are actually a pair of floats, with the
+          function value as X and the actual CDF as Y.  The last entry's function
+          value is the CDF total. */
+       int res = kernel_data.integrator.pdf_background_res;
+       int cdf_count = res + 1;
+
+       /* this is basically std::lower_bound as used by pbrt */
+       int first = 0;
+       int count = res;
+
+       while(count > 0) {
+               int step = count >> 1;
+               int middle = first + step;
+
+               if(kernel_tex_fetch(__light_background_marginal_cdf, middle).y < randv) {
+                       first = middle + 1;
+                       count -= step + 1;
+               }
+               else
+                       count = step;
+       }
+
+       int index_v = max(0, first - 1);
+       kernel_assert(index_v >= 0 && index_v < res);
+
+       float2 cdf_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v);
+       float2 cdf_next_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v + 1);
+       float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, res);
+
+       /* importance-sampled V direction */
+       float dv = (randv - cdf_v.y) / (cdf_next_v.y - cdf_v.y);
+       float v = (index_v + dv) / res;
+
+       /* this is basically std::lower_bound as used by pbrt */
+       first = 0;
+       count = res;
+       while(count > 0) {
+               int step = count >> 1;
+               int middle = first + step;
+
+               if(kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + middle).y < randu) {
+                       first = middle + 1;
+                       count -= step + 1;
+               }
+               else
+                       count = step;
+       }
+
+       int index_u = max(0, first - 1);
+       kernel_assert(index_u >= 0 && index_u < res);
+
+       float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + index_u);
+       float2 cdf_next_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + index_u + 1);
+       float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + res);
+
+       /* importance-sampled U direction */
+       float du = (randu - cdf_u.y) / (cdf_next_u.y - cdf_u.y);
+       float u = (index_u + du) / res;
+
+       /* spherical coordinates */
+       float theta = v * M_PI_F;
+       float phi = u * M_PI_F * 2.0f;
+
+       /* compute pdf */
+       float denom = cdf_last_u.x * cdf_last_v.x;
+       float sin_theta = sinf(theta);
+
+       if(sin_theta == 0.0f || denom == 0.0f)
+               *pdf = 0.0f;
+       else
+               *pdf = (cdf_u.x * cdf_v.x)/(2.0f * M_PI_F * M_PI_F * sin_theta * denom);
+
+       *pdf *= kernel_data.integrator.pdf_lights;
+
+       /* compute direction */
+       return spherical_to_direction(theta, phi);
+}
+
+__device float background_light_pdf(KernelGlobals *kg, float3 direction)
+{
+       float2 uv = direction_to_equirectangular(direction);
+       int res = kernel_data.integrator.pdf_background_res;
+
+       float sin_theta = sinf(uv.y * M_PI_F);
+
+       if(sin_theta == 0.0f)
+               return 0.0f;
+
+       int index_u = clamp((int)(uv.x * res), 0, res - 1);
+       int index_v = clamp((int)(uv.y * res), 0, res - 1);
+
+       /* pdfs in V direction */
+       float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * (res + 1) + res);
+       float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, res);
+
+       float denom = cdf_last_u.x * cdf_last_v.x;
+
+       if(denom == 0.0f)
+               return 0.0f;
+
+       /* pdfs in U direction */
+       float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * (res + 1) + index_u);
+       float2 cdf_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v);
+
+       float pdf = (cdf_u.x * cdf_v.x)/(2.0f * M_PI_F * M_PI_F * sin_theta * denom);
+
+       return pdf * kernel_data.integrator.pdf_lights;
+}
+
 __device void regular_light_sample(KernelGlobals *kg, int point,
-       float randu, float randv, float3 P, LightSample *ls)
+       float randu, float randv, float3 P, LightSample *ls, float *pdf)
 {
        float4 data0 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 0);
        float4 data1 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 1);
 
        LightType type = (LightType)__float_as_int(data0.x);
+       ls->type = type;
 
        if(type == LIGHT_DISTANT) {
                /* distant light */
@@ -79,6 +192,15 @@ __device void regular_light_sample(KernelGlobals *kg, int point,
                ls->D = -D;
                ls->t = FLT_MAX;
        }
+       else if(type == LIGHT_BACKGROUND) {
+               /* infinite area light (e.g. light dome or env light) */
+               float3 D = background_light_sample(kg, randu, randv, pdf);
+
+               ls->P = D;
+               ls->Ng = D;
+               ls->D = -D;
+               ls->t = FLT_MAX;
+       }
        else {
                ls->P = make_float3(data0.y, data0.z, data0.w);
 
@@ -139,6 +261,7 @@ __device void triangle_light_sample(KernelGlobals *kg, int prim, int object,
        ls->object = object;
        ls->prim = prim;
        ls->t = 0.0f;
+       ls->type = LIGHT_AREA;
 
 #ifdef __INSTANCING__
        /* instance transform */
@@ -192,7 +315,7 @@ __device int light_distribution_sample(KernelGlobals *kg, float randt)
 
 /* Generic Light */
 
-__device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float3 P, LightSample *ls)
+__device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float3 P, LightSample *ls, float *pdf)
 {
        /* sample index */
        int index = light_distribution_sample(kg, randt);
@@ -207,7 +330,7 @@ __device void light_sample(KernelGlobals *kg, float randt, float randu, float ra
        }
        else {
                int point = -prim-1;
-               regular_light_sample(kg, point, randu, randv, P, ls);
+               regular_light_sample(kg, point, randu, randv, P, ls, pdf);
        }
 
        /* compute incoming direction and distance */
@@ -227,9 +350,9 @@ __device float light_sample_pdf(KernelGlobals *kg, LightSample *ls, float3 I, fl
        return pdf;
 }
 
-__device void light_select(KernelGlobals *kg, int index, float randu, float randv, float3 P, LightSample *ls)
+__device void light_select(KernelGlobals *kg, int index, float randu, float randv, float3 P, LightSample *ls, float *pdf)
 {
-       regular_light_sample(kg, index, randu, randv, P, ls);
+       regular_light_sample(kg, index, randu, randv, P, ls, pdf);
 }
 
 __device float light_select_pdf(KernelGlobals *kg, LightSample *ls, float3 I, float t)
index df291b66b231746c193442c351efa953fed688ce..9776baf65e4dc984fc477fd2da7604a95e7024ba 100644 (file)
@@ -104,13 +104,13 @@ __device_inline void sample_uniform_hemisphere(const float3 N,
 
 __device float3 sample_uniform_sphere(float u1, float u2)
 {
-    float z = 1.0f - 2.0f*u1;
-    float r = sqrtf(fmaxf(0.0f, 1.0f - z*z));
-    float phi = 2.0f*M_PI_F*u2;
-    float x = r*cosf(phi);
-    float y = r*sinf(phi);
+       float z = 1.0f - 2.0f*u1;
+       float r = sqrtf(fmaxf(0.0f, 1.0f - z*z));
+       float phi = 2.0f*M_PI_F*u2;
+       float x = r*cosf(phi);
+       float y = r*sinf(phi);
 
-    return make_float3(x, y, z);
+       return make_float3(x, y, z);
 }
 
 __device float power_heuristic(float a, float b)
@@ -203,6 +203,28 @@ __device float3 spherical_to_direction(float theta, float phi)
                cosf(theta));
 }
 
+/* Equirectangular */
+
+__device float2 direction_to_equirectangular(float3 dir)
+{
+       float u = (atan2f(dir.y, dir.x) + M_PI_F)/(2.0f*M_PI_F);
+       float v = atan2f(dir.z, hypotf(dir.x, dir.y))/M_PI_F + 0.5f;
+
+       return make_float2(u, v);
+}
+
+__device float3 equirectangular_to_direction(float u, float v)
+{
+       /* XXX check correctness? */
+       float theta = M_PI_F*v;
+       float phi = 2.0f*M_PI_F*u;
+
+       return make_float3(
+               sin(theta)*cos(phi),
+               sin(theta)*sin(phi),
+               cos(theta));
+}
+
 CCL_NAMESPACE_END
 
 #endif /* __KERNEL_MONTECARLO_CL__ */
index b4c42d3bacc489ba81d070b0492d996cd8d773bf..318a6fea489cdb7ff88f6b77b4b74dd1d6000829 100644 (file)
@@ -64,5 +64,15 @@ __device_inline float object_surface_area(KernelGlobals *kg, int object)
        return f.x;
 }
 
+__device_inline float object_pass_id(KernelGlobals *kg, int object)
+{
+       if(object == ~0)
+               return 0.0f;
+
+       int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES;
+       float4 f = kernel_tex_fetch(__objects, offset);
+       return f.y;
+}
+
 CCL_NAMESPACE_END
 
index c437e06adfaaa1d4780a44718e9257a085ac6c07..393686bb2031209c4e7cd3a10018c81b7263ae6e 100644 (file)
@@ -35,21 +35,21 @@ CCL_NAMESPACE_BEGIN
 
 /* Path Tracing */
 
-void kernel_cpu_optimized_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state, int sample, int x, int y, int offset, int stride)
+void kernel_cpu_optimized_path_trace(KernelGlobals *kg, float *buffer, unsigned int *rng_state, int sample, int x, int y, int offset, int stride)
 {
        kernel_path_trace(kg, buffer, rng_state, sample, x, y, offset, stride);
 }
 
 /* Tonemapping */
 
-void kernel_cpu_optimized_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, int sample, int resolution, int x, int y, int offset, int stride)
+void kernel_cpu_optimized_tonemap(KernelGlobals *kg, uchar4 *rgba, float *buffer, int sample, int resolution, int x, int y, int offset, int stride)
 {
        kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y, offset, stride);
 }
 
 /* Shader Evaluate */
 
-void kernel_cpu_optimized_shader(KernelGlobals *kg, uint4 *input, float3 *output, int type, int i)
+void kernel_cpu_optimized_shader(KernelGlobals *kg, uint4 *input, float4 *output, int type, int i)
 {
        kernel_shader_evaluate(kg, input, output, (ShaderEvalType)type, i);
 }
diff --git a/intern/cycles/kernel/kernel_passes.h b/intern/cycles/kernel/kernel_passes.h
new file mode 100644 (file)
index 0000000..0e77581
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+CCL_NAMESPACE_BEGIN
+
+__device_inline void kernel_write_pass_float(__global float *buffer, int sample, float value)
+{
+       float *buf = buffer;
+       *buf = (sample == 0)? value: *buf + value;
+}
+
+__device_inline void kernel_write_pass_float3(__global float *buffer, int sample, float3 value)
+{
+       float3 *buf = (float3*)buffer;
+       *buf = (sample == 0)? value: *buf + value;
+}
+
+__device_inline void kernel_write_pass_float4(__global float *buffer, int sample, float4 value)
+{
+       float4 *buf = (float4*)buffer;
+       *buf = (sample == 0)? value: *buf + value;
+}
+
+__device_inline void kernel_clear_passes(__global float *buffer, int sample, int pass_stride)
+{
+#ifdef __PASSES__
+       if(sample == 0 && pass_stride != 4)
+               for(int i = 4; i < pass_stride; i++)
+                       buffer[i] = 0.0f;
+#endif
+}
+
+__device void kernel_write_data_passes(KernelGlobals *kg, __global float *buffer, PathRadiance *L,
+       ShaderData *sd, int sample, int path_flag, float3 throughput)
+{
+#ifdef __PASSES__
+       if(!(path_flag & PATH_RAY_CAMERA))
+               return;
+
+       int flag = kernel_data.film.pass_flag;
+
+       if(!(flag & PASS_ALL))
+               return;
+       
+       /* todo: add alpha treshold */
+       if(!(path_flag & PATH_RAY_TRANSPARENT)) {
+               if(sample == 0) {
+                       if(flag & PASS_DEPTH) {
+                               Transform tfm = kernel_data.cam.worldtocamera;
+                               float depth = len(transform(&tfm, sd->P));
+
+                               kernel_write_pass_float(buffer + kernel_data.film.pass_depth, sample, depth);
+                       }
+                       if(flag & PASS_OBJECT_ID) {
+                               float id = object_pass_id(kg, sd->object);
+                               kernel_write_pass_float(buffer + kernel_data.film.pass_object_id, sample, id);
+                       }
+                       if(flag & PASS_MATERIAL_ID) {
+                               float id = shader_pass_id(kg, sd);
+                               kernel_write_pass_float(buffer + kernel_data.film.pass_material_id, sample, id);
+                       }
+               }
+
+               if(flag & PASS_NORMAL) {
+                       float3 normal = sd->N;
+                       kernel_write_pass_float3(buffer + kernel_data.film.pass_normal, sample, normal);
+               }
+               if(flag & PASS_UV) {
+                       float3 uv = make_float3(0.0f, 0.0f, 0.0f); /* todo: request and lookup */
+                       kernel_write_pass_float3(buffer + kernel_data.film.pass_uv, sample, uv);
+               }
+       }
+
+       if(flag & (PASS_DIFFUSE_INDIRECT|PASS_DIFFUSE_COLOR|PASS_DIFFUSE_DIRECT))
+               L->color_diffuse += shader_bsdf_diffuse(kg, sd)*throughput;
+       if(flag & (PASS_GLOSSY_INDIRECT|PASS_GLOSSY_COLOR|PASS_GLOSSY_DIRECT))
+               L->color_glossy += shader_bsdf_glossy(kg, sd)*throughput;
+       if(flag & (PASS_TRANSMISSION_INDIRECT|PASS_TRANSMISSION_COLOR|PASS_TRANSMISSION_DIRECT))
+               L->color_transmission += shader_bsdf_transmission(kg, sd)*throughput;
+#endif
+}
+
+__device void kernel_write_light_passes(KernelGlobals *kg, __global float *buffer, PathRadiance *L, int sample)
+{
+#ifdef __PASSES__
+       int flag = kernel_data.film.pass_flag;
+
+       if(!kernel_data.film.use_light_pass)
+               return;
+       
+       if(flag & PASS_DIFFUSE_INDIRECT) {
+               float3 color = safe_divide_color(L->indirect_diffuse, L->color_diffuse);
+               kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_indirect, sample, color);
+       }
+       if(flag & PASS_GLOSSY_INDIRECT) {
+               float3 color = safe_divide_color(L->indirect_glossy, L->color_glossy);
+               kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_indirect, sample, color);
+       }
+       if(flag & PASS_TRANSMISSION_INDIRECT) {
+               float3 color = safe_divide_color(L->indirect_transmission, L->color_transmission);
+               kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_indirect, sample, color);
+       }
+       if(flag & PASS_DIFFUSE_DIRECT) {
+               float3 color = safe_divide_color(L->direct_diffuse, L->color_diffuse);
+               kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_direct, sample, color);
+       }
+       if(flag & PASS_GLOSSY_DIRECT) {
+               float3 color = safe_divide_color(L->direct_glossy, L->color_glossy);
+               kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_direct, sample, color);
+       }
+       if(flag & PASS_TRANSMISSION_DIRECT) {
+               float3 color = safe_divide_color(L->direct_transmission, L->color_transmission);
+               kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_direct, sample, color);
+       }
+
+       if(flag & PASS_EMISSION)
+               kernel_write_pass_float3(buffer + kernel_data.film.pass_emission, sample, L->emission);
+       if(flag & PASS_BACKGROUND)
+               kernel_write_pass_float3(buffer + kernel_data.film.pass_background, sample, L->background);
+
+       if(flag & PASS_DIFFUSE_COLOR)
+               kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_color, sample, L->color_diffuse);
+       if(flag & PASS_GLOSSY_COLOR)
+               kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_color, sample, L->color_glossy);
+       if(flag & PASS_TRANSMISSION_COLOR)
+               kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_color, sample, L->color_transmission);
+#endif
+}
+
+CCL_NAMESPACE_END
+
index d27ad861c6add93c300574dfaeaa925eaddc6e2a..c0bfa32040523388b7a1a4df90dee2a53df8d9d3 100644 (file)
 #else
 #include "kernel_bvh.h"
 #endif
+#include "kernel_accumulate.h"
 #include "kernel_camera.h"
 #include "kernel_shader.h"
 #include "kernel_light.h"
 #include "kernel_emission.h"
 #include "kernel_random.h"
+#include "kernel_passes.h"
 
 CCL_NAMESPACE_BEGIN
 
-#ifdef __MODIFY_TP__
-__device float3 path_terminate_modified_throughput(KernelGlobals *kg, __global float3 *buffer, int x, int y, int offset, int stride, int sample)
-{
-       /* modify throughput to influence path termination probability, to avoid
-          darker regions receiving fewer samples than lighter regions. also RGB
-          are weighted differently. proper validation still remains to be done. */
-       const float3 weights = make_float3(1.0f, 1.33f, 0.66f);
-       const float3 one = make_float3(1.0f, 1.0f, 1.0f);
-       const int minsample = 5;
-       const float minL = 0.1f;
-
-       if(sample >= minsample) {
-               float3 L = buffer[offset + x + y*stride];
-               float3 Lmin = make_float3(minL, minL, minL);
-               float correct = (float)(sample+1)/(float)sample;
-
-               L = film_map(L*correct, sample);
-
-               return weights/clamp(L, Lmin, one);
-       }
-
-       return weights;
-}
-#endif
-
 typedef struct PathState {
        uint flag;
        int bounce;
@@ -168,7 +145,7 @@ __device_inline float path_state_terminate_probability(KernelGlobals *kg, PathSt
        return average(throughput);
 }
 
-__device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ray, Intersection *isect, float3 *light_L)
+__device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ray, Intersection *isect, BsdfEval *L_light)
 {
        if(ray->t == 0.0f)
                return false;
@@ -208,7 +185,7 @@ __device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ra
                                }
 
                                if(!scene_intersect(kg, ray, PATH_RAY_SHADOW_TRANSPARENT, isect)) {
-                                       *light_L *= throughput;
+                                       bsdf_eval_mul(L_light, throughput);
                                        return false;
                                }
 
@@ -234,11 +211,14 @@ __device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ra
        return result;
 }
 
-__device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, Ray ray, float3 throughput)
+__device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, Ray ray, __global float *buffer)
 {
        /* initialize */
-       float3 L = make_float3(0.0f, 0.0f, 0.0f);
-       float Ltransparent = 0.0f;
+       PathRadiance L;
+       float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
+       float L_transparent = 0.0f;
+
+       path_radiance_init(&L, kernel_data.film.use_light_pass);
 
 #ifdef __EMISSION__
        float ray_pdf = 0.0f;
@@ -257,17 +237,12 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R
                if(!scene_intersect(kg, &ray, visibility, &isect)) {
                        /* eval background shader if nothing hit */
                        if(kernel_data.background.transparent && (state.flag & PATH_RAY_CAMERA)) {
-                               Ltransparent += average(throughput);
+                               L_transparent += average(throughput);
                        }
                        else {
-#ifdef __BACKGROUND__
-                               ShaderData sd;
-                               shader_setup_from_background(kg, &sd, &ray);
-                               L += throughput*shader_eval_background(kg, &sd, state.flag);
-                               shader_release(kg, &sd);
-#else
-                               L += throughput*make_float3(0.8f, 0.8f, 0.8f);
-#endif
+                               /* sample background shader */
+                               float3 L_background = indirect_background(kg, &ray, state.flag, ray_pdf);
+                               path_radiance_accum_background(&L, throughput, L_background, state.bounce);
                        }
 
                        break;
@@ -279,19 +254,24 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R
                float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF);
                shader_eval_surface(kg, &sd, rbsdf, state.flag);
 
+               kernel_write_data_passes(kg, buffer, &L, &sd, sample, state.flag, throughput);
+
 #ifdef __HOLDOUT__
                if((sd.flag & SD_HOLDOUT) && (state.flag & PATH_RAY_CAMERA)) {
                        float3 holdout_weight = shader_holdout_eval(kg, &sd);
 
                        if(kernel_data.background.transparent)
-                               Ltransparent += average(holdout_weight*throughput);
+                               /* any throughput is ok, should all be identical here */
+                               L_transparent += average(holdout_weight*throughput);
                }
 #endif
 
 #ifdef __EMISSION__
                /* emission */
-               if(sd.flag & SD_EMISSION)
-                       L += throughput*indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf);
+               if(sd.flag & SD_EMISSION) {
+                       float3 emission = indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf);
+                       path_radiance_accum_emission(&L, throughput, emission, state.bounce);
+               }
 #endif
 
                /* path termination. this is a strange place to put the termination, it's
@@ -315,7 +295,7 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R
                                float light_v = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT_V);
 
                                Ray light_ray;
-                               float3 light_L;
+                               BsdfEval L_light;
 
 #ifdef __MULTI_LIGHT__
                                /* index -1 means randomly sample from distribution */
@@ -325,10 +305,10 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R
 #else
                                const int i = -1;
 #endif
-                                       if(direct_emission(kg, &sd, i, light_t, light_o, light_u, light_v, &light_ray, &light_L)) {
+                                       if(direct_emission(kg, &sd, i, light_t, light_o, light_u, light_v, &light_ray, &L_light)) {
                                                /* trace shadow ray */
-                                               if(!shadow_blocked(kg, &state, &light_ray, &isect, &light_L))
-                                                       L += throughput*light_L;
+                                               if(!shadow_blocked(kg, &state, &light_ray, &isect, &L_light))
+                                                       path_radiance_accum_light(&L, throughput, &L_light, state.bounce);
                                        }
 #ifdef __MULTI_LIGHT__
                                }
@@ -343,7 +323,7 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R
 
                /* sample BSDF */
                float bsdf_pdf;
-               float3 bsdf_eval;
+               BsdfEval bsdf_eval;
                float3 bsdf_omega_in;
                differential3 bsdf_domega_in;
                float bsdf_u = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_U);
@@ -355,14 +335,14 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R
 
                shader_release(kg, &sd);
 
-               if(bsdf_pdf == 0.0f || is_zero(bsdf_eval))
+               if(bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval))
                        break;
 
                /* modify throughput */
-               throughput *= bsdf_eval/bsdf_pdf;
+               path_radiance_bsdf_bounce(&L, &throughput, &bsdf_eval, bsdf_pdf, state.bounce, label);
 
                /* set labels */
-#ifdef __EMISSION__
+#if defined(__EMISSION__) || defined(__BACKGROUND__)
                ray_pdf = bsdf_pdf;
 #endif
 
@@ -379,18 +359,33 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R
 #endif
        }
 
-       return make_float4(L.x, L.y, L.z, 1.0f - Ltransparent);
+       float3 L_sum = path_radiance_sum(&L);
+
+       kernel_write_light_passes(kg, buffer, &L, sample);
+
+       return make_float4(L_sum.x, L_sum.y, L_sum.z, 1.0f - L_transparent);
 }
 
-__device void kernel_path_trace(KernelGlobals *kg, __global float4 *buffer, __global uint *rng_state, int sample, int x, int y, int offset, int stride)
+__device void kernel_path_trace(KernelGlobals *kg,
+       __global float *buffer, __global uint *rng_state,
+       int sample, int x, int y, int offset, int stride)
 {
+       /* buffer offset */
+       int index = offset + x + y*stride;
+       int pass_stride = kernel_data.film.pass_stride;
+
+       rng_state += index;
+       buffer += index*pass_stride;
+
+       kernel_clear_passes(buffer, sample, pass_stride);
+
        /* initialize random numbers */
        RNG rng;
 
        float filter_u;
        float filter_v;
 
-       path_rng_init(kg, rng_state, sample, &rng, x, y, offset, stride, &filter_u, &filter_v);
+       path_rng_init(kg, rng_state, sample, &rng, x, y, &filter_u, &filter_v);
 
        /* sample camera ray */
        Ray ray;
@@ -401,23 +396,12 @@ __device void kernel_path_trace(KernelGlobals *kg, __global float4 *buffer, __gl
        camera_sample(kg, x, y, filter_u, filter_v, lens_u, lens_v, &ray);
 
        /* integrate */
-#ifdef __MODIFY_TP__
-       float3 throughput = path_terminate_modified_throughput(kg, buffer, x, y, offset, stride, sample);
-       float4 L = kernel_path_integrate(kg, &rng, sample, ray, throughput)/throughput;
-#else
-       float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
-       float4 L = kernel_path_integrate(kg, &rng, sample, ray, throughput);
-#endif
+       float4 L = kernel_path_integrate(kg, &rng, sample, ray, buffer);
 
        /* accumulate result in output buffer */
-       int index = offset + x + y*stride;
-
-       if(sample == 0)
-               buffer[index] = L;
-       else
-               buffer[index] += L;
+       kernel_write_pass_float4(buffer, sample, L);
 
-       path_rng_end(kg, rng_state, rng, x, y, offset, stride);
+       path_rng_end(kg, rng_state, rng);
 }
 
 CCL_NAMESPACE_END
index 41301ebd3dcee79ad4238005cad39a5616c48537..6d15100f8a32870c3d19bd101167d6055e2f2818 100644 (file)
@@ -123,7 +123,7 @@ __device_inline float path_rng(KernelGlobals *kg, RNG *rng, int sample, int dime
 #endif
 }
 
-__device_inline void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int sample, RNG *rng, int x, int y, int offset, int stride, float *fx, float *fy)
+__device_inline void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int sample, RNG *rng, int x, int y, float *fx, float *fy)
 {
 #ifdef __SOBOL_FULL_SCREEN__
        uint px, py;
@@ -135,19 +135,31 @@ __device_inline void path_rng_init(KernelGlobals *kg, __global uint *rng_state,
 
        *rng ^= kernel_data.integrator.seed;
 
-       *fx = size * (float)px * (1.0f/(float)0xFFFFFFFF) - x;
-       *fy = size * (float)py * (1.0f/(float)0xFFFFFFFF) - y;
+       if(sample == 0) {
+               *fx = 0.5f;
+               *fy = 0.5f;
+       }
+       else {
+               *fx = size * (float)px * (1.0f/(float)0xFFFFFFFF) - x;
+               *fy = size * (float)py * (1.0f/(float)0xFFFFFFFF) - y;
+       }
 #else
-       *rng = rng_state[offset + x + y*stride];
+       *rng = *rng_state;
 
        *rng ^= kernel_data.integrator.seed;
 
-       *fx = path_rng(kg, rng, sample, PRNG_FILTER_U);
-       *fy = path_rng(kg, rng, sample, PRNG_FILTER_V);
+       if(sample == 0) {
+               *fx = 0.5f;
+               *fy = 0.5f;
+       }
+       else {
+               *fx = path_rng(kg, rng, sample, PRNG_FILTER_U);
+               *fy = path_rng(kg, rng, sample, PRNG_FILTER_V);
+       }
 #endif
 }
 
-__device void path_rng_end(KernelGlobals *kg, __global uint *rng_state, RNG rng, int x, int y, int offset, int stride)
+__device void path_rng_end(KernelGlobals *kg, __global uint *rng_state, RNG rng)
 {
        /* nothing to do */
 }
@@ -163,21 +175,27 @@ __device float path_rng(KernelGlobals *kg, RNG *rng, int sample, int dimension)
        return (float)*rng * (1.0f/(float)0xFFFFFFFF);
 }
 
-__device void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int sample, RNG *rng, int x, int y, int offset, int stride, float *fx, float *fy)
+__device void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int sample, RNG *rng, int x, int y, float *fx, float *fy)
 {
        /* load state */
-       *rng = rng_state[offset + x + y*stride];
+       *rng = *rng_state;
 
        *rng ^= kernel_data.integrator.seed;
 
-       *fx = path_rng(kg, rng, sample, PRNG_FILTER_U);
-       *fy = path_rng(kg, rng, sample, PRNG_FILTER_V);
+       if(sample == 0) {
+               *fx = 0.5f;
+               *fy = 0.5f;
+       }
+       else {
+               *fx = path_rng(kg, rng, sample, PRNG_FILTER_U);
+               *fy = path_rng(kg, rng, sample, PRNG_FILTER_V);
+       }
 }
 
-__device void path_rng_end(KernelGlobals *kg, __global uint *rng_state, RNG rng, int x, int y, int offset, int stride)
+__device void path_rng_end(KernelGlobals *kg, __global uint *rng_state, RNG rng)
 {
        /* store state for next sample */
-       rng_state[offset + x + y*stride] = rng;
+       *rng_state = rng;
 }
 
 #endif
index 570e0721268a57fe57a09a73b47e43f02b42007b..1d2cf46aa566da67b863769d8b6c3d7b1a41a3e9 100644 (file)
@@ -75,7 +75,7 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
        if(sd->shader & SHADER_SMOOTH_NORMAL)
                sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
 
-       sd->flag = kernel_tex_fetch(__shader_flag, sd->shader & SHADER_MASK);
+       sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
 
 #ifdef __DPDU__
        /* dPdu/dPdv */
@@ -151,7 +151,7 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
                        instanced = true;
                else
 #endif
-                       sd->object = -sd->object-1;
+                       sd->object = ~sd->object;
 #ifdef __INSTANCING__
        }
 #endif
@@ -166,7 +166,7 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
 #endif
        }
 
-       sd->flag = kernel_tex_fetch(__shader_flag, sd->shader & SHADER_MASK);
+       sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
 
 #ifdef __DPDU__
        /* dPdu/dPdv */
@@ -243,7 +243,7 @@ __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData
        sd->Ng = -sd->P;
        sd->I = -sd->P;
        sd->shader = kernel_data.background.shader;
-       sd->flag = kernel_tex_fetch(__shader_flag, sd->shader & SHADER_MASK);
+       sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
 
 #ifdef __INSTANCING__
        sd->object = ~0;
@@ -275,8 +275,8 @@ __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData
 
 #ifdef __MULTI_CLOSURE__
 
-__device_inline float3 _shader_bsdf_multi_eval(const ShaderData *sd, const float3 omega_in, float *pdf,
-       int skip_bsdf, float3 sum_eval, float sum_pdf, float sum_sample_weight)
+__device_inline void _shader_bsdf_multi_eval(const ShaderData *sd, const float3 omega_in, float *pdf,
+       int skip_bsdf, BsdfEval *bsdf_eval, float sum_pdf, float sum_sample_weight)
 {
        for(int i = 0; i< sd->num_closure; i++) {
                if(i == skip_bsdf)
@@ -293,7 +293,7 @@ __device_inline float3 _shader_bsdf_multi_eval(const ShaderData *sd, const float
 #endif
 
                        if(bsdf_pdf != 0.0f) {
-                               sum_eval += eval*sc->weight;
+                               bsdf_eval_accum(bsdf_eval, sc->type, eval*sc->weight);
                                sum_pdf += bsdf_pdf*sc->sample_weight;
                        }
 
@@ -302,25 +302,27 @@ __device_inline float3 _shader_bsdf_multi_eval(const ShaderData *sd, const float
        }
 
        *pdf = sum_pdf/sum_sample_weight;
-       return sum_eval;
 }
 
 #endif
 
-__device float3 shader_bsdf_eval(KernelGlobals *kg, const ShaderData *sd,
-       const float3 omega_in, float *pdf)
+__device void shader_bsdf_eval(KernelGlobals *kg, const ShaderData *sd,
+       const float3 omega_in, BsdfEval *eval, float *pdf)
 {
 #ifdef __MULTI_CLOSURE__
-       return _shader_bsdf_multi_eval(sd, omega_in, pdf, -1, make_float3(0.0f, 0.0f, 0.0f), 0.0f, 0.0f);
+       bsdf_eval_init(eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass);
+
+       return _shader_bsdf_multi_eval(sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
 #else
        const ShaderClosure *sc = &sd->closure;
+
        *pdf = 0.0f;
-       return svm_bsdf_eval(sd, sc, omega_in, pdf)*sc->weight;
+       *eval = svm_bsdf_eval(sd, sc, omega_in, pdf)*sc->weight;
 #endif
 }
 
 __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
-       float randu, float randv, float3 *eval,
+       float randu, float randv, BsdfEval *bsdf_eval,
        float3 *omega_in, differential3 *domega_in, float *pdf)
 {
 #ifdef __MULTI_CLOSURE__
@@ -359,27 +361,28 @@ __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
 
        const ShaderClosure *sc = &sd->closure[sampled];
        int label;
+       float3 eval;
 
        *pdf = 0.0f;
 #ifdef __OSL__
-       label = OSLShader::bsdf_sample(sd, sc, randu, randv, *eval, *omega_in, *domega_in, *pdf);
+       label = OSLShader::bsdf_sample(sd, sc, randu, randv, eval, *omega_in, *domega_in, *pdf);
 #else
-       label = svm_bsdf_sample(sd, sc, randu, randv, eval, omega_in, domega_in, pdf);
+       label = svm_bsdf_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
 #endif
 
-       *eval *= sc->weight;
+       bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
 
        if(sd->num_closure > 1 && *pdf != 0.0f) {
                float sweight = sc->sample_weight;
-               *eval = _shader_bsdf_multi_eval(sd, *omega_in, pdf, sampled, *eval, *pdf*sweight, sweight);
+               _shader_bsdf_multi_eval(sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight);
        }
 
        return label;
 #else
        /* sample the single closure that we picked */
        *pdf = 0.0f;
-       int label = svm_bsdf_sample(sd, &sd->closure, randu, randv, eval, omega_in, domega_in, pdf);
-       *eval *= sd->closure.weight;
+       int label = svm_bsdf_sample(sd, &sd->closure, randu, randv, bsdf_eval, omega_in, domega_in, pdf);
+       *bsdf_eval *= sd->closure.weight;
        return label;
 #endif
 }
@@ -421,6 +424,68 @@ __device float3 shader_bsdf_transparency(KernelGlobals *kg, ShaderData *sd)
 #endif
 }
 
+__device float3 shader_bsdf_diffuse(KernelGlobals *kg, ShaderData *sd)
+{
+#ifdef __MULTI_CLOSURE__
+       float3 eval = make_float3(0.0f, 0.0f, 0.0f);
+
+       for(int i = 0; i< sd->num_closure; i++) {
+               ShaderClosure *sc = &sd->closure[i];
+
+               if(CLOSURE_IS_BSDF_DIFFUSE(sc->type))
+                       eval += sc->weight;
+       }
+
+       return eval;
+#else
+       if(CLOSURE_IS_BSDF_DIFFUSE(sd->closure.type))
+               return sd->closure.weight;
+       else
+               return make_float3(0.0f, 0.0f, 0.0f);
+#endif
+}
+
+__device float3 shader_bsdf_glossy(KernelGlobals *kg, ShaderData *sd)
+{
+#ifdef __MULTI_CLOSURE__
+       float3 eval = make_float3(0.0f, 0.0f, 0.0f);
+
+       for(int i = 0; i< sd->num_closure; i++) {
+               ShaderClosure *sc = &sd->closure[i];
+
+               if(CLOSURE_IS_BSDF_GLOSSY(sc->type))
+                       eval += sc->weight;
+       }
+
+       return eval;
+#else
+       if(CLOSURE_IS_BSDF_GLOSSY(sd->closure.type))
+               return sd->closure.weight;
+       else
+               return make_float3(0.0f, 0.0f, 0.0f);
+#endif
+}
+
+__device float3 shader_bsdf_transmission(KernelGlobals *kg, ShaderData *sd)
+{
+#ifdef __MULTI_CLOSURE__
+       float3 eval = make_float3(0.0f, 0.0f, 0.0f);
+
+       for(int i = 0; i< sd->num_closure; i++) {
+               ShaderClosure *sc = &sd->closure[i];
+
+               if(CLOSURE_IS_BSDF_TRANSMISSION(sc->type))
+                       eval += sc->weight;
+       }
+
+       return eval;
+#else
+       if(CLOSURE_IS_BSDF_TRANSMISSION(sd->closure.type))
+               return sd->closure.weight;
+       else
+               return make_float3(0.0f, 0.0f, 0.0f);
+#endif
+}
 
 /* Emission */
 
@@ -588,12 +653,17 @@ __device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
        int prim = kernel_tex_fetch(__prim_index, isect->prim);
        float4 Ns = kernel_tex_fetch(__tri_normal, prim);
        int shader = __float_as_int(Ns.w);
-       int flag = kernel_tex_fetch(__shader_flag, shader & SHADER_MASK);
+       int flag = kernel_tex_fetch(__shader_flag, (shader & SHADER_MASK)*2);
 
        return (flag & SD_HAS_SURFACE_TRANSPARENT) != 0;
 }
 #endif
 
+__device int shader_pass_id(KernelGlobals *kg, ShaderData *sd)
+{
+       return kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2 + 1);
+}
+
 /* Free ShaderData */
 
 __device void shader_release(KernelGlobals *kg, ShaderData *sd)
index 2bfb1b3b88e4470a9a2f1f4fef968ee683cc4719..ca7ae432efa314a596efe4440e428b7f5bf07dc2 100644 (file)
@@ -33,6 +33,8 @@ KERNEL_TEX(float4, texture_float4, __attributes_float3)
 /* lights */
 KERNEL_TEX(float4, texture_float4, __light_distribution)
 KERNEL_TEX(float4, texture_float4, __light_data)
+KERNEL_TEX(float2, texture_float2, __light_background_marginal_cdf)
+KERNEL_TEX(float2, texture_float2, __light_background_conditional_cdf)
 
 /* shaders */
 KERNEL_TEX(uint4, texture_uint4, __svm_nodes)
index 2c03a34df1fe4e57fd032fd91d95a7309c9a9194..b4b1da831627bcd93e040cbc2c25cd2dd011881b 100644 (file)
@@ -70,6 +70,9 @@ CCL_NAMESPACE_BEGIN
 #ifdef __KERNEL_ADV_SHADING__
 #define __MULTI_CLOSURE__
 #define __TRANSPARENT_SHADOWS__
+#ifdef __KERNEL_CPU__
+#define __PASSES__
+#endif
 #endif
 
 //#define __MULTI_LIGHT__
@@ -150,6 +153,75 @@ typedef enum ClosureLabel {
        LABEL_STOP = 2048
 } ClosureLabel;
 
+/* Render Passes */
+
+typedef enum PassType {
+       PASS_NONE = 0,
+       PASS_COMBINED = 1,
+       PASS_DEPTH = 2,
+       PASS_NORMAL = 8,
+       PASS_UV = 16,
+       PASS_OBJECT_ID = 32,
+       PASS_MATERIAL_ID = 64,
+       PASS_DIFFUSE_COLOR = 128,
+       PASS_GLOSSY_COLOR = 256,
+       PASS_TRANSMISSION_COLOR = 512,
+       PASS_DIFFUSE_INDIRECT = 1024,
+       PASS_GLOSSY_INDIRECT = 2048,
+       PASS_TRANSMISSION_INDIRECT = 4096,
+       PASS_DIFFUSE_DIRECT = 8192,
+       PASS_GLOSSY_DIRECT = 16384,
+       PASS_TRANSMISSION_DIRECT = 32768,
+       PASS_EMISSION = 65536,
+       PASS_BACKGROUND = 131072
+} PassType;
+
+#define PASS_ALL (~0)
+
+#ifdef __PASSES__
+
+typedef float3 PathThroughput;
+
+struct PathRadiance {
+       int use_light_pass;
+
+       float3 indirect;
+       float3 direct_throughput;
+       float3 direct_emission;
+
+       float3 color_diffuse;
+       float3 color_glossy;
+       float3 color_transmission;
+
+       float3 direct_diffuse;
+       float3 direct_glossy;
+       float3 direct_transmission;
+
+       float3 indirect_diffuse;
+       float3 indirect_glossy;
+       float3 indirect_transmission;
+
+       float3 emission;
+       float3 background;
+};
+
+struct BsdfEval {
+       int use_light_pass;
+
+       float3 diffuse;
+       float3 glossy;
+       float3 transmission;
+       float3 transparent;
+};
+
+#else
+
+typedef float3 PathThroughput;
+typedef float3 PathRadiance;
+typedef float3 BsdfEval;
+
+#endif
+
 /* Shader Flag */
 
 typedef enum ShaderFlag {
@@ -165,6 +237,7 @@ typedef enum ShaderFlag {
 typedef enum LightType {
        LIGHT_POINT,
        LIGHT_DISTANT,
+       LIGHT_BACKGROUND,
        LIGHT_AREA
 } LightType;
 
@@ -352,7 +425,32 @@ typedef struct KernelCamera {
 
 typedef struct KernelFilm {
        float exposure;
-       int pad1, pad2, pad3;
+       int pass_flag;
+       int pass_stride;
+       int use_light_pass;
+
+       int pass_combined;
+       int pass_depth;
+       int pass_normal;
+       int pass_pad;
+
+       int pass_uv;
+       int pass_object_id;
+       int pass_material_id;
+       int pass_diffuse_color;
+
+       int pass_glossy_color;
+       int pass_transmission_color;
+       int pass_diffuse_indirect;
+       int pass_glossy_indirect;
+
+       int pass_transmission_indirect;
+       int pass_diffuse_direct;
+       int pass_glossy_direct;
+       int pass_transmission_direct;
+
+       int pass_emission;
+       int pass_background;
 } KernelFilm;
 
 typedef struct KernelBackground {
@@ -379,18 +477,19 @@ typedef struct KernelIntegrator {
        int num_all_lights;
        float pdf_triangles;
        float pdf_lights;
+       int pdf_background_res;
 
        /* bounces */
        int min_bounce;
        int max_bounce;
 
-    int max_diffuse_bounce;
-    int max_glossy_bounce;
-    int max_transmission_bounce;
+       int max_diffuse_bounce;
+       int max_glossy_bounce;
+       int max_transmission_bounce;
 
        /* transparent */
-    int transparent_min_bounce;
-    int transparent_max_bounce;
+       int transparent_min_bounce;
+       int transparent_max_bounce;
        int transparent_shadows;
 
        /* caustics */
index 1a207d6c139ed2446ebff9b6de5595f04e735127..d3a1cf59a372918418d6341f98a40ff6d3763f0f 100644 (file)
@@ -20,6 +20,7 @@ set(SRC_OSL
        node_environment_texture.osl
        node_fresnel.osl
        node_gamma.osl
+       node_brightness.osl
        node_geometry.osl
        node_glass_bsdf.osl
        node_glossy_bsdf.osl
diff --git a/intern/cycles/kernel/osl/nodes/node_brightness.osl b/intern/cycles/kernel/osl/nodes/node_brightness.osl
new file mode 100644 (file)
index 0000000..a93ff06
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "stdosl.h"
+
+shader node_brightness(
+       color ColorIn = color(0.8, 0.8, 0.8),
+       float Bright = 0.0,
+       float Contrast = 0.0,
+       output ColorOut = color(0.8, 0.8, 0.8)
+{
+       float delta = Contrast * (1.0/200.0);
+       float a = 1.0 - delta * 2.0;
+       float b;
+
+       Bright *= 1.0/100.0;
+
+       /*
+       * The algorithm is by Werner D. Streidt
+       * (http://visca.com/ffactory/archives/5-99/msg00021.html)
+       * Extracted of OpenCV demhist.c
+       */
+
+       if (Contrast > 0.0) {
+               a = (a < 0.0 ? 1.0/a : 0.0);
+               b = a * (Brightness - delta);
+       }
+       else {
+               delta *= -1.0;
+               b = a * (Brightness + delta);
+       }
+
+       ColorOut = a * ColorIn + b;
+}
+
index d22c9181a84e091886fa8929048ab12eba5991d5..f1bae9c8d9f9f88dcc24f29fa6a2640825ddf520 100644 (file)
@@ -131,6 +131,7 @@ CCL_NAMESPACE_END
 #include "svm_hsv.h"
 #include "svm_image.h"
 #include "svm_gamma.h"
+#include "svm_brightness.h"
 #include "svm_invert.h"
 #include "svm_light_path.h"
 #include "svm_magic.h"
@@ -270,6 +271,9 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT
                        case NODE_GAMMA:
                                svm_node_gamma(sd, stack, node.y, node.z, node.w);
                                break;
+                       case NODE_BRIGHTCONTRAST:
+                               svm_node_brightness(sd, stack, node.y, node.z, node.w);
+                               break;
                        case NODE_MIX:
                                svm_node_mix(kg, sd, stack, node.y, node.z, node.w, &offset);
                                break;
diff --git a/intern/cycles/kernel/svm/svm_brightness.h b/intern/cycles/kernel/svm/svm_brightness.h
new file mode 100644 (file)
index 0000000..698899f
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+CCL_NAMESPACE_BEGIN
+
+__device void svm_node_brightness(ShaderData *sd, float *stack, uint in_color, uint out_color, uint node)
+{
+       uint bright_offset, contrast_offset;
+       float3 color = stack_load_float3(stack, in_color);
+
+       decode_node_uchar4(node, &bright_offset, &contrast_offset, NULL, NULL);
+       float brightness = stack_load_float(stack, bright_offset);
+       float contrast  = stack_load_float(stack, contrast_offset);
+
+       brightness *= 1.0f/100.0f;
+       float delta = contrast * (1.0f/200.0f);
+       float a = 1.0f - delta * 2.0f;
+       float b;
+
+       /*
+       * The algorithm is by Werner D. Streidt
+       * (http://visca.com/ffactory/archives/5-99/msg00021.html)
+       * Extracted of OpenCV demhist.c
+       */
+       if (contrast > 0.0f) {
+               a = (a > 0.0f? (1.0f / a): 0.0f);
+               b = a * (brightness - delta);
+       }
+       else {
+               delta *= -1.0f;
+               b = a * (brightness + delta);
+       }
+
+       color.x = a*color.x + b;
+       color.y = a*color.y + b;
+       color.z = a*color.z + b;
+
+       if (stack_valid(out_color))
+               stack_store_float3(stack, out_color, color);
+}
+
+CCL_NAMESPACE_END
index 62e24166970db8375f2214e5e31f0415ee31df98..073021bdd54f318b84aaf90ed6b6b1dacdcf7283 100644 (file)
@@ -175,9 +175,8 @@ __device void svm_node_tex_environment(KernelGlobals *kg, ShaderData *sd, float
        decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb);
 
        float3 co = stack_load_float3(stack, co_offset);
-       float u = (atan2f(co.y, co.x) + M_PI_F)/(2*M_PI_F);
-       float v = atan2f(co.z, hypotf(co.x, co.y))/M_PI_F + 0.5f;
-       float4 f = svm_image_texture(kg, id, u, v);
+       float2 uv = direction_to_equirectangular(co);
+       float4 f = svm_image_texture(kg, id, uv.x, uv.y);
        float3 r = make_float3(f.x, f.y, f.z);
 
        if(srgb) {
index 8203ed4c15ea12e4369af9550a5ffdc1638be093..533a2944557defa0ffde284646d498658a776f77 100644 (file)
@@ -87,7 +87,8 @@ typedef enum NodeType {
        NODE_INVERT = 5400,
        NODE_NORMAL = 5500,
        NODE_GAMMA = 5600,
-       NODE_TEX_CHECKER = 5700
+       NODE_TEX_CHECKER = 5700,
+       NODE_BRIGHTCONTRAST = 5800
 } NodeType;
 
 typedef enum NodeAttributeType {
@@ -265,22 +266,26 @@ typedef enum ShaderType {
 
 typedef enum ClosureType {
        CLOSURE_BSDF_ID,
+
        CLOSURE_BSDF_DIFFUSE_ID,
        CLOSURE_BSDF_OREN_NAYAR_ID,
-       CLOSURE_BSDF_TRANSLUCENT_ID,
+
        CLOSURE_BSDF_REFLECTION_ID,
-       CLOSURE_BSDF_REFRACTION_ID,
-       CLOSURE_BSDF_GLASS_ID,
-       CLOSURE_BSDF_TRANSPARENT_ID,
        CLOSURE_BSDF_MICROFACET_GGX_ID,
-       CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID,
        CLOSURE_BSDF_MICROFACET_BECKMANN_ID,
-       CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID,
        CLOSURE_BSDF_WARD_ID,
-       CLOSURE_BSDF_ASHIKHMIN_VELVET_ID,
-       CLOSURE_BSDF_WESTIN_BACKSCATTER_ID,
        CLOSURE_BSDF_WESTIN_SHEEN_ID,
 
+       CLOSURE_BSDF_TRANSLUCENT_ID,
+       CLOSURE_BSDF_REFRACTION_ID,
+       CLOSURE_BSDF_WESTIN_BACKSCATTER_ID,
+       CLOSURE_BSDF_ASHIKHMIN_VELVET_ID,
+       CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID,
+       CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID,
+       CLOSURE_BSDF_GLASS_ID,
+
+       CLOSURE_BSDF_TRANSPARENT_ID,
+
        CLOSURE_BSSRDF_CUBIC_ID,
        CLOSURE_EMISSION_ID,
        CLOSURE_DEBUG_ID,
@@ -296,7 +301,10 @@ typedef enum ClosureType {
 } ClosureType;
 
 /* watch this, being lazy with memory usage */
-#define CLOSURE_IS_BSDF(type) (type <= CLOSURE_BSDF_WESTIN_SHEEN_ID)
+#define CLOSURE_IS_BSDF(type) (type <= CLOSURE_BSDF_TRANSPARENT_ID)
+#define CLOSURE_IS_BSDF_DIFFUSE(type) (type >= CLOSURE_BSDF_DIFFUSE_ID && type <= CLOSURE_BSDF_OREN_NAYAR_ID)
+#define CLOSURE_IS_BSDF_GLOSSY(type) (type >= CLOSURE_BSDF_REFLECTION_ID && type <= CLOSURE_BSDF_WESTIN_SHEEN_ID)
+#define CLOSURE_IS_BSDF_TRANSMISSION(type) (type >= CLOSURE_BSDF_TRANSLUCENT_ID && type <= CLOSURE_BSDF_GLASS_ID)
 #define CLOSURE_IS_VOLUME(type) (type >= CLOSURE_VOLUME_ID && type <= CLOSURE_VOLUME_ISOTROPIC_ID)
 #define CLOSURE_IS_EMISSION(type) (type == CLOSURE_EMISSION_ID)
 #define CLOSURE_IS_HOLDOUT(type) (type == CLOSURE_HOLDOUT_ID)
index a6bbbc91901e536db3bc759fa582e9dfe7788e85..08dda9441119dba565a792c44ab9e570b86155c2 100644 (file)
@@ -22,6 +22,7 @@
 #include "device.h"
 
 #include "util_debug.h"
+#include "util_foreach.h"
 #include "util_hash.h"
 #include "util_image.h"
 #include "util_math.h"
 
 CCL_NAMESPACE_BEGIN
 
+/* Buffer Params */
+
+BufferParams::BufferParams()
+{
+       width = 0;
+       height = 0;
+
+       full_x = 0;
+       full_y = 0;
+       full_width = 0;
+       full_height = 0;
+
+       Pass::add(PASS_COMBINED, passes);
+}
+
+void BufferParams::get_offset_stride(int& offset, int& stride)
+{
+       offset = -(full_x + full_y*width);
+       stride = width;
+}
+
+bool BufferParams::modified(const BufferParams& params)
+{
+       return !(full_x == params.full_x
+               && full_y == params.full_y
+               && width == params.width
+               && height == params.height
+               && full_width == params.full_width
+               && full_height == params.full_height
+               && Pass::equals(passes, params.passes));
+}
+
+int BufferParams::get_passes_size()
+{
+       int size = 0;
+
+       foreach(Pass& pass, passes)
+               size += pass.components;
+       
+       return size;
+}
+
 /* Render Buffers */
 
 RenderBuffers::RenderBuffers(Device *device_)
@@ -64,7 +107,7 @@ void RenderBuffers::reset(Device *device, BufferParams& params_)
        device_free();
        
        /* allocate buffer */
-       buffer.resize(params.width, params.height);
+       buffer.resize(params.width*params.height*params.get_passes_size());
        device->mem_alloc(buffer, MEM_READ_WRITE);
        device->mem_zero(buffer);
 
@@ -82,31 +125,76 @@ void RenderBuffers::reset(Device *device, BufferParams& params_)
        device->mem_copy_to(rng_state);
 }
 
-float4 *RenderBuffers::copy_from_device(float exposure, int sample)
+bool RenderBuffers::copy_from_device()
 {
        if(!buffer.device_pointer)
-               return NULL;
+               return false;
 
        device->mem_copy_from(buffer, 0, params.width, params.height, sizeof(float4));
 
-       float4 *out = new float4[params.width*params.height];
-       float4 *in = (float4*)buffer.data_pointer;
-       float scale = 1.0f/(float)sample;
-       
-       for(int i = params.width*params.height - 1; i >= 0; i--) {
-               float4 rgba = in[i]*scale;
+       return true;
+}
+
+bool RenderBuffers::get_pass(PassType type, float exposure, int sample, int components, float *pixels)
+{
+       int pass_offset = 0;
+
+       foreach(Pass& pass, params.passes) {
+               if(pass.type != type) {
+                       pass_offset += pass.components;
+                       continue;
+               }
+
+               float *in = (float*)buffer.data_pointer + pass_offset;
+               int pass_stride = params.get_passes_size();
+
+               float scale = (pass.filter)? 1.0f/(float)sample: 1.0f;
+               float scale_exposure = (pass.exposure)? scale*exposure: scale;
+
+               int size = params.width*params.height;
+
+               if(components == 1) {
+                       assert(pass.components == components);
+
+                       /* scalar */
+                       for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
+                               float f = *in;
+
+                               pixels[0] = f*scale_exposure;
+                       }
+               }
+               else if(components == 3) {
+                       assert(pass.components == 4);
+
+                       /* RGB/vector */
+                       for(int i = 0; i < size; i++, in += pass_stride, pixels += 3) {
+                               float3 f = make_float3(in[0], in[1], in[2]);
+
+                               pixels[0] = f.x*scale_exposure;
+                               pixels[1] = f.y*scale_exposure;
+                               pixels[2] = f.z*scale_exposure;
+                       }
+               }
+               else if(components == 4) {
+                       assert(pass.components == components);
+
+                       /* RGBA */
+                       for(int i = 0; i < size; i++, in += pass_stride, pixels += 4) {
+                               float4 f = make_float4(in[0], in[1], in[2], in[3]);
 
-               rgba.x = rgba.x*exposure;
-               rgba.y = rgba.y*exposure;
-               rgba.z = rgba.z*exposure;
+                               pixels[0] = f.x*scale_exposure;
+                               pixels[1] = f.y*scale_exposure;
+                               pixels[2] = f.z*scale_exposure;
 
-               /* clamp since alpha might be > 1.0 due to russian roulette */
-               rgba.w = clamp(rgba.w, 0.0f, 1.0f);
+                               /* clamp since alpha might be > 1.0 due to russian roulette */
+                               pixels[3] = clamp(f.w*scale, 0.0f, 1.0f);
+                       }
+               }
 
-               out[i] = rgba;
+               return true;
        }
 
-       return out;
+       return false;
 }
 
 /* Display Buffer */
index f4a9b37c09ba4f1133bb1604fce79b657470c4ba..3062e5ae3e4701bcea5175bd17583f00ad5cb4a3 100644 (file)
 
 #include "device_memory.h"
 
+#include "film.h"
+
+#include "kernel_types.h"
+
 #include "util_string.h"
 #include "util_thread.h"
 #include "util_types.h"
@@ -45,32 +49,16 @@ public:
        int full_width;
        int full_height;
 
-       BufferParams()
-       {
-               width = 0;
-               height = 0;
-
-               full_x = 0;
-               full_y = 0;
-               full_width = 0;
-               full_height = 0;
-       }
-
-       void get_offset_stride(int& offset, int& stride)
-       {
-               offset = -(full_x + full_y*width);
-               stride = width;
-       }
-
-       bool modified(const BufferParams& params)
-       {
-               return !(full_x == params.full_x
-                       && full_y == params.full_y
-                       && width == params.width
-                       && height == params.height
-                       && full_width == params.full_width
-                       && full_height == params.full_height);
-       }
+       /* passes */
+       vector<Pass> passes;
+
+       /* functions */
+       BufferParams();
+
+       void get_offset_stride(int& offset, int& stride);
+       bool modified(const BufferParams& params);
+       void add_pass(PassType type);
+       int get_passes_size();
 };
 
 /* Render Buffers */
@@ -80,7 +68,7 @@ public:
        /* buffer parameters */
        BufferParams params;
        /* float buffer */
-       device_vector<float4> buffer;
+       device_vector<float> buffer;
        /* random number generator state */
        device_vector<uint> rng_state;
        /* mutex, must be locked manually by callers */
@@ -90,7 +78,9 @@ public:
        ~RenderBuffers();
 
        void reset(Device *device, BufferParams& params);
-       float4 *copy_from_device(float exposure, int sample);
+
+       bool copy_from_device();
+       bool get_pass(PassType type, float exposure, int sample, int components, float *pixels);
 
 protected:
        void device_free();
index 0ae2866f182262d495cb6b28d4dbafd2150b0cea..bc51384b873f3ff758b8f65dd8696cdb26aa20bf 100644 (file)
 #include "film.h"
 #include "scene.h"
 
+#include "util_foreach.h"
+
 CCL_NAMESPACE_BEGIN
 
+/* Pass */
+
+void Pass::add(PassType type, vector<Pass>& passes)
+{
+       Pass pass;
+
+       pass.type = type;
+       pass.filter = true;
+       pass.exposure = false;
+
+       switch(type) {
+               case PASS_NONE:
+                       pass.components = 0;
+                       break;
+               case PASS_COMBINED:
+                       pass.components = 4;
+                       pass.exposure = true;
+                       break;
+               case PASS_DEPTH:
+                       pass.components = 1;
+                       pass.filter = false;
+                       break;
+               case PASS_NORMAL:
+                       pass.components = 4;
+                       break;
+               case PASS_UV:
+                       pass.components = 4;
+                       break;
+               case PASS_OBJECT_ID:
+                       pass.components = 1;
+                       pass.filter = false;
+                       break;
+               case PASS_MATERIAL_ID:
+                       pass.components = 1;
+                       pass.filter = false;
+                       break;
+               case PASS_DIFFUSE_COLOR:
+                       pass.components = 4;
+                       break;
+               case PASS_GLOSSY_COLOR:
+                       pass.components = 4;
+                       break;
+               case PASS_TRANSMISSION_COLOR:
+                       pass.components = 4;
+                       break;
+               case PASS_DIFFUSE_INDIRECT:
+                       pass.components = 4;
+                       pass.exposure = true;
+                       break;
+               case PASS_GLOSSY_INDIRECT:
+                       pass.components = 4;
+                       pass.exposure = true;
+                       break;
+               case PASS_TRANSMISSION_INDIRECT:
+                       pass.components = 4;
+                       pass.exposure = true;
+                       break;
+               case PASS_DIFFUSE_DIRECT:
+                       pass.components = 4;
+                       pass.exposure = true;
+                       break;
+               case PASS_GLOSSY_DIRECT:
+                       pass.components = 4;
+                       pass.exposure = true;
+                       break;
+               case PASS_TRANSMISSION_DIRECT:
+                       pass.components = 4;
+                       pass.exposure = true;
+                       break;
+
+               case PASS_EMISSION:
+                       pass.components = 4;
+                       pass.exposure = true;
+                       break;
+               case PASS_BACKGROUND:
+                       pass.components = 4;
+                       pass.exposure = true;
+                       break;
+       }
+
+       passes.push_back(pass);
+}
+
+bool Pass::equals(const vector<Pass>& A, const vector<Pass>& B)
+{
+       if(A.size() != B.size())
+               return false;
+       
+       for(int i = 0; i < A.size(); i++)
+               if(A[i].type != B[i].type)
+                       return false;
+       
+       return true;
+}
+
+/* Film */
+
 Film::Film()
 {
        exposure = 0.8f;
+       Pass::add(PASS_COMBINED, passes);
        need_update = true;
 }
 
@@ -42,6 +142,82 @@ void Film::device_update(Device *device, DeviceScene *dscene)
 
        /* update __data */
        kfilm->exposure = exposure;
+       kfilm->pass_flag = 0;
+       kfilm->pass_stride = 0;
+       kfilm->use_light_pass = 0;
+
+       foreach(Pass& pass, passes) {
+               kfilm->pass_flag |= pass.type;
+
+               switch(pass.type) {
+                       case PASS_COMBINED:
+                               kfilm->pass_combined = kfilm->pass_stride;
+                               break;
+                       case PASS_DEPTH:
+                               kfilm->pass_depth = kfilm->pass_stride;
+                               break;
+                       case PASS_NORMAL:
+                               kfilm->pass_normal = kfilm->pass_stride;
+                               break;
+                       case PASS_UV:
+                               kfilm->pass_uv = kfilm->pass_stride;
+                               break;
+                       case PASS_OBJECT_ID:
+                               kfilm->pass_object_id = kfilm->pass_stride;
+                               break;
+                       case PASS_MATERIAL_ID:
+                               kfilm->pass_material_id = kfilm->pass_stride;
+                               break;
+                       case PASS_DIFFUSE_COLOR:
+                               kfilm->pass_diffuse_color = kfilm->pass_stride;
+                               kfilm->use_light_pass = 1;
+                               break;
+                       case PASS_GLOSSY_COLOR:
+                               kfilm->pass_glossy_color = kfilm->pass_stride;
+                               kfilm->use_light_pass = 1;
+                               break;
+                       case PASS_TRANSMISSION_COLOR:
+                               kfilm->pass_transmission_color = kfilm->pass_stride;
+                               kfilm->use_light_pass = 1;
+                               break;
+                       case PASS_DIFFUSE_INDIRECT:
+                               kfilm->pass_diffuse_indirect = kfilm->pass_stride;
+                               kfilm->use_light_pass = 1;
+                               break;
+                       case PASS_GLOSSY_INDIRECT:
+                               kfilm->pass_glossy_indirect = kfilm->pass_stride;
+                               kfilm->use_light_pass = 1;
+                               break;
+                       case PASS_TRANSMISSION_INDIRECT:
+                               kfilm->pass_transmission_indirect = kfilm->pass_stride;
+                               kfilm->use_light_pass = 1;
+                               break;
+                       case PASS_DIFFUSE_DIRECT:
+                               kfilm->pass_diffuse_direct = kfilm->pass_stride;
+                               kfilm->use_light_pass = 1;
+                               break;
+                       case PASS_GLOSSY_DIRECT:
+                               kfilm->pass_glossy_direct = kfilm->pass_stride;
+                               kfilm->use_light_pass = 1;
+                               break;
+                       case PASS_TRANSMISSION_DIRECT:
+                               kfilm->pass_transmission_direct = kfilm->pass_stride;
+                               kfilm->use_light_pass = 1;
+                               break;
+
+                       case PASS_EMISSION:
+                               kfilm->pass_emission = kfilm->pass_stride;
+                               kfilm->use_light_pass = 1;
+                               break;
+                       case PASS_BACKGROUND:
+                               kfilm->pass_background = kfilm->pass_stride;
+                               kfilm->use_light_pass = 1;
+                       case PASS_NONE:
+                               break;
+               }
+
+               kfilm->pass_stride += pass.components;
+       }
 
        need_update = false;
 }
@@ -52,7 +228,8 @@ void Film::device_free(Device *device, DeviceScene *dscene)
 
 bool Film::modified(const Film& film)
 {
-       return !(exposure == film.exposure);
+       return !(exposure == film.exposure
+               && Pass::equals(passes, film.passes));
 }
 
 void Film::tag_update(Scene *scene)
index df24fad3725f4d5026eab3bd3ef89ecae811b849..511ad316460483909e67e101f41ca9ddc538b062 100644 (file)
@@ -20,6 +20,9 @@
 #define __FILM_H__
 
 #include "util_string.h"
+#include "util_vector.h"
+
+#include "kernel_types.h"
 
 CCL_NAMESPACE_BEGIN
 
@@ -27,9 +30,21 @@ class Device;
 class DeviceScene;
 class Scene;
 
+class Pass {
+public:
+       PassType type;
+       int components;
+       bool filter;
+       bool exposure;
+
+       static void add(PassType type, vector<Pass>& passes);
+       static bool equals(const vector<Pass>& A, const vector<Pass>& B);
+};
+
 class Film {
 public:
        float exposure;
+       vector<Pass> passes;
        bool need_update;
 
        Film();
index 74943fd0ff7c549f35ebd6a3ee9dbcdcc939af97..777e764558f99ae760c11661b39348562671aba4 100644 (file)
 #include "util_foreach.h"
 #include "util_progress.h"
 
+#include "kernel_montecarlo.h"
+
 CCL_NAMESPACE_BEGIN
 
+static void dump_background_pixels(Device *device, DeviceScene *dscene, int res, vector<float3>& pixels)
+{
+       /* create input */
+       int width = res;
+       int height = res;
+
+       device_vector<uint4> d_input;
+       device_vector<float4> d_output;
+
+       uint4 *d_input_data = d_input.resize(width*height);
+
+       for(int y = 0; y < height; y++) {
+               for(int x = 0; x < width; x++) {
+                       float u = x/(float)width;
+                       float v = y/(float)height;
+                       float3 D = -equirectangular_to_direction(u, v);
+
+                       uint4 in = make_uint4(__float_as_int(D.x), __float_as_int(D.y), __float_as_int(D.z), 0);
+                       d_input_data[x + y*width] = in;
+               }
+       }
+
+       /* compute on device */
+       float4 *d_output_data = d_output.resize(width*height);
+       memset((void*)d_output.data_pointer, 0, d_output.memory_size());
+
+       device->const_copy_to("__data", &dscene->data, sizeof(dscene->data));
+
+       device->mem_alloc(d_input, MEM_READ_ONLY);
+       device->mem_copy_to(d_input);
+       device->mem_alloc(d_output, MEM_WRITE_ONLY);
+
+       DeviceTask main_task(DeviceTask::SHADER);
+       main_task.shader_input = d_input.device_pointer;
+       main_task.shader_output = d_output.device_pointer;
+       main_task.shader_eval_type = SHADER_EVAL_BACKGROUND;
+       main_task.shader_x = 0;
+       main_task.shader_w = width*height;
+
+       list<DeviceTask> split_tasks;
+       main_task.split_max_size(split_tasks, 128*128);
+
+       foreach(DeviceTask& task, split_tasks) {
+               device->task_add(task);
+               device->task_wait();
+       }
+
+       device->mem_copy_from(d_output, 0, 1, d_output.size(), sizeof(float4));
+       device->mem_free(d_input);
+       device->mem_free(d_output);
+
+       d_output_data = reinterpret_cast<float4*>(d_output.data_pointer);
+
+       pixels.resize(width*height);
+
+       for(int y = 0; y < height; y++) {
+               for(int x = 0; x < width; x++) {
+                       pixels[y*width + x].x = d_output_data[y*width + x].x;
+                       pixels[y*width + x].y = d_output_data[y*width + x].y;
+                       pixels[y*width + x].z = d_output_data[y*width + x].z;
+               }
+       }
+}
+
 /* Light */
 
 Light::Light()
@@ -44,6 +110,8 @@ Light::Light()
        axisv = make_float3(0.0f, 0.0f, 0.0f);
        sizev = 1.0f;
 
+       map_resolution = 512;
+
        cast_shadow = true;
        shader = 0;
 }
@@ -66,6 +134,8 @@ LightManager::~LightManager()
 
 void LightManager::device_update_distribution(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
 {
+       progress.set_status("Updating Lights", "Computing distribution");
+
        /* option to always sample all point lights */
        bool multi_light = false;
 
@@ -109,7 +179,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
 
        /* triangles */
        size_t offset = 0;
-       size_t j = 0;
+       int j = 0;
 
        foreach(Object *object, scene->objects) {
                Mesh *mesh = object->mesh;
@@ -128,7 +198,10 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
                /* sum area */
                if(have_emission) {
                        Transform tfm = object->tfm;
-                       int object_id = (mesh->transform_applied)? -j-1: j;
+                       int object_id = j;
+
+                       if(mesh->transform_applied)
+                               object_id = ~object_id;
 
                        for(size_t i = 0; i < mesh->triangles.size(); i++) {
                                Shader *shader = scene->shaders[mesh->shader[i]];
@@ -161,9 +234,9 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
        if(!multi_light) {
                float lightarea = (totarea > 0.0f)? totarea/scene->lights.size(): 1.0f;
 
-               for(size_t i = 0; i < scene->lights.size(); i++, offset++) {
+               for(int i = 0; i < scene->lights.size(); i++, offset++) {
                        distribution[offset].x = totarea;
-                       distribution[offset].y = __int_as_float(-i-1);
+                       distribution[offset].y = __int_as_float(~(int)i);
                        distribution[offset].z = 1.0f;
                        distribution[offset].w = scene->lights[i]->size;
                        totarea += lightarea;
@@ -229,6 +302,99 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
                dscene->light_distribution.clear();
 }
 
+void LightManager::device_update_background(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
+{
+       KernelIntegrator *kintegrator = &dscene->data.integrator;
+       Light *background_light = NULL;
+
+       /* find background light */
+       foreach(Light *light, scene->lights) {
+               if(light->type == LIGHT_BACKGROUND) {
+                       background_light = light;
+                       break;
+               }
+       }
+
+       /* no background light found, signal renderer to skip sampling */
+       if(!background_light) {
+               kintegrator->pdf_background_res = 0;
+               return;
+       }
+
+       progress.set_status("Updating Lights", "Importance map");
+
+       assert(kintegrator->use_direct_light);
+
+       /* get the resolution from the light's size (we stuff it in there) */
+       int res = background_light->map_resolution;
+       kintegrator->pdf_background_res = res;
+
+       assert(res > 0);
+
+       vector<float3> pixels;
+       dump_background_pixels(device, dscene, res, pixels);
+
+       if(progress.get_cancel())
+               return;
+
+       /* build row distributions and column distribution for the infinite area environment light */
+       int cdf_count = res + 1;
+       float2 *marg_cdf = dscene->light_background_marginal_cdf.resize(cdf_count);
+       float2 *cond_cdf = dscene->light_background_conditional_cdf.resize(cdf_count * cdf_count);
+
+       /* conditional CDFs (rows, U direction) */
+       for(int i = 0; i < res; i++) {
+               float sin_theta = sinf(M_PI_F * (i + 0.5f) / res);
+               float3 env_color = pixels[i * res];
+               float ave_luminamce = average(env_color);
+
+               cond_cdf[i * cdf_count].x = ave_luminamce * sin_theta;
+               cond_cdf[i * cdf_count].y = 0.0f;
+
+               for(int j = 1; j < res; j++) {
+                       env_color = pixels[i * res + j];
+                       ave_luminamce = average(env_color);
+
+                       cond_cdf[i * cdf_count + j].x = ave_luminamce * sin_theta;
+                       cond_cdf[i * cdf_count + j].y = cond_cdf[i * cdf_count + j - 1].y + cond_cdf[i * cdf_count + j - 1].x / res;
+               }
+
+               float cdf_total = cond_cdf[i * cdf_count + res - 1].y + cond_cdf[i * cdf_count + res - 1].x / res;
+
+               /* stuff the total into the brightness value for the last entry, because
+                  we are going to normalize the CDFs to 0.0 to 1.0 afterwards */
+               cond_cdf[i * cdf_count + res].x = cdf_total;
+
+               if(cdf_total > 0.0f)
+                       for(int j = 1; j < res; j++)
+                               cond_cdf[i * cdf_count + j].y /= cdf_total;
+
+               cond_cdf[i * cdf_count + res].y = 1.0f;
+       }
+
+       /* marginal CDFs (column, V direction, sum of rows) */
+       marg_cdf[0].x = cond_cdf[res].x;
+       marg_cdf[0].y = 0.0f;
+
+       for(int i = 1; i < res; i++) {
+               marg_cdf[i].x = cond_cdf[i * cdf_count + res].x;
+               marg_cdf[i].y = marg_cdf[i - 1].y + marg_cdf[i - 1].x / res;
+       }
+
+       float cdf_total = marg_cdf[res - 1].y + marg_cdf[res - 1].x / res;
+       marg_cdf[res].x = cdf_total;
+
+       if(cdf_total > 0.0f)
+               for(int i = 1; i < res; i++)
+                       marg_cdf[i].y /= cdf_total;
+
+       marg_cdf[res].y = 1.0f;
+
+       /* update device */
+       device->tex_alloc("__light_background_marginal_cdf", dscene->light_background_marginal_cdf);
+       device->tex_alloc("__light_background_conditional_cdf", dscene->light_background_conditional_cdf);
+}
+
 void LightManager::device_update_points(Device *device, DeviceScene *dscene, Scene *scene)
 {
        if(scene->lights.size() == 0)
@@ -261,6 +427,14 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
                        light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
                        light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
                }
+               else if(light->type == LIGHT_BACKGROUND) {
+                       shader_id &= ~SHADER_AREA_LIGHT;
+
+                       light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), 0.0f, 0.0f, 0.0f);
+                       light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), 0.0f, 0.0f, 0.0f);
+                       light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+                       light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+               }
                else if(light->type == LIGHT_AREA) {
                        float3 axisu = light->axisu*(light->sizeu*light->size);
                        float3 axisv = light->axisv*(light->sizev*light->size);
@@ -288,6 +462,9 @@ void LightManager::device_update(Device *device, DeviceScene *dscene, Scene *sce
        device_update_distribution(device, dscene, scene, progress);
        if(progress.get_cancel()) return;
 
+       device_update_background(device, dscene, scene, progress);
+       if(progress.get_cancel()) return;
+
        need_update = false;
 }
 
@@ -295,9 +472,13 @@ void LightManager::device_free(Device *device, DeviceScene *dscene)
 {
        device->tex_free(dscene->light_distribution);
        device->tex_free(dscene->light_data);
+       device->tex_free(dscene->light_background_marginal_cdf);
+       device->tex_free(dscene->light_background_conditional_cdf);
 
        dscene->light_distribution.clear();
        dscene->light_data.clear();
+       dscene->light_background_marginal_cdf.clear();
+       dscene->light_background_conditional_cdf.clear();
 }
 
 void LightManager::tag_update(Scene *scene)
index 19cbcb55386c0760512a5db3ddf883605c66f838..0ed143f5ad1b688ca5b44b5ad0a92ea267ca8b89 100644 (file)
@@ -46,6 +46,8 @@ public:
        float3 axisv;
        float sizev;
 
+       int map_resolution;
+
        bool cast_shadow;
 
        int shader;
@@ -68,6 +70,7 @@ public:
 protected:
        void device_update_points(Device *device, DeviceScene *dscene, Scene *scene);
        void device_update_distribution(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
+       void device_update_background(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
 };
 
 CCL_NAMESPACE_END
index c4f3e43bfba4e7ef109d6b894609cd8fc9c9c019..a6f8e3f6be88b3ff309c64028d68b0e2ab9fadc6 100644 (file)
@@ -89,7 +89,7 @@ bool MeshManager::displace(Device *device, Scene *scene, Mesh *mesh, Progress& p
                return false;
        
        /* run device task */
-       device_vector<float3> d_output;
+       device_vector<float4> d_output;
        d_output.resize(d_input.size());
 
        device->mem_alloc(d_input, MEM_READ_ONLY);
@@ -106,7 +106,7 @@ bool MeshManager::displace(Device *device, Scene *scene, Mesh *mesh, Progress& p
        device->task_add(task);
        device->task_wait();
 
-       device->mem_copy_from(d_output, 0, 1, d_output.size(), sizeof(float3));
+       device->mem_copy_from(d_output, 0, 1, d_output.size(), sizeof(float4));
        device->mem_free(d_input);
        device->mem_free(d_output);
 
@@ -118,7 +118,7 @@ bool MeshManager::displace(Device *device, Scene *scene, Mesh *mesh, Progress& p
        done.resize(mesh->verts.size(), false);
        int k = 0;
 
-       float3 *offset = (float3*)d_output.data_pointer;
+       float4 *offset = (float4*)d_output.data_pointer;
 
        for(size_t i = 0; i < mesh->triangles.size(); i++) {
                Mesh::Triangle t = mesh->triangles[i];
@@ -130,7 +130,8 @@ bool MeshManager::displace(Device *device, Scene *scene, Mesh *mesh, Progress& p
                for(int j = 0; j < 3; j++) {
                        if(!done[t.v[j]]) {
                                done[t.v[j]] = true;
-                               mesh->verts[t.v[j]] += offset[k++];
+                               float3 off = float4_to_float3(offset[k++]);
+                               mesh->verts[t.v[j]] += off;
                        }
                }
        }
index 7397c9c09af90a0e5c53b4ff97a462df1cc79516..982521b31f2dcd062110e54a8afa7b20e6b8fdf7 100644 (file)
@@ -1820,6 +1820,38 @@ void GammaNode::compile(OSLCompiler& compiler)
        compiler.add(this, "node_gamma");
 }
 
+/* Bright Contrast */
+BrightContrastNode::BrightContrastNode()
+: ShaderNode("brightness")
+{
+       add_input("Color", SHADER_SOCKET_COLOR);
+       add_input("Bright", SHADER_SOCKET_FLOAT);
+       add_input("Contrast", SHADER_SOCKET_FLOAT);
+       add_output("Color", SHADER_SOCKET_COLOR);
+}
+
+void BrightContrastNode::compile(SVMCompiler& compiler)
+{
+       ShaderInput *color_in = input("Color");
+       ShaderInput *bright_in = input("Bright");
+       ShaderInput *contrast_in = input("Contrast");
+       ShaderOutput *color_out = output("Color");
+
+       compiler.stack_assign(color_in);
+       compiler.stack_assign(bright_in);
+       compiler.stack_assign(contrast_in);
+       compiler.stack_assign(color_out);
+
+       compiler.add_node(NODE_BRIGHTCONTRAST,
+               color_in->stack_offset, color_out->stack_offset,
+               compiler.encode_uchar4(bright_in->stack_offset, contrast_in->stack_offset));
+}
+
+void BrightContrastNode::compile(OSLCompiler& compiler)
+{
+       compiler.add(this, "node_brightness");
+}
+
 /* Separate RGB */
 SeparateRGBNode::SeparateRGBNode()
 : ShaderNode("separate_rgb")
index c2f9ead5924132fc25f47e4a200ab777852177de..338af4ef48ac9c1158d7cae83a5f4986e99fb887 100644 (file)
@@ -320,6 +320,11 @@ public:
        SHADER_NODE_CLASS(GammaNode)
 };
 
+class BrightContrastNode : public ShaderNode {
+public:
+       SHADER_NODE_CLASS(BrightContrastNode)
+};
+
 class SeparateRGBNode : public ShaderNode {
 public:
        SHADER_NODE_CLASS(SeparateRGBNode)
index 3a9f0add735572e2b4e38f58c4a4d7a9c8a6ea8c..f83c85c632d03d3b43f1f0c674354084a99e3ce9 100644 (file)
@@ -36,6 +36,7 @@ Object::Object()
        mesh = NULL;
        tfm = transform_identity();
        visibility = ~0;
+       pass_id = 0;
 }
 
 Object::~Object()
@@ -135,6 +136,7 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
                /* todo: correct for displacement, and move to a better place */
                float uniform_scale;
                float surface_area = 0.0f;
+               float pass_id = ob->pass_id;
                
                if(transform_uniform_scale(tfm, uniform_scale)) {
                        map<Mesh*, float>::iterator it = surface_area_map.find(mesh);
@@ -171,7 +173,7 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
                memcpy(&objects[offset], &tfm, sizeof(float4)*4);
                memcpy(&objects[offset+4], &itfm, sizeof(float4)*4);
                memcpy(&objects[offset+8], &ntfm, sizeof(float4)*4);
-               objects[offset+12] = make_float4(surface_area, 0.0f, 0.0f, 0.0f);
+               objects[offset+12] = make_float4(surface_area, pass_id, 0.0f, 0.0f);
 
                i++;
 
index 7fe83cf7d914f1afcc67f1adc108bbd83f7a8c3d..14da2cfb35d4f4fa420be4cd0e3114f72a75acd3 100644 (file)
@@ -41,6 +41,7 @@ public:
        Transform tfm;
        BoundBox bounds;
        ustring name;
+       int pass_id;
        vector<ParamValue> attributes;
        uint visibility;
 
index 17bd7e20129642afa9965563e19a7d940091e5a1..4a5224f8a94f132c062a622002a0f111262eddb8 100644 (file)
@@ -78,6 +78,8 @@ public:
        /* lights */
        device_vector<float4> light_distribution;
        device_vector<float4> light_data;
+       device_vector<float2> light_background_marginal_cdf;
+       device_vector<float2> light_background_conditional_cdf;
 
        /* shaders */
        device_vector<uint4> svm_nodes;
index 6e827ec94bb623af7d499a30c6a57b51c0686987..12968a79ab2b26d343ea2056b29d0595adfc8dbd 100644 (file)
@@ -35,6 +35,7 @@ CCL_NAMESPACE_BEGIN
 Shader::Shader()
 {
        name = "";
+       pass_id = 0;
 
        graph = NULL;
        graph_bump = NULL;
@@ -167,7 +168,7 @@ void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Sc
        if(scene->shaders.size() == 0)
                return;
 
-       uint shader_flag_size = scene->shaders.size()*2;
+       uint shader_flag_size = scene->shaders.size()*4;
        uint *shader_flag = dscene->shader_flag.resize(shader_flag_size);
        uint i = 0;
 
@@ -184,7 +185,9 @@ void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Sc
                        flag |= SD_HOMOGENEOUS_VOLUME;
 
                shader_flag[i++] = flag;
+               shader_flag[i++] = shader->pass_id;
                shader_flag[i++] = flag;
+               shader_flag[i++] = shader->pass_id;
        }
 
        device->tex_alloc("__shader_flag", dscene->shader_flag);
index 45efa123ef678e1ab5d57c9d0e4eeb3f59bc3155..35f3cfe27f5e0d973ef0e965ea67d20060d97ded 100644 (file)
@@ -47,6 +47,7 @@ class Shader {
 public:
        /* name */
        string name;
+       int pass_id;
 
        /* shader graph */
        ShaderGraph *graph;
index dfdad22e17681aa0cd900715cbd48ec34a8a9ac8..582086d130b0b45db518616390ab07a8e0894a78 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <libavcodec/avcodec.h>
 #include <libavutil/rational.h>
+#include <libavutil/opt.h>
 
 #if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 101))
 #define FFMPEG_HAVE_PARSE_UTILS 1
index 3ec8d3d2fbf9181ca94ef7ff214d94927fef5430..ee67694760bc72f1c62d7214c7c5863fbcebbb96 100644 (file)
@@ -271,6 +271,15 @@ public:
         */
        virtual GHOST_TSuccess beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow** window,
                const bool stereoVisual, const GHOST_TUns16 numOfAASamples=0) = 0;
+       
+       /**
+        * Updates the resolution while in fullscreen mode.
+        * @param setting       The new setting of the display.
+        * @param window        Window displayed in full screen.
+        *
+        * @return      Indication of success.
+        */
+       virtual GHOST_TSuccess updateFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow** window) = 0;
 
        /**
         * Ends full screen mode.
index be5d45128f9fdbae8d7e039baad5fa9e51848b17..0f5149de03716c1af8b5d4bd33531d179a90fca1 100644 (file)
@@ -77,6 +77,12 @@ static const char* ndof_button_names[] = {
        "NDOF_BUTTON_8",
        "NDOF_BUTTON_9",
        "NDOF_BUTTON_10",
+       // more general-purpose buttons
+       "NDOF_BUTTON_A",
+       "NDOF_BUTTON_B",
+       "NDOF_BUTTON_C",
+       // the end
+       "NDOF_BUTTON_LAST"
 };
 #endif
 
@@ -137,8 +143,39 @@ static const NDOF_ButtonT SpacePilotPro_HID_map[] = {
        NDOF_BUTTON_MINUS
 };
 
+// latest HW: button-compatible with SpacePilotPro, just fewer of them
+static const NDOF_ButtonT SpaceMousePro_HID_map[] = {
+       NDOF_BUTTON_MENU,
+       NDOF_BUTTON_FIT,
+       NDOF_BUTTON_TOP,
+       NDOF_BUTTON_NONE, // left
+       NDOF_BUTTON_RIGHT,
+       NDOF_BUTTON_FRONT,
+       NDOF_BUTTON_NONE, // bottom
+       NDOF_BUTTON_NONE, // back
+       NDOF_BUTTON_ROLL_CW,
+       NDOF_BUTTON_NONE, // roll ccw
+       NDOF_BUTTON_NONE, // iso 1
+       NDOF_BUTTON_NONE, // iso 2
+       NDOF_BUTTON_1,
+       NDOF_BUTTON_2,
+       NDOF_BUTTON_3,
+       NDOF_BUTTON_4,
+       NDOF_BUTTON_NONE, // 5
+       NDOF_BUTTON_NONE, // 6
+       NDOF_BUTTON_NONE, // 7
+       NDOF_BUTTON_NONE, // 8
+       NDOF_BUTTON_NONE, // 9
+       NDOF_BUTTON_NONE, // 10
+       NDOF_BUTTON_NONE, // esc key
+       NDOF_BUTTON_NONE, // alt key
+       NDOF_BUTTON_NONE, // shift key
+       NDOF_BUTTON_NONE, // ctrl key
+       NDOF_BUTTON_ROTATE,
+};
+
 /* this is the older SpacePilot (sans Pro)
- * thanks to polosson for the info in this table */
+ * thanks to polosson for info about this device */
 static const NDOF_ButtonT SpacePilot_HID_map[] = {
        NDOF_BUTTON_1,
        NDOF_BUTTON_2,
@@ -163,6 +200,23 @@ static const NDOF_ButtonT SpacePilot_HID_map[] = {
        NDOF_BUTTON_NONE // the CONFIG button -- what does it do?
 };
 
+/* this is the older Spaceball 5000 USB
+ * thanks to Tehrasha Darkon for info about this device */
+static const NDOF_ButtonT Spaceball5000_HID_map[] = {
+       NDOF_BUTTON_1,
+       NDOF_BUTTON_2,
+       NDOF_BUTTON_3,
+       NDOF_BUTTON_4,
+       NDOF_BUTTON_5,
+       NDOF_BUTTON_6,
+       NDOF_BUTTON_7,
+       NDOF_BUTTON_8,
+       NDOF_BUTTON_9,
+       NDOF_BUTTON_A,
+       NDOF_BUTTON_B,
+       NDOF_BUTTON_C
+};
+
 GHOST_NDOFManager::GHOST_NDOFManager(GHOST_System& sys)
        : m_system(sys)
        , m_deviceType(NDOF_UnknownDevice) // each platform has its own device detection code
@@ -206,10 +260,16 @@ bool GHOST_NDOFManager::setDevice(unsigned short vendor_id, unsigned short produ
                                        m_buttonCount = 15;
                                        break;
                                case 0xC629:
-                                       puts("ndof: using SpacePilotPro");
+                                       puts("ndof: using SpacePilot Pro");
                                        m_deviceType = NDOF_SpacePilotPro;
                                        m_buttonCount = 31;
                                        break;
+                               case 0xC62B:
+                                       puts("ndof: using SpaceMouse Pro");
+                                       m_deviceType = NDOF_SpaceMousePro;
+                                       m_buttonCount = 27;
+                                       // ^^ actually has 15 buttons, but their HID codes range from 0 to 26
+                                       break;
 
                                // -- older devices --
                                case 0xC625:
@@ -218,6 +278,12 @@ bool GHOST_NDOFManager::setDevice(unsigned short vendor_id, unsigned short produ
                                        m_buttonCount = 21;
                                        break;
 
+                               case 0xC621:
+                                       puts("ndof: using Spaceball 5000");
+                                       m_deviceType = NDOF_Spaceball5000;
+                                       m_buttonCount = 12;
+                                       break;
+
                                case 0xC623:
                                        puts("ndof: SpaceTraveler not supported, please file a bug report");
                                        m_buttonCount = 8;
@@ -237,6 +303,8 @@ bool GHOST_NDOFManager::setDevice(unsigned short vendor_id, unsigned short produ
        else {
                m_buttonMask = ~(-1 << m_buttonCount);
 
+               // special case for SpaceMousePro? maybe...
+
 #ifdef DEBUG_NDOF_BUTTONS
                printf("ndof: %d buttons -> hex:%X\n", m_buttonCount, m_buttonMask);
 #endif
@@ -261,6 +329,16 @@ void GHOST_NDOFManager::updateRotation(short r[3], GHOST_TUns64 time)
 
 void GHOST_NDOFManager::sendButtonEvent(NDOF_ButtonT button, bool press, GHOST_TUns64 time, GHOST_IWindow* window)
 {
+       if (button == NDOF_BUTTON_NONE) {
+               // just being exceptionally cautious...
+               // air-tight button masking and proper function key emulation
+               // should guarantee we never get to this point
+#ifdef DEBUG_NDOF_BUTTONS
+               printf("discarding NDOF_BUTTON_NONE (should not escape the NDOF manager)\n");
+#endif
+               return;
+       }
+
        GHOST_EventNDOFButton* event = new GHOST_EventNDOFButton(time, window);
        GHOST_TEventNDOFButtonData* data = (GHOST_TEventNDOFButtonData*) event->getData();
 
@@ -317,6 +395,15 @@ void GHOST_NDOFManager::updateButton(int button_number, bool press, GHOST_TUns64
                                default: sendButtonEvent(SpacePilotPro_HID_map[button_number], press, time, window);
                        }
                        break;
+               case NDOF_SpaceMousePro:
+                       switch (button_number) {
+                               case 22: sendKeyEvent(GHOST_kKeyEsc, press, time, window); break;
+                               case 23: sendKeyEvent(GHOST_kKeyLeftAlt, press, time, window); break;
+                               case 24: sendKeyEvent(GHOST_kKeyLeftShift, press, time, window); break;
+                               case 25: sendKeyEvent(GHOST_kKeyLeftControl, press, time, window); break;
+                               default: sendButtonEvent(SpaceMousePro_HID_map[button_number], press, time, window);
+                       }
+                       break;
                case NDOF_SpacePilot:
                        switch (button_number) {
                                case 10: sendKeyEvent(GHOST_kKeyEsc, press, time, window); break;
@@ -327,8 +414,21 @@ void GHOST_NDOFManager::updateButton(int button_number, bool press, GHOST_TUns64
                                default: sendButtonEvent(SpacePilot_HID_map[button_number], press, time, window);
                        }
                        break;
+               case NDOF_Spaceball5000:
+                       // has no special 'keyboard' buttons
+                       sendButtonEvent(Spaceball5000_HID_map[button_number], press, time, window);
+                       break;
                case NDOF_UnknownDevice:
-                       printf("ndof: button %d on unknown device (ignoring)\n", button_number);
+                       printf("ndof: button %d on unknown device (", button_number);
+                       // map to the 'general purpose' buttons
+                       // this is mainly for old serial devices
+                       if (button_number < NDOF_BUTTON_LAST - NDOF_BUTTON_1) {
+                               printf("sending)\n");
+                               sendButtonEvent((NDOF_ButtonT)(NDOF_BUTTON_1 + button_number), press, time, window);
+                       }
+                       else {
+                               printf("discarding)\n");
+                       }
        }
 
        int mask = 1 << button_number;
index 34759035664b68168afb6f99899ecac9f14ca5a9..c4e980bb89502bcae8ce20b6dbdb4c8487773cd4 100644 (file)
@@ -37,9 +37,11 @@ typedef enum {
        NDOF_SpaceNavigator,
        NDOF_SpaceExplorer,
        NDOF_SpacePilotPro,
+       NDOF_SpaceMousePro,
 
        // older devices
-       NDOF_SpacePilot
+       NDOF_SpacePilot,
+       NDOF_Spaceball5000
 
        } NDOF_DeviceT;
 
@@ -86,7 +88,12 @@ typedef enum {
        NDOF_BUTTON_8,
        NDOF_BUTTON_9,
        NDOF_BUTTON_10,
-
+       // more general-purpose buttons
+       NDOF_BUTTON_A,
+       NDOF_BUTTON_B,
+       NDOF_BUTTON_C,
+       // the end
+       NDOF_BUTTON_LAST
        } NDOF_ButtonT;
 
 class GHOST_NDOFManager
index 4efdcbc6519b590ae330752dd009c326c8b798dc..944ade3f22b1e819504fc5bc2c0dd49f3153fd00 100644 (file)
@@ -168,6 +168,19 @@ GHOST_TSuccess GHOST_System::beginFullScreen(const GHOST_DisplaySetting& setting
 }
 
 
+GHOST_TSuccess GHOST_System::updateFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow** window)
+{
+       GHOST_TSuccess success = GHOST_kFailure;
+       GHOST_ASSERT(m_windowManager, "GHOST_System::updateFullScreen(): invalid window manager");
+       if(m_displayManager) {
+               if (m_windowManager->getFullScreen()) {
+                       success = m_displayManager->setCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay, setting);
+               }
+       }
+
+       return success;
+}
+
 GHOST_TSuccess GHOST_System::endFullScreen(void)
 {
        GHOST_TSuccess success = GHOST_kFailure;
index 6286121719d47e1be3324c551867b0cee78d561e..0bb0387a28786e41da311e6da48969167561a61f 100644 (file)
@@ -145,6 +145,15 @@ public:
         */
        virtual GHOST_TSuccess beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow** window,
                const bool stereoVisual, const GHOST_TUns16 numOfAASamples=0);
+               
+       /**
+        * Updates the resolution while in fullscreen mode.
+        * @param setting       The new setting of the display.
+        * @param window        Window displayed in full screen.
+        *
+        * @return      Indication of success.
+        */
+       virtual GHOST_TSuccess updateFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow** window);
 
        /**
         * Ends full screen mode.
index 4bf4edaf092d7b2f5b5742ee0f3d3fa157383892..22c16009591840b09ec591386b270d4f6e866e41 100644 (file)
@@ -422,6 +422,8 @@ processEvents(
        return anyProcessed;
 }
 
+
+#ifdef WITH_X11_XINPUT
 /* set currently using tablet mode (stylus or eraser) depending on device ID */
 static void setTabletMode(GHOST_WindowX11 * window, XID deviceid)
 {
@@ -430,6 +432,7 @@ static void setTabletMode(GHOST_WindowX11 * window, XID deviceid)
        else if(deviceid == window->GetXTablet().EraserID)
                window->GetXTablet().CommonData.Active= GHOST_kTabletModeEraser;
 }
+#endif /* WITH_X11_XINPUT */
 
        void
 GHOST_SystemX11::processEvent(XEvent *xe)
index 4a9b6b0e96e0c6170eeda96024c3797de236f9d1..5e1e5d0d778e01efad5e19489e0118e8d05268c7 100644 (file)
@@ -219,7 +219,8 @@ kmi.properties.value_1 = 'DISABLED'
 kmi.properties.value_2 = 'ENABLED'
 kmi = km.keymap_items.new('view3d.game_start', 'P', 'PRESS')
 kmi = km.keymap_items.new('object.select_all', 'A', 'PRESS')
-kmi = km.keymap_items.new('object.select_all', 'I', 'PRESS', ctrl=True).action = 'INVERT'
+kmi = km.keymap_items.new('object.select_all', 'I', 'PRESS', ctrl=True)
+kmi.properties.action = 'INVERT'
 kmi = km.keymap_items.new('object.select_linked', 'L', 'PRESS', shift=True)
 kmi = km.keymap_items.new('object.select_grouped', 'G', 'PRESS', shift=True)
 kmi = km.keymap_items.new('object.select_mirror', 'M', 'PRESS', shift=True, ctrl=True)
index 9be3b00e4cfc3bbdc91746cce7759969f655e388..766daba58b8388ed6ce7cad659effcfb2cf876fa 100644 (file)
@@ -814,12 +814,13 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
 
     def REMESH(self, layout, ob, md):
         layout.prop(md, "mode")
-
-        layout.prop(md, "octree_depth")
-        layout.prop(md, "scale")
+        
         row = layout.row()
-        row.active = md.mode == "SHARP"
-        row.prop(md, "sharpness")
+        row.prop(md, "octree_depth")
+        row.prop(md, "scale")
+
+        if md.mode == "SHARP":
+            layout.prop(md, "sharpness")
 
         layout.prop(md, "remove_disconnected_pieces")
         row = layout.row()
index 5e68351d9e6e4dbf65928c50e479d0894b85955c..4e511f18cd4dfd76650780a1160325573576590d 100644 (file)
@@ -911,7 +911,7 @@ class PARTICLE_PT_render(ParticleButtonsPanel, Panel):
                 col.prop_search(psys, "billboard_time_index_uv", ob.data, "uv_textures")
 
             split = layout.split(percentage=0.33)
-            split.label(text="Split uv's:")
+            split.label(text="Split UVs:")
             split.prop(part, "billboard_uv_split", text="Number of splits")
 
             if psys:
index 32b9450452573e4d21fa36fc52d3eb1c09f1824c..dc64aacf043da6edf920a70141284e5963612ce7 100644 (file)
@@ -87,6 +87,7 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel):
         col.label(text="Damping:")
         col.prop(cloth, "spring_damping", text="Spring")
         col.prop(cloth, "air_damping", text="Air")
+        col.prop(cloth, "vel_damping", text="Velocity")
 
         col.prop(cloth, "use_pin_cloth", text="Pinning")
         sub = col.column()
index bf8d7d8552f03bf8d3c6dd8858732d3906d5733f..e6801f00fce0e7397f382b175f4bb7b342021c9a 100644 (file)
@@ -412,14 +412,14 @@ class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel):
             col.prop(brush, "paint_distance", text="Paint Distance")
             split = layout.row().split(percentage=0.4)
             sub = split.column()
-            if brush.paint_source == 'DISTANCE':
+            if brush.paint_source in {'DISTANCE', 'VOLUME_DISTANCE'}:
                 sub.prop(brush, "use_proximity_project")
-            elif brush.paint_source == 'VOLUME_DISTANCE':
+            if brush.paint_source == 'VOLUME_DISTANCE':
                 sub.prop(brush, "invert_proximity")
                 sub.prop(brush, "use_negative_volume")
 
             sub = split.column()
-            if brush.paint_source == 'DISTANCE':
+            if brush.paint_source in {'DISTANCE', 'VOLUME_DISTANCE'}:
                 column = sub.column()
                 column.active = brush.use_proximity_project
                 column.prop(brush, "ray_direction")
index 8717a9b91140d591d5d3a4f757e9e8502af3b078..114d74f1060d5b7ef95a47d15fc043ab1d6bba1e 100644 (file)
@@ -79,6 +79,7 @@ class PHYSICS_PT_fluid(PhysicButtonsPanel, Panel):
             sub = col.column(align=True)
             sub.prop(fluid, "start_time", text="Start")
             sub.prop(fluid, "end_time", text="End")
+            col.prop(fluid, "simulation_rate", text="Speed")
 
             col = split.column()
             col.label()
@@ -230,6 +231,10 @@ class PHYSICS_PT_domain_gravity(PhysicButtonsPanel, Panel):
         if fluid.viscosity_preset == 'MANUAL':
             sub.prop(fluid, "viscosity_base", text="Base")
             sub.prop(fluid, "viscosity_exponent", text="Exponent", slider=True)
+        else:
+            # just for padding to prevent jumping around
+            sub.separator()
+            sub.separator()
 
         col.label(text="Optimization:")
         col.prop(fluid, "grid_levels", slider=True)
index 55c10a560154c1c8439819f51b945d010e7823c8..c179342bc4492cf6e2fa35a04ec635881bab5977 100644 (file)
@@ -172,6 +172,7 @@ class CLIP_PT_tools_tracking(Panel):
         props.backwards = True
         props.sequence = True
         props = row.operator("clip.track_markers", text="", icon='PLAY')
+        props.backwards = False
         props.sequence = True
         row.operator("clip.track_markers", text="", icon='FRAME_NEXT')
 
@@ -558,6 +559,9 @@ class CLIP_PT_display(Panel):
 
         col.prop(sc, "lock_selection")
 
+        if sc.view == 'GRAPH':
+            col.prop(sc, "lock_time_cursor")
+
         clip = sc.clip
         if clip:
             col.label(text="Display Aspect Ratio:")
index 409494b5cbb3ee58a9183387d0dc2a415d5d3e3a..aabf86c6c18b44cec35b8a4ac124f7c138b23566 100644 (file)
@@ -671,11 +671,11 @@ class IMAGE_PT_paint(Panel, ImagePaintPanel):
             col.prop(brush, "color", text="")
 
             row = col.row(align=True)
-            self.prop_unified_size(row, context, brush, "size", slider=True)
+            self.prop_unified_size(row, context, brush, "size", slider=True, text="Radius")
             self.prop_unified_size(row, context, brush, "use_pressure_size")
 
             row = col.row(align=True)
-            self.prop_unified_strength(row, context, brush, "strength", slider=True)
+            self.prop_unified_strength(row, context, brush, "strength", slider=True, text="Strength")
             self.prop_unified_strength(row, context, brush, "use_pressure_strength")
             
             row = col.row(align=True)
@@ -820,11 +820,11 @@ class IMAGE_UV_sculpt(Panel, ImagePaintPanel):
             col = layout.column()
 
             row = col.row(align=True)
-            self.prop_unified_size(row, context, brush, "size", slider=True)
+            self.prop_unified_size(row, context, brush, "size", slider=True, text="Radius")
             self.prop_unified_size(row, context, brush, "use_pressure_size")
 
             row = col.row(align=True)
-            self.prop_unified_strength(row, context, brush, "strength", slider=True)
+            self.prop_unified_strength(row, context, brush, "strength", slider=True, text="Strength")
             self.prop_unified_strength(row, context, brush, "use_pressure_strength")
             
         split = layout.split()
index 1593f2c71ec1783e54190196bab56d1de200a386..da6d1f7212359ab19190dc573d712c0c23865739 100644 (file)
@@ -68,7 +68,7 @@ class LOGIC_PT_properties(Panel):
             row = box.row()
             row.prop(prop, "name", text="")
             row.prop(prop, "type", text="")
-            row.prop(prop, "value", text="", toggle=True)  # we don't care about the type. rna will display correctly
+            row.prop(prop, "value", text="")
             row.prop(prop, "show_debug", text="", toggle=True, icon='INFO')
             row.operator("object.game_property_remove", text="", icon='X', emboss=False).index = i
 
index edbcf3ecf5b721470f7856b6dad7d80c7436aa6f..d29dff491329c490c1b8386cf8ed20f844602c8c 100644 (file)
@@ -58,6 +58,11 @@ class NODE_HT_header(Header):
                 # Don't show "Use Nodes" Button when Engine is BI for Lamps
                 if snode_id and not (scene.render.use_shading_nodes == 0 and ob.type == 'LAMP'):
                     layout.prop(snode_id, "use_nodes")
+                    
+            if snode.shader_type == 'WORLD':
+                layout.template_ID(scene, "world", new="world.new")
+                if snode_id:
+                    layout.prop(snode_id, "use_nodes")
 
         elif snode.tree_type == 'TEXTURE':
             layout.prop(snode, "texture_type", text="", expand=True)
index bbc04dad816f52003541082c58393c28172e4b0c..aa7cec0c01ac8894ed2be62f9081eed269f1dc57 100644 (file)
@@ -530,12 +530,12 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
                     else:
                         row.prop(brush, "use_space_atten", toggle=True, text="", icon='UNLOCKED')
 
-                self.prop_unified_strength(row, context, brush, "strength")
+                self.prop_unified_strength(row, context, brush, "strength", text="Strength")
                 self.prop_unified_strength(row, context, brush, "use_pressure_strength")
 
             if tool == 'ROTATE':
                 row = col.row(align=True)
-                self.prop_unified_strength(row, context, brush, "strength")
+                self.prop_unified_strength(row, context, brush, "strength", text="Strength")
                 self.prop_unified_strength(row, context, brush, "use_pressure_strength")
 
             if tool != 'SMOOTH':
@@ -627,7 +627,7 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
             self.prop_unified_size(row, context, brush, "use_pressure_size")
 
             row = col.row(align=True)
-            self.prop_unified_strength(row, context, brush, "strength")
+            self.prop_unified_strength(row, context, brush, "strength", text="Strength")
             self.prop_unified_strength(row, context, brush, "use_pressure_strength")
 
             row = col.row(align=True)
@@ -653,7 +653,7 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
             self.prop_unified_size(row, context, brush, "use_pressure_size")
 
             row = col.row(align=True)
-            self.prop_unified_strength(row, context, brush, "strength")
+            self.prop_unified_strength(row, context, brush, "strength", text="Strength")
             self.prop_unified_strength(row, context, brush, "use_pressure_strength")
 
             row = col.row(align=True)
@@ -671,7 +671,7 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
             self.prop_unified_size(row, context, brush, "use_pressure_size")
 
             row = col.row(align=True)
-            self.prop_unified_strength(row, context, brush, "strength")
+            self.prop_unified_strength(row, context, brush, "strength", text="Strength")
             self.prop_unified_strength(row, context, brush, "use_pressure_strength")
 
             # XXX - TODO
index 29b3047eca4ba0f6f69a721cec6226dd3a3f9b76..adcc7e8750a38ebce34525c6ba5bd76e1803f205 100644 (file)
 #include "endian.h"
 #include "avi_intern.h"
 
+#ifdef __BIG_ENDIAN__
+#include "MEM_guardedalloc.h"
+#endif
+
 #ifdef __BIG_ENDIAN__
 static void invert (int *num)
 {
index 5f451ce78217dc7df8331290d5a1e9a6a82cc2ce..a887412bbf47a41bccac0572f0d01de6e8e52fb0 100644 (file)
@@ -538,6 +538,15 @@ int sculpt_get_deform_matrices(struct Scene *scene, struct Object *ob,
                                                                float (**deformmats)[3][3], float (**deformcos)[3]);
 
 void weight_to_rgb(float r_rgb[3], const float weight);
+/* Update the weight MCOL preview layer.
+ * If weights are NULL, use object's active vgroup(s).
+ * Else, weights must be an array of weight float values.
+ *     If indices is NULL, it must be of numVerts length.
+ *     Else, it must be of num length, as indices, which contains vertices' idx to apply weights to.
+ *         (other vertices are assumed zero weight).
+ */
+void DM_update_weight_mcol(struct Object *ob, struct DerivedMesh *dm, int const draw_flag,
+                           float *weights, int num, const int *indices);
 
 /* convert layers requested by a GLSL material to actually available layers in
  * the DerivedMesh, with both a pointer for arrays and an offset for editmesh */
@@ -584,5 +593,10 @@ void DM_calc_auto_bump_scale(DerivedMesh *dm);
 /* Set object's bounding box based on DerivedMesh min/max data */
 void DM_set_object_boundbox(struct Object *ob, DerivedMesh *dm);
 
+/* debug only */
+#ifndef NDEBUG
+char *DM_debug_info(DerivedMesh *dm);
+void DM_debug_print(DerivedMesh *dm);
 #endif
 
+#endif
index a89bfbd50b1308b8150fc39727495237cfb1ba5f..11ab981822e443e34ac978affb874006f73f5561 100644 (file)
@@ -86,7 +86,7 @@ int bone_autoside_name (char name[64], int strip_number, short axis, float head,