Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2013-01-12 06:02:53 +0400
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2013-01-12 06:02:53 +0400
commit94ae0232b0337ab70cecaef03cd845887cd36eaa (patch)
treecaea2819c7fe0400fb91c9bdf0e99a9e0fd50cf6
parent9a109c22ae1ef8a5c75932d661610b23ec685bd7 (diff)
parentf68e9db583489d541d535791536ea20bc1ae1d76 (diff)
Merged changes in the trunk up to revision 53729.
Conflicts resolved: release/datafiles/startup.blend source/blender/blenloader/intern/readfile.c
-rw-r--r--SConstruct63
-rw-r--r--build_files/buildbot/config/user-config-cuda-glibc211-i686.py5
-rw-r--r--build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py5
-rw-r--r--build_files/buildbot/config/user-config-glibc211-i686.py6
-rw-r--r--build_files/buildbot/config/user-config-glibc211-x86_64.py6
-rw-r--r--build_files/buildbot/config/user-config-glibc27-i686.py149
-rw-r--r--build_files/buildbot/config/user-config-glibc27-x86_64.py149
-rw-r--r--build_files/buildbot/config/user-config-player-glibc211-i686.py2
-rw-r--r--build_files/buildbot/config/user-config-player-glibc211-x86_64.py2
-rw-r--r--build_files/buildbot/config/user-config-player-glibc27-i686.py114
-rw-r--r--build_files/buildbot/config/user-config-player-glibc27-x86_64.py114
-rw-r--r--build_files/buildbot/master.cfg4
-rw-r--r--build_files/buildbot/slave_compile.py53
-rw-r--r--build_files/buildbot/slave_pack.py12
-rwxr-xr-xbuild_files/cmake/cmake_netbeans_project.py4
-rwxr-xr-xbuild_files/cmake/cmake_qtcreator_project.py3
-rwxr-xr-xbuild_files/cmake/project_info.py10
-rw-r--r--build_files/scons/tools/btools.py15
-rw-r--r--doc/python_api/examples/bpy.props.5.py85
-rw-r--r--intern/cycles/blender/addon/properties.py14
-rw-r--r--intern/cycles/blender/addon/ui.py3
-rw-r--r--intern/cycles/blender/blender_curves.cpp20
-rw-r--r--intern/cycles/blender/blender_object.cpp8
-rw-r--r--intern/cycles/blender/blender_session.cpp2
-rw-r--r--intern/cycles/blender/blender_sync.cpp2
-rw-r--r--intern/cycles/device/CMakeLists.txt5
-rw-r--r--intern/cycles/kernel/kernel_camera.h1
-rw-r--r--intern/cycles/kernel/kernel_emission.h61
-rw-r--r--intern/cycles/kernel/kernel_light.h460
-rw-r--r--intern/cycles/kernel/kernel_path.h94
-rw-r--r--intern/cycles/kernel/kernel_types.h6
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp8
-rw-r--r--intern/cycles/kernel/osl/osl_shader.cpp6
-rw-r--r--intern/cycles/kernel/shaders/node_musgrave_texture.osl24
-rw-r--r--intern/cycles/kernel/shaders/node_texture.h13
-rw-r--r--intern/cycles/kernel/svm/svm_noise.h15
-rw-r--r--intern/cycles/render/light.cpp27
-rw-r--r--intern/cycles/render/session.cpp2
-rw-r--r--intern/cycles/render/session.h1
-rw-r--r--intern/cycles/render/tile.cpp60
-rw-r--r--intern/cycles/render/tile.h20
-rw-r--r--intern/cycles/util/util_math.h124
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.mm51
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp1
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp4
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.mm20
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp10
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.h2
-rw-r--r--intern/opencolorio/fallback_impl.cc2
-rw-r--r--intern/opencolorio/ocio_capi.cc4
-rw-r--r--intern/opencolorio/ocio_capi.h4
-rw-r--r--intern/opencolorio/ocio_impl.cc2
-rw-r--r--release/datafiles/startup.blendbin425180 -> 414132 bytes
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_follow_active.py5
-rw-r--r--release/scripts/startup/bl_operators/wm.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_data_mesh.py21
-rw-r--r--release/scripts/startup/bl_ui/properties_object.py3
-rw-r--r--release/scripts/startup/bl_ui/properties_texture.py2
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py2
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py8
-rw-r--r--source/blender/blenfont/intern/blf_glyph.c9
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h3
-rw-r--r--source/blender/blenkernel/BKE_blender.h2
-rw-r--r--source/blender/blenkernel/BKE_cdderivedmesh.h4
-rw-r--r--source/blender/blenkernel/BKE_customdata.h7
-rw-r--r--source/blender/blenkernel/BKE_main.h2
-rw-r--r--source/blender/blenkernel/BKE_mesh.h10
-rw-r--r--source/blender/blenkernel/BKE_report.h6
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c9
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c85
-rw-r--r--source/blender/blenkernel/intern/curve.c2
-rw-r--r--source/blender/blenkernel/intern/customdata.c115
-rw-r--r--source/blender/blenkernel/intern/displist.c7
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c157
-rw-r--r--source/blender/blenkernel/intern/fmodifier.c55
-rw-r--r--source/blender/blenkernel/intern/image.c2
-rw-r--r--source/blender/blenkernel/intern/mesh.c134
-rw-r--r--source/blender/blenkernel/intern/modifiers_bmesh.c47
-rw-r--r--source/blender/blenkernel/intern/particle_system.c18
-rw-r--r--source/blender/blenkernel/intern/pointcache.c22
-rw-r--r--source/blender/blenkernel/intern/report.c41
-rw-r--r--source/blender/blenkernel/intern/scene.c44
-rw-r--r--source/blender/blenkernel/intern/screen.c1
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c2
-rw-r--r--source/blender/blenkernel/intern/sequencer.c2
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c6
-rw-r--r--source/blender/blenlib/BLI_math_geom.h8
-rw-r--r--source/blender/blenlib/BLI_rect.h2
-rw-r--r--source/blender/blenlib/BLI_scanfill.h2
-rw-r--r--source/blender/blenlib/BLI_utildefines.h4
-rw-r--r--source/blender/blenlib/intern/math_geom.c145
-rw-r--r--source/blender/blenlib/intern/rct.c24
-rw-r--r--source/blender/blenlib/intern/string.c2
-rw-r--r--source/blender/blenloader/intern/readfile.c53
-rw-r--r--source/blender/blenloader/intern/runtime.c5
-rw-r--r--source/blender/blenloader/intern/writefile.c6
-rw-r--r--source/blender/bmesh/bmesh_class.h18
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.c34
-rw-r--r--source/blender/bmesh/intern/bmesh_log.c4
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.c116
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers_impl.c5
-rw-r--r--source/blender/bmesh/operators/bmo_triangulate.c2
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c15
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_collapse.c28
-rw-r--r--source/blender/compositor/intern/COM_Node.h6
-rw-r--r--source/blender/compositor/nodes/COM_ImageNode.cpp44
-rw-r--r--source/blender/compositor/nodes/COM_PixelateNode.cpp4
-rw-r--r--source/blender/editors/armature/meshlaplacian.c2
-rw-r--r--source/blender/editors/include/BIF_glutil.h8
-rw-r--r--source/blender/editors/include/ED_view3d.h8
-rw-r--r--source/blender/editors/include/UI_interface.h4
-rw-r--r--source/blender/editors/include/UI_resources.h6
-rw-r--r--source/blender/editors/interface/interface.c13
-rw-r--r--source/blender/editors/interface/interface_handlers.c94
-rw-r--r--source/blender/editors/interface/interface_icons.c4
-rw-r--r--source/blender/editors/interface/interface_layout.c2
-rw-r--r--source/blender/editors/interface/interface_regions.c2
-rw-r--r--source/blender/editors/interface/interface_widgets.c15
-rw-r--r--source/blender/editors/interface/resources.c26
-rw-r--r--source/blender/editors/interface/view2d.c2
-rw-r--r--source/blender/editors/interface/view2d_ops.c4
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c2
-rw-r--r--source/blender/editors/mesh/editmesh_select.c19
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c2
-rw-r--r--source/blender/editors/mesh/mesh_data.c2
-rw-r--r--source/blender/editors/physics/physics_fluid.c2
-rw-r--r--source/blender/editors/render/render_opengl.c18
-rw-r--r--source/blender/editors/render/render_preview.c31
-rw-r--r--source/blender/editors/screen/area.c4
-rw-r--r--source/blender/editors/screen/glutil.c8
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_2d.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c3
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c8
-rw-r--r--source/blender/editors/space_clip/clip_editor.c2
-rw-r--r--source/blender/editors/space_clip/clip_ops.c8
-rw-r--r--source/blender/editors/space_clip/space_clip.c1
-rw-r--r--source/blender/editors/space_file/file_ops.c5
-rw-r--r--source/blender/editors/space_graph/graph_edit.c9
-rw-r--r--source/blender/editors/space_image/image_draw.c13
-rw-r--r--source/blender/editors/space_image/image_ops.c6
-rw-r--r--source/blender/editors/space_info/textview.c6
-rw-r--r--source/blender/editors/space_node/drawnode.c14
-rw-r--r--source/blender/editors/space_node/node_view.c3
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c14
-rw-r--r--source/blender/editors/space_view3d/drawanimviz.c33
-rw-r--r--source/blender/editors/space_view3d/drawobject.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c167
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c264
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c5
-rw-r--r--source/blender/editors/space_view3d/view3d_fly.c24
-rw-r--r--source/blender/editors/transform/transform.c9
-rw-r--r--source/blender/editors/transform/transform_conversions.c74
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c6
-rw-r--r--source/blender/editors/uvedit/uvedit_intern.h1
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c13
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c13
-rw-r--r--source/blender/imbuf/IMB_imbuf.h5
-rw-r--r--source/blender/imbuf/IMB_thumbs.h2
-rw-r--r--source/blender/imbuf/intern/colormanagement.c20
-rw-r--r--source/blender/imbuf/intern/dds/ColorBlock.h2
-rw-r--r--source/blender/imbuf/intern/dds/DirectDrawSurface.h2
-rw-r--r--source/blender/imbuf/intern/divers.c47
-rw-r--r--source/blender/imbuf/intern/imageprocess.c50
-rw-r--r--source/blender/makesdna/DNA_mesh_types.h10
-rw-r--r--source/blender/makesdna/DNA_meshdata_types.h2
-rw-r--r--source/blender/makesdna/DNA_object_types.h6
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h12
-rw-r--r--source/blender/makesrna/RNA_access.h1
-rw-r--r--source/blender/makesrna/RNA_define.h13
-rw-r--r--source/blender/makesrna/RNA_types.h22
-rw-r--r--source/blender/makesrna/intern/makesrna.c35
-rw-r--r--source/blender/makesrna/intern/rna_ID.c2
-rw-r--r--source/blender/makesrna/intern/rna_access.c83
-rw-r--r--source/blender/makesrna/intern/rna_animation.c10
-rw-r--r--source/blender/makesrna/intern/rna_color.c2
-rw-r--r--source/blender/makesrna/intern/rna_define.c187
-rw-r--r--source/blender/makesrna/intern/rna_internal_types.h56
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c37
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c52
-rw-r--r--source/blender/makesrna/intern/rna_object.c9
-rw-r--r--source/blender/makesrna/intern/rna_object_api.c33
-rw-r--r--source/blender/makesrna/intern/rna_particle.c10
-rw-r--r--source/blender/makesrna/intern/rna_render.c4
-rw-r--r--source/blender/makesrna/intern/rna_scene.c2
-rw-r--r--source/blender/makesrna/intern/rna_sculpt_paint.c2
-rw-r--r--source/blender/makesrna/intern/rna_sequencer_api.c64
-rw-r--r--source/blender/makesrna/intern/rna_tracking.c57
-rw-r--r--source/blender/makesrna/intern/rna_ui.c28
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c131
-rw-r--r--source/blender/makesrna/intern/rna_wm.c8
-rw-r--r--source/blender/makesrna/intern/rna_world.c8
-rw-r--r--source/blender/modifiers/intern/MOD_screw.c2
-rw-r--r--source/blender/python/BPY_extern.h2
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops_call.c2
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.c16
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_customdata.c12
-rw-r--r--source/blender/python/generic/bpy_internal_import.h6
-rw-r--r--source/blender/python/generic/py_capi_utils.c52
-rw-r--r--source/blender/python/generic/py_capi_utils.h4
-rw-r--r--source/blender/python/intern/bpy.c24
-rw-r--r--source/blender/python/intern/bpy_app.c2
-rw-r--r--source/blender/python/intern/bpy_app_ffmpeg.c12
-rw-r--r--source/blender/python/intern/bpy_driver.c6
-rw-r--r--source/blender/python/intern/bpy_interface.c38
-rw-r--r--source/blender/python/intern/bpy_interface_atexit.c4
-rw-r--r--source/blender/python/intern/bpy_library.c2
-rw-r--r--source/blender/python/intern/bpy_operator.c26
-rw-r--r--source/blender/python/intern/bpy_operator_wrap.c4
-rw-r--r--source/blender/python/intern/bpy_path.c2
-rw-r--r--source/blender/python/intern/bpy_props.c1900
-rw-r--r--source/blender/python/intern/bpy_rna.c146
-rw-r--r--source/blender/python/intern/bpy_rna.h10
-rw-r--r--source/blender/python/intern/bpy_rna_anim.c16
-rw-r--r--source/blender/python/intern/bpy_rna_callback.c16
-rw-r--r--source/blender/python/intern/bpy_util.c10
-rw-r--r--source/blender/python/intern/bpy_util.h2
-rw-r--r--source/blender/quicktime/apple/qtkit_export.m6
-rw-r--r--source/blender/quicktime/quicktime_export.h4
-rw-r--r--source/blender/render/intern/raytrace/rayobject_octree.cpp2
-rw-r--r--source/blender/render/intern/source/multires_bake.c4
-rw-r--r--source/blender/render/intern/source/pipeline.c20
-rw-r--r--source/blender/render/intern/source/render_result.c10
-rw-r--r--source/blender/render/intern/source/zbuf.c13
-rw-r--r--source/blender/windowmanager/WM_api.h6
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c13
-rw-r--r--source/blender/windowmanager/intern/wm_files.c4
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c10
-rw-r--r--source/blender/windowmanager/intern/wm_window.c8
-rw-r--r--source/creator/creator.c123
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp5
-rw-r--r--source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp7
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp1
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp2
237 files changed, 5396 insertions, 2404 deletions
diff --git a/SConstruct b/SConstruct
index a16805bbfaf..171ebc8ddef 100644
--- a/SConstruct
+++ b/SConstruct
@@ -276,6 +276,11 @@ if 'blenderlite' in B.targets:
if k not in B.arguments:
env[k] = v
+if 'cudakernels' in B.targets:
+ env['WITH_BF_CYCLES'] = True
+ env['WITH_BF_CYCLES_CUDA_BINARIES'] = True
+ env['WITH_BF_PYTHON'] = False
+
# Extended OSX_SDK and 3D_CONNEXION_CLIENT_LIBRARY and JAckOSX detection for OSX
if env['OURPLATFORM']=='darwin':
print B.bc.OKGREEN + "Detected Xcode version: -- " + B.bc.ENDC + env['XCODE_CUR_VER'] + " --"
@@ -652,6 +657,7 @@ datafileslist = []
datafilestargetlist = []
dottargetlist = []
scriptinstall = []
+cubininstall = []
if env['OURPLATFORM']!='darwin':
dotblenderinstall = []
@@ -745,29 +751,30 @@ if env['OURPLATFORM']!='darwin':
source=['intern/cycles/doc/license/'+s for s in source]
scriptinstall.append(env.Install(dir=dir,source=source))
- # cuda binaries
- if env['WITH_BF_CYCLES_CUDA_BINARIES']:
- dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'lib')
- for arch in env['BF_CYCLES_CUDA_BINARIES_ARCH']:
- kernel_build_dir = os.path.join(B.root_build_dir, 'intern/cycles/kernel')
- cubin_file = os.path.join(kernel_build_dir, "kernel_%s.cubin" % arch)
- scriptinstall.append(env.Install(dir=dir,source=cubin_file))
+ if env['WITH_BF_CYCLES']:
+ # cuda binaries
+ if env['WITH_BF_CYCLES_CUDA_BINARIES']:
+ dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'lib')
+ for arch in env['BF_CYCLES_CUDA_BINARIES_ARCH']:
+ kernel_build_dir = os.path.join(B.root_build_dir, 'intern/cycles/kernel')
+ cubin_file = os.path.join(kernel_build_dir, "kernel_%s.cubin" % arch)
+ cubininstall.append(env.Install(dir=dir,source=cubin_file))
- # osl shaders
- if env['WITH_BF_CYCLES_OSL']:
- dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'shader')
+ # osl shaders
+ if env['WITH_BF_CYCLES_OSL']:
+ dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'shader')
- osl_source_dir = Dir('./intern/cycles/kernel/shaders').srcnode().path
- oso_build_dir = os.path.join(B.root_build_dir, 'intern/cycles/kernel/shaders')
+ osl_source_dir = Dir('./intern/cycles/kernel/shaders').srcnode().path
+ oso_build_dir = os.path.join(B.root_build_dir, 'intern/cycles/kernel/shaders')
- headers='node_color.h node_fresnel.h node_texture.h oslutil.h stdosl.h'.split()
- source=['intern/cycles/kernel/shaders/'+s for s in headers]
- scriptinstall.append(env.Install(dir=dir,source=source))
+ headers='node_color.h node_fresnel.h node_texture.h oslutil.h stdosl.h'.split()
+ source=['intern/cycles/kernel/shaders/'+s for s in headers]
+ scriptinstall.append(env.Install(dir=dir,source=source))
- for f in os.listdir(osl_source_dir):
- if f.endswith('.osl'):
- oso_file = os.path.join(oso_build_dir, f.replace('.osl', '.oso'))
- scriptinstall.append(env.Install(dir=dir,source=oso_file))
+ for f in os.listdir(osl_source_dir):
+ if f.endswith('.osl'):
+ oso_file = os.path.join(oso_build_dir, f.replace('.osl', '.oso'))
+ scriptinstall.append(env.Install(dir=dir,source=oso_file))
if env['WITH_BF_OCIO']:
colormanagement = os.path.join('release', 'datafiles', 'colormanagement')
@@ -862,9 +869,9 @@ textinstall = env.Install(dir=env['BF_INSTALLDIR'], source=textlist)
if env['OURPLATFORM']=='darwin':
allinstall = [blenderinstall, textinstall]
elif env['OURPLATFORM']=='linux':
- allinstall = [blenderinstall, dotblenderinstall, scriptinstall, textinstall, iconinstall]
+ allinstall = [blenderinstall, dotblenderinstall, scriptinstall, textinstall, iconinstall, cubininstall]
else:
- allinstall = [blenderinstall, dotblenderinstall, scriptinstall, textinstall]
+ allinstall = [blenderinstall, dotblenderinstall, scriptinstall, textinstall, cubininstall]
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'):
dllsources = []
@@ -994,6 +1001,20 @@ buildslave_alias = env.Alias('buildslave', buildslave_cmd)
Depends(buildslave_cmd, allinstall)
+cudakernels_action = env.Action(btools.cudakernels, btools.cudakernels_print)
+cudakernels_cmd = env.Command('cudakernels_exec', None, cudakernels_action)
+cudakernels_alias = env.Alias('cudakernels', cudakernels_cmd)
+
+cudakernel_dir = os.path.join(os.path.abspath(os.path.normpath(B.root_build_dir)), 'intern/cycles/kernel')
+cuda_kernels = []
+
+for x in env['BF_CYCLES_CUDA_BINARIES_ARCH']:
+ cubin = os.path.join(cudakernel_dir, 'kernel_' + x + '.cubin')
+ cuda_kernels.append(cubin)
+
+Depends(cudakernels_cmd, cuda_kernels)
+Depends(cudakernels_cmd, cubininstall)
+
Default(B.program_list)
if not env['WITHOUT_BF_INSTALL']:
diff --git a/build_files/buildbot/config/user-config-cuda-glibc211-i686.py b/build_files/buildbot/config/user-config-cuda-glibc211-i686.py
new file mode 100644
index 00000000000..e72218e6615
--- /dev/null
+++ b/build_files/buildbot/config/user-config-cuda-glibc211-i686.py
@@ -0,0 +1,5 @@
+BF_BUILDDIR = '../blender-build/linux-glibc211-i686'
+BF_INSTALLDIR = '../blender-install/linux-glibc211-i686'
+BF_NUMJOBS = 1
+
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
diff --git a/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py b/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py
new file mode 100644
index 00000000000..10738a11eaa
--- /dev/null
+++ b/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py
@@ -0,0 +1,5 @@
+BF_BUILDDIR = '../blender-build/linux-glibc211-x86_64'
+BF_INSTALLDIR = '../blender-install/linux-glibc211-x86_64'
+BF_NUMJOBS = 1
+
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
diff --git a/build_files/buildbot/config/user-config-glibc211-i686.py b/build_files/buildbot/config/user-config-glibc211-i686.py
index 149a01433a6..540416ee1fb 100644
--- a/build_files/buildbot/config/user-config-glibc211-i686.py
+++ b/build_files/buildbot/config/user-config-glibc211-i686.py
@@ -1,6 +1,7 @@
BF_BUILDDIR = '../blender-build/linux-glibc211-i686'
BF_INSTALLDIR = '../blender-install/linux-glibc211-i686'
-BF_NUMJOBS = 2
+BF_NUMJOBS = 4
+WITHOUT_BF_OVERWRITE_INSTALL = True
# Python configuration
BF_PYTHON_VERSION = '3.3'
@@ -109,8 +110,7 @@ BF_JACK_LIB_STATIC = '${BF_ZLIB}/lib/libjack.a'
# Cycles
WITH_BF_CYCLES = True
-WITH_BF_CYCLES_CUDA_BINARIES = True
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
+WITH_BF_CYCLES_CUDA_BINARIES = False
WITH_BF_OIIO = True
WITH_BF_STATICOIIO = True
diff --git a/build_files/buildbot/config/user-config-glibc211-x86_64.py b/build_files/buildbot/config/user-config-glibc211-x86_64.py
index 0fae7f0cdb3..c0ba8060712 100644
--- a/build_files/buildbot/config/user-config-glibc211-x86_64.py
+++ b/build_files/buildbot/config/user-config-glibc211-x86_64.py
@@ -1,6 +1,7 @@
BF_BUILDDIR = '../blender-build/linux-glibc211-x86_64'
BF_INSTALLDIR = '../blender-install/linux-glibc211-x86_64'
-BF_NUMJOBS = 2
+BF_NUMJOBS = 4
+WITHOUT_BF_OVERWRITE_INSTALL = True
# Python configuration
BF_PYTHON_VERSION = '3.3'
@@ -109,8 +110,7 @@ BF_JACK_LIB_STATIC = '${BF_ZLIB}/lib/libjack.a'
# Cycles
WITH_BF_CYCLES = True
-WITH_BF_CYCLES_CUDA_BINARIES = True
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
+WITH_BF_CYCLES_CUDA_BINARIES = False
WITH_BF_OIIO = True
WITH_BF_STATICOIIO = True
diff --git a/build_files/buildbot/config/user-config-glibc27-i686.py b/build_files/buildbot/config/user-config-glibc27-i686.py
deleted file mode 100644
index 46f3ccb3df7..00000000000
--- a/build_files/buildbot/config/user-config-glibc27-i686.py
+++ /dev/null
@@ -1,149 +0,0 @@
-BF_BUILDDIR = '../blender-build/linux-glibc27-i686'
-BF_INSTALLDIR = '../blender-install/linux-glibc27-i686'
-BF_NUMJOBS = 2
-
-# Python configuration
-BF_PYTHON_VERSION = '3.3'
-BF_PYTHON_ABI_FLAGS = 'm'
-BF_PYTHON = '/opt/python3'
-
-WITH_BF_STATICPYTHON = True
-
-# OpenCollada configuration
-WITH_BF_COLLADA = True
-BF_OPENCOLLADA = '/opt/opencollada'
-BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include'
-BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver buffer ftoa libxml2-static libexpat-static libpcre-static'
-BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib /home/sources/staticlibs/lib32'
-BF_PCRE_LIB = ''
-BF_EXPAT_LIB = ''
-
-# FFMPEG configuration
-WITH_BF_FFMPEG = True
-WITH_BF_STATICFFMPEG = True
-
-BF_FFMPEG = '/home/sources/staticlibs/ffmpeg'
-BF_FFMPEG_LIBPATH = '${BF_FFMPEG}/lib32'
-BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \
- '${BF_FFMPEG_LIBPATH}/libavcodec.a ${BF_FFMPEG_LIBPATH}/libavdevice.a ${BF_FFMPEG_LIBPATH}/libavutil.a ' + \
- '${BF_FFMPEG_LIBPATH}/libxvidcore.a ${BF_FFMPEG_LIBPATH}/libx264.a ${BF_FFMPEG_LIBPATH}/libmp3lame.a ' + \
- '${BF_FFMPEG_LIBPATH}/libvpx.a ${BF_FFMPEG_LIBPATH}/libvorbis.a ${BF_FFMPEG_LIBPATH}/libogg.a ' + \
- '${BF_FFMPEG_LIBPATH}/libvorbisenc.a ${BF_FFMPEG_LIBPATH}/libtheora.a ' + \
- '${BF_FFMPEG_LIBPATH}/libschroedinger-1.0.a ${BF_FFMPEG_LIBPATH}/liborc-0.4.a ${BF_FFMPEG_LIBPATH}/libdirac_encoder.a ' + \
- '${BF_FFMPEG_LIBPATH}/libfaad.a'
-
-# Don't depend on system's libstdc++
-WITH_BF_STATICCXX = True
-BF_CXX_LIB_STATIC = '/usr/lib/gcc/i486-linux-gnu/4.3.4/libstdc++.a'
-
-WITH_BF_OPENAL = True
-WITH_BF_STATICOPENAL = True
-BF_OPENAL_LIB_STATIC = '/opt/openal/lib/libopenal.a'
-
-WITH_BF_GETTEXT_STATIC = True
-BF_FREETYPE_LIB_STATIC = True
-
-WITH_BF_OPENEXR = True
-WITH_BF_STATICOPENEXR = True
-
-WITH_BF_TIFF = True
-WITH_BF_STATICTIFF = True
-BF_TIFF_LIB_STATIC = '${BF_TIFF}/lib/libtiff.a'
-
-WITH_BF_JPEG = True
-BF_JPEG_LIB = 'libjpeg'
-BF_JPEG_LIBPATH = '/home/sources/staticlibs/lib32'
-
-WITH_BF_PNG = True
-BF_PNG_LIB = 'libpng'
-BF_PNG_LIBPATH = '/home/sources/staticlibs/lib32'
-
-WITH_BF_STATICLIBSAMPLERATE = True
-
-WITH_BF_ZLIB = True
-WITH_BF_STATICZLIB = True
-BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a'
-
-WITH_BF_SDL = True
-WITH_BF_OGG = True
-
-WITH_BF_OPENMP = True
-
-WITH_BF_GAMEENGINE = True
-WITH_BF_BULLET = True
-
-# Blender player (would be enabled in it's own config)
-WITH_BF_PLAYER = False
-
-# Use jemalloc memory manager
-WITH_BF_JEMALLOC = True
-WITH_BF_STATICJEMALLOC = True
-BF_JEMALLOC = '/home/sources/staticlibs/jemalloc'
-BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib32'
-
-# Use 3d mouse library
-WITH_BF_3DMOUSE = True
-WITH_BF_STATIC3DMOUSE = True
-BF_3DMOUSE = '/home/sources/staticlibs/spnav'
-BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib32'
-
-# FFT
-WITH_BF_FFTW3 = True
-WITH_BF_STATICFFTW3 = True
-
-# JACK
-WITH_BF_JACK = False
-
-# Cycles
-WITH_BF_CYCLES = True
-WITH_BF_CYCLES_CUDA_BINARIES = True
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
-
-WITH_BF_OIIO = True
-WITH_BF_STATICOIIO = True
-BF_OIIO = '/opt/oiio'
-BF_OIIO_INC = '${BF_OIIO}/include'
-BF_OIIO_LIB_STATIC = '${BF_OIIO_LIBPATH}/libOpenImageIO.a ${BF_OPENEXR}/lib/libIlmImf.a'
-BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
-
-WITH_BF_CYCLES_OSL = True
-WITH_BF_STATICOSL = False
-BF_OSL = '/opt/osl'
-BF_OSL_INC = '${BF_OSL}/include'
-# note oslexec would passed via program linkflags, which is needed to
-# make llvm happy with osl_allocate_closure_component
-BF_OSL_LIB = 'oslcomp oslexec oslquery'
-BF_OSL_LIBPATH = '${BF_OSL}/lib'
-BF_OSL_COMPILER = '${BF_OSL}/bin/oslc'
-
-WITH_BF_LLVM = True
-WITH_BF_STATICLLVM = False
-BF_LLVM = '/opt/llvm-3.1'
-BF_LLVM_LIB = 'LLVMBitReader LLVMJIT LLVMipo LLVMVectorize LLVMBitWriter LLVMX86CodeGen LLVMX86Desc LLVMX86Info LLVMX86AsmPrinter ' + \
- 'LLVMX86Utils LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMInstCombine LLVMTransformUtils LLVMipa LLVMAnalysis LLVMExecutionEngine ' + \
- 'LLVMTarget LLVMMC LLVMCore LLVMSupport'
-BF_LLVM_LIBPATH = '${BF_LLVM}/lib'
-
-# Color management
-WITH_BF_OCIO = True
-WITH_BF_STATICOCIO = True
-BF_OCIO = '/opt/ocio'
-BF_OCIO_INC = '${BF_OCIO}/include'
-BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a'
-BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
-
-WITH_BF_BOOST = True
-WITH_BF_STATICBOOST = True
-BF_BOOST = '/opt/boost'
-BF_BOOST_INC = '${BF_BOOST}/include'
-BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
-BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
-
-# Ocean Simulation
-WITH_BF_OCEANSIM = True
-
-# Compilation and optimization
-BF_DEBUG = False
-REL_CCFLAGS = ['-DNDEBUG', '-DNDEBUG', '-O2'] # C & C++
-PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib32']
-BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map']
diff --git a/build_files/buildbot/config/user-config-glibc27-x86_64.py b/build_files/buildbot/config/user-config-glibc27-x86_64.py
deleted file mode 100644
index 23ddcf7a5b9..00000000000
--- a/build_files/buildbot/config/user-config-glibc27-x86_64.py
+++ /dev/null
@@ -1,149 +0,0 @@
-BF_BUILDDIR = '../blender-build/linux-glibc27-x86_64'
-BF_INSTALLDIR = '../blender-install/linux-glibc27-x86_64'
-BF_NUMJOBS = 2
-
-# Python configuration
-BF_PYTHON_VERSION = '3.3'
-BF_PYTHON_ABI_FLAGS = 'm'
-BF_PYTHON = '/opt/python3'
-
-WITH_BF_STATICPYTHON = True
-
-# OpenCollada configuration
-WITH_BF_COLLADA = True
-BF_OPENCOLLADA = '/opt/opencollada'
-BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include'
-BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver buffer ftoa libxml2-static libexpat-static libpcre-static'
-BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib /home/sources/staticlibs/lib64'
-BF_PCRE_LIB = ''
-BF_EXPAT_LIB = ''
-
-# FFMPEG configuration
-WITH_BF_FFMPEG = True
-WITH_BF_STATICFFMPEG = True
-
-BF_FFMPEG = '/home/sources/staticlibs/ffmpeg'
-BF_FFMPEG_LIBPATH = '${BF_FFMPEG}/lib64'
-BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \
- '${BF_FFMPEG_LIBPATH}/libavcodec.a ${BF_FFMPEG_LIBPATH}/libavdevice.a ${BF_FFMPEG_LIBPATH}/libavutil.a ' + \
- '${BF_FFMPEG_LIBPATH}/libxvidcore.a ${BF_FFMPEG_LIBPATH}/libx264.a ${BF_FFMPEG_LIBPATH}/libmp3lame.a ' + \
- '${BF_FFMPEG_LIBPATH}/libvpx.a ${BF_FFMPEG_LIBPATH}/libvorbis.a ${BF_FFMPEG_LIBPATH}/libogg.a ' + \
- '${BF_FFMPEG_LIBPATH}/libvorbisenc.a ${BF_FFMPEG_LIBPATH}/libtheora.a ' + \
- '${BF_FFMPEG_LIBPATH}/libschroedinger-1.0.a ${BF_FFMPEG_LIBPATH}/liborc-0.4.a ${BF_FFMPEG_LIBPATH}/libdirac_encoder.a ' + \
- '${BF_FFMPEG_LIBPATH}/libfaad.a'
-
-# Don't depend on system's libstdc++
-WITH_BF_STATICCXX = True
-BF_CXX_LIB_STATIC = '/usr/lib/gcc/x86_64-linux-gnu/4.3.4/libstdc++.a'
-
-WITH_BF_OPENAL = True
-WITH_BF_STATICOPENAL = True
-BF_OPENAL_LIB_STATIC = '/opt/openal/lib/libopenal.a'
-
-WITH_BF_GETTEXT_STATIC = True
-BF_FREETYPE_LIB_STATIC = True
-
-WITH_BF_OPENEXR = True
-WITH_BF_STATICOPENEXR = True
-
-WITH_BF_TIFF = True
-WITH_BF_STATICTIFF = True
-BF_TIFF_LIB_STATIC = '${BF_TIFF}/lib/libtiff.a'
-
-WITH_BF_JPEG = True
-BF_JPEG_LIB = 'libjpeg'
-BF_JPEG_LIBPATH = '/home/sources/staticlibs/lib64'
-
-WITH_BF_PNG = True
-BF_PNG_LIB = 'libpng'
-BF_PNG_LIBPATH = '/home/sources/staticlibs/lib64'
-
-WITH_BF_STATICLIBSAMPLERATE = True
-
-WITH_BF_ZLIB = True
-WITH_BF_STATICZLIB = True
-BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a'
-
-WITH_BF_SDL = True
-WITH_BF_OGG = True
-
-WITH_BF_OPENMP = True
-
-WITH_BF_GAMEENGINE = True
-WITH_BF_BULLET = True
-
-# Blender player (would be enabled in it's own config)
-WITH_BF_PLAYER = False
-
-# Use jemalloc memory manager
-WITH_BF_JEMALLOC = True
-WITH_BF_STATICJEMALLOC = True
-BF_JEMALLOC = '/home/sources/staticlibs/jemalloc'
-BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib64'
-
-# Use 3d mouse library
-WITH_BF_3DMOUSE = True
-WITH_BF_STATIC3DMOUSE = True
-BF_3DMOUSE = '/home/sources/staticlibs/spnav'
-BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib64'
-
-# FFT
-WITH_BF_FFTW3 = True
-WITH_BF_STATICFFTW3 = True
-
-# JACK
-WITH_BF_JACK = False
-
-# Cycles
-WITH_BF_CYCLES = True
-WITH_BF_CYCLES_CUDA_BINARIES = True
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
-
-WITH_BF_OIIO = True
-WITH_BF_STATICOIIO = True
-BF_OIIO = '/opt/oiio'
-BF_OIIO_INC = '${BF_OIIO}/include'
-BF_OIIO_LIB_STATIC = '${BF_OIIO_LIBPATH}/libOpenImageIO.a ${BF_OPENEXR}/lib/libIlmImf.a'
-BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
-
-WITH_BF_CYCLES_OSL = True
-WITH_BF_STATICOSL = False
-BF_OSL = '/opt/osl'
-BF_OSL_INC = '${BF_OSL}/include'
-# note oslexec would passed via program linkflags, which is needed to
-# make llvm happy with osl_allocate_closure_component
-BF_OSL_LIB = 'oslcomp oslexec oslquery'
-BF_OSL_LIBPATH = '${BF_OSL}/lib'
-BF_OSL_COMPILER = '${BF_OSL}/bin/oslc'
-
-WITH_BF_LLVM = True
-WITH_BF_STATICLLVM = False
-BF_LLVM = '/opt/llvm-3.1'
-BF_LLVM_LIB = 'LLVMBitReader LLVMJIT LLVMipo LLVMVectorize LLVMBitWriter LLVMX86CodeGen LLVMX86Desc LLVMX86Info LLVMX86AsmPrinter ' + \
- 'LLVMX86Utils LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMInstCombine LLVMTransformUtils LLVMipa LLVMAnalysis LLVMExecutionEngine ' + \
- 'LLVMTarget LLVMMC LLVMCore LLVMSupport'
-BF_LLVM_LIBPATH = '${BF_LLVM}/lib'
-
-# Color management
-WITH_BF_OCIO = True
-WITH_BF_STATICOCIO = True
-BF_OCIO = '/opt/ocio'
-BF_OCIO_INC = '${BF_OCIO}/include'
-BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a'
-BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
-
-WITH_BF_BOOST = True
-WITH_BF_STATICBOOST = True
-BF_BOOST = '/opt/boost'
-BF_BOOST_INC = '${BF_BOOST}/include'
-BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
-BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
-
-# Ocean Simulation
-WITH_BF_OCEANSIM = True
-
-# Compilation and optimization
-BF_DEBUG = False
-REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++
-PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib64']
-BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map']
diff --git a/build_files/buildbot/config/user-config-player-glibc211-i686.py b/build_files/buildbot/config/user-config-player-glibc211-i686.py
index 37fe511fac8..a99337f03e6 100644
--- a/build_files/buildbot/config/user-config-player-glibc211-i686.py
+++ b/build_files/buildbot/config/user-config-player-glibc211-i686.py
@@ -1,6 +1,6 @@
BF_BUILDDIR = '../blender-build/linux-glibc211-i686'
BF_INSTALLDIR = '../blender-install/linux-glibc211-i686'
-BF_NUMJOBS = 2
+BF_NUMJOBS = 4
# Python configuration
BF_PYTHON_VERSION = '3.3'
diff --git a/build_files/buildbot/config/user-config-player-glibc211-x86_64.py b/build_files/buildbot/config/user-config-player-glibc211-x86_64.py
index 8f51c5ad8be..c17cff2893d 100644
--- a/build_files/buildbot/config/user-config-player-glibc211-x86_64.py
+++ b/build_files/buildbot/config/user-config-player-glibc211-x86_64.py
@@ -1,6 +1,6 @@
BF_BUILDDIR = '../blender-build/linux-glibc211-x86_64'
BF_INSTALLDIR = '../blender-install/linux-glibc211-x86_64'
-BF_NUMJOBS = 2
+BF_NUMJOBS = 4
# Python configuration
BF_PYTHON_VERSION = '3.3'
diff --git a/build_files/buildbot/config/user-config-player-glibc27-i686.py b/build_files/buildbot/config/user-config-player-glibc27-i686.py
deleted file mode 100644
index 300af2295f0..00000000000
--- a/build_files/buildbot/config/user-config-player-glibc27-i686.py
+++ /dev/null
@@ -1,114 +0,0 @@
-BF_BUILDDIR = '../blender-build/linux-glibc27-i686'
-BF_INSTALLDIR = '../blender-install/linux-glibc27-i686'
-BF_NUMJOBS = 2
-
-# Python configuration
-BF_PYTHON_VERSION = '3.3'
-BF_PYTHON_ABI_FLAGS = 'm'
-BF_PYTHON = '/opt/python3'
-
-WITH_BF_STATICPYTHON = True
-
-# OpenCollada configuration
-WITH_BF_COLLADA = False
-
-# FFMPEG configuration
-WITH_BF_FFMPEG = True
-WITH_BF_STATICFFMPEG = True
-
-BF_FFMPEG = '/home/sources/staticlibs/ffmpeg'
-BF_FFMPEG_LIBPATH = '${BF_FFMPEG}/lib32'
-BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \
- '${BF_FFMPEG_LIBPATH}/libavcodec.a ${BF_FFMPEG_LIBPATH}/libavdevice.a ${BF_FFMPEG_LIBPATH}/libavutil.a ' + \
- '${BF_FFMPEG_LIBPATH}/libxvidcore.a ${BF_FFMPEG_LIBPATH}/libx264.a ${BF_FFMPEG_LIBPATH}/libmp3lame.a ' + \
- '${BF_FFMPEG_LIBPATH}/libvpx.a ${BF_FFMPEG_LIBPATH}/libvorbis.a ${BF_FFMPEG_LIBPATH}/libogg.a ' + \
- '${BF_FFMPEG_LIBPATH}/libvorbisenc.a ${BF_FFMPEG_LIBPATH}/libtheora.a ' + \
- '${BF_FFMPEG_LIBPATH}/libschroedinger-1.0.a ${BF_FFMPEG_LIBPATH}/liborc-0.4.a ${BF_FFMPEG_LIBPATH}/libdirac_encoder.a ' + \
- '${BF_FFMPEG_LIBPATH}/libfaad.a'
-
-# Don't depend on system's libstdc++
-WITH_BF_STATICCXX = True
-BF_CXX_LIB_STATIC = '/usr/lib/gcc/i486-linux-gnu/4.3.4/libstdc++.a'
-
-WITH_BF_OPENAL = True
-WITH_BF_STATICOPENAL = True
-BF_OPENAL_LIB_STATIC = '/opt/openal/lib/libopenal.a'
-
-WITH_BF_GETTEXT_STATIC = True
-BF_FREETYPE_LIB_STATIC = True
-
-WITH_BF_OPENEXR = False
-WITH_BF_STATICOPENEXR = True
-
-WITH_BF_TIFF = False
-WITH_BF_STATICTIFF = True
-BF_TIFF_LIB_STATIC = '${BF_TIFF}/lib/libtiff.a'
-
-WITH_BF_JPEG = True
-BF_JPEG_LIB = 'libjpeg'
-BF_JPEG_LIBPATH = '/home/sources/staticlibs/lib32'
-
-WITH_BF_PNG = True
-BF_PNG_LIB = 'libpng'
-BF_PNG_LIBPATH = '/home/sources/staticlibs/lib32'
-
-WITH_BF_STATICLIBSAMPLERATE = True
-
-WITH_BF_ZLIB = True
-WITH_BF_STATICZLIB = True
-BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a'
-
-WITH_BF_SDL = True
-WITH_BF_OGG = False
-
-WITH_BF_OPENMP = True
-
-WITH_BF_GAMEENGINE = True
-WITH_BF_BULLET = True
-
-# Do not build blender when building blenderplayer
-WITH_BF_NOBLENDER = True
-WITH_BF_PLAYER = True
-
-# Use jemalloc memory manager
-WITH_BF_JEMALLOC = True
-WITH_BF_STATICJEMALLOC = True
-BF_JEMALLOC = '/home/sources/staticlibs/jemalloc'
-BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib32'
-
-# Use 3d mouse library
-WITH_BF_3DMOUSE = True
-WITH_BF_STATIC3DMOUSE = True
-BF_3DMOUSE = '/home/sources/staticlibs/spnav'
-BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib32'
-
-# Color management
-WITH_BF_OCIO = True
-WITH_BF_STATICOCIO = True
-BF_OCIO = '/opt/ocio'
-BF_OCIO_INC = '${BF_OCIO}/include'
-BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a'
-BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
-
-WITH_BF_BOOST = True
-WITH_BF_STATICBOOST = True
-BF_BOOST = '/opt/boost'
-BF_BOOST_INC = '${BF_BOOST}/include'
-BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
-BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
-
-# JACK
-WITH_BF_JACK = False
-
-# Motion Tracking
-WITH_BF_LIBMV = False
-
-# Ocean Simulation
-WITH_BF_FFTW3 = True
-WITH_BF_STATICFFTW3 = True
-WITH_BF_OCEANSIM = True
-
-# Compilation and optimization
-BF_DEBUG = False
-REL_CCFLAGS = ['-DNDEBUG', '-O2'] # C & C++
-PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib32']
diff --git a/build_files/buildbot/config/user-config-player-glibc27-x86_64.py b/build_files/buildbot/config/user-config-player-glibc27-x86_64.py
deleted file mode 100644
index 722c3a00a66..00000000000
--- a/build_files/buildbot/config/user-config-player-glibc27-x86_64.py
+++ /dev/null
@@ -1,114 +0,0 @@
-BF_BUILDDIR = '../blender-build/linux-glibc27-x86_64'
-BF_INSTALLDIR = '../blender-install/linux-glibc27-x86_64'
-BF_NUMJOBS = 2
-
-# Python configuration
-BF_PYTHON_VERSION = '3.3'
-BF_PYTHON_ABI_FLAGS = 'm'
-BF_PYTHON = '/opt/python3'
-
-WITH_BF_STATICPYTHON = True
-
-# OpenCollada configuration
-WITH_BF_COLLADA = False
-
-# FFMPEG configuration
-WITH_BF_FFMPEG = True
-WITH_BF_STATICFFMPEG = True
-
-BF_FFMPEG = '/home/sources/staticlibs/ffmpeg'
-BF_FFMPEG_LIBPATH = '${BF_FFMPEG}/lib64'
-BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \
- '${BF_FFMPEG_LIBPATH}/libavcodec.a ${BF_FFMPEG_LIBPATH}/libavdevice.a ${BF_FFMPEG_LIBPATH}/libavutil.a ' + \
- '${BF_FFMPEG_LIBPATH}/libxvidcore.a ${BF_FFMPEG_LIBPATH}/libx264.a ${BF_FFMPEG_LIBPATH}/libmp3lame.a ' + \
- '${BF_FFMPEG_LIBPATH}/libvpx.a ${BF_FFMPEG_LIBPATH}/libvorbis.a ${BF_FFMPEG_LIBPATH}/libogg.a ' + \
- '${BF_FFMPEG_LIBPATH}/libvorbisenc.a ${BF_FFMPEG_LIBPATH}/libtheora.a ' + \
- '${BF_FFMPEG_LIBPATH}/libschroedinger-1.0.a ${BF_FFMPEG_LIBPATH}/liborc-0.4.a ${BF_FFMPEG_LIBPATH}/libdirac_encoder.a ' + \
- '${BF_FFMPEG_LIBPATH}/libfaad.a'
-
-# Don't depend on system's libstdc++
-WITH_BF_STATICCXX = True
-BF_CXX_LIB_STATIC = '/usr/lib/gcc/x86_64-linux-gnu/4.3.4/libstdc++.a'
-
-WITH_BF_OPENAL = True
-WITH_BF_STATICOPENAL = True
-BF_OPENAL_LIB_STATIC = '/opt/openal/lib/libopenal.a'
-
-WITH_BF_GETTEXT_STATIC = True
-BF_FREETYPE_LIB_STATIC = True
-
-WITH_BF_OPENEXR = False
-WITH_BF_STATICOPENEXR = True
-
-WITH_BF_TIFF = False
-WITH_BF_STATICTIFF = True
-BF_TIFF_LIB_STATIC = '${BF_TIFF}/lib/libtiff.a'
-
-WITH_BF_JPEG = True
-BF_JPEG_LIB = 'libjpeg'
-BF_JPEG_LIBPATH = '/home/sources/staticlibs/lib64'
-
-WITH_BF_STATICLIBSAMPLERATE = True
-
-WITH_BF_PNG = True
-BF_PNG_LIB = 'libpng'
-BF_PNG_LIBPATH = '/home/sources/staticlibs/lib64'
-
-WITH_BF_ZLIB = True
-WITH_BF_STATICZLIB = True
-BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a'
-
-WITH_BF_SDL = True
-WITH_BF_OGG = False
-
-WITH_BF_OPENMP = True
-
-WITH_BF_GAMEENGINE = True
-WITH_BF_BULLET = True
-
-# Do not build blender when building blenderplayer
-WITH_BF_NOBLENDER = True
-WITH_BF_PLAYER = True
-
-# Use jemalloc memory manager
-WITH_BF_JEMALLOC = True
-WITH_BF_STATICJEMALLOC = True
-BF_JEMALLOC = '/home/sources/staticlibs/jemalloc'
-BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib64'
-
-# Use 3d mouse library
-WITH_BF_3DMOUSE = True
-WITH_BF_STATIC3DMOUSE = True
-BF_3DMOUSE = '/home/sources/staticlibs/spnav'
-BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib64'
-
-# Color management
-WITH_BF_OCIO = True
-WITH_BF_STATICOCIO = True
-BF_OCIO = '/opt/ocio'
-BF_OCIO_INC = '${BF_OCIO}/include'
-BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a'
-BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
-
-WITH_BF_BOOST = True
-WITH_BF_STATICBOOST = True
-BF_BOOST = '/opt/boost'
-BF_BOOST_INC = '${BF_BOOST}/include'
-BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
-BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
-
-# JACK
-WITH_BF_JACK = False
-
-# Motion Tracking
-WITH_BF_LIBMV = False
-
-# Ocean Simulation
-WITH_BF_FFTW3 = True
-WITH_BF_STATICFFTW3 = True
-WITH_BF_OCEANSIM = True
-
-# Compilation and optimization
-BF_DEBUG = False
-REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++
-PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib64']
diff --git a/build_files/buildbot/master.cfg b/build_files/buildbot/master.cfg
index 90f0c805f58..9d0839bd0d7 100644
--- a/build_files/buildbot/master.cfg
+++ b/build_files/buildbot/master.cfg
@@ -116,10 +116,10 @@ add_builder(c, 'mac_x86_64_10_5_scons', '', generic_builder, '', True)
add_builder(c, 'mac_i386_scons', 'darwin-9.x.universal', generic_builder)
add_builder(c, 'mac_ppc_scons', 'darwin-9.x.universal', generic_builder)
#add_builder(c, 'linux_x86_64_cmake', '', generic_builder)
-add_builder(c, 'linux_glibc27_i386_scons', '', generic_builder)
+#add_builder(c, 'linux_glibc27_i386_scons', '', generic_builder)
add_builder(c, 'linux_glibc211_i386_scons', '', generic_builder)
#add_builder(c, 'salad_linux_i386_scons', '', generic_builder, 'soc-2011-salad')
-add_builder(c, 'linux_glibc27_x86_64_scons', '', generic_builder)
+#add_builder(c, 'linux_glibc27_x86_64_scons', '', generic_builder)
add_builder(c, 'linux_glibc211_x86_64_scons', '', generic_builder)
#add_builder(c, 'salad_linux_x86_64_scons', '', generic_builder, 'soc-2011-salad')
add_builder(c, 'win32_scons', 'windows', generic_builder)
diff --git a/build_files/buildbot/slave_compile.py b/build_files/buildbot/slave_compile.py
index bedada93a5a..dab8a8e6483 100644
--- a/build_files/buildbot/slave_compile.py
+++ b/build_files/buildbot/slave_compile.py
@@ -60,6 +60,27 @@ else:
if builder.find('linux') != -1:
import shutil
+ configs = []
+ if builder.endswith('linux_glibc211_x86_64_scons'):
+ configs = ['user-config-player-glibc211-x86_64.py',
+ 'user-config-cuda-glibc211-x86_64.py',
+ 'user-config-glibc211-x86_64.py'
+ ]
+ chroot_name = 'buildbot_squeeze_x86_64'
+ cuda_chroot = 'buildbot_squeeze_x86_64'
+ elif builder.endswith('linux_glibc211_i386_scons'):
+ configs = ['user-config-player-glibc211-i686.py',
+ 'user-config-cuda-glibc211-i686.py',
+ 'user-config-glibc211-i686.py']
+ chroot_name = 'buildbot_squeeze_i686'
+
+ # use 64bit cuda toolkit, so there'll be no memory limit issues
+ cuda_chroot = 'buildbot_squeeze_x86_64'
+
+ # Compilation will happen inside of chroot environment
+ prog_scons_cmd = ['schroot', '-c', chroot_name, '--'] + scons_cmd
+ cuda_scons_cmd = ['schroot', '-c', cuda_chroot, '--'] + scons_cmd
+
# We're using the same rules as release builder, so tweak
# build and install dirs
build_dir = os.path.join('..', 'build', builder)
@@ -74,20 +95,6 @@ else:
buildbot_dir = os.path.dirname(os.path.realpath(__file__))
config_dir = os.path.join(buildbot_dir, 'config')
- configs = []
- if builder.endswith('linux_glibc27_x86_64_scons'):
- configs = ['user-config-player-glibc27-x86_64.py',
- 'user-config-glibc27-x86_64.py']
- elif builder.endswith('linux_glibc27_i386_scons'):
- configs = ['user-config-player-glibc27-i686.py',
- 'user-config-glibc27-i686.py']
- if builder.endswith('linux_glibc211_x86_64_scons'):
- configs = ['user-config-player-glibc211-x86_64.py',
- 'user-config-glibc211-x86_64.py']
- elif builder.endswith('linux_glibc211_i386_scons'):
- configs = ['user-config-player-glibc211-i686.py',
- 'user-config-glibc211-i686.py']
-
for config in configs:
config_fpath = os.path.join(config_dir, config)
@@ -100,14 +107,24 @@ else:
scons_options += common_options
- if config.find('player') == -1:
- scons_options.append('blender')
- else:
+ if config.find('player') != -1:
scons_options.append('blenderplayer')
+ cur_scons_cmd = prog_scons_cmd
+ elif config.find('cuda') != -1:
+ scons_options.append('cudakernels')
+ cur_scons_cmd = cuda_scons_cmd
+
+ if config.find('i686') != -1:
+ scons_options.append('BF_BITNESS=32')
+ elif config.find('x86_64') != -1:
+ scons_options.append('BF_BITNESS=64')
+ else:
+ scons_options.append('blender')
+ cur_scons_cmd = prog_scons_cmd
scons_options.append('BF_CONFIG=' + config_fpath)
- retcode = subprocess.call(scons_cmd + scons_options)
+ retcode = subprocess.call(cur_scons_cmd + scons_options)
if retcode != 0:
print('Error building rules wuth config ' + config)
sys.exit(retcode)
diff --git a/build_files/buildbot/slave_pack.py b/build_files/buildbot/slave_pack.py
index b7775ef872f..3d4f423be9c 100644
--- a/build_files/buildbot/slave_pack.py
+++ b/build_files/buildbot/slave_pack.py
@@ -57,17 +57,13 @@ if builder.find('scons') != -1:
config = None
bits = None
- if builder.endswith('linux_glibc27_x86_64_scons'):
- config = 'user-config-glibc27-x86_64.py'
- bits = 64
- elif builder.endswith('linux_glibc27_i386_scons'):
- config = 'user-config-glibc27-i686.py'
- bits = 32
if builder.endswith('linux_glibc211_x86_64_scons'):
config = 'user-config-glibc211-x86_64.py'
+ chroot_name = 'buildbot_squeeze_x86_64'
bits = 64
elif builder.endswith('linux_glibc211_i386_scons'):
config = 'user-config-glibc211-i686.py'
+ chroot_name = 'buildbot_squeeze_i686'
bits = 32
if config is not None:
@@ -76,7 +72,7 @@ if builder.find('scons') != -1:
blender = os.path.join(install_dir, 'blender')
blenderplayer = os.path.join(install_dir, 'blenderplayer')
- subprocess.call(['strip', '--strip-all', blender, blenderplayer])
+ subprocess.call(['schroot', '-c', chroot_name, '--', 'strip', '--strip-all', blender, blenderplayer])
extra = '/' + os.path.join('home', 'sources', 'release-builder', 'extra')
mesalibs = os.path.join(extra, 'mesalibs' + str(bits) + '.tar.bz2')
@@ -86,7 +82,7 @@ if builder.find('scons') != -1:
os.system('cp %s %s' % (software_gl, install_dir))
os.system('chmod 755 %s' % (os.path.join(install_dir, 'blender-softwaregl')))
- retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options)
+ retcode = subprocess.call(['schroot', '-c', chroot_name, '--', 'python', 'scons/scons.py'] + scons_options)
sys.exit(retcode)
else:
diff --git a/build_files/cmake/cmake_netbeans_project.py b/build_files/cmake/cmake_netbeans_project.py
index 2f36cad4d24..17490e36bb3 100755
--- a/build_files/cmake/cmake_netbeans_project.py
+++ b/build_files/cmake/cmake_netbeans_project.py
@@ -56,6 +56,10 @@ def create_nb_project_main():
pass
else:
includes, defines = cmake_advanced_info()
+
+ if (includes, defines) == (None, None):
+ return
+
# for some reason it doesnt give all internal includes
includes = list(set(includes) | set(dirname(f) for f in files if is_c_header(f)))
includes.sort()
diff --git a/build_files/cmake/cmake_qtcreator_project.py b/build_files/cmake/cmake_qtcreator_project.py
index 86201da23de..4cf854aad77 100755
--- a/build_files/cmake/cmake_qtcreator_project.py
+++ b/build_files/cmake/cmake_qtcreator_project.py
@@ -81,6 +81,9 @@ def create_qtc_project_main():
else:
includes, defines = cmake_advanced_info()
+ if (includes, defines) == (None, None):
+ return
+
# for some reason it doesnt give all internal includes
includes = list(set(includes) | set(os.path.dirname(f)
for f in files_rel if is_c_header(f)))
diff --git a/build_files/cmake/project_info.py b/build_files/cmake/project_info.py
index 495ca71263e..e73b94a7051 100755
--- a/build_files/cmake/project_info.py
+++ b/build_files/cmake/project_info.py
@@ -149,14 +149,20 @@ def cmake_advanced_info():
raise Exception("Unknown make program %r" % make_exe)
os.system(cmd)
+ return join(CMAKE_DIR, ".cproject")
+
includes = []
defines = []
- create_eclipse_project()
+ project_path = create_eclipse_project()
+
+ if not exists(project_path):
+ print("Generating Eclipse Prokect File Failed: %r not found" % project_path)
+ return None, None
from xml.dom.minidom import parse
- tree = parse(join(CMAKE_DIR, ".cproject"))
+ tree = parse(project_path)
# to check on nicer xml
# f = open(".cproject_pretty", 'w')
diff --git a/build_files/scons/tools/btools.py b/build_files/scons/tools/btools.py
index 521138cba6a..82d7350bfce 100644
--- a/build_files/scons/tools/btools.py
+++ b/build_files/scons/tools/btools.py
@@ -216,7 +216,8 @@ def print_targets(targs, bc):
def validate_targets(targs, bc):
valid_list = ['.', 'blender', 'blenderstatic', 'blenderplayer', 'webplugin',
'blendernogame', 'blenderstaticnogame', 'blenderlite', 'release',
- 'everything', 'clean', 'install-bin', 'install', 'nsis','buildslave']
+ 'everything', 'clean', 'install-bin', 'install', 'nsis','buildslave',
+ 'cudakernels']
oklist = []
for t in targs:
if t in valid_list:
@@ -829,6 +830,18 @@ def NSIS_Installer(target=None, source=None, env=None):
print data.strip().split("\n")[-1]
return rv
+def cudakernels_print(target, source, env):
+ return "Running cudakernels target"
+
+def cudakernels(target=None, source=None, env=None):
+ """
+ Builder for cuda kernels compilation. Used by release build environment only
+ """
+
+ # Currently nothing to do, everything is handled by a dependency resolver
+
+ pass
+
def check_environ():
problematic_envvars = ""
for i in os.environ:
diff --git a/doc/python_api/examples/bpy.props.5.py b/doc/python_api/examples/bpy.props.5.py
new file mode 100644
index 00000000000..e49d0f2a0a0
--- /dev/null
+++ b/doc/python_api/examples/bpy.props.5.py
@@ -0,0 +1,85 @@
+"""
+Get/Set Example
+++++++++++++++
+
+Get/Set functions can be used for boolean, int, float, string and enum properties.
+If these callbacks are defined the property will not be stored in the ID properties
+automatically, instead the get/set functions will be called when the property is
+read or written from the API.
+"""
+
+import bpy
+
+
+# Simple property reading/writing from ID properties.
+# This is what the RNA would do internally.
+def get_float(self):
+ return self["testprop"]
+
+def set_float(self, value):
+ self["testprop"] = value
+
+bpy.types.Scene.test_float = bpy.props.FloatProperty(get=get_float, set=set_float)
+
+
+# Read-only string property, returns the current date
+def get_date(self):
+ import datetime
+ return str(datetime.datetime.now())
+
+bpy.types.Scene.test_date = bpy.props.StringProperty(get=get_date)
+
+
+# Boolean array. Set function stores a single boolean value, returned as the second component.
+# Array getters must return a list or tuple
+# Array size must match the property vector size exactly
+def get_array(self):
+ return (True, self["somebool"])
+
+def set_array(self, values):
+ self["somebool"] = values[0] and values[1]
+
+bpy.types.Scene.test_array = bpy.props.BoolVectorProperty(size=2, get=get_array, set=set_array)
+
+
+# Enum property.
+# Note: the getter/setter callback must use integer identifiers!
+test_items = [
+ ("RED", "Red", "", 1),
+ ("GREEN", "Red", "", 2),
+ ("BLUE", "Red", "", 3),
+ ("YELLOW", "Red", "", 4),
+ ]
+
+def get_enum(self):
+ import random
+ return random.randint(1, 4)
+
+def set_enum(self, value):
+ print("setting value", value)
+
+bpy.types.Scene.test_enum = bpy.props.EnumProperty(items=test_items, get=get_enum, set=set_enum)
+
+
+# Testing
+
+scene = bpy.context.scene
+
+scene.test_float = 12.34
+print (scene.test_float)
+
+scene.test_array = (True, False)
+print ([x for x in scene.test_array])
+
+#scene.test_date = "blah" # this would fail, property is read-only
+print (scene.test_date)
+
+scene.test_enum = 'BLUE'
+print (scene.test_enum)
+
+
+# >>> 12.34000015258789
+# >>> [True, False]
+# >>> 2013-01-05 16:33:52.135340
+# >>> setting value 3
+# >>> GREEN
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 2bc4afe969e..8b90b0bd4ff 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -95,6 +95,14 @@ enum_curves_interpolation = (
('CARDINAL', "Cardinal interpolation", "Use cardinal interpolation between segments"),
('BSPLINE', "B-spline interpolation", "Use b-spline interpolation between segments"),
)
+
+enum_tile_order = (
+ ('CENTER', "Center", "Render from center to the edges"),
+ ('RIGHT_TO_LEFT', "Right to Left", "Render from right to left"),
+ ('LEFT_TO_RIGHT', "Left to Right", "Render from left to right"),
+ ('TOP_TO_BOTTOM', "Top to Bottom", "Render from top to bottom"),
+ ('BOTTOM_TO_TOP', "Bottom to Top", "Render from bottom to top"),
+ )
class CyclesRenderSettings(bpy.types.PropertyGroup):
@classmethod
@@ -352,6 +360,12 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
description="Cache last built BVH to disk for faster re-render if no geometry changed",
default=False,
)
+ cls.tile_order = EnumProperty(
+ name="Tile Order",
+ description="Tile order for rendering",
+ items=enum_tile_order,
+ default='CENTER',
+ )
cls.use_progressive_refine = BoolProperty(
name="Progressive Refine",
description="Instead of rendering each tile until it is finished, "
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 554a9204c7f..6a3a0c63236 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -191,7 +191,8 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel):
sub.prop(rd, "threads")
sub = col.column(align=True)
- sub.label(text="Tile Size:")
+ sub.label(text="Tiles:")
+ sub.prop(cscene, "tile_order", text="")
sub.prop(rd, "tile_x", text="X")
sub.prop(rd, "tile_y", text="Y")
diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp
index 4fad7d45162..41e1249dae7 100644
--- a/intern/cycles/blender/blender_curves.cpp
+++ b/intern/cycles/blender/blender_curves.cpp
@@ -330,13 +330,17 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par
bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents)
{
+#if 0
int keyno = 0;
+#endif
if(!(mesh && b_mesh && b_ob && CData))
return false;
+#if 0
Transform tfm = get_transform(b_ob->matrix_world());
Transform itfm = transform_quick_inverse(tfm);
+#endif
BL::Object::modifiers_iterator b_mod;
for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
@@ -348,12 +352,13 @@ bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Parti
BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
if((b_psys.settings().render_type()==BL::ParticleSettings::render_type_PATH)&&(b_psys.settings().type()==BL::ParticleSettings::type_HAIR)) {
-
+#if 0
int mi = clamp(b_psys.settings().material()-1, 0, mesh->used_shaders.size()-1);
int shader = mesh->used_shaders[mi];
int draw_step = b_psys.settings().draw_step();
int ren_step = (int)pow((float)2.0f,(float)draw_step);
- /*b_psys.settings().render_step(draw_step);*/
+ b_psys.settings().render_step(draw_step);
+#endif
int totparts = b_psys.particles.length();
int totchild = b_psys.child_particles.length() * b_psys.settings().draw_percentage() / 100;
@@ -397,13 +402,16 @@ bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Parti
bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents, int vcol_num)
{
+#if 0
int keyno = 0;
-
+#endif
if(!(mesh && b_mesh && b_ob && CData))
return false;
+#if 0
Transform tfm = get_transform(b_ob->matrix_world());
Transform itfm = transform_quick_inverse(tfm);
+#endif
BL::Object::modifiers_iterator b_mod;
for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
@@ -415,13 +423,13 @@ bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par
BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
if((b_psys.settings().render_type()==BL::ParticleSettings::render_type_PATH)&&(b_psys.settings().type()==BL::ParticleSettings::type_HAIR)) {
-
+#if 0
int mi = clamp(b_psys.settings().material()-1, 0, mesh->used_shaders.size()-1);
int shader = mesh->used_shaders[mi];
int draw_step = b_psys.settings().draw_step();
int ren_step = (int)pow((float)2.0f,(float)draw_step);
- /*b_psys.settings().render_step(draw_step);*/
-
+ b_psys.settings().render_step(draw_step);
+#endif
int totparts = b_psys.particles.length();
int totchild = b_psys.child_particles.length() * b_psys.settings().draw_percentage() / 100;
int totcurves = totchild;
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index ad701266c5b..e9bcea70ab6 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -127,8 +127,8 @@ void BlenderSync::sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSI
case BL::Lamp::type_AREA: {
BL::AreaLamp b_area_lamp(b_lamp);
light->size = 1.0f;
- light->axisu = make_float3(tfm.x.x, tfm.y.x, tfm.z.x);
- light->axisv = make_float3(tfm.x.y, tfm.y.y, tfm.z.y);
+ light->axisu = transform_get_column(&tfm, 0);
+ light->axisv = transform_get_column(&tfm, 1);
light->sizeu = b_area_lamp.size();
if(b_area_lamp.shape() == BL::AreaLamp::shape_RECTANGLE)
light->sizev = b_area_lamp.size_y();
@@ -140,8 +140,8 @@ void BlenderSync::sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSI
}
/* location and (inverted!) direction */
- light->co = make_float3(tfm.x.w, tfm.y.w, tfm.z.w);
- light->dir = -make_float3(tfm.x.z, tfm.y.z, tfm.z.z);
+ light->co = transform_get_column(&tfm, 3);
+ light->dir = -transform_get_column(&tfm, 2);
/* shader */
vector<uint> used_shaders;
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 770b71afcdc..d0c7c06cbb3 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -139,6 +139,8 @@ void BlenderSession::reset_session(BL::BlendData b_data_, BL::Scene b_scene_)
session->progress.reset();
scene->reset();
+ session->tile_manager.set_tile_order(session_params.tile_order);
+
/* peak memory usage should show current render peak, not peak for all renders
* made by this render session
*/
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index b9860ca90f2..a2a8c23404f 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -396,6 +396,8 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine b_engine, BL::Use
params.tile_size = make_int2(tile_x, tile_y);
}
+
+ params.tile_order = RNA_enum_get(&cscene, "tile_order");
params.start_resolution = get_int(cscene, "preview_start_resolution");
diff --git a/intern/cycles/device/CMakeLists.txt b/intern/cycles/device/CMakeLists.txt
index 0071bbe5cdc..661d43ab036 100644
--- a/intern/cycles/device/CMakeLists.txt
+++ b/intern/cycles/device/CMakeLists.txt
@@ -18,11 +18,14 @@ set(SRC
device_cpu.cpp
device_cuda.cpp
device_multi.cpp
- device_network.cpp
device_opencl.cpp
device_task.cpp
)
+if(WITH_NETWORK)
+ list(APPEND SRC device_network.cpp)
+endif()
+
set(SRC_HEADERS
device.h
device_memory.h
diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h
index 97d37a8b3f4..cd896ffe133 100644
--- a/intern/cycles/kernel/kernel_camera.h
+++ b/intern/cycles/kernel/kernel_camera.h
@@ -199,7 +199,6 @@ __device void camera_sample_panorama(KernelGlobals *kg, float raster_x, float ra
Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y + 1.0f, 0.0f));
ray->dD.dy = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y))) - ray->D;
-
#endif
}
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h
index d5506ad1dd0..54bc0717b60 100644
--- a/intern/cycles/kernel/kernel_emission.h
+++ b/intern/cycles/kernel/kernel_emission.h
@@ -66,6 +66,8 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando,
else
eval = make_float3(0.0f, 0.0f, 0.0f);
}
+
+ eval *= ls->eval_fac;
shader_release(kg, &sd);
@@ -74,29 +76,29 @@ __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, BsdfEval *eval,
- bool *is_lamp)
+ int *lamp)
{
LightSample ls;
- float pdf = -1.0f;
-
#ifdef __NON_PROGRESSIVE__
if(lindex != -1) {
/* sample position on a specified light */
- light_select(kg, lindex, randu, randv, sd->P, &ls, &pdf);
+ light_select(kg, lindex, randu, randv, sd->P, &ls);
}
else
#endif
{
/* sample a light and position on int */
- light_sample(kg, randt, randu, randv, sd->time, sd->P, &ls, &pdf);
+ light_sample(kg, randt, randu, randv, sd->time, sd->P, &ls);
}
- /* compute pdf */
- if(pdf < 0.0f)
- pdf = light_sample_pdf(kg, &ls, -ls.D, ls.t);
+ /* return lamp index for MIS */
+ if(ls.use_mis)
+ *lamp = ls.lamp;
+ else
+ *lamp= ~0;
- if(pdf == 0.0f)
+ if(ls.pdf == 0.0f)
return false;
/* evaluate closure */
@@ -112,13 +114,13 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
shader_bsdf_eval(kg, sd, ls.D, eval, &bsdf_pdf);
- if(ls.prim != ~0 || ls.type == LIGHT_BACKGROUND) {
+ if(ls.use_mis) {
/* multiple importance sampling */
- float mis_weight = power_heuristic(pdf, bsdf_pdf);
+ float mis_weight = power_heuristic(ls.pdf, bsdf_pdf);
light_eval *= mis_weight;
}
- bsdf_eval_mul(eval, light_eval*(ls.eval_fac/pdf));
+ bsdf_eval_mul(eval, light_eval/ls.pdf);
if(bsdf_eval_is_zero(eval))
return false;
@@ -144,14 +146,12 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
ray->t = 0.0f;
}
- *is_lamp = (ls.prim == ~0);
-
return true;
}
-/* Indirect Emission */
+/* Indirect Primitive Emission */
-__device float3 indirect_emission(KernelGlobals *kg, ShaderData *sd, float t, int path_flag, float bsdf_pdf)
+__device float3 indirect_primitive_emission(KernelGlobals *kg, ShaderData *sd, float t, int path_flag, float bsdf_pdf)
{
/* evaluate emissive closure */
float3 L = shader_emissive_eval(kg, sd);
@@ -172,6 +172,35 @@ __device float3 indirect_emission(KernelGlobals *kg, ShaderData *sd, float t, in
return L;
}
+/* Indirect Lamp Emission */
+
+__device bool indirect_lamp_emission(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf, float randt, float3 *emission)
+{
+ LightSample ls;
+ int lamp = lamp_light_eval_sample(kg, randt);
+
+ if(lamp == ~0)
+ return false;
+
+ if(!lamp_light_eval(kg, lamp, ray->P, ray->D, ray->t, &ls))
+ return false;
+
+ /* todo: missing texture coordinates */
+ float u = 0.0f;
+ float v = 0.0f;
+ float3 L = direct_emissive_eval(kg, 0.0f, &ls, u, v, -ray->D, ls.t, ray->time);
+
+ if(!(path_flag & PATH_RAY_MIS_SKIP)) {
+ /* multiple importance sampling, get regular light pdf,
+ * and compute weight with respect to BSDF pdf */
+ float mis_weight = power_heuristic(bsdf_pdf, ls.pdf);
+ L *= mis_weight;
+ }
+
+ *emission = L;
+ return true;
+}
+
/* Indirect Background */
__device float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf)
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index ea0e4d014fe..e0d0802ae84 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -18,49 +18,27 @@
CCL_NAMESPACE_BEGIN
+/* Light Sample result */
+
typedef struct LightSample {
- float3 P;
- float3 D;
- float3 Ng;
- float t;
- float eval_fac;
- int object;
- int prim;
- int shader;
- LightType type;
+ float3 P; /* position on light, or direction for distant light */
+ float3 Ng; /* normal on light */
+ float3 D; /* direction from shading point to light */
+ float t; /* distance to light (FLT_MAX for distant light) */
+ float pdf; /* light sampling probability density function */
+ float eval_fac; /* intensity multiplier */
+ int object; /* object id for triangle/curve lights */
+ int prim; /* primitive id for triangle/curve ligths */
+ int shader; /* shader id */
+ int lamp; /* lamp id */
+ int use_mis; /* for lamps with size zero */
+ LightType type; /* type of light */
} LightSample;
-/* Regular Light */
-
-__device float3 disk_light_sample(float3 v, float randu, float randv)
-{
- float3 ru, rv;
-
- make_orthonormals(v, &ru, &rv);
- to_unit_disk(&randu, &randv);
-
- return ru*randu + rv*randv;
-}
-
-__device float3 distant_light_sample(float3 D, float size, float randu, float randv)
-{
- return normalize(D + disk_light_sample(D, randu, randv)*size);
-}
-
-__device float3 sphere_light_sample(float3 P, float3 center, float size, float randu, float randv)
-{
- return disk_light_sample(normalize(P - center), randu, randv)*size;
-}
-
-__device float3 area_light_sample(float3 axisu, float3 axisv, float randu, float randv)
-{
- randu = randu - 0.5f;
- randv = randv - 0.5f;
-
- return axisu*randu + axisv*randv;
-}
+/* Background Light */
#ifdef __BACKGROUND_MIS__
+
__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
@@ -169,33 +147,108 @@ __device float background_light_pdf(KernelGlobals *kg, float3 direction)
}
#endif
-__device void regular_light_sample(KernelGlobals *kg, int point,
- float randu, float randv, float3 P, LightSample *ls, float *pdf)
+/* Regular Light */
+
+__device float3 disk_light_sample(float3 v, float randu, float randv)
+{
+ float3 ru, rv;
+
+ make_orthonormals(v, &ru, &rv);
+ to_unit_disk(&randu, &randv);
+
+ return ru*randu + rv*randv;
+}
+
+__device float3 distant_light_sample(float3 D, float radius, float randu, float randv)
+{
+ return normalize(D + disk_light_sample(D, randu, randv)*radius);
+}
+
+__device float3 sphere_light_sample(float3 P, float3 center, float radius, float randu, float randv)
{
- float4 data0 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 0);
- float4 data1 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 1);
+ return disk_light_sample(normalize(P - center), randu, randv)*radius;
+}
+
+__device float3 area_light_sample(float3 axisu, float3 axisv, float randu, float randv)
+{
+ randu = randu - 0.5f;
+ randv = randv - 0.5f;
+
+ return axisu*randu + axisv*randv;
+}
+
+__device float spot_light_attenuation(float4 data1, float4 data2, LightSample *ls)
+{
+ float3 dir = make_float3(data2.y, data2.z, data2.w);
+ float3 I = ls->Ng;
+
+ float spot_angle = data1.w;
+ float spot_smooth = data2.x;
+
+ float attenuation = dot(dir, I);
+
+ if(attenuation <= spot_angle) {
+ attenuation = 0.0f;
+ }
+ else {
+ float t = attenuation - spot_angle;
+
+ if(t < spot_smooth && spot_smooth != 0.0f)
+ attenuation *= smoothstepf(t/spot_smooth);
+ }
+
+ return attenuation;
+}
+
+__device float lamp_light_pdf(KernelGlobals *kg, const float3 Ng, const float3 I, float t)
+{
+ float cos_pi = dot(Ng, I);
+
+ if(cos_pi <= 0.0f)
+ return 0.0f;
+
+ return t*t/cos_pi;
+}
+
+__device void lamp_light_sample(KernelGlobals *kg, int lamp,
+ float randu, float randv, float3 P, LightSample *ls)
+{
+ float4 data0 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 0);
+ float4 data1 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 1);
LightType type = (LightType)__float_as_int(data0.x);
ls->type = type;
+#ifdef __LAMP_MIS__
+ ls->use_mis = true;
+#else
+ ls->use_mis = false;
+#endif
if(type == LIGHT_DISTANT) {
/* distant light */
- float3 D = make_float3(data0.y, data0.z, data0.w);
- float size = data1.y;
+ float3 lightD = make_float3(data0.y, data0.z, data0.w);
+ float3 D = lightD;
+ float radius = data1.y;
+ float invarea = data1.w;
- if(size > 0.0f)
- D = distant_light_sample(D, size, randu, randv);
+ if(radius > 0.0f)
+ D = distant_light_sample(D, radius, randu, randv);
+ else
+ ls->use_mis = false;
ls->P = D;
ls->Ng = D;
ls->D = -D;
ls->t = FLT_MAX;
- ls->eval_fac = 1.0f;
+
+ float costheta = dot(lightD, D);
+ ls->pdf = invarea/(costheta*costheta*costheta);
+ ls->eval_fac = ls->pdf*kernel_data.integrator.inv_pdf_lights;
}
#ifdef __BACKGROUND_MIS__
else if(type == LIGHT_BACKGROUND) {
/* infinite area light (e.g. light dome or env light) */
- float3 D = background_light_sample(kg, randu, randv, pdf);
+ float3 D = background_light_sample(kg, randu, randv, &ls->pdf);
ls->P = D;
ls->Ng = D;
@@ -207,127 +260,235 @@ __device void regular_light_sample(KernelGlobals *kg, int point,
else {
ls->P = make_float3(data0.y, data0.z, data0.w);
- if(type == LIGHT_POINT) {
- float size = data1.y;
-
- /* sphere light */
- if(size > 0.0f)
- ls->P += sphere_light_sample(P, ls->P, size, randu, randv);
+ if(type == LIGHT_POINT || type == LIGHT_SPOT) {
+ float radius = data1.y;
- ls->Ng = normalize(P - ls->P);
- ls->eval_fac = 0.25f*M_1_PI_F;
- }
- else if(type == LIGHT_SPOT) {
- float4 data2 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 2);
- float size = data1.y;
-
- /* spot light */
- if(size > 0.0f)
- ls->P += sphere_light_sample(P, ls->P, size, randu, randv);
-
- float3 dir = make_float3(data1.z, data1.w, data2.x);
- float3 I = normalize(P - ls->P);
+ if(radius > 0.0f)
+ /* sphere light */
+ ls->P += sphere_light_sample(P, ls->P, radius, randu, randv);
+ else
+ ls->use_mis = false;
- float spot_angle = data2.y;
- float spot_smooth = data2.z;
+ ls->D = normalize_len(ls->P - P, &ls->t);
+ ls->Ng = -ls->D;
- float eval_fac = dot(dir, I);
+ float invarea = data1.z;
+ ls->eval_fac = (0.25f*M_1_PI_F)*invarea;
+ ls->pdf = invarea;
- if(eval_fac <= spot_angle) {
- eval_fac = 0.0f;
+ if(type == LIGHT_SPOT) {
+ /* spot light attentuation */
+ float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2);
+ ls->eval_fac *= spot_light_attenuation(data1, data2, ls);
}
- else {
- float t = eval_fac - spot_angle;
-
- if(t < spot_smooth && spot_smooth != 0.0f)
- eval_fac *= smoothstepf(t/spot_smooth);
- }
-
- ls->Ng = I;
- ls->eval_fac = eval_fac*0.25f*M_1_PI_F;
}
else {
/* area light */
- float4 data2 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 2);
- float4 data3 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 3);
+ float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2);
+ float4 data3 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 3);
- float3 axisu = make_float3(data1.y, data1.z, data2.w);
+ float3 axisu = make_float3(data1.y, data1.z, data1.w);
float3 axisv = make_float3(data2.y, data2.z, data2.w);
float3 D = make_float3(data3.y, data3.z, data3.w);
ls->P += area_light_sample(axisu, axisv, randu, randv);
ls->Ng = D;
- ls->eval_fac = 0.25f;
+ ls->D = normalize_len(ls->P - P, &ls->t);
+
+ float invarea = data2.x;
+
+ if(invarea == 0.0f) {
+ ls->use_mis = false;
+ invarea = 1.0f;
+ }
+
+ ls->eval_fac = 0.25f*invarea;
+ ls->pdf = invarea;
}
- ls->t = 0.0f;
+ ls->eval_fac *= kernel_data.integrator.inv_pdf_lights;
+ ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
}
ls->shader = __float_as_int(data1.x);
ls->object = ~0;
ls->prim = ~0;
+ ls->lamp = lamp;
}
-__device float regular_light_pdf(KernelGlobals *kg,
- const float3 Ng, const float3 I, float t)
+__device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D, float t, LightSample *ls)
{
- float pdf = kernel_data.integrator.pdf_lights;
+ float4 data0 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 0);
+ float4 data1 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 1);
- if(t == FLT_MAX)
- return pdf;
+ LightType type = (LightType)__float_as_int(data0.x);
+ ls->type = type;
+ ls->shader = __float_as_int(data1.x);
+ ls->object = ~0;
+ ls->prim = ~0;
+ ls->lamp = lamp;
+ ls->use_mis = false; /* flag not used for eval */
- float cos_pi = dot(Ng, I);
+ if(type == LIGHT_DISTANT) {
+ /* distant light */
+ float radius = data1.y;
+
+ if(radius == 0.0f)
+ return false;
+ if(t != FLT_MAX)
+ return false;
+
+ /* a distant light is infinitely far away, but equivalent to a disk
+ * shaped light exactly 1 unit away from the current shading point.
+ *
+ * radius t^2/cos(theta)
+ * <----------> t = sqrt(1^2 + tan(theta)^2)
+ * tan(th) area = radius*radius*pi
+ * <----->
+ * \ | (1 + tan(theta)^2)/cos(theta)
+ * \ | (1 + tan(acos(cos(theta)))^2)/cos(theta)
+ * t \th| 1 simplifies to
+ * \-| 1/(cos(theta)^3)
+ * \| magic!
+ * P
+ */
+
+ float3 lightD = make_float3(data0.y, data0.z, data0.w);
+ float costheta = dot(-lightD, D);
+ float cosangle = data1.z;
+
+ if(costheta < cosangle)
+ return false;
+
+ ls->P = -D;
+ ls->Ng = -D;
+ ls->D = D;
+ ls->t = FLT_MAX;
- if(cos_pi <= 0.0f)
- return 0.0f;
+ float invarea = data1.w;
+ ls->pdf = invarea/(costheta*costheta*costheta);
+ ls->eval_fac = ls->pdf;
+ }
+ else if(type == LIGHT_POINT || type == LIGHT_SPOT) {
+ float3 lightP = make_float3(data0.y, data0.z, data0.w);
+ float radius = data1.y;
- return t*t*pdf/cos_pi;
+ /* sphere light */
+ if(radius == 0.0f)
+ return false;
+
+ if(!ray_aligned_disk_intersect(P, D, t,
+ lightP, radius, &ls->P, &ls->t))
+ return false;
+
+ ls->Ng = -D;
+ ls->D = D;
+
+ float invarea = data1.z;
+ ls->eval_fac = (0.25f*M_1_PI_F)*invarea;
+ ls->pdf = invarea;
+
+ if(type == LIGHT_SPOT) {
+ /* spot light attentuation */
+ float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2);
+ ls->eval_fac *= spot_light_attenuation(data1, data2, ls);
+
+ if(ls->eval_fac == 0.0f)
+ return false;
+ }
+ }
+ else if(type == LIGHT_AREA) {
+ /* area light */
+ float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2);
+ float4 data3 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 3);
+
+ float invarea = data2.x;
+ if(invarea == 0.0f)
+ return false;
+
+ float3 axisu = make_float3(data1.y, data1.z, data1.w);
+ float3 axisv = make_float3(data2.y, data2.z, data2.w);
+ float3 Ng = make_float3(data3.y, data3.z, data3.w);
+
+ /* one sided */
+ if(dot(D, Ng) >= 0.0f)
+ return false;
+
+ ls->P = make_float3(data0.y, data0.z, data0.w);
+
+ if(!ray_quad_intersect(P, D, t,
+ ls->P, axisu, axisv, &ls->P, &ls->t))
+ return false;
+
+ ls->D = D;
+ ls->Ng = Ng;
+ ls->pdf = invarea;
+ ls->eval_fac = 0.25f*ls->pdf;
+ }
+ else
+ return false;
+
+ /* compute pdf */
+ if(ls->t != FLT_MAX)
+ ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
+ ls->eval_fac *= kernel_data.integrator.inv_pdf_lights;
+
+ return true;
}
/* Triangle Light */
-__device void triangle_light_sample(KernelGlobals *kg, int prim, int object,
- float randu, float randv, float time, LightSample *ls)
+__device void object_transform_light_sample(KernelGlobals *kg, LightSample *ls, int object, float time)
{
- /* triangle, so get position, normal, shader */
- ls->P = triangle_sample_MT(kg, prim, randu, randv);
- ls->Ng = triangle_normal_MT(kg, prim, &ls->shader);
- ls->object = object;
- ls->prim = prim;
- ls->t = 0.0f;
- ls->type = LIGHT_AREA;
- ls->eval_fac = 1.0f;
-
#ifdef __INSTANCING__
/* instance transform */
- if(ls->object >= 0) {
+ if(object >= 0) {
#ifdef __OBJECT_MOTION__
Transform itfm;
Transform tfm = object_fetch_transform_motion_test(kg, object, time, &itfm);
#else
- Transform tfm = object_fetch_transform(kg, ls->object, OBJECT_TRANSFORM);
- Transform itfm = object_fetch_transform(kg, ls->object, OBJECT_INVERSE_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
+ Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
#endif
ls->P = transform_point(&tfm, ls->P);
- ls->Ng = normalize(transform_direction_transposed(&itfm, ls->Ng));
+ ls->Ng = normalize(transform_direction(&tfm, ls->Ng));
}
#endif
}
+__device void triangle_light_sample(KernelGlobals *kg, int prim, int object,
+ float randu, float randv, float time, LightSample *ls)
+{
+ /* triangle, so get position, normal, shader */
+ ls->P = triangle_sample_MT(kg, prim, randu, randv);
+ ls->Ng = triangle_normal_MT(kg, prim, &ls->shader);
+ ls->object = object;
+ ls->prim = prim;
+ ls->lamp = ~0;
+ ls->use_mis = true;
+ ls->t = 0.0f;
+ ls->type = LIGHT_AREA;
+ ls->eval_fac = 1.0f;
+
+ object_transform_light_sample(kg, ls, object, time);
+}
+
__device float triangle_light_pdf(KernelGlobals *kg,
const float3 Ng, const float3 I, float t)
{
+ float pdf = kernel_data.integrator.pdf_triangles;
float cos_pi = fabsf(dot(Ng, I));
if(cos_pi == 0.0f)
return 0.0f;
- return (t*t*kernel_data.integrator.pdf_triangles)/cos_pi;
+ return t*t*pdf/cos_pi;
}
+/* Curve Light */
+
#ifdef __HAIR__
-/* Strand Light */
__device void curve_segment_light_sample(KernelGlobals *kg, int prim, int object,
int segment, float randu, float randv, float time, LightSample *ls)
@@ -358,27 +519,16 @@ __device void curve_segment_light_sample(KernelGlobals *kg, int prim, int object
ls->P = randu * l * tg + (gd * l + r1) * ls->Ng;
ls->object = object;
ls->prim = prim;
+ ls->lamp = ~0;
+ ls->use_mis = true;
ls->t = 0.0f;
ls->type = LIGHT_STRAND;
ls->eval_fac = 1.0f;
ls->shader = __float_as_int(v00.z);
-#ifdef __INSTANCING__
- /* instance transform */
- if(ls->object >= 0) {
-#ifdef __OBJECT_MOTION__
- Transform itfm;
- Transform tfm = object_fetch_transform_motion_test(kg, object, time, &itfm);
-#else
- Transform tfm = object_fetch_transform(kg, ls->object, OBJECT_TRANSFORM);
- Transform itfm = object_fetch_transform(kg, ls->object, OBJECT_INVERSE_TRANSFORM);
-#endif
-
- ls->P = transform_point(&tfm, ls->P);
- ls->Ng = normalize(transform_direction(&tfm, ls->Ng));
- }
-#endif
+ object_transform_light_sample(kg, ls, object, time);
}
+
#endif
/* Light Distribution */
@@ -412,7 +562,7 @@ __device int light_distribution_sample(KernelGlobals *kg, float randt)
/* Generic Light */
-__device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float time, float3 P, LightSample *ls, float *pdf)
+__device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float time, float3 P, LightSample *ls)
{
/* sample index */
int index = light_distribution_sample(kg, randt);
@@ -420,12 +570,12 @@ __device void light_sample(KernelGlobals *kg, float randt, float randu, float ra
/* fetch light data */
float4 l = kernel_tex_fetch(__light_distribution, index);
int prim = __float_as_int(l.y);
-#ifdef __HAIR__
- int segment = __float_as_int(l.z);
-#endif
if(prim >= 0) {
int object = __float_as_int(l.w);
+#ifdef __HAIR__
+ int segment = __float_as_int(l.z);
+#endif
#ifdef __HAIR__
if (segment != ~0)
@@ -433,27 +583,15 @@ __device void light_sample(KernelGlobals *kg, float randt, float randu, float ra
else
#endif
triangle_light_sample(kg, prim, object, randu, randv, time, ls);
+
+ /* compute incoming direction, distance and pdf */
+ ls->D = normalize_len(ls->P - P, &ls->t);
+ ls->pdf = triangle_light_pdf(kg, ls->Ng, -ls->D, ls->t);
}
else {
- int point = -prim-1;
- regular_light_sample(kg, point, randu, randv, P, ls, pdf);
+ int lamp = -prim-1;
+ lamp_light_sample(kg, lamp, randu, randv, P, ls);
}
-
- /* compute incoming direction and distance */
- if(ls->t != FLT_MAX)
- ls->D = normalize_len(ls->P - P, &ls->t);
-}
-
-__device float light_sample_pdf(KernelGlobals *kg, LightSample *ls, float3 I, float t)
-{
- float pdf;
-
- if(ls->prim != ~0)
- pdf = triangle_light_pdf(kg, ls->Ng, I, t);
- else
- pdf = regular_light_pdf(kg, ls->Ng, I, t);
-
- return pdf;
}
__device int light_select_num_samples(KernelGlobals *kg, int index)
@@ -462,18 +600,26 @@ __device int light_select_num_samples(KernelGlobals *kg, int index)
return __float_as_int(data3.x);
}
-__device void light_select(KernelGlobals *kg, int index, float randu, float randv, float3 P, LightSample *ls, float *pdf)
+__device void light_select(KernelGlobals *kg, int index, float randu, float randv, float3 P, LightSample *ls)
{
- regular_light_sample(kg, index, randu, randv, P, ls, pdf);
-
- /* compute incoming direction and distance */
- if(ls->t != FLT_MAX)
- ls->D = normalize_len(ls->P - P, &ls->t);
+ lamp_light_sample(kg, index, randu, randv, P, ls);
}
-__device float light_select_pdf(KernelGlobals *kg, LightSample *ls, float3 I, float t)
+__device int lamp_light_eval_sample(KernelGlobals *kg, float randt)
{
- return regular_light_pdf(kg, ls->Ng, I, t);
+ /* sample index */
+ int index = light_distribution_sample(kg, randt);
+
+ /* fetch light data */
+ float4 l = kernel_tex_fetch(__light_distribution, index);
+ int prim = __float_as_int(l.y);
+
+ if(prim < 0) {
+ int lamp = -prim-1;
+ return lamp;
+ }
+ else
+ return ~0;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index 20feaf50a2e..532c32896d9 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -238,6 +238,9 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
float min_ray_pdf = FLT_MAX;
float ray_pdf = 0.0f;
+#ifdef __LAMP_MIS__
+ float ray_t = 0.0f;
+#endif
PathState state;
int rng_offset = PRNG_BASE_NUM;
@@ -248,8 +251,29 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
/* intersect scene */
Intersection isect;
uint visibility = path_state_ray_visibility(kg, &state);
+ bool hit = scene_intersect(kg, &ray, visibility, &isect);
- if(!scene_intersect(kg, &ray, visibility, &isect)) {
+#ifdef __LAMP_MIS__
+ if(kernel_data.integrator.pdf_lights > 0.0f && !(state.flag & PATH_RAY_CAMERA)) {
+ /* ray starting from previous non-transparent bounce */
+ Ray light_ray;
+
+ light_ray.P = ray.P - ray_t*ray.D;
+ ray_t += isect.t;
+ light_ray.D = ray.D;
+ light_ray.t = ray_t;
+ light_ray.time = ray.time;
+
+ /* intersect with lamp */
+ float light_t = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT);
+ float3 emission;
+
+ if(indirect_lamp_emission(kg, &light_ray, state.flag, ray_pdf, light_t, &emission))
+ path_radiance_accum_emission(&L, throughput, emission, state.bounce);
+ }
+#endif
+
+ if(!hit) {
/* eval background shader if nothing hit */
if(kernel_data.background.transparent && (state.flag & PATH_RAY_CAMERA)) {
L_transparent += average(throughput);
@@ -313,7 +337,8 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
#ifdef __EMISSION__
/* emission */
if(sd.flag & SD_EMISSION) {
- float3 emission = indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf);
+ /* todo: is isect.t wrong here for transparent surfaces? */
+ float3 emission = indirect_primitive_emission(kg, &sd, isect.t, state.flag, ray_pdf);
path_radiance_accum_emission(&L, throughput, emission, state.bounce);
}
#endif
@@ -374,18 +399,19 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
Ray light_ray;
BsdfEval L_light;
- bool is_lamp;
+ int lamp;
#ifdef __OBJECT_MOTION__
light_ray.time = sd.time;
#endif
- if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp)) {
+ if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &lamp)) {
/* trace shadow ray */
float3 shadow;
if(!shadow_blocked(kg, &state, &light_ray, &shadow)) {
/* accumulate */
+ bool is_lamp = (lamp != ~0);
path_radiance_accum_light(&L, throughput, &L_light, shadow, state.bounce, is_lamp);
}
}
@@ -422,6 +448,9 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
/* set labels */
if(!(label & LABEL_TRANSPARENT)) {
ray_pdf = bsdf_pdf;
+#ifdef __LAMP_MIS__
+ ray_t = 0.0f;
+#endif
min_ray_pdf = fminf(bsdf_pdf, min_ray_pdf);
}
@@ -457,15 +486,41 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
#ifdef __NON_PROGRESSIVE__
__device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray ray, __global float *buffer,
- float3 throughput, float min_ray_pdf, float ray_pdf, PathState state, int rng_offset, PathRadiance *L)
+ float3 throughput, float throughput_normalize,
+ float min_ray_pdf, float ray_pdf, PathState state, int rng_offset, PathRadiance *L)
{
+#ifdef __LAMP_MIS__
+ float ray_t = 0.0f;
+#endif
+
/* path iteration */
for(;; rng_offset += PRNG_BOUNCE_NUM) {
/* intersect scene */
Intersection isect;
uint visibility = path_state_ray_visibility(kg, &state);
+ bool hit = scene_intersect(kg, &ray, visibility, &isect);
- if(!scene_intersect(kg, &ray, visibility, &isect)) {
+#ifdef __LAMP_MIS__
+ if(kernel_data.integrator.pdf_lights > 0.0f && !(state.flag & PATH_RAY_CAMERA)) {
+ /* ray starting from previous non-transparent bounce */
+ Ray light_ray;
+
+ light_ray.P = ray.P - ray_t*ray.D;
+ ray_t += isect.t;
+ light_ray.D = ray.D;
+ light_ray.t = ray_t;
+ light_ray.time = ray.time;
+
+ /* intersect with lamp */
+ float light_t = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT);
+ float3 emission;
+
+ if(indirect_lamp_emission(kg, &light_ray, state.flag, ray_pdf, light_t, &emission))
+ path_radiance_accum_emission(L, throughput, emission, state.bounce);
+ }
+#endif
+
+ if(!hit) {
#ifdef __BACKGROUND__
/* sample background shader */
float3 L_background = indirect_background(kg, &ray, state.flag, ray_pdf);
@@ -496,7 +551,7 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray
#ifdef __EMISSION__
/* emission */
if(sd.flag & SD_EMISSION) {
- float3 emission = indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf);
+ float3 emission = indirect_primitive_emission(kg, &sd, isect.t, state.flag, ray_pdf);
path_radiance_accum_emission(L, throughput, emission, state.bounce);
}
#endif
@@ -504,7 +559,7 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray
/* path termination. this is a strange place to put the termination, it's
* mainly due to the mixed in MIS that we use. gives too many unneeded
* shader evaluations, only need emission if we are going to terminate */
- float probability = path_state_terminate_probability(kg, &state, throughput);
+ float probability = path_state_terminate_probability(kg, &state, throughput*throughput_normalize);
float terminate = path_rng(kg, rng, sample, rng_offset + PRNG_TERMINATE);
if(terminate >= probability) {
@@ -557,19 +612,20 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray
Ray light_ray;
BsdfEval L_light;
- bool is_lamp;
+ int lamp;
#ifdef __OBJECT_MOTION__
light_ray.time = sd.time;
#endif
/* sample random light */
- if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp)) {
+ if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &lamp)) {
/* trace shadow ray */
float3 shadow;
if(!shadow_blocked(kg, &state, &light_ray, &shadow)) {
/* accumulate */
+ bool is_lamp = (lamp != ~0);
path_radiance_accum_light(L, throughput, &L_light, shadow, state.bounce, is_lamp);
}
}
@@ -606,6 +662,9 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray
/* set labels */
if(!(label & LABEL_TRANSPARENT)) {
ray_pdf = bsdf_pdf;
+#ifdef __LAMP_MIS__
+ ray_t = 0.0f;
+#endif
min_ray_pdf = fminf(bsdf_pdf, min_ray_pdf);
}
@@ -697,7 +756,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
#ifdef __EMISSION__
/* emission */
if(sd.flag & SD_EMISSION) {
- float3 emission = indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf);
+ float3 emission = indirect_primitive_emission(kg, &sd, isect.t, state.flag, ray_pdf);
path_radiance_accum_emission(&L, throughput, emission, state.bounce);
}
#endif
@@ -760,7 +819,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
if(sd.flag & SD_BSDF_HAS_EVAL) {
Ray light_ray;
BsdfEval L_light;
- bool is_lamp;
+ int lamp;
#ifdef __OBJECT_MOTION__
light_ray.time = sd.time;
@@ -778,12 +837,13 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
float light_u = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_LIGHT_U);
float light_v = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_LIGHT_V);
- if(direct_emission(kg, &sd, i, 0.0f, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp)) {
+ if(direct_emission(kg, &sd, i, 0.0f, 0.0f, light_u, light_v, &light_ray, &L_light, &lamp)) {
/* trace shadow ray */
float3 shadow;
if(!shadow_blocked(kg, &state, &light_ray, &shadow)) {
/* accumulate */
+ bool is_lamp = (lamp != ~0);
path_radiance_accum_light(&L, throughput*num_samples_inv, &L_light, shadow, state.bounce, is_lamp);
}
}
@@ -807,12 +867,13 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
if(kernel_data.integrator.num_all_lights)
light_t = 0.5f*light_t;
- if(direct_emission(kg, &sd, -1, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp)) {
+ if(direct_emission(kg, &sd, -1, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &lamp)) {
/* trace shadow ray */
float3 shadow;
if(!shadow_blocked(kg, &state, &light_ray, &shadow)) {
/* accumulate */
+ bool is_lamp = (lamp != ~0);
path_radiance_accum_light(&L, throughput*num_samples_inv, &L_light, shadow, state.bounce, is_lamp);
}
}
@@ -885,8 +946,9 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
bsdf_ray.time = sd.time;
#endif
- kernel_path_indirect(kg, rng, sample*num_samples, bsdf_ray, buffer,
- tp*num_samples_inv, min_ray_pdf, bsdf_pdf, ps, rng_offset+PRNG_BOUNCE_NUM, &L);
+ kernel_path_indirect(kg, rng, sample*num_samples + j, bsdf_ray, buffer,
+ tp*num_samples_inv, num_samples,
+ min_ray_pdf, bsdf_pdf, ps, rng_offset+PRNG_BOUNCE_NUM, &L);
}
}
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 2bd6b5859f3..102be440978 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -48,6 +48,7 @@ CCL_NAMESPACE_BEGIN
#endif
#define __NON_PROGRESSIVE__
#define __HAIR__
+#define __LAMP_MIS__
#endif
#ifdef __KERNEL_CUDA__
@@ -384,7 +385,7 @@ typedef enum AttributeStandard {
/* Closure data */
-#define MAX_CLOSURE 8
+#define MAX_CLOSURE 16
typedef struct ShaderClosure {
ClosureType type;
@@ -636,6 +637,7 @@ typedef struct KernelIntegrator {
int num_all_lights;
float pdf_triangles;
float pdf_lights;
+ float inv_pdf_lights;
int pdf_background_res;
/* bounces */
@@ -671,7 +673,7 @@ typedef struct KernelIntegrator {
int transmission_samples;
int ao_samples;
int mesh_light_samples;
- int pad1, pad2;
+ int pad1;
} KernelIntegrator;
typedef struct KernelBVH {
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index 28742d56e3b..92a023bd765 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -605,7 +605,11 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD
return set_attribute_int(3, type, derivatives, val);
}
else if ((name == u_geom_trianglevertices || name == u_geom_polyvertices)
+#ifdef __HAIR__
&& sd->segment == ~0) {
+#else
+ ) {
+#endif
float3 P[3];
triangle_vertices(kg, sd->prim, P);
@@ -675,7 +679,11 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
else {
object = sd->object;
prim = sd->prim;
+#ifdef __HAIR__
segment = sd->segment;
+#else
+ segment = ~0;
+#endif
if (object == ~0)
return get_background_attribute(kg, sd, name, type, derivatives, val);
diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp
index 59e307bb408..a32c526a2be 100644
--- a/intern/cycles/kernel/osl/osl_shader.cpp
+++ b/intern/cycles/kernel/osl/osl_shader.cpp
@@ -457,7 +457,11 @@ float3 OSLShader::volume_eval_phase(const ShaderClosure *sc, const float3 omega_
int OSLShader::find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, AttributeElement *elem)
{
/* for OSL, a hash map is used to lookup the attribute by name. */
- int object = sd->object*ATTR_PRIM_TYPES + (sd->segment != ~0);
+ int object = sd->object*ATTR_PRIM_TYPES;
+#ifdef __HAIR__
+ if(sd->segment != ~0) object += ATTR_PRIM_CURVE;
+#endif
+
OSLGlobals::AttributeMap &attr_map = kg->osl->attribute_map[object];
ustring stdname(std::string("geom:") + std::string(Attribute::standard_name((AttributeStandard)id)));
OSLGlobals::AttributeMap::const_iterator it = attr_map.find(stdname);
diff --git a/intern/cycles/kernel/shaders/node_musgrave_texture.osl b/intern/cycles/kernel/shaders/node_musgrave_texture.osl
index 541f26b4e56..38232ea0aeb 100644
--- a/intern/cycles/kernel/shaders/node_musgrave_texture.osl
+++ b/intern/cycles/kernel/shaders/node_musgrave_texture.osl
@@ -37,14 +37,14 @@ float noise_musgrave_fBm(point p, string basis, float H, float lacunarity, float
int i;
for (i = 0; i < (int)octaves; i++) {
- value += noise("perlin", p) * pwr;
+ value += safe_noise(p) * pwr;
pwr *= pwHL;
p *= lacunarity;
}
rmd = octaves - floor(octaves);
if (rmd != 0.0)
- value += rmd * noise("perlin", p) * pwr;
+ value += rmd * safe_noise(p) * pwr;
return value;
}
@@ -65,14 +65,14 @@ float noise_musgrave_multi_fractal(point p, string basis, float H, float lacunar
int i;
for (i = 0; i < (int)octaves; i++) {
- value *= (pwr * noise("perlin", p) + 1.0);
+ value *= (pwr * safe_noise(p) + 1.0);
pwr *= pwHL;
p *= lacunarity;
}
rmd = octaves - floor(octaves);
if (rmd != 0.0)
- value *= (rmd * pwr * noise("perlin", p) + 1.0); /* correct? */
+ value *= (rmd * pwr * safe_noise(p) + 1.0); /* correct? */
return value;
}
@@ -93,11 +93,11 @@ float noise_musgrave_hetero_terrain(point p, string basis, float H, float lacuna
int i;
/* first unscaled octave of function; later octaves are scaled */
- value = offset + noise("perlin", p);
+ value = offset + safe_noise(p);
p *= lacunarity;
for (i = 1; i < (int)octaves; i++) {
- increment = (noise("perlin", p) + offset) * pwr * value;
+ increment = (safe_noise(p) + offset) * pwr * value;
value += increment;
pwr *= pwHL;
p *= lacunarity;
@@ -105,7 +105,7 @@ float noise_musgrave_hetero_terrain(point p, string basis, float H, float lacuna
rmd = octaves - floor(octaves);
if (rmd != 0.0) {
- increment = (noise("perlin", p) + offset) * pwr * value;
+ increment = (safe_noise(p) + offset) * pwr * value;
value += rmd * increment;
}
@@ -128,7 +128,7 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H,
float pwr = pwHL;
int i;
- result = noise("perlin", p) + offset;
+ result = safe_noise(p) + offset;
weight = gain * result;
p *= lacunarity;
@@ -136,7 +136,7 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H,
if (weight > 1.0)
weight = 1.0;
- signal = (noise("perlin", p) + offset) * pwr;
+ signal = (safe_noise(p) + offset) * pwr;
pwr *= pwHL;
result += weight * signal;
weight *= gain * signal;
@@ -145,7 +145,7 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H,
rmd = octaves - floor(octaves);
if (rmd != 0.0)
- result += rmd * ((noise("perlin", p) + offset) * pwr);
+ result += rmd * ((safe_noise(p) + offset) * pwr);
return result;
}
@@ -166,7 +166,7 @@ float noise_musgrave_ridged_multi_fractal(point p, string basis, float H,
float pwr = pwHL;
int i;
- signal = offset - fabs(noise("perlin", p));
+ signal = offset - fabs(safe_noise(p));
signal *= signal;
result = signal;
weight = 1.0;
@@ -174,7 +174,7 @@ float noise_musgrave_ridged_multi_fractal(point p, string basis, float H,
for (i = 1; i < (int)octaves; i++) {
p *= lacunarity;
weight = clamp(signal * gain, 0.0, 1.0);
- signal = offset - fabs(noise("perlin", p));
+ signal = offset - fabs(safe_noise(p));
signal *= signal;
signal *= weight;
result += signal * pwr;
diff --git a/intern/cycles/kernel/shaders/node_texture.h b/intern/cycles/kernel/shaders/node_texture.h
index 1b3ba8207ab..2de0fc0ea57 100644
--- a/intern/cycles/kernel/shaders/node_texture.h
+++ b/intern/cycles/kernel/shaders/node_texture.h
@@ -151,12 +151,23 @@ float voronoi_CrS(point p) { return 2.0 * voronoi_Cr(p) - 1.0; }
/* Noise Bases */
+float safe_noise(point p)
+{
+ float f = noise(p);
+
+ /* can happen for big coordinates, things even out to 0.5 then anyway */
+ if(!isfinite(f))
+ return 0.5;
+
+ return f;
+}
+
float noise_basis(point p, string basis)
{
float result = 0.0;
if (basis == "Perlin")
- result = noise(p); /* returns perlin noise in range 0..1 */
+ result = safe_noise(p); /* returns perlin noise in range 0..1 */
if (basis == "Voronoi F1")
result = voronoi_F1S(p);
if (basis == "Voronoi F2")
diff --git a/intern/cycles/kernel/svm/svm_noise.h b/intern/cycles/kernel/svm/svm_noise.h
index 224a1d96543..5ead6486dd6 100644
--- a/intern/cycles/kernel/svm/svm_noise.h
+++ b/intern/cycles/kernel/svm/svm_noise.h
@@ -84,9 +84,8 @@ __device uint phash(int kx, int ky, int kz, int3 p)
__device float floorfrac(float x, int* i)
{
- float f = floorf(x);
- *i = (int)f;
- return x - f;
+ *i = quick_floor(x);
+ return x - *i;
}
__device float fade(float t)
@@ -133,7 +132,10 @@ __device_noinline float perlin(float x, float y, float z)
grad (hash (X+1, Y , Z+1), fx-1.0f, fy , fz-1.0f )),
nerp (u, grad (hash (X , Y+1, Z+1), fx , fy-1.0f, fz-1.0f ),
grad (hash (X+1, Y+1, Z+1), fx-1.0f, fy-1.0f, fz-1.0f ))));
- return scale3(result);
+ float r = scale3(result);
+
+ /* can happen for big coordinates, things even out to 0.0 then anyway */
+ return (isfinite(r))? r: 0.0f;
}
__device_noinline float perlin_periodic(float x, float y, float z, float3 pperiod)
@@ -162,7 +164,10 @@ __device_noinline float perlin_periodic(float x, float y, float z, float3 pperio
grad (phash (X+1, Y , Z+1, p), fx-1.0f, fy , fz-1.0f )),
nerp (u, grad (phash (X , Y+1, Z+1, p), fx , fy-1.0f, fz-1.0f ),
grad (phash (X+1, Y+1, Z+1, p), fx-1.0f, fy-1.0f, fz-1.0f ))));
- return scale3(result);
+ float r = scale3(result);
+
+ /* can happen for big coordinates, things even out to 0.0 then anyway */
+ return (isfinite(r))? r: 0.0f;
}
/* perlin noise in range 0..1 */
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index c8e3e94ec98..1b94d603a26 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -323,6 +323,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
/* precompute pdfs */
kintegrator->pdf_triangles = 0.0f;
kintegrator->pdf_lights = 0.0f;
+ kintegrator->inv_pdf_lights = 0.0f;
/* sample one, with 0.5 probability of light or triangle */
kintegrator->num_all_lights = num_lights;
@@ -337,6 +338,8 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
kintegrator->pdf_lights = 1.0f/num_lights;
if(trianglearea > 0.0f)
kintegrator->pdf_lights *= 0.5f;
+
+ kintegrator->inv_pdf_lights = 1.0f/kintegrator->pdf_lights;
}
/* CDF */
@@ -349,6 +352,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
kintegrator->num_all_lights = 0;
kintegrator->pdf_triangles = 0.0f;
kintegrator->pdf_lights = 0.0f;
+ kintegrator->inv_pdf_lights = 0.0f;
}
}
@@ -475,16 +479,25 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
if(light->type == LIGHT_POINT) {
shader_id &= ~SHADER_AREA_LIGHT;
+ float radius = light->size;
+ float invarea = (radius > 0.0f)? 1.0f/(M_PI_F*radius*radius): 1.0f;
+
light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
- light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, 0.0f, 0.0f);
+ light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), radius, invarea, 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(samples, 0.0f, 0.0f, 0.0f);
}
else if(light->type == LIGHT_DISTANT) {
shader_id &= ~SHADER_AREA_LIGHT;
+ float radius = light->size;
+ float angle = atanf(radius);
+ float cosangle = cosf(angle);
+ float area = M_PI_F*radius*radius;
+ float invarea = (area > 0.0f)? 1.0f/area: 1.0f;
+
light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), dir.x, dir.y, dir.z);
- light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, 0.0f, 0.0f);
+ light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), radius, cosangle, invarea);
light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
}
@@ -499,21 +512,25 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
else if(light->type == LIGHT_AREA) {
float3 axisu = light->axisu*(light->sizeu*light->size);
float3 axisv = light->axisv*(light->sizev*light->size);
+ float area = len(axisu)*len(axisv);
+ float invarea = (area > 0.0f)? 1.0f/area: 0.0f;
light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), axisu.x, axisu.y, axisu.z);
- light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, axisv.x, axisv.y, axisv.z);
+ light_data[i*LIGHT_SIZE + 2] = make_float4(invarea, axisv.x, axisv.y, axisv.z);
light_data[i*LIGHT_SIZE + 3] = make_float4(samples, dir.x, dir.y, dir.z);
}
else if(light->type == LIGHT_SPOT) {
shader_id &= ~SHADER_AREA_LIGHT;
+ float radius = light->size;
+ float invarea = (radius > 0.0f)? 1.0f/(M_PI_F*radius*radius): 1.0f;
float spot_angle = cosf(light->spot_angle*0.5f);
float spot_smooth = (1.0f - spot_angle)*light->spot_smooth;
light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
- light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, dir.x, dir.y);
- light_data[i*LIGHT_SIZE + 2] = make_float4(dir.z, spot_angle, spot_smooth, 0.0f);
+ light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), radius, invarea, spot_angle);
+ light_data[i*LIGHT_SIZE + 2] = make_float4(spot_smooth, dir.x, dir.y, dir.z);
light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
}
}
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index 36948adce17..e49a4a3ed34 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -41,7 +41,7 @@ CCL_NAMESPACE_BEGIN
Session::Session(const SessionParams& params_)
: params(params_),
tile_manager(params.progressive, params.samples, params.tile_size, params.start_resolution,
- params.background == false || params.progressive_refine, params.background,
+ params.background == false || params.progressive_refine, params.background, params.tile_order,
max(params.device.multi_devices.size(), 1)),
stats()
{
diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h
index cfc1502287d..27073d2fd9c 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -51,6 +51,7 @@ public:
bool experimental;
int samples;
int2 tile_size;
+ int tile_order;
int start_resolution;
int threads;
diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp
index bbcdb47260e..d62ecd8a88c 100644
--- a/intern/cycles/render/tile.cpp
+++ b/intern/cycles/render/tile.cpp
@@ -24,10 +24,11 @@
CCL_NAMESPACE_BEGIN
TileManager::TileManager(bool progressive_, int num_samples_, int2 tile_size_, int start_resolution_,
- bool preserve_tile_device_, bool background_, int num_devices_)
+ bool preserve_tile_device_, bool background_, int tile_order_, int num_devices_)
{
progressive = progressive_;
tile_size = tile_size_;
+ tile_order = tile_order_;
start_resolution = start_resolution_;
num_devices = num_devices_;
preserve_tile_device = preserve_tile_device_;
@@ -165,6 +166,20 @@ void TileManager::set_tiles()
state.buffer.full_height = max(1, params.full_height/resolution);
}
+list<Tile>::iterator TileManager::next_viewport_tile(int device)
+{
+ list<Tile>::iterator iter;
+
+ int logical_device = preserve_tile_device? device: 0;
+
+ for(iter = state.tiles.begin(); iter != state.tiles.end(); iter++) {
+ if(iter->device == logical_device && iter->rendering == false)
+ return iter;
+ }
+
+ return state.tiles.end();
+}
+
list<Tile>::iterator TileManager::next_center_tile(int device)
{
list<Tile>::iterator iter, best = state.tiles.end();
@@ -210,28 +225,53 @@ list<Tile>::iterator TileManager::next_center_tile(int device)
return best;
}
-list<Tile>::iterator TileManager::next_simple_tile(int device)
+list<Tile>::iterator TileManager::next_simple_tile(int device, int tile_order)
{
- list<Tile>::iterator iter;
+ list<Tile>::iterator iter, best = state.tiles.end();
+ int resolution = state.resolution_divider;
int logical_device = preserve_tile_device? device: 0;
+ int64_t cordx = max(1, params.width/resolution);
+ int64_t cordy = max(1, params.height/resolution);
+ int64_t mindist = cordx * cordy;
+
for(iter = state.tiles.begin(); iter != state.tiles.end(); iter++) {
- if(iter->device == logical_device && iter->rendering == false)
- return iter;
+ if(iter->device == logical_device && iter->rendering == false) {
+ Tile &cur_tile = *iter;
+
+ int64_t distx = cordx;
+
+ if (tile_order == TileManager::RIGHT_TO_LEFT)
+ distx = cordx - cur_tile.x;
+ else if (tile_order == TileManager::LEFT_TO_RIGHT)
+ distx = cordx + cur_tile.x;
+ else if (tile_order == TileManager::TOP_TO_BOTTOM)
+ distx = cordx - cur_tile.y;
+ else /* TileManager::BOTTOM_TO_TOP */
+ distx = cordx + cur_tile.y;
+
+ if(distx < mindist) {
+ best = iter;
+ mindist = distx;
+ }
+ }
}
- return state.tiles.end();
+ return best;
}
bool TileManager::next_tile(Tile& tile, int device)
{
list<Tile>::iterator tile_it;
-
- if(background)
- tile_it = next_center_tile(device);
+ if (background) {
+ if(tile_order == TileManager::CENTER)
+ tile_it = next_center_tile(device);
+ else
+ tile_it = next_simple_tile(device, tile_order);
+ }
else
- tile_it = next_simple_tile(device);
+ tile_it = next_viewport_tile(device);
if(tile_it != state.tiles.end()) {
tile_it->rendering = true;
diff --git a/intern/cycles/render/tile.h b/intern/cycles/render/tile.h
index 6f7a8f20734..99cffb49c08 100644
--- a/intern/cycles/render/tile.h
+++ b/intern/cycles/render/tile.h
@@ -59,7 +59,7 @@ public:
} state;
TileManager(bool progressive, int num_samples, int2 tile_size, int start_resolution,
- bool preserve_tile_device, bool background, int num_devices = 1);
+ bool preserve_tile_device, bool background, int tile_order, int num_devices = 1);
~TileManager();
void reset(BufferParams& params, int num_samples);
@@ -68,12 +68,23 @@ public:
bool next_tile(Tile& tile, int device = 0);
bool done();
+ void set_tile_order(int tile_order_) { tile_order = tile_order_; }
protected:
+ /* Note: this should match enum_tile_order in properties.py */
+ enum {
+ CENTER = 0,
+ RIGHT_TO_LEFT = 1,
+ LEFT_TO_RIGHT = 2,
+ TOP_TO_BOTTOM = 3,
+ BOTTOM_TO_TOP = 4
+ } TileOrder;
+
void set_tiles();
bool progressive;
int num_samples;
int2 tile_size;
+ int tile_order;
int start_resolution;
int num_devices;
@@ -106,9 +117,12 @@ protected:
* mimics behavior of blender internal's tile order
*/
list<Tile>::iterator next_center_tile(int device);
+
+ /* returns simple tile order */
+ list<Tile>::iterator next_simple_tile(int device, int tile_order);
- /* returns first unhandled tile starting from left bottom corner of the image */
- list<Tile>::iterator next_simple_tile(int device);
+ /* returns first unhandled tile (for viewport) */
+ list<Tile>::iterator next_viewport_tile(int device);
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h
index 8932c85db07..c37fa1a4dc6 100644
--- a/intern/cycles/util/util_math.h
+++ b/intern/cycles/util/util_math.h
@@ -1161,6 +1161,130 @@ __device float safe_divide(float a, float b)
return result;
}
+/* Ray Intersection */
+
+__device bool ray_sphere_intersect(
+ float3 ray_P, float3 ray_D, float ray_t,
+ float3 sphere_P, float sphere_radius,
+ float3 *isect_P, float *isect_t)
+{
+ float3 d = sphere_P - ray_P;
+ float radiussq = sphere_radius*sphere_radius;
+ float tsq = dot(d, d);
+
+ if(tsq > radiussq) { /* ray origin outside sphere */
+ float tp = dot(d, ray_D);
+
+ if(tp < 0.0f) /* dir points away from sphere */
+ return false;
+
+ float dsq = tsq - tp*tp; /* pythagoras */
+
+ if(dsq > radiussq) /* closest point on ray outside sphere */
+ return false;
+
+ float t = tp - sqrtf(radiussq - dsq); /* pythagoras */
+
+ if(t < ray_t) {
+ *isect_t = t;
+ *isect_P = ray_P + ray_D*t;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+__device bool ray_aligned_disk_intersect(
+ float3 ray_P, float3 ray_D, float ray_t,
+ float3 disk_P, float disk_radius,
+ float3 *isect_P, float *isect_t)
+{
+ /* aligned disk normal */
+ float disk_t;
+ float3 disk_N = normalize_len(ray_P - disk_P, &disk_t);
+ float div = dot(ray_D, disk_N);
+
+ if(div == 0.0f)
+ return false;
+
+ /* compute t to intersection point */
+ float t = -disk_t/div;
+ if(t < 0.0f || t > ray_t)
+ return false;
+
+ /* test if within radius */
+ float3 P = ray_P + ray_D*t;
+ if(len_squared(P - disk_P) > disk_radius*disk_radius)
+ return false;
+
+ *isect_P = P;
+ *isect_t = t;
+
+ return true;
+}
+
+__device bool ray_triangle_intersect(
+ float3 ray_P, float3 ray_D, float ray_t,
+ float3 v0, float3 v1, float3 v2,
+ float3 *isect_P, float *isect_t)
+{
+ /* Calculate intersection */
+ float3 e1 = v1 - v0;
+ float3 e2 = v2 - v0;
+ float3 s1 = cross(ray_D, e2);
+
+ const float divisor = dot(s1, e1);
+ if(divisor == 0.0f)
+ return false;
+
+ const float invdivisor = 1.0f/divisor;
+
+ /* compute first barycentric coordinate */
+ const float3 d = ray_P - v0;
+ const float u = dot(d, s1)*invdivisor;
+ if(u < 0.0f)
+ return false;
+
+ /* Compute second barycentric coordinate */
+ const float3 s2 = cross(d, e1);
+ const float v = dot(ray_D, s2)*invdivisor;
+ if(v < 0.0f)
+ return false;
+
+ const float b0 = 1.0f - u - v;
+ if(b0 < 0.0f)
+ return false;
+
+ /* compute t to intersection point */
+ const float t = dot(e2, s2)*invdivisor;
+ if(t < 0.0f || t > ray_t)
+ return false;
+
+ *isect_t = t;
+ *isect_P = ray_P + ray_D*t;
+
+ return true;
+}
+
+__device bool ray_quad_intersect(
+ float3 ray_P, float3 ray_D, float ray_t,
+ float3 quad_P, float3 quad_u, float3 quad_v,
+ float3 *isect_P, float *isect_t)
+{
+ float3 v0 = quad_P - quad_u*0.5f - quad_v*0.5f;
+ float3 v1 = quad_P + quad_u*0.5f - quad_v*0.5f;
+ float3 v2 = quad_P + quad_u*0.5f + quad_v*0.5f;
+ float3 v3 = quad_P - quad_u*0.5f + quad_v*0.5f;
+
+ if(ray_triangle_intersect(ray_P, ray_D, ray_t, v0, v1, v2, isect_P, isect_t))
+ return true;
+ else if(ray_triangle_intersect(ray_P, ray_D, ray_t, v0, v2, v3, isect_P, isect_t))
+ return true;
+
+ return false;
+}
+
CCL_NAMESPACE_END
#endif /* __UTIL_MATH_H__ */
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm
index 2d9d89d9ad0..ac3e22368bc 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.mm
+++ b/intern/ghost/intern/GHOST_SystemCocoa.mm
@@ -574,13 +574,7 @@ GHOST_SystemCocoa::GHOST_SystemCocoa()
rstring = (char*)malloc( len );
sysctl( mib, 2, rstring, &len, NULL, 0 );
- //Hack on MacBook revision, as multitouch avail. function missing
- //MacbookAir or MacBook version >= 5 (retina is MacBookPro10,1)
- if (strstr(rstring,"MacBookAir") ||
- (strstr(rstring,"MacBook") && (rstring[strlen(rstring)-3]>='5') && (rstring[strlen(rstring)-3]<='9')) ||
- (strstr(rstring,"MacBook") && (rstring[strlen(rstring)-4]>='1') && (rstring[strlen(rstring)-4]<='9')))
- m_hasMultiTouchTrackpad = true;
- else m_hasMultiTouchTrackpad = false;
+ m_hasMultiTouchTrackpad = false;
free( rstring );
rstring = NULL;
@@ -1445,6 +1439,27 @@ bool GHOST_SystemCocoa::handleTabletEvent(void *eventPtr)
}
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
+enum {
+ NSEventPhaseNone = 0,
+ NSEventPhaseBegan = 0x1 << 0,
+ NSEventPhaseStationary = 0x1 << 1,
+ NSEventPhaseChanged = 0x1 << 2,
+ NSEventPhaseEnded = 0x1 << 3,
+ NSEventPhaseCancelled = 0x1 << 4,
+};
+typedef NSUInteger NSEventPhase;
+
+@interface NSEvent (AvailableOn1070AndLater)
+- (BOOL)hasPreciseScrollingDeltas;
+- (CGFloat)scrollingDeltaX;
+- (CGFloat)scrollingDeltaY;
+- (NSEventPhase)momentumPhase;
+- (BOOL)isDirectionInvertedFromDevice;
+- (NSEventPhase)phase;
+@end
+#endif
+
GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
{
NSEvent *event = (NSEvent *)eventPtr;
@@ -1577,15 +1592,23 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
}
break;
+ /* these events only happen on swiping trackpads */
+ case NSEventTypeBeginGesture:
+ m_hasMultiTouchTrackpad = 1;
+ break;
+ case NSEventTypeEndGesture:
+ m_hasMultiTouchTrackpad = 0;
+ break;
+
case NSScrollWheel:
{
- int momentum = 0;
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
- m_hasMultiTouchTrackpad = 0;
- momentum = [event momentumPhase] || [event phase];
-#endif
- /* standard scrollwheel case */
- if (!m_hasMultiTouchTrackpad && momentum == 0) {
+ int *momentum = NULL;
+
+ if ([event respondsToSelector:@selector(momentumPhase)])
+ momentum = (int *)[event momentumPhase];
+
+ /* standard scrollwheel case, if no swiping happened, and no momentum (kinetic scroll) works */
+ if (!m_hasMultiTouchTrackpad && momentum == NULL) {
GHOST_TInt32 delta;
double deltaF = [event deltaY];
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 9f62ed76735..75d606a5d79 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -761,6 +761,7 @@ GHOST_Event *GHOST_SystemWin32::processWindowEvent(GHOST_TEventType type, GHOST_
if (type == GHOST_kEventWindowActivate) {
system->getWindowManager()->setActiveWindow(window);
+ ((GHOST_WindowWin32*)window)->bringTabletContextToFront();
}
return new GHOST_Event(system->getMilliSeconds(), type, window);
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index 2d3cc4f88dc..f5cb0d9323c 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -132,7 +132,7 @@ GHOST_SystemX11(
GHOST_ASSERT(false, "Could not instantiate timer!");
}
- /* Taking care not to overflow the tv.tv_sec*1000 */
+ /* Taking care not to overflow the tv.tv_sec * 1000 */
m_start_time = GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000;
@@ -190,7 +190,7 @@ getMilliSeconds() const
GHOST_ASSERT(false, "Could not compute time!");
}
- /* Taking care not to overflow the tv.tv_sec*1000 */
+ /* Taking care not to overflow the tv.tv_sec * 1000 */
return GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000 - m_start_time;
}
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm
index 2d58f0612ce..e89dd1b41dc 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.mm
+++ b/intern/ghost/intern/GHOST_WindowCocoa.mm
@@ -428,6 +428,14 @@ extern "C" {
#pragma mark initialization / finalization
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
+@interface NSView (NSOpenGLSurfaceResolution)
+- (BOOL)wantsBestResolutionOpenGLSurface;
+- (void)setWantsBestResolutionOpenGLSurface:(BOOL)flag;
+- (NSRect)convertRectToBacking:(NSRect)bounds;
+@end
+#endif
+
NSOpenGLContext* GHOST_WindowCocoa::s_firstOpenGLcontext = nil;
GHOST_WindowCocoa::GHOST_WindowCocoa(
@@ -579,13 +587,15 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
setDrawingContextType(type);
updateDrawingContext();
activateDrawingContext();
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 // retina support started with 10.7.4 afaik
+
if (m_systemCocoa->m_nativePixel) {
- [m_openGLView setWantsBestResolutionOpenGLSurface:YES];
- NSRect backingBounds = [m_openGLView convertRectToBacking:[m_openGLView bounds]];
- m_systemCocoa->m_nativePixelSize = (float)backingBounds.size.width / (float)rect.size.width;
+ if ([m_openGLView respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) {
+ [m_openGLView setWantsBestResolutionOpenGLSurface:YES];
+
+ NSRect backingBounds = [m_openGLView convertRectToBacking:[m_openGLView bounds]];
+ m_systemCocoa->m_nativePixelSize = (float)backingBounds.size.width / (float)rect.size.width;
+ }
}
-#endif
m_tablet.Active = GHOST_kTabletModeNone;
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index fead1884f8a..bf429527199 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -1192,6 +1192,16 @@ void GHOST_WindowWin32::processWin32TabletEvent(WPARAM wParam, LPARAM lParam)
}
}
+void GHOST_WindowWin32::bringTabletContextToFront()
+{
+ if (m_wintab) {
+ GHOST_WIN32_WTOverlap fpWTOverlap = (GHOST_WIN32_WTOverlap) ::GetProcAddress(m_wintab, "WTOverlap");
+ if (fpWTOverlap) {
+ fpWTOverlap(m_tablet, TRUE);
+ }
+ }
+}
+
/** Reverse the bits in a GHOST_TUns8 */
static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch)
{
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
index 9e4377b8225..7f50d58ce35 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -58,6 +58,7 @@ typedef UINT (API * GHOST_WIN32_WTInfo)(UINT, UINT, LPVOID);
typedef HCTX (API * GHOST_WIN32_WTOpen)(HWND, LPLOGCONTEXTA, BOOL);
typedef BOOL (API * GHOST_WIN32_WTClose)(HCTX);
typedef BOOL (API * GHOST_WIN32_WTPacket)(HCTX, UINT, LPVOID);
+typedef BOOL (API * GHOST_WIN32_WTOverlap)(HCTX, BOOL);
/**
* GHOST window on M$ Windows OSs.
@@ -273,6 +274,7 @@ public:
void processWin32TabletInitEvent();
void processWin32TabletEvent(WPARAM wParam, LPARAM lParam);
+ void bringTabletContextToFront();
protected:
GHOST_TSuccess initMultisample(PIXELFORMATDESCRIPTOR pfd);
diff --git a/intern/opencolorio/fallback_impl.cc b/intern/opencolorio/fallback_impl.cc
index 44c02d1442b..d01d8d4c8f4 100644
--- a/intern/opencolorio/fallback_impl.cc
+++ b/intern/opencolorio/fallback_impl.cc
@@ -331,7 +331,7 @@ void FallbackImpl::displayTransformRelease(OCIO_DisplayTransformRcPtr *)
}
OCIO_PackedImageDesc *FallbackImpl::createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels,
- long chanStrideBytes, long xStrideBytes, long yStrideBytes)
+ long chanStrideBytes, long xStrideBytes, long yStrideBytes)
{
OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription*)MEM_callocN(sizeof(OCIO_PackedImageDescription), "OCIO_PackedImageDescription");
diff --git a/intern/opencolorio/ocio_capi.cc b/intern/opencolorio/ocio_capi.cc
index 18fa4b7cb1b..4f839a61fad 100644
--- a/intern/opencolorio/ocio_capi.cc
+++ b/intern/opencolorio/ocio_capi.cc
@@ -238,12 +238,12 @@ void OCIO_displayTransformRelease(OCIO_DisplayTransformRcPtr *dt)
}
OCIO_PackedImageDesc *OCIO_createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels,
- long chanStrideBytes, long xStrideBytes, long yStrideBytes)
+ long chanStrideBytes, long xStrideBytes, long yStrideBytes)
{
return impl->createOCIO_PackedImageDesc(data, width, height, numChannels, chanStrideBytes, xStrideBytes, yStrideBytes);
}
-void OCIO_OCIO_PackedImageDescRelease(OCIO_PackedImageDesc* id)
+void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc* id)
{
impl->OCIO_PackedImageDescRelease(id);
}
diff --git a/intern/opencolorio/ocio_capi.h b/intern/opencolorio/ocio_capi.h
index 0ce5f8a1456..19fd8fe643b 100644
--- a/intern/opencolorio/ocio_capi.h
+++ b/intern/opencolorio/ocio_capi.h
@@ -105,9 +105,9 @@ void OCIO_displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_Const
void OCIO_displayTransformRelease(OCIO_DisplayTransformRcPtr *dt);
OCIO_PackedImageDesc *OCIO_createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels,
- long chanStrideBytes, long xStrideBytes, long yStrideBytes);
+ long chanStrideBytes, long xStrideBytes, long yStrideBytes);
-void OCIO_OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p);
+void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p);
OCIO_ExponentTransformRcPtr *OCIO_createExponentTransform(void);
void OCIO_exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent);
diff --git a/intern/opencolorio/ocio_impl.cc b/intern/opencolorio/ocio_impl.cc
index 2d73d2ff56b..b073a038f0d 100644
--- a/intern/opencolorio/ocio_impl.cc
+++ b/intern/opencolorio/ocio_impl.cc
@@ -479,7 +479,7 @@ void OCIOImpl::displayTransformRelease(OCIO_DisplayTransformRcPtr *dt)
}
OCIO_PackedImageDesc *OCIOImpl::createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels,
- long chanStrideBytes, long xStrideBytes, long yStrideBytes)
+ long chanStrideBytes, long xStrideBytes, long yStrideBytes)
{
try {
void *mem = MEM_mallocN(sizeof(PackedImageDesc), __func__);
diff --git a/release/datafiles/startup.blend b/release/datafiles/startup.blend
index c66002de805..dc684178f40 100644
--- a/release/datafiles/startup.blend
+++ b/release/datafiles/startup.blend
Binary files differ
diff --git a/release/scripts/startup/bl_operators/uvcalc_follow_active.py b/release/scripts/startup/bl_operators/uvcalc_follow_active.py
index d870ef963ea..7b6013f3044 100644
--- a/release/scripts/startup/bl_operators/uvcalc_follow_active.py
+++ b/release/scripts/startup/bl_operators/uvcalc_follow_active.py
@@ -49,8 +49,13 @@ def extend(obj, operator, EXTEND_MODE):
# our own local walker
def walk_face_init(faces, f_act):
+ # first tag all faces True (so we dont uvmap them)
+ for f in bm.faces:
+ f.tag = True
+ # then tag faces arg False
for f in faces:
f.tag = False
+ # tag the active face True since we begin there
f_act.tag = True
def walk_face(f):
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index c24e0920213..00cc763c4e1 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -44,7 +44,7 @@ class MESH_OT_delete_edgeloop(Operator):
mesh = context.object.data
use_mirror_x = mesh.use_mirror_x
mesh.use_mirror_x = False
- if 'FINISHED' in bpy.ops.transform.edge_slide(value=1.0):
+ if 'FINISHED' in bpy.ops.transform.edge_slide(value=1.0, correct_uv=True):
bpy.ops.mesh.select_more()
bpy.ops.mesh.remove_doubles()
ret = {'FINISHED'}
diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py
index 538063cb038..5fdb71b855f 100644
--- a/release/scripts/startup/bl_ui/properties_data_mesh.py
+++ b/release/scripts/startup/bl_ui/properties_data_mesh.py
@@ -330,7 +330,7 @@ class DATA_PT_uv_texture(MeshButtonsPanel, Panel):
row = layout.row()
col = row.column()
- col.template_list("MESH_UL_uvmaps_vcols", "", me, "uv_textures", me.uv_textures, "active_index", rows=2)
+ col.template_list("MESH_UL_uvmaps_vcols", "uvmaps", me, "uv_textures", me.uv_textures, "active_index", rows=2)
col = row.column(align=True)
col.operator("mesh.uv_texture_add", icon='ZOOMIN', text="")
@@ -353,7 +353,7 @@ class DATA_PT_vertex_colors(MeshButtonsPanel, Panel):
row = layout.row()
col = row.column()
- col.template_list("MESH_UL_uvmaps_vcols", "", me, "vertex_colors", me.vertex_colors, "active_index", rows=2)
+ col.template_list("MESH_UL_uvmaps_vcols", "vcols", me, "vertex_colors", me.vertex_colors, "active_index", rows=2)
col = row.column(align=True)
col.operator("mesh.vertex_color_add", icon='ZOOMIN', text="")
@@ -372,17 +372,20 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
- # me = context.mesh
+ obj = context.object
+ me = context.mesh
col = layout.column()
- # sticky has no UI access since 2.49 - we may remove
- '''
- row = col.row(align=True)
- row.operator("mesh.customdata_create_sticky")
- row.operator("mesh.customdata_clear_sticky", icon='X')
- '''
+
col.operator("mesh.customdata_clear_mask", icon='X')
col.operator("mesh.customdata_clear_skin", icon='X')
+ col = layout.column()
+
+ col.enabled = (obj.mode != 'EDIT')
+ col.prop(me, "use_customdata_vertex_bevel")
+ col.prop(me, "use_customdata_edge_bevel")
+ col.prop(me, "use_customdata_edge_crease")
+
class DATA_PT_custom_props_mesh(MeshButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py
index 8a668b5d95b..951807488e7 100644
--- a/release/scripts/startup/bl_ui/properties_object.py
+++ b/release/scripts/startup/bl_ui/properties_object.py
@@ -289,6 +289,9 @@ class OBJECT_PT_relations_extras(ObjectButtonsPanel, Panel):
row.active = ((ob.parent is not None) and (ob.use_slow_parent))
row.prop(ob, "slow_parent_offset", text="Offset")
+ layout.prop(ob, "extra_recalc_object")
+ layout.prop(ob, "extra_recalc_data")
+
from bl_ui.properties_animviz import (MotionPathButtonsPanel,
OnionSkinButtonsPanel)
diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py
index eddb542ccc3..6842b324b0e 100644
--- a/release/scripts/startup/bl_ui/properties_texture.py
+++ b/release/scripts/startup/bl_ui/properties_texture.py
@@ -64,7 +64,7 @@ class TEXTURE_UL_texslots(UIList):
tex = slot.texture if slot else None
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.label(tex.name if tex else "", icon_value=icon)
- if tex:
+ if tex and isinstance(item, bpy.types.MaterialTextureSlot):
layout.prop(ma, "use_textures", text="", index=index)
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 58c433d3772..a9712b1557e 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -200,7 +200,7 @@ class USERPREF_PT_interface(Panel):
col.prop(view, "show_playback_fps", text="Playback FPS")
col.prop(view, "use_global_scene")
col.prop(view, "object_origin_size")
-
+
col.separator()
col.separator()
col.separator()
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 0e1f5d8dff2..3c56ff82a77 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -1120,11 +1120,11 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel, Panel):
row.menu("VIEW3D_MT_tools_projectpaint_stencil", text=stencil_text)
row.prop(ipaint, "invert_stencil", text="", icon='IMAGE_ALPHA')
- row = layout.row()
- row.active = (settings.brush.image_tool == 'CLONE')
- row.prop(ipaint, "use_clone_layer", text="Clone")
+ col = layout.column()
+ col.active = (settings.brush.image_tool == 'CLONE')
+ col.prop(ipaint, "use_clone_layer", text="Clone from UV map")
clone_text = mesh.uv_texture_clone.name if mesh.uv_texture_clone else ""
- row.menu("VIEW3D_MT_tools_projectpaint_clone", text=clone_text)
+ col.menu("VIEW3D_MT_tools_projectpaint_clone", text=clone_text)
layout.prop(ipaint, "seam_bleed")
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index 9c7623f3757..12c0088e93e 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -83,7 +83,7 @@ GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font)
memset(gc->glyph_ascii_table, 0, sizeof(gc->glyph_ascii_table));
memset(gc->bucket, 0, sizeof(gc->bucket));
- gc->textures = (GLuint *)malloc(sizeof(GLuint) * 256);
+ gc->textures = (GLuint *)MEM_mallocN(sizeof(GLuint) * 256, __func__);
gc->ntex = 256;
gc->cur_tex = -1;
gc->x_offs = 0;
@@ -150,7 +150,7 @@ void blf_glyph_cache_free(GlyphCacheBLF *gc)
if (gc->cur_tex + 1 > 0)
glDeleteTextures(gc->cur_tex + 1, gc->textures);
- free((void *)gc->textures);
+ MEM_freeN((void *)gc->textures);
MEM_freeN(gc);
}
@@ -178,8 +178,7 @@ static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc)
gc->p2_height = font->max_tex_size;
tot_mem = gc->p2_width * gc->p2_height;
- buf = (unsigned char *)malloc(tot_mem);
- memset((void *)buf, 0, tot_mem);
+ buf = (unsigned char *)MEM_callocN(tot_mem, __func__);
glGenTextures(1, &gc->textures[gc->cur_tex]);
glBindTexture(GL_TEXTURE_2D, (font->tex_bind_state = gc->textures[gc->cur_tex]));
@@ -189,7 +188,7 @@ static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, gc->p2_width, gc->p2_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, buf);
- free((void *)buf);
+ MEM_freeN((void *)buf);
}
GlyphBLF *blf_glyph_search(GlyphCacheBLF *gc, unsigned int c)
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index ed90c63d949..f06547fe2e3 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -173,6 +173,9 @@ struct DerivedMesh {
float auto_bump_scale;
DMDirtyFlag dirty;
+ /* use for converting to BMesh which doesn't store bevel weight and edge crease by default */
+ char cd_flag;
+
/** Calculate vert and face normals */
void (*calcNormals)(DerivedMesh *dm);
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index 10528f1b270..9c6d26c08bc 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -42,7 +42,7 @@ extern "C" {
* and keep comment above the defines.
* Use STRINGIFY() rather than defining with quotes */
#define BLENDER_VERSION 265
-#define BLENDER_SUBVERSION 5
+#define BLENDER_SUBVERSION 8
/* 262 was the last editmesh release but it has compatibility code for bmesh data */
#define BLENDER_MINVERSION 262
diff --git a/source/blender/blenkernel/BKE_cdderivedmesh.h b/source/blender/blenkernel/BKE_cdderivedmesh.h
index 2b2497f3f50..af5e925987d 100644
--- a/source/blender/blenkernel/BKE_cdderivedmesh.h
+++ b/source/blender/blenkernel/BKE_cdderivedmesh.h
@@ -63,14 +63,12 @@ DerivedMesh *CDDM_from_editbmesh(struct BMEditMesh *em, int use_mdisps, int use_
/* merge verts */
DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap);
-DerivedMesh *CDDM_from_curve_orco(struct Scene *scene, struct Object *ob);
-
/* creates a CDDerivedMesh from the given curve object */
struct DerivedMesh *CDDM_from_curve(struct Object *ob);
/* creates a CDDerivedMesh from the given curve object and specified dispbase */
/* useful for OrcoDM creation for curves with constructive modifiers */
-DerivedMesh *CDDM_from_curve_displist(struct Object *ob, struct ListBase *dispbase, int **orco_index_ptr);
+DerivedMesh *CDDM_from_curve_displist(struct Object *ob, struct ListBase *dispbase);
/* Copies the given DerivedMesh with verts, faces & edges stored as
* custom element data.
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 4736e7b7312..36733d1ced0 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -39,6 +39,7 @@ extern "C" {
#endif
#include "../blenloader/BLO_sys_types.h" /* XXX, should have a more generic include for this */
+#include "BLI_utildefines.h"
struct BMesh;
struct ID;
@@ -215,6 +216,8 @@ void CustomData_free_elem(struct CustomData *data, int index, int count);
void CustomData_interp(const struct CustomData *source, struct CustomData *dest,
int *src_indices, float *weights, float *sub_weights,
int count, int dest_index);
+void CustomData_bmesh_interp_n(struct CustomData *data, void **src_blocks, const float *weights,
+ const float *sub_weights, int count, void *dest_block, int n);
void CustomData_bmesh_interp(struct CustomData *data, void **src_blocks,
const float *weights, const float *sub_weights, int count,
void *dest_block);
@@ -246,6 +249,8 @@ void *CustomData_get_layer(const struct CustomData *data, int type);
void *CustomData_get_layer_n(const struct CustomData *data, int type, int n);
void *CustomData_get_layer_named(const struct CustomData *data, int type,
const char *name);
+int CustomData_get_offset(const struct CustomData *data, int type);
+int CustomData_get_n_offset(const struct CustomData *data, int type, int n);
int CustomData_get_layer_index(const struct CustomData *data, int type);
int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n);
@@ -304,7 +309,7 @@ void CustomData_bmesh_free_block(struct CustomData *data, void **block);
/* copy custom data to/from layers as in mesh/derivedmesh, to editmesh
* blocks of data. the CustomData's must not be compatible */
void CustomData_to_bmesh_block(const struct CustomData *source,
- struct CustomData *dest, int src_index, void **dest_block);
+ struct CustomData *dest, int src_index, void **dest_block, bool use_default_init);
void CustomData_from_bmesh_block(const struct CustomData *source,
struct CustomData *dest, void *src_block, int dest_index);
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h
index ec465502ca0..be42ee524de 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -96,7 +96,7 @@ typedef struct Main {
} Main;
#define MAIN_VERSION_ATLEAST(main, ver, subver) \
- ((main)->versionfile >= (ver) || (main->versionfile == (ver) && (main)->subversionfile >= (subver)))
+ ((main)->versionfile > (ver) || (main->versionfile == (ver) && (main)->subversionfile >= (subver)))
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index db9f1228f76..3466a914bce 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -154,13 +154,9 @@ int BKE_mesh_nurbs_to_mdata(struct Object *ob, struct MVert **allvert, int *tot
int *totloop, int *totpoly);
int BKE_mesh_nurbs_displist_to_mdata(struct Object *ob, struct ListBase *dispbase, struct MVert **allvert, int *_totvert,
struct MEdge **alledge, int *_totedge, struct MLoop **allloop, struct MPoly **allpoly,
- int *_totloop, int *_totpoly, int **orco_index_ptr);
-void BKE_mesh_nurbs_to_mdata_orco(struct MPoly *mpoly, int totpoly,
- struct MLoop *mloops, struct MLoopUV *mloopuvs,
- float (*orco)[3], int (*orco_index)[4]);
+ struct MLoopUV **alluv, int *_totloop, int *_totpoly);
+void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase, int use_orco_uv);
void BKE_mesh_from_nurbs(struct Object *ob);
-void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase,
- int **orco_index_ptr);
void BKE_mesh_from_curve(struct Scene *scene, struct Object *ob);
void BKE_mesh_delete_material_index(struct Mesh *me, short index);
void BKE_mesh_smooth_flag_set(struct Object *meshOb, int enableSmooth);
@@ -334,6 +330,8 @@ void BKE_mesh_loops_to_mface_corners(struct CustomData *fdata, struct CustomData
void BKE_mesh_poly_calc_angles(struct MVert *mvert, struct MLoop *mloop,
struct MPoly *mp, float angles[]);
+void BKE_mesh_do_versions_cd_flag_init(struct Mesh *mesh);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_report.h b/source/blender/blenkernel/BKE_report.h
index 4d69a013101..e659954a3ac 100644
--- a/source/blender/blenkernel/BKE_report.h
+++ b/source/blender/blenkernel/BKE_report.h
@@ -35,6 +35,7 @@ extern "C" {
#endif
#include "DNA_windowmanager_types.h"
+#include "BLI_utildefines.h"
/* Reporting Information and Errors
*
@@ -72,7 +73,10 @@ void BKE_reports_print(ReportList *reports, ReportType level);
Report *BKE_reports_last_displayable(ReportList *reports);
int BKE_reports_contain(ReportList *reports, ReportType level);
-
+
+bool BKE_report_write_file_fp(FILE *fp, ReportList *reports, const char *header);
+bool BKE_report_write_file(const char *filepath, ReportList *reports, const char *header);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index ec8d37e1ae3..dde1d5870ca 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -313,6 +313,8 @@ void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type
CustomData_copy(&source->polyData, &dm->polyData, CD_MASK_DERIVEDMESH,
CD_CALLOC, numPolys);
+ dm->cd_flag = source->cd_flag;
+
dm->type = type;
dm->numVertData = numVerts;
dm->numEdgeData = numEdges;
@@ -483,11 +485,13 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob)
totedge = tmp.totedge = dm->getNumEdges(dm);
totloop = tmp.totloop = dm->getNumLoops(dm);
totpoly = tmp.totpoly = dm->getNumPolys(dm);
+ tmp.totface = 0;
CustomData_copy(&dm->vertData, &tmp.vdata, CD_MASK_MESH, CD_DUPLICATE, totvert);
CustomData_copy(&dm->edgeData, &tmp.edata, CD_MASK_MESH, CD_DUPLICATE, totedge);
CustomData_copy(&dm->loopData, &tmp.ldata, CD_MASK_MESH, CD_DUPLICATE, totloop);
CustomData_copy(&dm->polyData, &tmp.pdata, CD_MASK_MESH, CD_DUPLICATE, totpoly);
+ me->cd_flag = dm->cd_flag;
if (CustomData_has_layer(&dm->vertData, CD_SHAPEKEY)) {
KeyBlock *kb;
@@ -538,9 +542,10 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob)
}
/* yes, must be before _and_ after tessellate */
- mesh_update_customdata_pointers(&tmp, TRUE);
+ mesh_update_customdata_pointers(&tmp, false);
- BKE_mesh_tessface_calc(&tmp);
+ /* since 2.65 caller must do! */
+ // BKE_mesh_tessface_calc(&tmp);
CustomData_free(&me->vdata, me->totvert);
CustomData_free(&me->edata, me->totedge);
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 51890851ebc..85dd4c67fdf 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -647,6 +647,23 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
index_mp_to_orig = NULL;
}
+ /* TODO: not entirely correct, but currently dynamic topology will
+ * destroy UVs anyway, so textured display wouldn't work anyway
+ *
+ * this will do more like solid view with lights set up for
+ * textured view, but object itself will be displayed gray
+ * (the same as it'll display without UV maps in textured view)
+ */
+ if (cddm->pbvh && cddm->pbvh_draw && BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH) {
+ if (dm->numTessFaceData) {
+ glDisable(GL_TEXTURE_2D);
+ BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, FALSE);
+ glEnable(GL_TEXTURE_2D);
+ }
+
+ return;
+ }
+
colType = CD_TEXTURE_MCOL;
mcol = dm->getTessFaceDataArray(dm, colType);
if (!mcol) {
@@ -1726,6 +1743,7 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
mesh->totloop, mesh->totpoly);
dm->deformedOnly = 1;
+ dm->cd_flag = mesh->cd_flag;
alloctype = CD_REFERENCE;
@@ -1757,49 +1775,10 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
DerivedMesh *CDDM_from_curve(Object *ob)
{
- return CDDM_from_curve_displist(ob, &ob->disp, NULL);
+ return CDDM_from_curve_displist(ob, &ob->disp);
}
-DerivedMesh *CDDM_from_curve_orco(struct Scene *scene, Object *ob)
-{
- int *orco_index_ptr = NULL;
- int (*orco_index)[4] = NULL;
- float (*orco)[3] = NULL;
- DerivedMesh *dm = CDDM_from_curve_displist(ob, &ob->disp, &orco_index_ptr);
-
- if (orco_index_ptr) {
- orco = (float (*)[3])BKE_curve_make_orco(scene, ob);
- }
-
- if (orco && orco_index_ptr) {
- const char *uvname = "Orco";
-
- int totpoly = dm->getNumPolys(dm);
-
- MPoly *mpolys = dm->getPolyArray(dm);
- MLoop *mloops = dm->getLoopArray(dm);
-
- MLoopUV *mloopuvs;
-
- CustomData_add_layer_named(&dm->polyData, CD_MTEXPOLY, CD_DEFAULT, NULL, dm->numPolyData, uvname);
- mloopuvs = CustomData_add_layer_named(&dm->loopData, CD_MLOOPUV, CD_DEFAULT, NULL, dm->numLoopData, uvname);
-
- BKE_mesh_nurbs_to_mdata_orco(mpolys, totpoly,
- mloops, mloopuvs,
- orco, orco_index);
- }
-
- if (orco_index) {
- MEM_freeN(orco_index);
- }
- if (orco) {
- MEM_freeN(orco);
- }
-
- return dm;
-}
-
-DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase, int **orco_index_ptr)
+DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase)
{
DerivedMesh *dm;
CDDerivedMesh *cddm;
@@ -1810,7 +1789,8 @@ DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase, int **orco
int totvert, totedge, totloop, totpoly;
if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert, &alledge,
- &totedge, &allloop, &allpoly, &totloop, &totpoly, orco_index_ptr) != 0)
+ &totedge, &allloop, &allpoly, NULL,
+ &totloop, &totpoly) != 0)
{
/* Error initializing mdata. This often happens when curve is empty */
return CDDM_new(0, 0, 0, 0, 0);
@@ -1909,13 +1889,12 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
int numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
int numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
int *index, add_orig;
- int has_crease, has_edge_bweight, has_vert_bweight;
CustomDataMask mask;
unsigned int i, j;
- has_edge_bweight = CustomData_has_layer(&bm->edata, CD_BWEIGHT);
- has_vert_bweight = CustomData_has_layer(&bm->vdata, CD_BWEIGHT);
- has_crease = CustomData_has_layer(&bm->edata, CD_CREASE);
+ const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
dm->deformedOnly = 1;
@@ -1955,8 +1934,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
mv->flag = BM_vert_flag_to_mflag(eve);
- if (has_vert_bweight)
- mv->bweight = (unsigned char)(BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT) * 255.0f);
+ if (cd_vert_bweight_offset != -1) mv->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset);
if (add_orig) *index = i;
@@ -1974,11 +1952,6 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
med->v1 = BM_elem_index_get(eed->v1);
med->v2 = BM_elem_index_get(eed->v2);
- if (has_crease)
- med->crease = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_CREASE) * 255.0f);
- if (has_edge_bweight)
- med->bweight = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_BWEIGHT) * 255.0f);
-
med->flag = BM_edge_flag_to_mflag(eed);
/* handle this differently to editmode switching,
@@ -1989,6 +1962,9 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
}
}
+ if (cd_edge_crease_offset != -1) med->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_crease_offset);
+ if (cd_edge_bweight_offset != -1) med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_bweight_offset);
+
CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i);
if (add_orig) *index = i;
}
@@ -2051,6 +2027,8 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
}
bm->elem_index_dirty &= ~BM_FACE;
+ dm->cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
+
return dm;
}
@@ -2088,6 +2066,7 @@ static DerivedMesh *cddm_copy_ex(DerivedMesh *source, int faces_from_tessfaces)
DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces,
numLoops, numPolys);
dm->deformedOnly = source->deformedOnly;
+ dm->cd_flag = source->cd_flag;
dm->dirty = source->dirty;
CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 1d199cdf1e2..fe8bd0cc5a4 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -875,7 +875,7 @@ static void basisNurb(float t, short order, short pnts, float *knots, float *bas
void BKE_nurb_makeFaces(Nurb *nu, float *coord_array, int rowstride, int resolu, int resolv)
-/* coord_array has to be 3*4*resolu*resolv in size, and zero-ed */
+/* coord_array has to be (3 * 4 * resolu * resolv) in size, and zero-ed */
{
BPoint *bp;
float *basisu, *basis, *basisv, *sum, *fp, *in;
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 0f352dede23..f3548f776f5 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -2095,6 +2095,23 @@ void *CustomData_get_layer_named(const struct CustomData *data, int type,
return data->layers[layer_index].data;
}
+int CustomData_get_offset(const CustomData *data, int type)
+{
+ /* get the layer index of the active layer of type */
+ int layer_index = CustomData_get_active_layer_index(data, type);
+ if (layer_index < 0) return -1;
+
+ return data->layers[layer_index].offset;
+}
+
+int CustomData_get_n_offset(const CustomData *data, int type, int n)
+{
+ /* get the layer index of the active layer of type */
+ int layer_index = CustomData_get_layer_index_n(data, type, n);
+ if (layer_index < 0) return -1;
+
+ return data->layers[layer_index].offset;
+}
int CustomData_set_layer_name(const CustomData *data, int type, int n, const char *name)
{
@@ -2298,34 +2315,46 @@ void CustomData_bmesh_merge(CustomData *source, CustomData *dest,
BMIter iter;
CustomData destold;
void *tmp;
- int t;
+ int iter_type;
+ int totelem;
/* copy old layer description so that old data can be copied into
* the new allocation */
destold = *dest;
- if (destold.layers) destold.layers = MEM_dupallocN(destold.layers);
-
- CustomData_merge(source, dest, mask, alloctype, 0);
- dest->pool = NULL;
- CustomData_bmesh_init_pool(dest, 512, htype);
+ if (destold.layers) {
+ destold.layers = MEM_dupallocN(destold.layers);
+ }
switch (htype) {
case BM_VERT:
- t = BM_VERTS_OF_MESH; break;
+ iter_type = BM_VERTS_OF_MESH;
+ totelem = bm->totvert;
+ break;
case BM_EDGE:
- t = BM_EDGES_OF_MESH; break;
+ iter_type = BM_EDGES_OF_MESH;
+ totelem = bm->totedge;
+ break;
case BM_LOOP:
- t = BM_LOOPS_OF_FACE; break;
+ iter_type = BM_LOOPS_OF_FACE;
+ totelem = bm->totloop;
+ break;
case BM_FACE:
- t = BM_FACES_OF_MESH; break;
+ iter_type = BM_FACES_OF_MESH;
+ totelem = bm->totface;
+ break;
default: /* should never happen */
BLI_assert(!"invalid type given");
- t = BM_VERTS_OF_MESH;
+ iter_type = BM_VERTS_OF_MESH;
+ totelem = bm->totvert;
}
- if (t != BM_LOOPS_OF_FACE) {
+ CustomData_merge(source, dest, mask, alloctype, 0);
+ dest->pool = NULL;
+ CustomData_bmesh_init_pool(dest, totelem, htype);
+
+ if (iter_type != BM_LOOPS_OF_FACE) {
/*ensure all current elements follow new customdata layout*/
- BM_ITER_MESH (h, &iter, bm, t) {
+ BM_ITER_MESH (h, &iter, bm, iter_type) {
tmp = NULL;
CustomData_bmesh_copy_data(&destold, dest, h->data, &tmp);
CustomData_bmesh_free_block(&destold, &h->data);
@@ -2618,6 +2647,19 @@ void CustomData_bmesh_set_layer_n(CustomData *data, void *block, int n, void *so
memcpy(dest, source, typeInfo->size);
}
+/**
+ * \param src_blocks must be pointers to the data, offset by layer->offset already.
+ */
+void CustomData_bmesh_interp_n(CustomData *data, void **src_blocks, const float *weights,
+ const float *sub_weights, int count, void *dest_block, int n)
+{
+ CustomDataLayer *layer = &data->layers[n];
+ const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
+
+ typeInfo->interp(src_blocks, weights, sub_weights, count,
+ (char *)dest_block + layer->offset);
+}
+
void CustomData_bmesh_interp(CustomData *data, void **src_blocks, const float *weights,
const float *sub_weights, int count, void *dest_block)
{
@@ -2640,36 +2682,47 @@ void CustomData_bmesh_interp(CustomData *data, void **src_blocks, const float *w
for (j = 0; j < count; ++j) {
sources[j] = (char *)src_blocks[j] + layer->offset;
}
-
- typeInfo->interp(sources, weights, sub_weights, count,
- (char *)dest_block + layer->offset);
+ CustomData_bmesh_interp_n(data, sources, weights, sub_weights, count, dest_block, i);
}
}
if (count > SOURCE_BUF_SIZE) MEM_freeN(sources);
}
-void CustomData_bmesh_set_default(CustomData *data, void **block)
+static void CustomData_bmesh_set_default_n(CustomData *data, void **block, int n)
{
const LayerTypeInfo *typeInfo;
+ int offset = data->layers[n].offset;
+
+ typeInfo = layerType_getInfo(data->layers[n].type);
+
+ if (typeInfo->set_default) {
+ typeInfo->set_default((char *)*block + offset, 1);
+ }
+ else {
+ memset((char *)*block + offset, 0, typeInfo->size);
+ }
+}
+
+void CustomData_bmesh_set_default(CustomData *data, void **block)
+{
int i;
if (*block == NULL)
CustomData_bmesh_alloc_block(data, block);
for (i = 0; i < data->totlayer; ++i) {
- int offset = data->layers[i].offset;
-
- typeInfo = layerType_getInfo(data->layers[i].type);
-
- if (typeInfo->set_default)
- typeInfo->set_default((char *)*block + offset, 1);
- else memset((char *)*block + offset, 0, typeInfo->size);
+ CustomData_bmesh_set_default_n(data, block, i);
}
}
+/**
+ * \param use_default_init initializes data which can't be copied,
+ * typically you'll want to use this if the BM_xxx create function
+ * is called with BM_CREATE_SKIP_CD flag
+ */
void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest,
- int src_index, void **dest_block)
+ int src_index, void **dest_block, bool use_default_init)
{
const LayerTypeInfo *typeInfo;
int dest_i, src_i, src_offset;
@@ -2685,11 +2738,14 @@ void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest,
* (this should work because layers are ordered by type)
*/
while (dest_i < dest->totlayer && dest->layers[dest_i].type < source->layers[src_i].type) {
+ if (use_default_init) {
+ CustomData_bmesh_set_default_n(dest, dest_block, dest_i);
+ }
dest_i++;
}
/* if there are no more dest layers, we're done */
- if (dest_i >= dest->totlayer) return;
+ if (dest_i >= dest->totlayer) break;
/* if we found a matching layer, copy the data */
if (dest->layers[dest_i].type == source->layers[src_i].type) {
@@ -2712,6 +2768,13 @@ void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest,
dest_i++;
}
}
+
+ if (use_default_init) {
+ while (dest_i < dest->totlayer) {
+ CustomData_bmesh_set_default_n(dest, dest_block, dest_i);
+ dest_i++;
+ }
+ }
}
void CustomData_from_bmesh_block(const CustomData *source, CustomData *dest,
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 71e9daaee6b..643c7b1d972 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -975,7 +975,7 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba
curve_to_filledpoly(cu, nurb, dispbase);
}
- dm = CDDM_from_curve_displist(ob, dispbase, NULL);
+ dm = CDDM_from_curve_displist(ob, dispbase);
CDDM_calc_normals_mapping(dm);
}
@@ -1065,7 +1065,7 @@ static DerivedMesh *create_orco_dm(Scene *scene, Object *ob)
/* OrcoDM should be created from underformed disp lists */
BKE_displist_make_curveTypes_forOrco(scene, ob, &disp);
- dm = CDDM_from_curve_displist(ob, &disp, NULL);
+ dm = CDDM_from_curve_displist(ob, &disp);
BKE_displist_free(&disp);
@@ -1485,8 +1485,7 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
float *cur_data = data;
if (cu->taperobj == NULL) {
- if ( (cu->bevobj != NULL) || !((cu->flag & CU_FRONT) || (cu->flag & CU_BACK)) )
- fac = bevp->radius;
+ fac = bevp->radius;
}
else {
float len, taper_fac;
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index 1c43b418a1c..91577320a9c 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -782,22 +782,18 @@ static void emDM_drawMappedFaces(DerivedMesh *dm,
if (poly_prev != GL_ZERO) glEnd();
}
-static void bmdm_get_tri_tex(BMesh *bm, BMLoop **ls, MLoopUV *luv[3], MLoopCol *lcol[3],
- int has_uv, int has_col)
+static void bmdm_get_tri_uv(BMLoop *ls[3], MLoopUV *luv[3], const int cd_loop_uv_offset)
{
- if (has_uv) {
- luv[0] = CustomData_bmesh_get(&bm->ldata, ls[0]->head.data, CD_MLOOPUV);
- luv[1] = CustomData_bmesh_get(&bm->ldata, ls[1]->head.data, CD_MLOOPUV);
- luv[2] = CustomData_bmesh_get(&bm->ldata, ls[2]->head.data, CD_MLOOPUV);
- }
-
- if (has_col) {
- lcol[0] = CustomData_bmesh_get(&bm->ldata, ls[0]->head.data, CD_MLOOPCOL);
- lcol[1] = CustomData_bmesh_get(&bm->ldata, ls[1]->head.data, CD_MLOOPCOL);
- lcol[2] = CustomData_bmesh_get(&bm->ldata, ls[2]->head.data, CD_MLOOPCOL);
- }
-
+ luv[0] = BM_ELEM_CD_GET_VOID_P(ls[0], cd_loop_uv_offset);
+ luv[1] = BM_ELEM_CD_GET_VOID_P(ls[1], cd_loop_uv_offset);
+ luv[2] = BM_ELEM_CD_GET_VOID_P(ls[2], cd_loop_uv_offset);
+}
+static void bmdm_get_tri_col(BMLoop *ls[3], MLoopCol *lcol[3], const int cd_loop_color_offset)
+{
+ lcol[0] = BM_ELEM_CD_GET_VOID_P(ls[0], cd_loop_color_offset);
+ lcol[1] = BM_ELEM_CD_GET_VOID_P(ls[1], cd_loop_color_offset);
+ lcol[2] = BM_ELEM_CD_GET_VOID_P(ls[2], cd_loop_color_offset);
}
static void emDM_drawFacesTex_common(DerivedMesh *dm,
@@ -813,15 +809,19 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
float (*vertexNos)[3] = bmdm->vertexNos;
BMFace *efa;
MLoopUV *luv[3], dummyluv = {{0}};
- MLoopCol *lcol[3] = {NULL}, dummylcol = {0};
- int i, has_vcol = CustomData_has_layer(&bm->ldata, CD_MLOOPCOL);
- int has_uv = CustomData_has_layer(&bm->pdata, CD_MTEXPOLY);
+ MLoopCol *lcol[3] = {NULL} /* , dummylcol = {0} */;
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const int cd_loop_color_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPCOL);
+ const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY);
+ bool has_uv = (cd_loop_uv_offset != -1);
+ bool has_vcol = (cd_loop_color_offset != -1);
+ int i;
(void) compareDrawOptions;
luv[0] = luv[1] = luv[2] = &dummyluv;
- dummylcol.r = dummylcol.g = dummylcol.b = dummylcol.a = 255;
+ // dummylcol.r = dummylcol.g = dummylcol.b = dummylcol.a = 255; /* UNUSED */
/* always use smooth shading even for flat faces, else vertex colors wont interpolate */
glShadeModel(GL_SMOOTH);
@@ -833,7 +833,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
for (i = 0; i < em->tottri; i++) {
BMLoop **ls = em->looptris[i];
- MTexPoly *tp = has_uv ? CustomData_bmesh_get(&bm->pdata, ls[0]->f->head.data, CD_MTEXPOLY) : NULL;
+ MTexPoly *tp = (cd_poly_tex_offset != -1) ? BM_ELEM_CD_GET_VOID_P(ls[0]->f, cd_poly_tex_offset) : NULL;
MTFace mtf = {{{0}}};
/*unsigned char *cp = NULL;*/ /*UNUSED*/
int drawSmooth = BM_elem_flag_test(ls[0]->f, BM_ELEM_SMOOTH);
@@ -841,7 +841,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
efa = ls[0]->f;
- if (has_uv) {
+ if (cd_poly_tex_offset != -1) {
ME_MTEXFACE_CPY(&mtf, tp);
}
@@ -858,25 +858,27 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
if (!drawSmooth) {
glNormal3fv(bmdm->polyNos[BM_elem_index_get(efa)]);
- bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
+ if (has_uv) bmdm_get_tri_uv(ls, luv, cd_loop_uv_offset);
+ if (has_vcol) bmdm_get_tri_col(ls, lcol, cd_loop_color_offset);
glTexCoord2fv(luv[0]->uv);
- if (lcol[0])
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[0]->r));
glVertex3fv(vertexCos[BM_elem_index_get(ls[0]->v)]);
glTexCoord2fv(luv[1]->uv);
- if (lcol[1])
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[1]->r));
glVertex3fv(vertexCos[BM_elem_index_get(ls[1]->v)]);
glTexCoord2fv(luv[2]->uv);
- if (lcol[2])
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[2]->r));
glVertex3fv(vertexCos[BM_elem_index_get(ls[2]->v)]);
}
else {
- bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
+ if (has_uv) bmdm_get_tri_uv(ls, luv, cd_loop_uv_offset);
+ if (has_vcol) bmdm_get_tri_col(ls, lcol, cd_loop_color_offset);
glTexCoord2fv(luv[0]->uv);
if (lcol[0])
@@ -905,7 +907,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
for (i = 0; i < em->tottri; i++) {
BMLoop **ls = em->looptris[i];
- MTexPoly *tp = has_uv ? CustomData_bmesh_get(&bm->pdata, ls[0]->f->head.data, CD_MTEXPOLY) : NULL;
+ MTexPoly *tp = (cd_poly_tex_offset != -1) ? BM_ELEM_CD_GET_VOID_P(ls[0]->f, cd_poly_tex_offset) : NULL;
MTFace mtf = {{{0}}};
/*unsigned char *cp = NULL;*/ /*UNUSED*/
int drawSmooth = BM_elem_flag_test(ls[0]->f, BM_ELEM_SMOOTH);
@@ -913,12 +915,12 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
efa = ls[0]->f;
- if (has_uv) {
+ if (cd_poly_tex_offset != -1) {
ME_MTEXFACE_CPY(&mtf, tp);
}
if (drawParams)
- draw_option = drawParams(&mtf, has_vcol, efa->mat_nr);
+ draw_option = drawParams(&mtf, (has_vcol), efa->mat_nr);
else if (drawParamsMapped)
draw_option = drawParamsMapped(userData, BM_elem_index_get(efa));
else
@@ -930,46 +932,42 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
if (!drawSmooth) {
glNormal3fv(efa->no);
- bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
+ if (has_uv) bmdm_get_tri_uv(ls, luv, cd_loop_uv_offset);
+ if (has_vcol) bmdm_get_tri_col(ls, lcol, cd_loop_color_offset);
- if (luv[0])
- glTexCoord2fv(luv[0]->uv);
- if (lcol[0])
+ glTexCoord2fv(luv[0]->uv);
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[0]->r));
glVertex3fv(ls[0]->v->co);
- if (luv[1])
- glTexCoord2fv(luv[1]->uv);
- if (lcol[1])
+ glTexCoord2fv(luv[1]->uv);
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[1]->r));
glVertex3fv(ls[1]->v->co);
- if (luv[2])
- glTexCoord2fv(luv[2]->uv);
- if (lcol[2])
+ glTexCoord2fv(luv[2]->uv);
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[2]->r));
glVertex3fv(ls[2]->v->co);
}
else {
- bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
+ if (has_uv) bmdm_get_tri_uv(ls, luv, cd_loop_uv_offset);
+ if (has_vcol) bmdm_get_tri_col(ls, lcol, cd_loop_color_offset);
- if (luv[0])
- glTexCoord2fv(luv[0]->uv);
- if (lcol[0])
+ glTexCoord2fv(luv[0]->uv);
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[0]->r));
glNormal3fv(ls[0]->v->no);
glVertex3fv(ls[0]->v->co);
- if (luv[1])
- glTexCoord2fv(luv[1]->uv);
- if (lcol[1])
+ glTexCoord2fv(luv[1]->uv);
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[1]->r));
glNormal3fv(ls[1]->v->no);
glVertex3fv(ls[1]->v->co);
- if (luv[2])
- glTexCoord2fv(luv[2]->uv);
- if (lcol[2])
+ glTexCoord2fv(luv[2]->uv);
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[2]->r));
glNormal3fv(ls[2]->v->no);
glVertex3fv(ls[2]->v->co);
@@ -1309,14 +1307,16 @@ static int emDM_getNumPolys(DerivedMesh *dm)
static int bmvert_to_mvert(BMesh *bm, BMVert *ev, MVert *vert_r)
{
+ float *f;
+
copy_v3_v3(vert_r->co, ev->co);
normal_float_to_short_v3(vert_r->no, ev->no);
vert_r->flag = BM_vert_flag_to_mflag(ev);
- if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
- vert_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->vdata, ev, CD_BWEIGHT) * 255.0f);
+ if ((f = CustomData_bmesh_get(&bm->vdata, ev->head.data, CD_BWEIGHT))) {
+ vert_r->bweight = (unsigned char)((*f) * 255.0f);
}
return 1;
@@ -1332,8 +1332,8 @@ static void emDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
return;
}
- // ev = EDBM_vert_at_index(bmdm->tc, index);
- ev = BM_vert_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */
+ ev = bmdm->tc->vert_index[index]; /* should be EDBM_vert_at_index() */
+ // ev = BM_vert_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */
bmvert_to_mvert(bmdm->tc->bm, ev, vert_r);
if (bmdm->vertexCos)
@@ -1345,27 +1345,27 @@ static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
BMesh *bm = bmdm->tc->bm;
BMEdge *e;
+ float *f;
if (index < 0 || index >= bmdm->te) {
printf("error in emDM_getEdge.\n");
return;
}
- // e = EDBM_edge_at_index(bmdm->tc, index);
- e = BM_edge_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */
-
- if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
- edge_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->edata, e, CD_BWEIGHT) * 255.0f);
- }
-
- if (CustomData_has_layer(&bm->edata, CD_CREASE)) {
- edge_r->crease = (unsigned char) (BM_elem_float_data_get(&bm->edata, e, CD_CREASE) * 255.0f);
- }
+ e = bmdm->tc->edge_index[index]; /* should be EDBM_edge_at_index() */
+ // e = BM_edge_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */
edge_r->flag = BM_edge_flag_to_mflag(e);
edge_r->v1 = BM_elem_index_get(e->v1);
edge_r->v2 = BM_elem_index_get(e->v2);
+
+ if ((f = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BWEIGHT))) {
+ edge_r->bweight = (unsigned char)((*f) * 255.0f);
+ }
+ if ((f = CustomData_bmesh_get(&bm->edata, e->head.data, CD_CREASE))) {
+ edge_r->crease = (unsigned char)((*f) * 255.0f);
+ }
}
static void emDM_getTessFace(DerivedMesh *dm, int index, MFace *face_r)
@@ -1400,7 +1400,7 @@ static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
BMesh *bm = bmdm->tc->bm;
BMVert *eve;
BMIter iter;
- const int has_bweight = CustomData_has_layer(&bm->vdata, CD_BWEIGHT);
+ const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
if (bmdm->vertexCos) {
int i;
@@ -1410,9 +1410,8 @@ static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
normal_float_to_short_v3(vert_r->no, eve->no);
vert_r->flag = BM_vert_flag_to_mflag(eve);
- if (has_bweight) {
- vert_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT) * 255.0f);
- }
+ if (cd_vert_bweight_offset != -1) vert_r->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset);
+
vert_r++;
}
}
@@ -1422,9 +1421,8 @@ static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
normal_float_to_short_v3(vert_r->no, eve->no);
vert_r->flag = BM_vert_flag_to_mflag(eve);
- if (has_bweight) {
- vert_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT) * 255.0f);
- }
+ if (cd_vert_bweight_offset != -1) vert_r->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset);
+
vert_r++;
}
}
@@ -1435,24 +1433,20 @@ static void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
BMEdge *eed;
BMIter iter;
- const int has_bweight = CustomData_has_layer(&bm->edata, CD_BWEIGHT);
- const int has_crease = CustomData_has_layer(&bm->edata, CD_CREASE);
+
+ const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
BM_mesh_elem_index_ensure(bm, BM_VERT);
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
- if (has_bweight) {
- edge_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->edata, eed, CD_BWEIGHT) * 255.0f);
- }
-
- if (has_crease) {
- edge_r->crease = (unsigned char) (BM_elem_float_data_get(&bm->edata, eed, CD_CREASE) * 255.0f);
- }
+ edge_r->v1 = BM_elem_index_get(eed->v1);
+ edge_r->v2 = BM_elem_index_get(eed->v2);
edge_r->flag = BM_edge_flag_to_mflag(eed);
- edge_r->v1 = BM_elem_index_get(eed->v1);
- edge_r->v2 = BM_elem_index_get(eed->v2);
+ if (cd_edge_crease_offset != -1) edge_r->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_crease_offset);
+ if (cd_edge_bweight_offset != -1) edge_r->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_bweight_offset);
edge_r++;
}
@@ -1660,6 +1654,9 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em,
DM_init((DerivedMesh *)bmdm, DM_TYPE_EDITBMESH, em->bm->totvert,
em->bm->totedge, em->tottri, em->bm->totloop, em->bm->totface);
+ /* could also get from the objects mesh directly */
+ bmdm->dm.cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
+
bmdm->dm.getVertCos = emDM_getVertCos;
bmdm->dm.getMinMax = emDM_getMinMax;
diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c
index 2b393b4d90b..7b007af86d6 100644
--- a/source/blender/blenkernel/intern/fmodifier.c
+++ b/source/blender/blenkernel/intern/fmodifier.c
@@ -141,55 +141,34 @@ static void fcm_generator_verify(FModifier *fcm)
switch (data->mode) {
case FCM_GENERATOR_POLYNOMIAL: /* expanded polynomial expression */
{
+ const int arraysize_new = data->poly_order + 1;
/* arraysize needs to be order+1, so resize if not */
- if (data->arraysize != (data->poly_order + 1)) {
- float *nc;
-
- /* make new coefficients array, and copy over as much data as can fit */
- nc = MEM_callocN(sizeof(float) * (data->poly_order + 1), "FMod_Generator_Coefs");
-
+ if (data->arraysize != arraysize_new) {
if (data->coefficients) {
- if ((int)data->arraysize > (data->poly_order + 1))
- memcpy(nc, data->coefficients, sizeof(float) * (data->poly_order + 1));
- else
- memcpy(nc, data->coefficients, sizeof(float) * data->arraysize);
-
- /* free the old data */
- MEM_freeN(data->coefficients);
+ data->coefficients = MEM_recallocN(data->coefficients, sizeof(float) * arraysize_new);
}
-
- /* set the new data */
- data->coefficients = nc;
- data->arraysize = data->poly_order + 1;
+ else {
+ data->coefficients = MEM_callocN(sizeof(float) * arraysize_new, "FMod_Generator_Coefs");
+ }
+ data->arraysize = arraysize_new;
}
+ break;
}
- break;
-
case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* expanded polynomial expression */
{
- /* arraysize needs to be 2*order, so resize if not */
- if (data->arraysize != (data->poly_order * 2)) {
- float *nc;
-
- /* make new coefficients array, and copy over as much data as can fit */
- nc = MEM_callocN(sizeof(float) * (data->poly_order * 2), "FMod_Generator_Coefs");
-
+ const int arraysize_new = data->poly_order * 2;
+ /* arraysize needs to be (2 * order), so resize if not */
+ if (data->arraysize != arraysize_new) {
if (data->coefficients) {
- if (data->arraysize > (unsigned int)(data->poly_order * 2))
- memcpy(nc, data->coefficients, sizeof(float) * (data->poly_order * 2));
- else
- memcpy(nc, data->coefficients, sizeof(float) * data->arraysize);
-
- /* free the old data */
- MEM_freeN(data->coefficients);
+ data->coefficients = MEM_recallocN(data->coefficients, sizeof(float) * arraysize_new);
}
-
- /* set the new data */
- data->coefficients = nc;
- data->arraysize = data->poly_order * 2;
+ else {
+ data->coefficients = MEM_callocN(sizeof(float) * arraysize_new, "FMod_Generator_Coefs");
+ }
+ data->arraysize = arraysize_new;
}
+ break;
}
- break;
}
}
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index dbc423f98b3..21417386d65 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -904,7 +904,7 @@ void BKE_image_free_all_textures(void)
image_free_buffers(ima);
}
}
- /* printf("freed total %d MB\n", totsize/(1024*1024)); */
+ /* printf("freed total %d MB\n", totsize / (1024 * 1024)); */
}
/* except_frame is weak, only works for seqs without offset... */
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 30e7cb3bb36..dec7556392f 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -1204,8 +1204,8 @@ int BKE_mesh_nurbs_to_mdata(Object *ob, MVert **allvert, int *totvert,
return BKE_mesh_nurbs_displist_to_mdata(ob, &ob->disp,
allvert, totvert,
alledge, totedge,
- allloop, allpoly,
- totloop, totpoly, NULL);
+ allloop, allpoly, NULL,
+ totloop, totpoly);
}
/* BMESH: this doesn't calculate all edges from polygons,
@@ -1213,25 +1213,24 @@ int BKE_mesh_nurbs_to_mdata(Object *ob, MVert **allvert, int *totvert,
/* Initialize mverts, medges and, faces for converting nurbs to mesh and derived mesh */
/* use specified dispbase */
-/* TODO: orco values for non DL_SURF types */
int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
MVert **allvert, int *_totvert,
MEdge **alledge, int *_totedge,
MLoop **allloop, MPoly **allpoly,
- int *_totloop, int *_totpoly,
- int **orco_index_ptr)
+ MLoopUV **alluv,
+ int *_totloop, int *_totpoly)
{
DispList *dl;
Curve *cu;
MVert *mvert;
MPoly *mpoly;
MLoop *mloop;
+ MLoopUV *mloopuv = NULL;
MEdge *medge;
float *data;
int a, b, ofs, vertcount, startvert, totvert = 0, totedge = 0, totloop = 0, totvlak = 0;
int p1, p2, p3, p4, *index;
int conv_polys = 0;
- int (*orco_index)[4] = NULL;
cu = ob->data;
@@ -1278,15 +1277,13 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
*alledge = medge = MEM_callocN(sizeof(MEdge) * totedge, "nurbs_init medge");
*allloop = mloop = MEM_callocN(sizeof(MLoop) * totvlak * 4, "nurbs_init mloop"); // totloop
*allpoly = mpoly = MEM_callocN(sizeof(MPoly) * totvlak, "nurbs_init mloop");
+
+ if (alluv)
+ *alluv = mloopuv = MEM_callocN(sizeof(MLoopUV) * totvlak * 4, "nurbs_init mloopuv");
/* verts and faces */
vertcount = 0;
- if (orco_index_ptr) {
- *orco_index_ptr = MEM_callocN(sizeof(int) * totvlak * 4, "nurbs_init orco");
- orco_index = (int (*)[4]) *orco_index_ptr;
- }
-
dl = dispbase->first;
while (dl) {
int smooth = dl->rt & CU_SMOOTH ? 1 : 0;
@@ -1359,6 +1356,15 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
mpoly->totloop = 3;
mpoly->mat_nr = dl->col;
+ if (mloopuv) {
+ int i;
+
+ for (i = 0; i < 3; i++, mloopuv++) {
+ mloopuv->uv[0] = (mloop[i].v - startvert)/(float)(dl->nr - 1);
+ mloopuv->uv[1] = 0.0f;
+ }
+ }
+
if (smooth) mpoly->flag |= ME_SMOOTH;
mpoly++;
mloop += 3;
@@ -1408,13 +1414,29 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
mpoly->totloop = 4;
mpoly->mat_nr = dl->col;
- if (orco_index) {
- const int poly_index = mpoly - *allpoly;
- const int p_orco_base = startvert + ((dl->nr + 1) * a) + b;
- orco_index[poly_index][0] = p_orco_base + 1;
- orco_index[poly_index][1] = p_orco_base + dl->nr + 2;
- orco_index[poly_index][2] = p_orco_base + dl->nr + 1;
- orco_index[poly_index][3] = p_orco_base;
+ if (mloopuv) {
+ int orco_sizeu = dl->nr - 1;
+ int orco_sizev = dl->parts - 1;
+ int i;
+
+ /* exception as handled in convertblender.c too */
+ if (dl->flag & DL_CYCL_U) {
+ orco_sizeu++;
+ if (dl->flag & DL_CYCL_V)
+ orco_sizev++;
+ }
+
+ for (i = 0; i < 4; i++, mloopuv++) {
+ /* find uv based on vertex index into grid array */
+ int v = mloop[i].v - startvert;
+
+ mloopuv->uv[0] = (v / dl->nr)/(float)orco_sizev;
+ mloopuv->uv[1] = (v % dl->nr)/(float)orco_sizeu;
+
+ /* cyclic correction */
+ if ((i == 0 || i == 1) && mloopuv->uv[1] == 0.0f)
+ mloopuv->uv[1] = 1.0f;
+ }
}
if (smooth) mpoly->flag |= ME_SMOOTH;
@@ -1427,7 +1449,6 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
p1++;
}
}
-
}
dl = dl->next;
@@ -1448,33 +1469,8 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
}
-MINLINE void copy_uv_orco_v2_v2(float r[2], const float a[2])
-{
- r[0] = 0.5f + a[0] * 0.5f;
- r[1] = 0.5f + a[1] * 0.5f;
-}
-
-/**
- * orco is normally from #BKE_curve_make_orco
- */
-void BKE_mesh_nurbs_to_mdata_orco(MPoly *mpoly, int totpoly,
- MLoop *mloops, MLoopUV *mloopuvs,
- float (*orco)[3], int (*orco_index)[4])
-{
- MPoly *mp;
-
- int i, j;
- for (i = 0, mp = mpoly; i < totpoly; i++, mp++) {
- MLoop *ml = mloops + mp->loopstart;
- MLoopUV *mluv = mloopuvs + mp->loopstart;
- for (j = 0; j < mp->totloop; j++, ml++, mluv++) {
- copy_uv_orco_v2_v2(mluv->uv, orco[orco_index[i][j]]);
- }
- }
-}
-
/* this may fail replacing ob->data, be sure to check ob->type */
-void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_index_ptr)
+void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int use_orco_uv)
{
Main *bmain = G.main;
Object *ob1;
@@ -1484,6 +1480,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_ind
MVert *allvert = NULL;
MEdge *alledge = NULL;
MLoop *allloop = NULL;
+ MLoopUV *alluv = NULL;
MPoly *allpoly = NULL;
int totvert, totedge, totloop, totpoly;
@@ -1492,7 +1489,8 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_ind
if (dm == NULL) {
if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert,
&alledge, &totedge, &allloop,
- &allpoly, &totloop, &totpoly, orco_index_ptr) != 0)
+ &allpoly, (use_orco_uv)? &alluv: NULL,
+ &totloop, &totpoly) != 0)
{
/* Error initializing */
return;
@@ -1510,6 +1508,12 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_ind
me->mloop = CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, allloop, me->totloop);
me->mpoly = CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, allpoly, me->totpoly);
+ if (alluv) {
+ const char *uvname = "Orco";
+ me->mtpoly = CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, uvname);
+ me->mloopuv = CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_ASSIGN, alluv, me->totloop, uvname);
+ }
+
BKE_mesh_calc_normals(me->mvert, me->totvert, me->mloop, me->mpoly, me->totloop, me->totpoly, NULL);
BKE_mesh_calc_edges(me, TRUE);
@@ -1548,7 +1552,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_ind
void BKE_mesh_from_nurbs(Object *ob)
{
- BKE_mesh_from_nurbs_displist(ob, &ob->disp, NULL);
+ BKE_mesh_from_nurbs_displist(ob, &ob->disp, false);
}
typedef struct EdgeLink {
@@ -3337,3 +3341,39 @@ void BKE_mesh_poly_calc_angles(MVert *mvert, MLoop *mloop,
}
}
#endif
+
+
+void BKE_mesh_do_versions_cd_flag_init(Mesh *mesh)
+{
+ if (UNLIKELY(mesh->cd_flag)) {
+ return;
+ }
+ else {
+ MVert *mv;
+ MEdge *med;
+ int i;
+
+ for (mv = mesh->mvert, i = 0; i < mesh->totvert; mv++, i++) {
+ if (mv->bweight != 0) {
+ mesh->cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
+ break;
+ }
+ }
+
+ for (med = mesh->medge, i = 0; i < mesh->totedge; med++, i++) {
+ if (med->bweight != 0) {
+ mesh->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
+ if (mesh->cd_flag & ME_CDFLAG_EDGE_CREASE) {
+ break;
+ }
+ }
+ if (med->crease != 0) {
+ mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE;
+ if (mesh->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) {
+ break;
+ }
+ }
+ }
+
+ }
+}
diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c
index 7df7561a1a1..a6c2325c740 100644
--- a/source/blender/blenkernel/intern/modifiers_bmesh.c
+++ b/source/blender/blenkernel/intern/modifiers_bmesh.c
@@ -59,9 +59,14 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
BLI_array_declare(verts);
BLI_array_declare(edges);
int i, j, k, totvert, totedge /* , totface */ /* UNUSED */ ;
- int is_init = (bm->totvert == 0) && (bm->totedge == 0) && (bm->totface == 0);
+ bool is_init = (bm->totvert == 0) && (bm->totedge == 0) && (bm->totface == 0);
+ bool is_cddm = (dm->type == DM_TYPE_CDDM); /* duplicate the arrays for non cddm */
char has_orig_hflag = 0;
+ int cd_vert_bweight_offset;
+ int cd_edge_bweight_offset;
+ int cd_edge_crease_offset;
+
if (is_init == FALSE) {
/* check if we have an origflag */
has_orig_hflag |= CustomData_has_layer(&bm->vdata, CD_ORIGINDEX) ? BM_VERT : 0;
@@ -75,43 +80,45 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
CustomData_bmesh_merge(&dm->loopData, &bm->ldata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_LOOP);
CustomData_bmesh_merge(&dm->polyData, &bm->pdata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_FACE);
+ if (is_init) {
+ BM_mesh_cd_flag_apply(bm, dm->cd_flag);
+ }
+
+ cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
+
totvert = dm->getNumVerts(dm);
totedge = dm->getNumEdges(dm);
/* totface = dm->getNumPolys(dm); */ /* UNUSED */
- /* add crease layer */
- BM_data_layer_add(bm, &bm->edata, CD_CREASE);
- /* add bevel weight layers */
- BM_data_layer_add(bm, &bm->edata, CD_BWEIGHT);
- BM_data_layer_add(bm, &bm->vdata, CD_BWEIGHT);
-
vtable = MEM_callocN(sizeof(void **) * totvert, __func__);
etable = MEM_callocN(sizeof(void **) * totedge, __func__);
/*do verts*/
- mv = mvert = dm->dupVertArray(dm);
+ mv = mvert = is_cddm ? dm->getVertArray(dm) : dm->dupVertArray(dm);
for (i = 0; i < totvert; i++, mv++) {
v = BM_vert_create(bm, mv->co, NULL, BM_CREATE_SKIP_CD);
normal_short_to_float_v3(v->no, mv->no);
v->head.hflag = BM_vert_flag_from_mflag(mv->flag);
BM_elem_index_set(v, i); /* set_inline */
- CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v->head.data);
+ CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v->head.data, true);
vtable[i] = v;
/* add bevel weight */
- BM_elem_float_data_set(&bm->vdata, v, CD_BWEIGHT, (float)mv->bweight / 255.0f);
+ if (cd_vert_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(v, cd_vert_bweight_offset, (float)mv->bweight / 255.0f);
if (UNLIKELY(has_orig_hflag & BM_VERT)) {
int *orig_index = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_ORIGINDEX);
*orig_index = ORIGINDEX_NONE;
}
}
- MEM_freeN(mvert);
+ if (!is_cddm) MEM_freeN(mvert);
if (is_init) bm->elem_index_dirty &= ~BM_VERT;
/*do edges*/
- me = medge = dm->dupEdgeArray(dm);
+ me = medge = is_cddm ? dm->getEdgeArray(dm) : dm->dupEdgeArray(dm);
for (i = 0; i < totedge; i++, me++) {
//BLI_assert(BM_edge_exists(vtable[me->v1], vtable[me->v2]) == NULL);
e = BM_edge_create(bm, vtable[me->v1], vtable[me->v2], NULL, BM_CREATE_SKIP_CD);
@@ -119,20 +126,18 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
e->head.hflag = BM_edge_flag_from_mflag(me->flag);
BM_elem_index_set(e, i); /* set_inline */
- CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->head.data);
+ CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->head.data, true);
etable[i] = e;
- /* add crease */
- BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (float)me->crease / 255.0f);
- /* add bevel weight */
- BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (float)me->bweight / 255.0f);
+ if (cd_edge_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_bweight_offset, (float)me->bweight / 255.0f);
+ if (cd_edge_crease_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_crease_offset, (float)me->crease / 255.0f);
if (UNLIKELY(has_orig_hflag & BM_EDGE)) {
int *orig_index = CustomData_bmesh_get(&bm->edata, e->head.data, CD_ORIGINDEX);
*orig_index = ORIGINDEX_NONE;
}
}
- MEM_freeN(medge);
+ if (!is_cddm) MEM_freeN(medge);
if (is_init) bm->elem_index_dirty &= ~BM_EDGE;
/* do faces */
@@ -156,7 +161,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
edges[j] = etable[ml->e];
}
- f = BM_face_create_ngon(bm, verts[0], verts[1], edges, mp->totloop, BM_CREATE_SKIP_CD);
+ f = BM_face_create(bm, verts, edges, mp->totloop, BM_CREATE_SKIP_CD);
if (UNLIKELY(f == NULL)) {
continue;
@@ -169,10 +174,10 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f);
for (k = mp->loopstart; l; l = BM_iter_step(&liter), k++) {
- CustomData_to_bmesh_block(&dm->loopData, &bm->ldata, k, &l->head.data);
+ CustomData_to_bmesh_block(&dm->loopData, &bm->ldata, k, &l->head.data, true);
}
- CustomData_to_bmesh_block(&dm->polyData, &bm->pdata, i, &f->head.data);
+ CustomData_to_bmesh_block(&dm->polyData, &bm->pdata, i, &f->head.data, true);
if (face_normals) {
copy_v3_v3(f->no, face_normals[i]);
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 3b897e94241..5eac86a7e77 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -2396,6 +2396,7 @@ typedef struct SPHRangeData {
ParticleData *pa;
float h;
+ float mass;
float massfac;
int use_size;
} SPHRangeData;
@@ -2408,7 +2409,7 @@ static void sph_evaluate_func(BVHTree *tree, ParticleSystem **psys, float co[3],
for (i=0; i < 10 && psys[i]; i++) {
pfr->npsys = psys[i];
- pfr->massfac = psys[i]->part->mass;
+ pfr->massfac = psys[i]->part->mass / pfr->mass;
pfr->use_size = psys[i]->part->flag & PART_SIZEMASS;
if (tree) {
@@ -2491,7 +2492,6 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
ParticleSpring *spring = NULL;
SPHRangeData pfr;
SPHNeighbor *pfn;
- float mass = sphdata->mass;
float *gravity = sphdata->gravity;
EdgeHash *springhash = sphdata->eh;
@@ -2501,7 +2501,7 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
float visc = fluid->viscosity_omega;
float stiff_visc = fluid->viscosity_beta * (fluid->flag & SPH_FAC_VISCOSITY ? fluid->viscosity_omega : 1.f);
- float inv_mass = 1.0f/mass;
+ float inv_mass = 1.0f / sphdata->mass;
float spring_constant = fluid->spring_k;
/* 4.0 seems to be a pretty good value */
@@ -2526,6 +2526,7 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
pfr.data = data;
pfr.h = h;
pfr.pa = pa;
+ pfr.mass = sphdata->mass;
sph_evaluate_func( NULL, psys, state->co, &pfr, interaction_radius, sph_density_accum_cb);
@@ -2644,7 +2645,7 @@ static void sphclassical_density_accum_cb(void *userdata, int index, float UNUSE
* q1(x) = (2.0 - x)**4 * ( 1.0 + 2.0 * x)
* plot [0:2] q1(x) */
q = qfac / pow3(pfr->h) * pow4(2.0f - rij_h) * ( 1.0f + 2.0f * rij_h);
- q *= pfr->massfac;
+ q *= pfr->npsys->part->mass;
if (pfr->use_size)
q *= pfr->pa->size;
@@ -2696,7 +2697,8 @@ static void sphclassical_force_cb(void *sphdata_v, ParticleKey *state, float *fo
/* 4.77 is an experimentally determined density factor */
float rest_density = fluid->rest_density * (fluid->flag & SPH_FAC_DENSITY ? 4.77f : 1.0f);
- float stiffness = fluid->stiffness_k;
+ // Use speed of sound squared
+ float stiffness = pow2(fluid->stiffness_k);
ParticleData *npa;
float vec[3];
@@ -2792,6 +2794,7 @@ static void sphclassical_calc_dens(ParticleData *pa, float UNUSED(dfra), SPHData
pfr.data = data;
pfr.h = interaction_radius * sphdata->hfac;
pfr.pa = pa;
+ pfr.mass = sphdata->mass;
sph_evaluate_func( NULL, psys, pa->state.co, &pfr, interaction_radius, sphclassical_density_accum_cb);
pa->sphdensity = MIN2(MAX2(data[0], fluid->rest_density * 0.9f), fluid->rest_density * 1.1f);
@@ -2851,7 +2854,8 @@ void psys_sph_density(BVHTree *tree, SPHData *sphdata, float co[3], float vars[2
density[0] = density[1] = 0.0f;
pfr.data = density;
- pfr.h = interaction_radius*sphdata->hfac;
+ pfr.h = interaction_radius * sphdata->hfac;
+ pfr.mass = sphdata->mass;
sph_evaluate_func(tree, psys, co, &pfr, interaction_radius, sphdata->density_cb);
@@ -4220,7 +4224,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
ParticleSettings *part = sim->psys->part;
psys_sph_init(sim, &sphdata);
- if (part->fluid->flag & SPH_SOLVER_DDR) {
+ if (part->fluid->solver == SPH_SOLVER_DDR) {
/* Apply SPH forces using double-density relaxation algorithm
* (Clavat et. al.) */
#pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5)
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 9c3c1b0e508..97948683e22 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -272,7 +272,7 @@ static void ptcache_particle_read(int index, void *psys_v, void **data, float cf
ParticleSystem *psys= psys_v;
ParticleData *pa;
BoidParticle *boid;
- float timestep = 0.04f*psys->part->timetweak;
+ float timestep = 0.04f * psys->part->timetweak;
if (index >= psys->totpart)
return;
@@ -333,7 +333,7 @@ static void ptcache_particle_interpolate(int index, void *psys_v, void **data, f
ParticleSystem *psys= psys_v;
ParticleData *pa;
ParticleKey keys[4];
- float dfra, timestep = 0.04f*psys->part->timetweak;
+ float dfra, timestep = 0.04f * psys->part->timetweak;
if (index >= psys->totpart)
return;
@@ -559,7 +559,7 @@ static int ptcache_smoke_write(PTCacheFile *pf, void *smoke_v)
float dt, dx, *dens, *react, *fuel, *flame, *heat, *heatold, *vx, *vy, *vz, *r, *g, *b;
unsigned char *obstacles;
unsigned int in_len = sizeof(float)*(unsigned int)res;
- unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len)*4, "pointcache_lzo_buffer");
+ unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len) * 4, "pointcache_lzo_buffer");
//int mode = res >= 1000000 ? 2 : 1;
int mode=1; // light
if (sds->cache_comp == SM_CACHE_HEAVY) mode=2; // heavy
@@ -792,7 +792,7 @@ static int ptcache_dynamicpaint_write(PTCacheFile *pf, void *dp_v)
int cache_compress = 1;
/* version header */
- ptcache_file_write(pf, DPAINT_CACHE_VERSION, 1, sizeof(char)*4);
+ ptcache_file_write(pf, DPAINT_CACHE_VERSION, 1, sizeof(char) * 4);
if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ && surface->data) {
int total_points=surface->data->total_points;
@@ -831,7 +831,7 @@ static int ptcache_dynamicpaint_read(PTCacheFile *pf, void *dp_v)
char version[4];
/* version header */
- ptcache_file_read(pf, version, 1, sizeof(char)*4);
+ ptcache_file_read(pf, version, 1, sizeof(char) * 4);
if (strncmp(version, DPAINT_CACHE_VERSION, 4)) {printf("Dynamic Paint: Invalid cache version: %s!\n", version); return 0;}
if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ && surface->data) {
@@ -1163,7 +1163,7 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int dup
*/
#define MAX_PTCACHE_PATH FILE_MAX
-#define MAX_PTCACHE_FILE ((FILE_MAX)*2)
+#define MAX_PTCACHE_FILE (FILE_MAX * 2)
static int ptcache_path(PTCacheID *pid, char *filename)
{
@@ -1258,7 +1258,7 @@ static PTCacheFile *ptcache_file_open(PTCacheID *pid, int mode, int cfra)
{
PTCacheFile *pf;
FILE *fp = NULL;
- char filename[(FILE_MAX)*2];
+ char filename[FILE_MAX * 2];
#ifndef DURIAN_POINTCACHE_LIB_OK
/* don't allow writing for linked objects */
@@ -1311,7 +1311,7 @@ static int ptcache_file_compressed_read(PTCacheFile *pf, unsigned char *result,
size_t out_len = len;
#endif
unsigned char *in;
- unsigned char *props = MEM_callocN(16*sizeof(char), "tmp");
+ unsigned char *props = MEM_callocN(16 * sizeof(char), "tmp");
ptcache_file_read(pf, &compressed, 1, sizeof(unsigned char));
if (compressed) {
@@ -1354,7 +1354,7 @@ static int ptcache_file_compressed_write(PTCacheFile *pf, unsigned char *in, uns
int r = 0;
unsigned char compressed = 0;
size_t out_len= 0;
- unsigned char *props = MEM_callocN(16*sizeof(char), "tmp");
+ unsigned char *props = MEM_callocN(16 * sizeof(char), "tmp");
size_t sizeOfIt = 5;
(void)mode; /* unused when building w/o compression */
@@ -1787,7 +1787,7 @@ static int ptcache_mem_frame_to_disk(PTCacheID *pid, PTCacheMem *pm)
for (i=0; i<BPHYS_TOT_DATA; i++) {
if (pm->data[i]) {
unsigned int in_len = pm->totpoint*ptcache_data_size[i];
- unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len)*4, "pointcache_lzo_buffer");
+ unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len) * 4, "pointcache_lzo_buffer");
ptcache_file_compressed_write(pf, (unsigned char *)(pm->data[i]), in_len, out, pid->cache->compression);
MEM_freeN(out);
}
@@ -1820,7 +1820,7 @@ static int ptcache_mem_frame_to_disk(PTCacheID *pid, PTCacheMem *pm)
if (pid->cache->compression) {
unsigned int in_len = extra->totdata * ptcache_extra_datasize[extra->type];
- unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len)*4, "pointcache_lzo_buffer");
+ unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len) * 4, "pointcache_lzo_buffer");
ptcache_file_compressed_write(pf, (unsigned char *)(extra->data), in_len, out, pid->cache->compression);
MEM_freeN(out);
}
diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c
index 185aeac5452..1fd7dc14c23 100644
--- a/source/blender/blenkernel/intern/report.c
+++ b/source/blender/blenkernel/intern/report.c
@@ -27,6 +27,10 @@
* \ingroup bke
*/
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
#include "MEM_guardedalloc.h"
@@ -39,10 +43,6 @@
#include "BKE_report.h"
#include "BKE_global.h" /* G.background only */
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-
static const char *report_type_str(int type)
{
switch (type) {
@@ -302,3 +302,36 @@ int BKE_reports_contain(ReportList *reports, ReportType level)
return FALSE;
}
+bool BKE_report_write_file_fp(FILE *fp, ReportList *reports, const char *header)
+{
+ Report *report;
+
+ if (header) {
+ fputs(header, fp);
+ }
+
+ for (report = reports->list.first; report; report = report->next) {
+ fprintf((FILE *)fp, "%s # %s\n", report->message, report->typestr);
+ }
+
+ return true;
+}
+
+bool BKE_report_write_file(const char *filepath, ReportList *reports, const char *header)
+{
+ FILE *fp;
+
+ errno = 0;
+ fp = BLI_fopen(filepath, "wb");
+ if (fp == NULL) {
+ fprintf(stderr, "Unable to save '%s': %s\n",
+ filepath, errno ? strerror(errno) : "Unknown error opening file");
+ return false;
+ }
+
+ BKE_report_write_file_fp(fp, reports, header);
+
+ fclose(fp);
+
+ return true;
+}
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 04e612d1a33..eb56f34b99b 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -1045,6 +1045,47 @@ static void scene_update_drivers(Main *UNUSED(bmain), Scene *scene)
}
}
+/* deps hack - do extra recalcs at end */
+static void scene_depsgraph_hack(Scene *scene, Scene *scene_parent)
+{
+ Base *base;
+
+ scene->customdata_mask = scene_parent->customdata_mask;
+
+ /* sets first, we allow per definition current scene to have
+ * dependencies on sets, but not the other way around. */
+ if (scene->set)
+ scene_depsgraph_hack(scene->set, scene_parent);
+
+ for (base = scene->base.first; base; base = base->next) {
+ Object *ob = base->object;
+
+ if (ob->depsflag) {
+ int recalc = 0;
+ // printf("depshack %s\n", ob->id.name+2);
+
+ if (ob->depsflag & OB_DEPS_EXTRA_OB_RECALC)
+ recalc |= OB_RECALC_OB;
+ if (ob->depsflag & OB_DEPS_EXTRA_DATA_RECALC)
+ recalc |= OB_RECALC_DATA;
+
+ ob->recalc |= recalc;
+ BKE_object_handle_update(scene_parent, ob);
+
+ if (ob->dup_group && (ob->transflag & OB_DUPLIGROUP)) {
+ GroupObject *go;
+
+ for (go = ob->dup_group->gobject.first; go; go = go->next) {
+ if (go->ob)
+ go->ob->recalc |= recalc;
+ }
+ group_handle_recalc_and_update(scene_parent, ob, ob->dup_group);
+ }
+ }
+ }
+
+}
+
static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scene_parent)
{
Base *base;
@@ -1080,6 +1121,7 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen
/* update masking curves */
BKE_mask_update_scene(bmain, scene, FALSE);
+
}
/* this is called in main loop, doing tagged updates before redraw */
@@ -1172,6 +1214,8 @@ void BKE_scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
/* BKE_object_handle_update() on all objects, groups and sets */
scene_update_tagged_recursive(bmain, sce, sce);
+ scene_depsgraph_hack(sce, sce);
+
/* notify editors and python about recalc */
BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_SCENE_UPDATE_POST);
BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_FRAME_CHANGE_POST);
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 81bcdc4b06e..95b72d0185c 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -167,6 +167,7 @@ ARegion *BKE_area_region_copy(SpaceType *st, ARegion *ar)
newar->prev = newar->next = NULL;
newar->handlers.first = newar->handlers.last = NULL;
newar->uiblocks.first = newar->uiblocks.last = NULL;
+ newar->ui_lists.first = newar->ui_lists.last = NULL;
newar->swinid = 0;
/* use optional regiondata callback */
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index 3ca04f235b8..c64609c8e70 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -1150,7 +1150,7 @@ static void do_mul_effect_byte(float facf0, float facf1, int x, int y, unsigned
fac3 = (int)(256.0f * facf1);
/* formula:
- * fac * (a * b) + (1-fac)*a => fac * a * (b - 1) + axaux = c * px + py * s; //+centx
+ * fac * (a * b) + (1 - fac) * a => fac * a * (b - 1) + axaux = c * px + py * s; //+centx
* yaux = -s * px + c * py; //+centy
*/
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 8d010de408a..2c1fd092fbb 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -2391,7 +2391,7 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float
BKE_scene_update_for_newframe(context.bmain, scene, scene->lay);
ibuf = sequencer_view3d_cb(scene, camera, context.rectx, context.recty, IB_rect,
context.scene->r.seq_prev_type, context.scene->r.seq_flag & R_SEQ_SOLID_TEX,
- TRUE, FALSE, err_out);
+ TRUE, scene->r.alphamode, err_out);
if (ibuf == NULL) {
fprintf(stderr, "seq_render_scene_strip failed to get opengl buffer: %s\n", err_out);
}
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index b1917c6091d..01409a0f7e4 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -1322,8 +1322,8 @@ static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop)
for (index = 0; index < totface; index++) {
CCGFace *f = ccgdm->faceMap[index].face;
int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
- /* int flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH; */ /* UNUSED */
- /* int mat_nr = (faceFlags)? faceFlags[index*2+1]: 0; */ /* UNUSED */
+ /* int flag = (faceFlags) ? faceFlags[index * 2]: ME_SMOOTH; */ /* UNUSED */
+ /* int mat_nr = (faceFlags) ? faceFlags[index * 2 + 1]: 0; */ /* UNUSED */
for (S = 0; S < numVerts; S++) {
for (y = 0; y < gridSize - 1; y++) {
@@ -3328,7 +3328,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
/*I think this is for interpolating the center vert?*/
- w2 = w; // + numVerts*(g2_wid-1)*(g2_wid-1); //numVerts*((g2_wid-1)*g2_wid+g2_wid-1);
+ w2 = w; // + numVerts*(g2_wid-1) * (g2_wid-1); //numVerts*((g2_wid-1) * g2_wid+g2_wid-1);
DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2,
numVerts, vertNum);
if (vertOrigIndex) {
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index b322d9d7aef..448396811d3 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -53,6 +53,7 @@ float area_tri_signed_v2(const float v1[2], const float v2[2], const float v3[2]
float area_tri_v3(const float a[3], const float b[3], const float c[3]);
float area_quad_v3(const float a[3], const float b[3], const float c[3], const float d[3]);
float area_poly_v3(int nr, float verts[][3], const float normal[3]);
+float area_poly_v2(int nr, float verts[][2]);
int is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
int is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]);
@@ -260,7 +261,12 @@ MINLINE void madd_sh_shfl(float r[9], const float sh[3], const float f);
float form_factor_hemi_poly(float p[3], float n[3],
float v1[3], float v2[3], float v3[3], float v4[3]);
-void axis_dominant_v3(int *axis_a, int *axis_b, const float axis[3]);
+void axis_dominant_v3(int *r_axis_a, int *r_axis_b, const float axis[3]);
+float axis_dominant_v3_max(int *r_axis_a, int *r_axis_b, const float axis[3])
+#ifdef __GNUC__
+__attribute__((warn_unused_result))
+#endif
+;
MINLINE int max_axis_v3(const float vec[3]);
MINLINE int min_axis_v3(const float vec[3]);
diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h
index f2e26093711..3c9363039b2 100644
--- a/source/blender/blenlib/BLI_rect.h
+++ b/source/blender/blenlib/BLI_rect.h
@@ -56,6 +56,8 @@ void BLI_rctf_translate(struct rctf *rect, float x, float y);
void BLI_rcti_translate(struct rcti *rect, int x, int y);
void BLI_rcti_resize(struct rcti *rect, int x, int y);
void BLI_rctf_resize(struct rctf *rect, float x, float y);
+void BLI_rcti_scale(rcti *rect, const float scale);
+void BLI_rctf_scale(rctf *rect, const float scale);
void BLI_rctf_interp(struct rctf *rect, const struct rctf *rect_a, const struct rctf *rect_b, const float fac);
//void BLI_rcti_interp(struct rctf *rect, struct rctf *rect_a, struct rctf *rect_b, float fac);
int BLI_rctf_clamp_pt_v(const struct rctf *rect, float xy[2]);
diff --git a/source/blender/blenlib/BLI_scanfill.h b/source/blender/blenlib/BLI_scanfill.h
index 5204e0dd718..7830c0675b4 100644
--- a/source/blender/blenlib/BLI_scanfill.h
+++ b/source/blender/blenlib/BLI_scanfill.h
@@ -103,7 +103,7 @@ enum {
BLI_SCANFILL_CALC_REMOVE_DOUBLES = (1 << 1),
/* note: This flag removes checks for overlapping polygons.
- * when this flag is set, we'll never get back more faces then (totvert - 2)*/
+ * when this flag is set, we'll never get back more faces then (totvert - 2) */
BLI_SCANFILL_CALC_HOLES = (1 << 2)
};
diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h
index cb30138c4f9..43b1e7871cd 100644
--- a/source/blender/blenlib/BLI_utildefines.h
+++ b/source/blender/blenlib/BLI_utildefines.h
@@ -32,6 +32,10 @@
* \ingroup bli
*/
+#ifndef NDEBUG /* for BLI_assert */
+#include <stdio.h>
+#endif
+
/* note: use of (int, TRUE / FALSE) is deprecated,
* use (bool, true / false) instead */
#ifdef HAVE_STDBOOL_H
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 3527af365ec..fc1d0e99a30 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -131,35 +131,43 @@ float area_tri_v3(const float v1[3], const float v2[3], const float v3[3])
float area_poly_v3(int nr, float verts[][3], const float normal[3])
{
- float x, y, z, area, max;
- float *cur, *prev;
- int a, px = 0, py = 1;
-
- /* first: find dominant axis: 0==X, 1==Y, 2==Z
- * don't use 'axis_dominant_v3()' because we need max axis too */
- x = fabsf(normal[0]);
- y = fabsf(normal[1]);
- z = fabsf(normal[2]);
- max = max_fff(x, y, z);
- if (max == y) py = 2;
- else if (max == x) {
- px = 1;
- py = 2;
- }
+ int a, px, py;
+ const float max = axis_dominant_v3_max(&px, &py, normal);
+ float area;
+ float *co_curr, *co_prev;
/* The Trapezium Area Rule */
- prev = verts[nr - 1];
- cur = verts[0];
- area = 0;
+ co_prev = verts[nr - 1];
+ co_curr = verts[0];
+ area = 0.0f;
for (a = 0; a < nr; a++) {
- area += (cur[px] - prev[px]) * (cur[py] + prev[py]);
- prev = verts[a];
- cur = verts[a + 1];
+ area += (co_curr[px] - co_prev[px]) * (co_curr[py] + co_prev[py]);
+ co_prev = verts[a];
+ co_curr = verts[a + 1];
}
return fabsf(0.5f * area / max);
}
+float area_poly_v2(int nr, float verts[][2])
+{
+ int a;
+ float area;
+ float *co_curr, *co_prev;
+
+ /* The Trapezium Area Rule */
+ co_prev = verts[nr - 1];
+ co_curr = verts[0];
+ area = 0.0f;
+ for (a = 0; a < nr; a++) {
+ area += (co_curr[0] - co_prev[0]) * (co_curr[1] + co_prev[1]);
+ co_prev = verts[a];
+ co_curr = verts[a + 1];
+ }
+
+ return fabsf(0.5f * area);
+}
+
/********************************* Distance **********************************/
/* distance p to line v1-v2
@@ -329,7 +337,7 @@ void closest_on_tri_to_point_v3(float r[3], const float p[3],
return;
}
/* Check if P in edge region of AB, if so return projection of P onto AB */
- vc = d1*d4 - d3*d2;
+ vc = d1 * d4 - d3 * d2;
if (vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f) {
float v = d1 / (d1 - d3);
/* barycentric coordinates (1-v,v,0) */
@@ -346,7 +354,7 @@ void closest_on_tri_to_point_v3(float r[3], const float p[3],
return;
}
/* Check if P in edge region of AC, if so return projection of P onto AC */
- vb = d5*d2 - d1*d6;
+ vb = d5 * d2 - d1 * d6;
if (vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f) {
float w = d2 / (d2 - d6);
/* barycentric coordinates (1-w,0,w) */
@@ -354,7 +362,7 @@ void closest_on_tri_to_point_v3(float r[3], const float p[3],
return;
}
/* Check if P in edge region of BC, if so return projection of P onto BC */
- va = d3*d6 - d5*d4;
+ va = d3 * d6 - d5 * d4;
if (va <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f) {
float w = (d4 - d3) / ((d4 - d3) + (d5 - d6));
/* barycentric coordinates (0,1-w,w) */
@@ -1817,7 +1825,7 @@ static int point_in_slice_as(float p[3], float origin[3], float normal[3])
return 1;
}
-/*mama (knowing the squared length of the normal)*/
+/*mama (knowing the squared length of the normal) */
static int point_in_slice_m(float p[3], float origin[3], float normal[3], float lns)
{
float h, rp[3];
@@ -1952,15 +1960,27 @@ void plot_line_v2v2i(const int p1[2], const int p2[2], int (*callback)(int, int,
/****************************** Interpolation ********************************/
/* get the 2 dominant axis values, 0==X, 1==Y, 2==Z */
-void axis_dominant_v3(int *axis_a, int *axis_b, const float axis[3])
+void axis_dominant_v3(int *r_axis_a, int *r_axis_b, const float axis[3])
+{
+ const float xn = fabsf(axis[0]);
+ const float yn = fabsf(axis[1]);
+ const float zn = fabsf(axis[2]);
+
+ if (zn >= xn && zn >= yn) { *r_axis_a = 0; *r_axis_b = 1; }
+ else if (yn >= xn && yn >= zn) { *r_axis_a = 0; *r_axis_b = 2; }
+ else { *r_axis_a = 1; *r_axis_b = 2; }
+}
+
+/* same as axis_dominant_v3 but return the max value */
+float axis_dominant_v3_max(int *r_axis_a, int *r_axis_b, const float axis[3])
{
const float xn = fabsf(axis[0]);
const float yn = fabsf(axis[1]);
const float zn = fabsf(axis[2]);
- if (zn >= xn && zn >= yn) { *axis_a = 0; *axis_b = 1; }
- else if (yn >= xn && yn >= zn) { *axis_a = 0; *axis_b = 2; }
- else { *axis_a = 1; *axis_b = 2; }
+ if (zn >= xn && zn >= yn) { *r_axis_a = 0; *r_axis_b = 1; return zn; }
+ else if (yn >= xn && yn >= zn) { *r_axis_a = 0; *r_axis_b = 2; return yn; }
+ else { *r_axis_a = 1; *r_axis_b = 2; return xn; }
}
static float tri_signed_area(const float v1[3], const float v2[3], const float v3[3], const int i, const int j)
@@ -2334,14 +2354,25 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[
{
/* TODO: t1 and t2 overlap each iter, we could call this only once per iter and reuse previous value */
float totweight, t1, t2, len, *vmid, *vprev, *vnext;
- int i;
+ int i, i_next, i_curr;
+ bool edge_interp = false;
totweight = 0.0f;
for (i = 0; i < n; i++) {
+ i_curr = i;
+ i_next = (i == n - 1) ? 0 : i + 1;
+
vmid = v[i];
vprev = (i == 0) ? v[n - 1] : v[i - 1];
- vnext = (i == n - 1) ? v[0] : v[i + 1];
+ vnext = v[i_next];
+
+ /* Mark Mayer et al algorithm that is used here does not operate well if vertex is close
+ * to borders of face. In that case, do simple linear interpolation between the two edge vertices */
+ if (dist_to_line_segment_v3(co, vmid, vnext) < 10 * FLT_EPSILON) {
+ edge_interp = true;
+ break;
+ }
t1 = mean_value_half_tan_v3(co, vprev, vmid);
t2 = mean_value_half_tan_v3(co, vmid, vnext);
@@ -2351,25 +2382,49 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[
totweight += w[i];
}
- if (totweight != 0.0f) {
- for (i = 0; i < n; i++) {
- w[i] /= totweight;
+ if (edge_interp) {
+ float len_curr = len_v3v3(co, vmid);
+ float len_next = len_v3v3(co, vnext);
+ float edge_len = len_curr + len_next;
+ for (i = 0; i < n; i++)
+ w[i] = 0.0;
+
+ w[i_curr] = len_next / edge_len;
+ w[i_next] = len_curr / edge_len;
+ }
+ else {
+ if (totweight != 0.0f) {
+ for (i = 0; i < n; i++) {
+ w[i] /= totweight;
+ }
}
}
}
+
void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[2])
{
/* TODO: t1 and t2 overlap each iter, we could call this only once per iter and reuse previous value */
float totweight, t1, t2, len, *vmid, *vprev, *vnext;
- int i;
+ int i, i_next, i_curr;
+ bool edge_interp = false;
totweight = 0.0f;
for (i = 0; i < n; i++) {
+ i_curr = i;
+ i_next = (i == n - 1) ? 0 : i + 1;
+
vmid = v[i];
vprev = (i == 0) ? v[n - 1] : v[i - 1];
- vnext = (i == n - 1) ? v[0] : v[i + 1];
+ vnext = v[i_next];
+
+ /* Mark Mayer et al algorithm that is used here does not operate well if vertex is close
+ * to borders of face. In that case, do simple linear interpolation between the two edge vertices */
+ if (dist_to_line_segment_v2(co, vmid, vnext) < 10 * FLT_EPSILON) {
+ edge_interp = true;
+ break;
+ }
t1 = mean_value_half_tan_v2(co, vprev, vmid);
t2 = mean_value_half_tan_v2(co, vmid, vnext);
@@ -2379,9 +2434,21 @@ void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[
totweight += w[i];
}
- if (totweight != 0.0f) {
- for (i = 0; i < n; i++) {
- w[i] /= totweight;
+ if (edge_interp) {
+ float len_curr = len_v2v2(co, vmid);
+ float len_next = len_v2v2(co, vnext);
+ float edge_len = len_curr + len_next;
+ for (i = 0; i < n; i++)
+ w[i] = 0.0;
+
+ w[i_curr] = len_next / edge_len;
+ w[i_next] = len_curr / edge_len;
+ }
+ else {
+ if (totweight != 0.0f) {
+ for (i = 0; i < n; i++) {
+ w[i] /= totweight;
+ }
}
}
}
diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c
index fb767f54e55..4bd7715ea7a 100644
--- a/source/blender/blenlib/intern/rct.c
+++ b/source/blender/blenlib/intern/rct.c
@@ -317,6 +317,30 @@ void BLI_rctf_resize(rctf *rect, float x, float y)
rect->ymax = rect->ymin + y;
}
+void BLI_rcti_scale(rcti *rect, const float scale)
+{
+ const int cent_x = BLI_rcti_cent_x(rect);
+ const int cent_y = BLI_rcti_cent_y(rect);
+ const int size_x_half = BLI_rcti_size_x(rect) * (scale * 0.5f);
+ const int size_y_half = BLI_rcti_size_y(rect) * (scale * 0.5f);
+ rect->xmin = cent_x - size_x_half;
+ rect->ymin = cent_y - size_y_half;
+ rect->xmax = cent_x + size_x_half;
+ rect->ymax = cent_y + size_y_half;
+}
+
+void BLI_rctf_scale(rctf *rect, const float scale)
+{
+ const float cent_x = BLI_rctf_cent_x(rect);
+ const float cent_y = BLI_rctf_cent_y(rect);
+ const float size_x_half = BLI_rctf_size_x(rect) * (scale * 0.5f);
+ const float size_y_half = BLI_rctf_size_y(rect) * (scale * 0.5f);
+ rect->xmin = cent_x - size_x_half;
+ rect->ymin = cent_y - size_y_half;
+ rect->xmax = cent_x + size_x_half;
+ rect->ymax = cent_y + size_y_half;
+}
+
void BLI_rctf_interp(rctf *rect, const rctf *rect_a, const rctf *rect_b, const float fac)
{
const float ifac = 1.0f - fac;
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index f23f75f69d9..28fdf7b61db 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -412,7 +412,7 @@ int BLI_natstrcmp(const char *s1, const char *s2)
void BLI_timestr(double _time, char *str)
{
/* format 00:00:00.00 (hr:min:sec) string has to be 12 long */
- int hr = ( (int) _time) / (60*60);
+ int hr = ( (int) _time) / (60 * 60);
int min = (((int) _time) / 60 ) % 60;
int sec = ( (int) (_time)) % 60;
int hun = ( (int) (_time * 100.0)) % 100;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 151a929a445..df68f711843 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -5137,6 +5137,16 @@ static void direct_link_scene(FileData *fd, Scene *sce)
sce->toolsettings->imapaint.paintcursor = NULL;
sce->toolsettings->particle.paintcursor = NULL;
+
+ /* in rare cases this is needed, see [#33806] */
+ if (sce->toolsettings->vpaint) {
+ sce->toolsettings->vpaint->vpaint_prev = NULL;
+ sce->toolsettings->vpaint->tot = 0;
+ }
+ if (sce->toolsettings->wpaint) {
+ sce->toolsettings->wpaint->wpaint_prev = NULL;
+ sce->toolsettings->wpaint->tot = 0;
+ }
}
if (sce->ed) {
@@ -8811,6 +8821,49 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
+ if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 7)) {
+ Curve *cu;
+
+ for (cu = main->curve.first; cu; cu = cu->id.next) {
+ if (cu->flag & (CU_FRONT | CU_BACK)) {
+ if ( cu->ext1 != 0.0f || cu->ext2 != 0.0f) {
+ Nurb *nu;
+
+ for (nu = cu->nurb.first; nu; nu = nu->next) {
+ int a;
+
+ if (nu->bezt) {
+ BezTriple *bezt = nu->bezt;
+ a = nu->pntsu;
+
+ while (a--) {
+ bezt->radius = 1.0f;
+ bezt++;
+ }
+ }
+ else if (nu->bp) {
+ BPoint *bp = nu->bp;
+ a = nu->pntsu * nu->pntsv;
+
+ while (a--) {
+ bp->radius = 1.0f;
+ bp++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(main, 265, 8)) {
+ Mesh *me;
+ for (me = main->mesh.first; me; me = me->id.next) {
+ BKE_mesh_do_versions_cd_flag_init(me);
+ }
+ }
+
+ // if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 7)) {
#ifdef WITH_FREESTYLE
/* default values in Freestyle settings */
diff --git a/source/blender/blenloader/intern/runtime.c b/source/blender/blenloader/intern/runtime.c
index 5d8a865eea8..cbbaf713e84 100644
--- a/source/blender/blenloader/intern/runtime.c
+++ b/source/blender/blenloader/intern/runtime.c
@@ -48,11 +48,12 @@
#include "BLO_readfile.h"
#include "BLO_runtime.h"
+#include "BLI_blenlib.h"
+#include "BLI_utildefines.h"
+
#include "BKE_blender.h"
#include "BKE_report.h"
-#include "BLI_blenlib.h"
-
/* Runtime reading */
static int handle_read_msb_int(int handle)
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index b1aee9f498a..63d8c9b0e0e 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1423,8 +1423,8 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
int size = mmd->dyngridsize;
writestruct(wd, DATA, "MDefInfluence", mmd->totinfluence, mmd->bindinfluences);
- writedata(wd, DATA, sizeof(int)*(mmd->totvert+1), mmd->bindoffsets);
- writedata(wd, DATA, sizeof(float)*3*mmd->totcagevert,
+ writedata(wd, DATA, sizeof(int) * (mmd->totvert + 1), mmd->bindoffsets);
+ writedata(wd, DATA, sizeof(float) * 3 * mmd->totcagevert,
mmd->bindcagecos);
writestruct(wd, DATA, "MDefCell", size*size*size, mmd->dyngrid);
writestruct(wd, DATA, "MDefInfluence", mmd->totinfluence, mmd->dyninfluences);
@@ -1681,7 +1681,7 @@ static void write_mdisps(WriteData *wd, int count, MDisps *mdlist, int external)
MDisps *md = &mdlist[i];
if (md->disps) {
if (!external)
- writedata(wd, DATA, sizeof(float)*3*md->totdisp, md->disps);
+ writedata(wd, DATA, sizeof(float) * 3 * md->totdisp, md->disps);
}
if (md->hidden)
diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h
index 0961106f141..e838b130cef 100644
--- a/source/blender/bmesh/bmesh_class.h
+++ b/source/blender/bmesh/bmesh_class.h
@@ -184,10 +184,10 @@ typedef struct BMesh {
* BM_LOOP isn't handled so far. */
char elem_index_dirty;
- /*element pools*/
+ /* element pools */
struct BLI_mempool *vpool, *epool, *lpool, *fpool;
- /*operator api stuff (must be all NULL or all alloc'd)*/
+ /* operator api stuff (must be all NULL or all alloc'd) */
struct BLI_mempool *vtoolflagpool, *etoolflagpool, *ftoolflagpool;
int stackdepth;
@@ -205,7 +205,7 @@ typedef struct BMesh {
* Only use when the edit mesh cant be accessed - campbell */
short selectmode;
- /*ID of the shape key this bmesh came from*/
+ /* ID of the shape key this bmesh came from */
int shapenr;
int walkers, totflags;
@@ -257,6 +257,18 @@ enum {
/* defines */
+#define BM_ELEM_CD_GET_VOID_P(ele, offset) \
+ ((void)0, (void *)((char *)(ele)->head.data + (offset)))
+
+#define BM_ELEM_CD_SET_FLOAT(ele, offset, f) \
+ { *((float *)((char *)(ele)->head.data + (offset))) = (f); } (void)0
+
+#define BM_ELEM_CD_GET_FLOAT(ele, offset) \
+ ((void)0, *((float *)((char *)(ele)->head.data + (offset))))
+
+#define BM_ELEM_CD_GET_FLOAT_AS_UCHAR(ele, offset) \
+ (unsigned char)(BM_ELEM_CD_GET_FLOAT(ele, offset) * 255.0f)
+
/*forward declarations*/
#ifdef USE_BMESH_HOLES
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c
index 4ec91b8d8d7..1afaf851e2a 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -606,9 +606,9 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
void **vblocks = do_vertex ? BLI_array_alloca(vblocks, source->len) : NULL;
void **blocks = BLI_array_alloca(blocks, source->len);
float (*cos)[3] = BLI_array_alloca(cos, source->len);
+ float (*cos_2d)[2] = BLI_array_alloca(cos_2d, source->len);
float *w = BLI_array_alloca(w, source->len);
- float co[3];
- float cent[3] = {0.0f, 0.0f, 0.0f};
+ float co[2];
int i, ax, ay;
BM_elem_attrs_copy(bm, bm, source, target->f);
@@ -617,7 +617,6 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
l_iter = l_first = BM_FACE_FIRST_LOOP(source);
do {
copy_v3_v3(cos[i], l_iter->v->co);
- add_v3_v3(cent, cos[i]);
w[i] = 0.0f;
blocks[i] = l_iter->head.data;
@@ -634,28 +633,17 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
axis_dominant_v3(&ax, &ay, source->no);
- /* scale source face coordinates a bit, so points sitting directly on an
- * edge will work. */
- mul_v3_fl(cent, 1.0f / (float)source->len);
for (i = 0; i < source->len; i++) {
- float vec[3], tmp[3];
- sub_v3_v3v3(vec, cent, cos[i]);
- mul_v3_fl(vec, 0.001f);
- add_v3_v3(cos[i], vec);
-
- copy_v3_v3(tmp, cos[i]);
- cos[i][0] = tmp[ax];
- cos[i][1] = tmp[ay];
- cos[i][2] = 0.0f;
+ cos_2d[i][0] = cos[i][ax];
+ cos_2d[i][1] = cos[i][ay];
}
/* interpolate */
co[0] = target->v->co[ax];
co[1] = target->v->co[ay];
- co[2] = 0.0f;
- interp_weights_poly_v3(w, cos, source->len, co);
+ interp_weights_poly_v2(w, cos_2d, source->len, co);
CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, source->len, target->head.data);
if (do_vertex) {
CustomData_bmesh_interp(&bm->vdata, vblocks, w, NULL, source->len, target->v->head.data);
@@ -676,30 +664,18 @@ void BM_vert_interp_from_face(BMesh *bm, BMVert *v, BMFace *source)
void **blocks = BLI_array_alloca(blocks, source->len);
float (*cos)[3] = BLI_array_alloca(cos, source->len);
float *w = BLI_array_alloca(w, source->len);
- float cent[3] = {0.0f, 0.0f, 0.0f};
int i;
i = 0;
l_iter = l_first = BM_FACE_FIRST_LOOP(source);
do {
copy_v3_v3(cos[i], l_iter->v->co);
- add_v3_v3(cent, cos[i]);
w[i] = 0.0f;
blocks[i] = l_iter->v->head.data;
i++;
} while ((l_iter = l_iter->next) != l_first);
- /* scale source face coordinates a bit, so points sitting directly on an
- * edge will work. */
- mul_v3_fl(cent, 1.0f / (float)source->len);
- for (i = 0; i < source->len; i++) {
- float vec[3];
- sub_v3_v3v3(vec, cent, cos[i]);
- mul_v3_fl(vec, 0.01f);
- add_v3_v3(cos[i], vec);
- }
-
/* interpolate */
interp_weights_poly_v3(w, cos, source->len, v->co);
CustomData_bmesh_interp(&bm->vdata, blocks, w, NULL, source->len, v->head.data);
diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c
index b821c9875db..a2510129df6 100644
--- a/source/blender/bmesh/intern/bmesh_log.c
+++ b/source/blender/bmesh/intern/bmesh_log.c
@@ -523,14 +523,14 @@ void BM_log_mesh_elems_reorder(BMesh *bm, BMLog *log)
i = 0;
varr = MEM_mallocN(sizeof(int) * bm->totvert, AT);
BM_ITER_MESH (v, &bm_iter, bm, BM_VERTS_OF_MESH) {
- ((unsigned int*)varr)[i++] = bm_log_vert_id_get(log, v);
+ ((unsigned int *)varr)[i++] = bm_log_vert_id_get(log, v);
}
/* Put all face IDs into an array */
i = 0;
farr = MEM_mallocN(sizeof(int) * bm->totface, AT);
BM_ITER_MESH (f, &bm_iter, bm, BM_FACES_OF_MESH) {
- ((unsigned int*)farr)[i++] = bm_log_face_id_get(log, f);
+ ((unsigned int *)farr)[i++] = bm_log_face_id_get(log, f);
}
/* Create BMVert index remap array */
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c
index 388d148377a..8198e30bac6 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c
@@ -98,6 +98,70 @@
#include "bmesh.h"
#include "intern/bmesh_private.h" /* for element checking */
+void BM_mesh_cd_flag_ensure(BMesh *bm, Mesh *mesh, const char cd_flag)
+{
+ const char cd_flag_all = BM_mesh_cd_flag_from_bmesh(bm) | cd_flag;
+ BM_mesh_cd_flag_apply(bm, cd_flag_all);
+ if (mesh) {
+ mesh->cd_flag = cd_flag_all;
+ }
+}
+
+void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag)
+{
+ /* CustomData_bmesh_init_pool() must run first */
+ BLI_assert(bm->vdata.totlayer == 0 || bm->vdata.pool != NULL);
+ BLI_assert(bm->edata.totlayer == 0 || bm->edata.pool != NULL);
+
+ if (cd_flag & ME_CDFLAG_VERT_BWEIGHT) {
+ if (!CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
+ BM_data_layer_add(bm, &bm->vdata, CD_BWEIGHT);
+ }
+ }
+ else {
+ if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
+ BM_data_layer_free(bm, &bm->vdata, CD_BWEIGHT);
+ }
+ }
+
+ if (cd_flag & ME_CDFLAG_EDGE_BWEIGHT) {
+ if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
+ BM_data_layer_add(bm, &bm->edata, CD_BWEIGHT);
+ }
+ }
+ else {
+ if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
+ BM_data_layer_free(bm, &bm->edata, CD_BWEIGHT);
+ }
+ }
+
+ if (cd_flag & ME_CDFLAG_EDGE_CREASE) {
+ if (!CustomData_has_layer(&bm->edata, CD_CREASE)) {
+ BM_data_layer_add(bm, &bm->edata, CD_CREASE);
+ }
+ }
+ else {
+ if (CustomData_has_layer(&bm->edata, CD_CREASE)) {
+ BM_data_layer_free(bm, &bm->edata, CD_CREASE);
+ }
+ }
+}
+
+char BM_mesh_cd_flag_from_bmesh(BMesh *bm)
+{
+ char cd_flag = 0;
+ if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
+ cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
+ }
+ if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
+ cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
+ }
+ if (CustomData_has_layer(&bm->edata, CD_CREASE)) {
+ cd_flag |= ME_CDFLAG_EDGE_CREASE;
+ }
+ return cd_flag;
+}
+
/* Mesh -> BMesh */
void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
{
@@ -116,6 +180,10 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
int *keyi;
int totuv, i, j;
+ int cd_vert_bweight_offset;
+ int cd_edge_bweight_offset;
+ int cd_edge_crease_offset;
+
/* free custom data */
/* this isnt needed in most cases but do just incase */
CustomData_free(&bm->vdata, bm->totvert);
@@ -152,15 +220,6 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
CustomData_set_layer_name(&bm->ldata, CD_MLOOPUV, i, bm->pdata.layers[li].name);
}
- if (!CustomData_has_layer(&bm->edata, CD_CREASE))
- CustomData_add_layer(&bm->edata, CD_CREASE, CD_ASSIGN, NULL, 0);
-
- if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT))
- CustomData_add_layer(&bm->edata, CD_BWEIGHT, CD_ASSIGN, NULL, 0);
-
- if (!CustomData_has_layer(&bm->vdata, CD_BWEIGHT))
- CustomData_add_layer(&bm->vdata, CD_BWEIGHT, CD_ASSIGN, NULL, 0);
-
if ((act_key_nr != 0) && (me->key != NULL)) {
actkey = BLI_findlink(&me->key->block, act_key_nr - 1);
}
@@ -205,6 +264,12 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
CustomData_bmesh_init_pool(&bm->ldata, me->totloop, BM_LOOP);
CustomData_bmesh_init_pool(&bm->pdata, me->totpoly, BM_FACE);
+ BM_mesh_cd_flag_apply(bm, me->cd_flag);
+
+ cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
+
for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) {
v = BM_vert_create(bm, keyco && set_key ? keyco[i] : mvert->co, NULL, BM_CREATE_SKIP_CD);
BM_elem_index_set(v, i); /* set_ok */
@@ -221,9 +286,9 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
normal_short_to_float_v3(v->no, mvert->no);
/* Copy Custom Data */
- CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data);
+ CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data, true);
- BM_elem_float_data_set(&bm->vdata, v, CD_BWEIGHT, (float)mvert->bweight / 255.0f);
+ if (cd_vert_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(v, cd_vert_bweight_offset, (float)mvert->bweight / 255.0f);
/* set shapekey data */
if (me->key) {
@@ -267,10 +332,11 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
}
/* Copy Custom Data */
- CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data);
+ CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data, true);
+
+ if (cd_edge_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_bweight_offset, (float)medge->bweight / 255.0f);
+ if (cd_edge_crease_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_crease_offset, (float)medge->crease / 255.0f);
- BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (float)medge->crease / 255.0f);
- BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (float)medge->bweight / 255.0f);
}
bm->elem_index_dirty &= ~BM_EDGE; /* added in order, clear dirty flag */
@@ -338,11 +404,11 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
j = 0;
BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, j) {
/* Save index of correspsonding MLoop */
- CustomData_to_bmesh_block(&me->ldata, &bm->ldata, mpoly->loopstart + j, &l->head.data);
+ CustomData_to_bmesh_block(&me->ldata, &bm->ldata, mpoly->loopstart + j, &l->head.data, true);
}
/* Copy Custom Data */
- CustomData_to_bmesh_block(&me->pdata, &bm->pdata, i, &f->head.data);
+ CustomData_to_bmesh_block(&me->pdata, &bm->pdata, i, &f->head.data, true);
}
bm->elem_index_dirty &= ~BM_FACE; /* added in order, clear dirty flag */
@@ -496,6 +562,10 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess)
BMIter iter, liter;
int i, j, ototvert;
+ const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
+
ototvert = me->totvert;
/* new vertex block */
@@ -555,10 +625,6 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess)
i = 0;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- float *bweight = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_BWEIGHT);
-
- mvert->bweight = bweight ? (char)((*bweight) * 255) : 0;
-
copy_v3_v3(mvert->co, v->co);
normal_float_to_short_v3(mvert->no, v->no);
@@ -569,6 +635,8 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess)
/* copy over customdat */
CustomData_from_bmesh_block(&bm->vdata, &me->vdata, v->head.data, i);
+ if (cd_vert_bweight_offset != -1) mvert->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(v, cd_vert_bweight_offset);
+
i++;
mvert++;
@@ -579,13 +647,8 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess)
med = medge;
i = 0;
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- float *crease = CustomData_bmesh_get(&bm->edata, e->head.data, CD_CREASE);
- float *bweight = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BWEIGHT);
-
med->v1 = BM_elem_index_get(e->v1);
med->v2 = BM_elem_index_get(e->v2);
- med->crease = crease ? (char)((*crease) * 255) : 0;
- med->bweight = bweight ? (char)((*bweight) * 255) : 0;
med->flag = BM_edge_flag_to_mflag(e);
@@ -596,6 +659,9 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess)
bmesh_quick_edgedraw_flag(med, e);
+ if (cd_edge_crease_offset != -1) med->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_crease_offset);
+ if (cd_edge_bweight_offset != -1) med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_bweight_offset);
+
i++;
med++;
BM_CHECK_ELEMENT(e);
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.h b/source/blender/bmesh/intern/bmesh_mesh_conv.h
index f9c51584081..55ac39c6745 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.h
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.h
@@ -34,6 +34,10 @@
struct Mesh;
+void BM_mesh_cd_flag_ensure(BMesh *bm, struct Mesh *mesh, const char cd_flag);
+void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag);
+char BM_mesh_cd_flag_from_bmesh(BMesh *bm);
+
void BM_mesh_bm_from_me(BMesh *bm, struct Mesh *me, int set_key, int act_key_nr);
void BM_mesh_bm_to_me(BMesh *bm, struct Mesh *me, int dotess);
diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c
index 953e7f4d20c..4545c9bb564 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.c
+++ b/source/blender/bmesh/intern/bmesh_polygon.c
@@ -158,7 +158,6 @@ float BM_face_calc_area(BMFace *f)
BMLoop *l;
BMIter iter;
float (*verts)[3] = BLI_array_alloca(verts, f->len);
- float normal[3];
float area;
int i;
@@ -173,6 +172,7 @@ float BM_face_calc_area(BMFace *f)
area = area_quad_v3(verts[0], verts[1], verts[2], verts[3]);
}
else {
+ float normal[3];
calc_poly_normal(normal, verts, f->len);
area = area_poly_v3(f->len, verts, normal);
}
diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c
index bb013e6428e..538a9058ed5 100644
--- a/source/blender/bmesh/intern/bmesh_walkers_impl.c
+++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c
@@ -403,6 +403,11 @@ static void *bmw_IslandWalker_step(BMWalker *walker)
continue;
}
+ /* saves checking BLI_ghash_haskey below (manifold edges theres a 50% chance) */
+ if (f == iwalk->cur) {
+ continue;
+ }
+
if (BLI_ghash_haskey(walker->visithash, f)) {
continue;
}
diff --git a/source/blender/bmesh/operators/bmo_triangulate.c b/source/blender/bmesh/operators/bmo_triangulate.c
index d20d01af114..663ee463a2c 100644
--- a/source/blender/bmesh/operators/bmo_triangulate.c
+++ b/source/blender/bmesh/operators/bmo_triangulate.c
@@ -190,7 +190,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
/* sf_edge->tmp.p = e; */ /* UNUSED */
}
- BLI_scanfill_calc(&sf_ctx, 0);
+ BLI_scanfill_calc(&sf_ctx, BLI_SCANFILL_CALC_HOLES);
for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {
BMFace *f = BM_face_create_quad_tri(bm,
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 759246c38e0..a593e40d850 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -1499,7 +1499,7 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
{
BMEdge *bme;
BevVert *bv;
- BMEdge *bme2, *unflagged_bme;
+ BMEdge *bme2, *unflagged_bme, *first_bme;
BMFace *f;
BMIter iter, iter2;
EdgeHalf *e;
@@ -1511,10 +1511,16 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
* Only bevel selected edges that have exactly two incident faces.
*/
+ if (bp->vertex_only)
+ first_bme = v->e;
+ else
+ first_bme = NULL;
BM_ITER_ELEM (bme, &iter, v, BM_EDGES_OF_VERT) {
if (BM_elem_flag_test(bme, BM_ELEM_TAG) && !bp->vertex_only) {
BLI_assert(BM_edge_is_manifold(bme));
nsel++;
+ if (!first_bme)
+ first_bme = bme;
}
ntot++;
@@ -1543,7 +1549,8 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
/* add edges to bv->edges in order that keeps adjacent edges sharing
* a face, if possible */
i = 0;
- bme = v->e;
+
+ bme = first_bme;
BM_BEVEL_EDGE_TAG_ENABLE(bme);
e = &bv->edges[0];
e->e = bme;
@@ -1557,6 +1564,8 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
continue;
if (!unflagged_bme)
unflagged_bme = bme2;
+ if (!bme->l)
+ continue;
BM_ITER_ELEM (f, &iter2, bme2, BM_FACES_OF_EDGE) {
if (BM_face_edge_share_loop(f, bme)) {
found_shared_face = 1;
@@ -1591,7 +1600,7 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
}
/* find wrap-around shared face */
BM_ITER_ELEM (f, &iter2, bme, BM_FACES_OF_EDGE) {
- if (BM_face_edge_share_loop(f, bv->edges[0].e)) {
+ if (bv->edges[0].e->l && BM_face_edge_share_loop(f, bv->edges[0].e)) {
if (bv->edges[0].fnext == f)
continue; /* if two shared faces, want the other one now */
bv->edges[ntot - 1].fnext = f;
diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
index 7c054d84405..794afb3e0d2 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
@@ -172,7 +172,7 @@ static int bm_edge_collapse_is_degenerate_flip(BMEdge *e, const float optimize_c
#endif
/* use a small value rather then zero so we don't flip a face in multiple steps
- * (first making it zero area, then flipping again)*/
+ * (first making it zero area, then flipping again) */
if (dot_v3v3(cross_exist, cross_optim) <= FLT_EPSILON) {
//printf("no flip\n");
return TRUE;
@@ -441,6 +441,8 @@ static void bm_decim_triangulate_end(BMesh *bm)
static void bm_edge_collapse_loop_customdata(BMesh *bm, BMLoop *l, BMVert *v_clear, BMVert *v_other,
const float customdata_fac)
{
+ /* disable seam check - the seam check would have to be done per layer, its not really that important */
+//#define USE_SEAM
/* these don't need to be updated, since they will get removed when the edge collapses */
BMLoop *l_clear, *l_other;
const int is_manifold = BM_edge_is_manifold(l->e);
@@ -464,7 +466,9 @@ static void bm_edge_collapse_loop_customdata(BMesh *bm, BMLoop *l, BMVert *v_cle
/* now we have both corners of the face 'l->f' */
for (side = 0; side < 2; side++) {
+#ifdef USE_SEAM
int is_seam = FALSE;
+#endif
void *src[2];
BMFace *f_exit = is_manifold ? l->radial_next->f : NULL;
BMEdge *e_prev = l->e;
@@ -501,34 +505,40 @@ static void bm_edge_collapse_loop_customdata(BMesh *bm, BMLoop *l, BMVert *v_cle
break;
}
+#ifdef USE_SEAM
/* break out unless we find a match */
is_seam = TRUE;
+#endif
/* ok. we have a loop. now be smart with it! */
for (i = 0; i < bm->ldata.totlayer; i++) {
if (CustomData_layer_has_math(&bm->ldata, i)) {
const int offset = bm->ldata.layers[i].offset;
const int type = bm->ldata.layers[i].type;
- void *cd_src, *cd_iter;
-
- /* todo, make nicer macros for this */
- cd_src = (char *)src[0] + offset;
- // cd_dst = (char *)src[1] + offset; // UNUSED
- cd_iter = (char *)l_iter->head.data + offset;
+ void *cd_src[2] = {(char *)src[0] + offset,
+ (char *)src[1] + offset};
+ void *cd_iter = (char *)l_iter->head.data + offset;;
/* detect seams */
- if (CustomData_data_equals(type, cd_src, cd_iter)) {
- CustomData_bmesh_interp(&bm->ldata, src, w, NULL, 2, l_iter->head.data);
+ if (CustomData_data_equals(type, cd_src[0], cd_iter)) {
+ CustomData_bmesh_interp_n(&bm->ldata, cd_src, w, NULL, 2, l_iter->head.data, i);
+#ifdef USE_SEAM
is_seam = FALSE;
+#endif
}
}
}
+#ifdef USE_SEAM
if (is_seam) {
break;
}
+#endif
}
}
+
+//#undef USE_SEAM
+
}
#endif /* USE_CUSTOMDATA */
diff --git a/source/blender/compositor/intern/COM_Node.h b/source/blender/compositor/intern/COM_Node.h
index c098d6da32b..5b0381f6443 100644
--- a/source/blender/compositor/intern/COM_Node.h
+++ b/source/blender/compositor/intern/COM_Node.h
@@ -58,7 +58,7 @@ private:
* @brief The group node this node belongs to.
* @note: used to find the links in the current subtree for muting nodes
*/
- bNode* m_bNodeGroup;
+ bNode *m_bNodeGroup;
public:
Node(bNode *editorNode, bool create_sockets = true);
@@ -145,8 +145,8 @@ public:
*/
OutputSocket *findOutputSocketBybNodeSocket(bNodeSocket *socket);
- inline void setbNodeGroup(bNode* group) {this->m_bNodeGroup = group;}
- inline bNode* getbNodeGroup() {return this->m_bNodeGroup;}
+ inline void setbNodeGroup(bNode *group) {this->m_bNodeGroup = group;}
+ inline bNode *getbNodeGroup() {return this->m_bNodeGroup;}
protected:
void addPreviewOperation(ExecutionSystem *system, CompositorContext *context, InputSocket *inputSocket);
void addPreviewOperation(ExecutionSystem *system, CompositorContext *context, OutputSocket *outputSocket);
diff --git a/source/blender/compositor/nodes/COM_ImageNode.cpp b/source/blender/compositor/nodes/COM_ImageNode.cpp
index 4293e344c65..864d6f08311 100644
--- a/source/blender/compositor/nodes/COM_ImageNode.cpp
+++ b/source/blender/compositor/nodes/COM_ImageNode.cpp
@@ -28,6 +28,10 @@
#include "BKE_node.h"
#include "BLI_utildefines.h"
+#include "COM_SetValueOperation.h"
+#include "COM_SetVectorOperation.h"
+#include "COM_SetColorOperation.h"
+
ImageNode::ImageNode(bNode *editorNode) : Node(editorNode)
{
/* pass */
@@ -165,6 +169,46 @@ void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c
graph->addOperation(depthOperation);
}
}
+ if (numberOfOutputs > 3) {
+ /* happens when unlinking image datablock from multilayer node */
+ for (int i = 3; i < numberOfOutputs; i++) {
+ OutputSocket *output = this->getOutputSocket(i);
+ NodeOperation *operation = NULL;
+ switch (output->getDataType()) {
+ case COM_DT_VALUE:
+ {
+ SetValueOperation *valueoperation = new SetValueOperation();
+ valueoperation->setValue(0.0f);
+ operation = valueoperation;
+ break;
+ }
+ case COM_DT_VECTOR:
+ {
+ SetVectorOperation *vectoroperation = new SetVectorOperation();
+ vectoroperation->setX(0.0f);
+ vectoroperation->setY(0.0f);
+ vectoroperation->setW(0.0f);
+ operation = vectoroperation;
+ break;
+ }
+ case COM_DT_COLOR:
+ {
+ SetColorOperation *coloroperation = new SetColorOperation();
+ coloroperation->setChannel1(0.0f);
+ coloroperation->setChannel2(0.0f);
+ coloroperation->setChannel3(0.0f);
+ coloroperation->setChannel4(0.0f);
+ operation = coloroperation;
+ break;
+ }
+ }
+
+ if (operation) {
+ output->relinkConnections(operation->getOutputSocket());
+ graph->addOperation(operation);
+ }
+ }
+ }
}
}
diff --git a/source/blender/compositor/nodes/COM_PixelateNode.cpp b/source/blender/compositor/nodes/COM_PixelateNode.cpp
index f1c7c616a30..b751c9a6e9f 100644
--- a/source/blender/compositor/nodes/COM_PixelateNode.cpp
+++ b/source/blender/compositor/nodes/COM_PixelateNode.cpp
@@ -36,8 +36,8 @@ void PixelateNode::convertToOperations(ExecutionSystem *graph, CompositorContext
OutputSocket *outputSocket = this->getOutputSocket(0);
DataType datatype = inputSocket->getDataType();
if (inputSocket->isConnected()) {
- SocketConnection * connection = inputSocket->getConnection();
- OutputSocket* otherOutputSocket = connection->getFromSocket();
+ SocketConnection *connection = inputSocket->getConnection();
+ OutputSocket *otherOutputSocket = connection->getFromSocket();
datatype = otherOutputSocket->getDataType();
}
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index 19a97fa0810..a7e84d590b5 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -1769,7 +1769,7 @@ static void harmonic_coordinates_bind(Scene *UNUSED(scene), MeshDeformModifierDa
mdb->totalphi = MEM_callocN(sizeof(float) * mdb->size3, "MeshDeformBindTotalPhi");
mdb->boundisect = MEM_callocN(sizeof(*mdb->boundisect) * mdb->size3, "MDefBoundIsect");
mdb->semibound = MEM_callocN(sizeof(int) * mdb->size3, "MDefSemiBound");
- mdb->bvhtree = bvhtree_from_mesh_faces(&mdb->bvhdata, mdb->cagedm, FLT_EPSILON*100, 4, 6);
+ mdb->bvhtree = bvhtree_from_mesh_faces(&mdb->bvhdata, mdb->cagedm, FLT_EPSILON * 100, 4, 6);
mdb->inside = MEM_callocN(sizeof(int) * mdb->totvert, "MDefInside");
if (mmd->flag & MOD_MDEF_DYNAMIC_BIND)
diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h
index 577113927d1..31f89063f05 100644
--- a/source/blender/editors/include/BIF_glutil.h
+++ b/source/blender/editors/include/BIF_glutil.h
@@ -51,10 +51,10 @@ void fdrawcheckerboard(float x1, float y1, float x2, float y2);
/* OpenGL stipple defines */
/* OpenGL stipple defines */
-extern unsigned char stipple_halftone[128];
-extern unsigned char stipple_quarttone[128];
-extern unsigned char stipple_diag_stripes_pos[128];
-extern unsigned char stipple_diag_stripes_neg[128];
+extern const unsigned char stipple_halftone[128];
+extern const unsigned char stipple_quarttone[128];
+extern const unsigned char stipple_diag_stripes_pos[128];
+extern const unsigned char stipple_diag_stripes_neg[128];
/**
* Draw a lined (non-looping) arc with the given
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 3d13938c204..ac2c47216a6 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -270,13 +270,13 @@ int ED_view3d_scene_layer_set(int lay, const int *values, int *active);
int ED_view3d_context_activate(struct bContext *C);
void ED_view3d_draw_offscreen_init(struct Scene *scene, struct View3D *v3d);
void ED_view3d_draw_offscreen(struct Scene *scene, struct View3D *v3d, struct ARegion *ar,
- int winx, int winy, float viewmat[4][4], float winmat[4][4], int do_bgpic, int colormanage_background);
+ int winx, int winy, float viewmat[4][4], float winmat[4][4], int do_bgpic);
struct ImBuf *ED_view3d_draw_offscreen_imbuf(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey, unsigned int flag,
- int draw_background, int colormanage_background, char err_out[256]);
+ int draw_background, int alpha_mode, char err_out[256]);
struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple(struct Scene *scene, struct Object *camera, int width, int height, unsigned int flag, int drawtype,
- int use_solid_tex, int draw_background, int colormanage_background, char err_out[256]);
-
+ int use_solid_tex, int draw_background, int alpha_mode, char err_out[256]);
+void ED_view3d_offscreen_sky_color_get(struct Scene *scene, float sky_color[3]);
struct Base *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]);
void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar, short do_clip);
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 080367c4325..292cc4cdca0 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -42,6 +42,7 @@ struct ID;
struct Main;
struct ListBase;
struct ARegion;
+struct ARegionType;
struct ScrArea;
struct wmWindow;
struct wmWindowManager;
@@ -253,7 +254,8 @@ typedef enum {
HISTOGRAM = (48 << 9),
WAVEFORM = (49 << 9),
VECTORSCOPE = (50 << 9),
- PROGRESSBAR = (51 << 9)
+ PROGRESSBAR = (51 << 9),
+ SEARCH_MENU_UNLINK = (52 << 9)
} eButType;
#define BUTTYPE (63 << 9)
diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h
index 1035f5815f2..29b1a74e859 100644
--- a/source/blender/editors/include/UI_resources.h
+++ b/source/blender/editors/include/UI_resources.h
@@ -228,7 +228,11 @@ enum {
TH_AXIS_X, /* X/Y/Z Axis */
TH_AXIS_Y,
- TH_AXIS_Z
+ TH_AXIS_Z,
+
+ TH_LOW_GRAD,
+ TH_HIGH_GRAD,
+ TH_SHOW_BACK_GRAD
};
/* XXX WARNING: previous is saved in file, so do not change order! */
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 1d26cbd344b..1dee497ff11 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1605,7 +1605,7 @@ void ui_set_but_val(uiBut *but, double value)
int ui_get_but_string_max_length(uiBut *but)
{
- if (ELEM(but->type, TEX, SEARCH_MENU))
+ if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK))
return but->hardmax;
else if (but->type == IDPOIN)
return MAX_ID_NAME - 2;
@@ -1688,7 +1688,7 @@ static float ui_get_but_step_unit(uiBut *but, float step_default)
void ui_get_but_string(uiBut *but, char *str, size_t maxlen)
{
- if (but->rnaprop && ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
+ if (but->rnaprop && ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
PropertyType type;
const char *buf = NULL;
int buf_len;
@@ -1742,7 +1742,7 @@ void ui_get_but_string(uiBut *but, char *str, size_t maxlen)
BLI_strncpy(str, but->poin, maxlen);
return;
}
- else if (but->type == SEARCH_MENU) {
+ else if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
/* string */
BLI_strncpy(str, but->poin, maxlen);
return;
@@ -1833,7 +1833,7 @@ int ui_set_but_string_eval_num(bContext *C, uiBut *but, const char *str, double
int ui_set_but_string(bContext *C, uiBut *but, const char *str)
{
- if (but->rnaprop && ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
+ if (but->rnaprop && ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
if (RNA_property_editable(&but->rnapoin, but->rnaprop)) {
PropertyType type;
@@ -1890,7 +1890,7 @@ int ui_set_but_string(bContext *C, uiBut *but, const char *str)
return 1;
}
- else if (but->type == SEARCH_MENU) {
+ else if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
/* string */
BLI_strncpy(but->poin, str, but->hardmax);
return 1;
@@ -2360,6 +2360,7 @@ void ui_check_but(uiBut *but)
case IDPOIN:
case TEX:
case SEARCH_MENU:
+ case SEARCH_MENU_UNLINK:
if (!but->editstr) {
char str[UI_MAX_DRAW_STR];
@@ -2741,7 +2742,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
}
if ((block->flag & UI_BLOCK_LOOP) ||
- ELEM8(but->type, MENU, TEX, LABEL, IDPOIN, BLOCK, BUTM, SEARCH_MENU, PROGRESSBAR))
+ ELEM9(but->type, MENU, TEX, LABEL, IDPOIN, BLOCK, BUTM, SEARCH_MENU, PROGRESSBAR, SEARCH_MENU_UNLINK))
{
but->flag |= (UI_TEXT_LEFT | UI_ICON_LEFT);
}
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 1c9cd92271c..c87bb2a97a1 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -238,6 +238,7 @@ void ui_pan_to_scroll(wmEvent *event, int *type, int *val)
*type = WHEELUPMOUSE;
else
*type = WHEELDOWNMOUSE;
+
lastdy = 0;
}
}
@@ -1061,6 +1062,7 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
ui_apply_but_BUT(C, but, data);
break;
case TEX:
+ case SEARCH_MENU_UNLINK:
case SEARCH_MENU:
ui_apply_but_TEX(C, but, data);
break;
@@ -1168,7 +1170,7 @@ static void ui_but_drop(bContext *C, wmEvent *event, uiBut *but, uiHandleButtonD
for (wmd = drags->first; wmd; wmd = wmd->next) {
if (wmd->type == WM_DRAG_ID) {
/* align these types with UI_but_active_drop_name */
- if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
+ if (ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
ID *id = (ID *)wmd->poin;
if (but->poin == NULL && but->rnapoin.data == NULL) {}
@@ -1269,7 +1271,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
}
/* text/string and ID data */
- else if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
+ else if (ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
uiHandleButtonData *active_data = but->active;
if (but->poin == NULL && but->rnapoin.data == NULL) {
@@ -1288,7 +1290,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
if (ui_is_but_utf8(but)) BLI_strncpy_utf8(active_data->str, buf, active_data->maxlen);
else BLI_strncpy(active_data->str, buf, active_data->maxlen);
- if (but->type == SEARCH_MENU) {
+ if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
/* else uiSearchboxData.active member is not updated [#26856] */
ui_searchbox_update(C, data->searchbox, but, 1);
}
@@ -1435,7 +1437,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, sho
/* XXX solve generic */
if (but->type == NUM || but->type == NUMSLI)
startx += (int)(0.5f * (BLI_rctf_size_y(&but->rect)));
- else if (ELEM(but->type, TEX, SEARCH_MENU)) {
+ else if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
startx += 5;
if (but->flag & UI_HAS_ICON)
startx += UI_DPI_ICON_SIZE;
@@ -1815,7 +1817,7 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
but->selend = len;
/* optional searchbox */
- if (but->type == SEARCH_MENU) {
+ if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
data->searchbox = ui_searchbox_create(C, data->region, but);
ui_searchbox_update(C, data->searchbox, but, 1); /* 1 = reset */
}
@@ -1861,7 +1863,7 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
return;
for (but = actbut->next; but; but = but->next) {
- if (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
+ if (ELEM8(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
if (!(but->flag & UI_BUT_DISABLED)) {
data->postbut = but;
data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
@@ -1870,7 +1872,7 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
}
}
for (but = block->buttons.first; but != actbut; but = but->next) {
- if (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
+ if (ELEM8(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
if (!(but->flag & UI_BUT_DISABLED)) {
data->postbut = but;
data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
@@ -1889,7 +1891,7 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
return;
for (but = actbut->prev; but; but = but->prev) {
- if (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
+ if (ELEM8(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
if (!(but->flag & UI_BUT_DISABLED)) {
data->postbut = but;
data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
@@ -1898,7 +1900,7 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
}
}
for (but = block->buttons.last; but != actbut; but = but->prev) {
- if (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
+ if (ELEM8(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
if (!(but->flag & UI_BUT_DISABLED)) {
data->postbut = but;
data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
@@ -2429,6 +2431,34 @@ static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
return WM_UI_HANDLER_CONTINUE;
}
+static int ui_do_but_SEARCH_UNLINK(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+{
+ /* unlink icon is on right */
+ if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN) && event->val == KM_PRESS) {
+ ARegion *ar = CTX_wm_region(C);
+ rcti rect;
+ int x = event->x, y = event->y;
+
+ ui_window_to_block(ar, but->block, &x, &y);
+
+ BLI_rcti_rctf_copy(&rect, &but->rect);
+
+ rect.xmin = rect.xmax - (BLI_rcti_size_y(&rect));
+ if ( BLI_rcti_isect_pt(&rect, x, y) ) {
+ /* most likely NULL, but let's check, and give it temp zero string */
+ if (data->str == NULL)
+ data->str = MEM_callocN(16, "temp str");
+ data->str[0] = 0;
+
+ ui_apply_but_TEX(C, but, data);
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ return ui_do_but_TEX(C, block, but, data, event);
+}
+
static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
{
if (data->state == BUTTON_STATE_HIGHLIGHT) {
@@ -2717,7 +2747,9 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
ui_pan_to_scroll(event, &type, &val);
/* XXX hardcoded keymap check.... */
- if (type == WHEELDOWNMOUSE && event->alt) {
+ if (type == MOUSEPAN && event->alt)
+ retval = WM_UI_HANDLER_BREAK; /* allow accumulating values, otherwise scrolling gets preference */
+ else if (type == WHEELDOWNMOUSE && event->alt) {
mx = but->rect.xmin;
click = 1;
}
@@ -2945,7 +2977,9 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
ui_pan_to_scroll(event, &type, &val);
/* XXX hardcoded keymap check.... */
- if (type == WHEELDOWNMOUSE && event->alt) {
+ if (type == MOUSEPAN && event->alt)
+ retval = WM_UI_HANDLER_BREAK; /* allow accumulating values, otherwise scrolling gets preference */
+ else if (type == WHEELDOWNMOUSE && event->alt) {
mx = but->rect.xmin;
click = 2;
}
@@ -5133,6 +5167,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
case SEARCH_MENU:
retval = ui_do_but_TEX(C, block, but, data, event);
break;
+ case SEARCH_MENU_UNLINK:
+ retval = ui_do_but_SEARCH_UNLINK(C, block, but, data, event);
+ break;
case MENU:
case ICONROW:
case ICONTEXTROW:
@@ -5246,7 +5283,7 @@ int UI_but_active_drop_name(bContext *C)
uiBut *but = ui_but_find_activated(ar);
if (but) {
- if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU))
+ if (ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK))
return 1;
}
@@ -5572,7 +5609,7 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
copy_v2_fl(data->ungrab_mval, FLT_MAX);
#endif
- if (ELEM(but->type, BUT_CURVE, SEARCH_MENU)) {
+ if (ELEM3(but->type, BUT_CURVE, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
/* XXX curve is temp */
}
else {
@@ -6010,19 +6047,18 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
retval = WM_UI_HANDLER_CONTINUE;
break;
- case WHEELUPMOUSE:
- case WHEELDOWNMOUSE:
- case MIDDLEMOUSE:
- /* XXX hardcoded keymap check... but anyway, while view changes, tooltips should be removed */
- if (data->tooltiptimer) {
- WM_event_remove_timer(data->wm, data->window, data->tooltiptimer);
- data->tooltiptimer = NULL;
- }
- /* pass on purposedly */
- default:
- /* handle button type specific events */
- retval = ui_do_button(C, block, but, event);
}
+ /* XXX hardcoded keymap check... but anyway, while view changes, tooltips should be removed */
+ case WHEELUPMOUSE:
+ case WHEELDOWNMOUSE:
+ case MIDDLEMOUSE:
+ case MOUSEPAN:
+ button_timers_tooltip_remove(C, but);
+
+ /* pass on purposedly */
+ default:
+ /* handle button type specific events */
+ retval = ui_do_button(C, block, but, event);
}
}
else if (data->state == BUTTON_STATE_WAIT_RELEASE) {
@@ -6383,7 +6419,7 @@ static int ui_menu_scroll(ARegion *ar, uiBlock *block, int my, uiBut *to_bt)
for (bt = block->buttons.first; bt; bt = bt->next)
ymax = max_ff(ymax, bt->rect.ymax);
- if (ymax + dy - UI_UNIT_Y*0.5f < block->rect.ymax - UI_MENU_SCROLL_PAD)
+ if (ymax + dy - UI_UNIT_Y * 0.5f < block->rect.ymax - UI_MENU_SCROLL_PAD)
dy = block->rect.ymax - ymax - UI_MENU_SCROLL_PAD;
}
else {
@@ -6393,7 +6429,7 @@ static int ui_menu_scroll(ARegion *ar, uiBlock *block, int my, uiBut *to_bt)
for (bt = block->buttons.first; bt; bt = bt->next)
ymin = min_ff(ymin, bt->rect.ymin);
- if (ymin + dy + UI_UNIT_Y*0.5f > block->rect.ymin + UI_MENU_SCROLL_PAD)
+ if (ymin + dy + UI_UNIT_Y * 0.5f > block->rect.ymin + UI_MENU_SCROLL_PAD)
dy = block->rect.ymin - ymin + UI_MENU_SCROLL_PAD;
}
@@ -6436,7 +6472,7 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
/* if there's an active modal button, don't check events or outside, except for search menu */
but = ui_but_find_activated(ar);
- if (but && button_modal_state(but->active->state) && but->type != SEARCH_MENU) {
+ if (but && button_modal_state(but->active->state) && but->type != SEARCH_MENU && but->type != SEARCH_MENU_UNLINK) {
/* if a button is activated modal, always reset the start mouse
* position of the towards mechanism to avoid loosing focus,
* and don't handle events */
@@ -6462,7 +6498,7 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
if (block->block_event_func && block->block_event_func(C, block, event)) {
/* pass */
} /* events not for active search menu button */
- else if (but == NULL || but->type != SEARCH_MENU) {
+ else if (but == NULL || (but->type != SEARCH_MENU && but->type != SEARCH_MENU_UNLINK)) {
switch (event->type) {
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index ebc80d61af3..68780083b97 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -950,8 +950,8 @@ static void icon_draw_texture(float x, float y, float w, float h, int ix, int iy
{
float x1, x2, y1, y2;
- if (rgb) glColor4f(alpha*rgb[0], rgb[1], rgb[2], alpha);
- else glColor4f(alpha, alpha, alpha, alpha);
+ if (rgb) glColor4f(rgb[0], rgb[1], rgb[2], alpha);
+ else glColor4f(alpha, alpha, alpha, alpha);
x1 = ix * icongltex.invw;
x2 = (ix + ih) * icongltex.invw;
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index f4af1f036a3..3b0a1cd3eb5 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -1386,7 +1386,7 @@ void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRN
/* turn button into search button */
if (searchprop) {
- but->type = SEARCH_MENU;
+ but->type = SEARCH_MENU_UNLINK;
but->hardmax = MAX2(but->hardmax, 256.0f);
but->rnasearchpoin = *searchptr;
but->rnasearchprop = searchprop;
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 4a8ad5d24a6..ca5e2a1926c 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -466,7 +466,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
data->totline++;
}
- if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
+ if (ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
/* full string */
ui_get_but_string(but, buf, sizeof(buf));
if (buf[0]) {
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index e4ad3a4f73b..6b44a82a52a 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -897,7 +897,7 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, const rcti
}
}
else if (but->block->flag & UI_BLOCK_LOOP) {
- if (but->type == SEARCH_MENU)
+ if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK))
xs = rect->xmin + 4.0f * ofs;
else
xs = rect->xmin + ofs;
@@ -1283,7 +1283,7 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
else if (ELEM4(but->type, NUM, NUMABS, NUMSLI, SLI)) {
ui_text_clip_right_label(fstyle, but, rect);
}
- else if (ELEM(but->type, TEX, SEARCH_MENU)) {
+ else if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
ui_text_clip_left(fstyle, but, rect);
}
else if ((but->block->flag & UI_BLOCK_LOOP) && (but->type == BUT)) {
@@ -1331,6 +1331,14 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
else if ((but->flag & UI_TEXT_LEFT)) {
rect->xmin += (0.4f * U.widget_unit) / but->block->aspect;
}
+
+ /* unlink icon for this button type */
+ if (but->type == SEARCH_MENU_UNLINK && but->drawstr[0]) {
+ rcti temp = *rect;
+
+ temp.xmin = temp.xmax - BLI_rcti_size_y(rect);
+ widget_draw_icon(but, ICON_X, 1.0f, &temp);
+ }
/* always draw text for textbutton cursor */
widget_draw_text(fstyle, wcol, but, rect);
@@ -3215,7 +3223,8 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
case TEX:
wt = widget_type(UI_WTYPE_NAME);
break;
-
+
+ case SEARCH_MENU_UNLINK:
case SEARCH_MENU:
wt = widget_type(UI_WTYPE_NAME);
if (but->block->flag & UI_BLOCK_LOOP)
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 361bdfacbb2..471193d10d8 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -170,6 +170,16 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
else
cp = ts->button;
break;
+ case TH_LOW_GRAD:
+ cp = ts->gradients.gradient;
+ break;
+ case TH_HIGH_GRAD:
+ cp = ts->gradients.high_gradient;
+ break;
+ case TH_SHOW_BACK_GRAD:
+ cp = &setting;
+ setting = ts->gradients.show_grad;
+ break;
case TH_TEXT:
if (theme_regionid == RGN_TYPE_WINDOW)
cp = ts->text;
@@ -782,7 +792,10 @@ void ui_theme_init_default(void)
rgba_char_args_set(btheme->tv3d.camera_path, 0x00, 0x00, 0x00, 255);
rgba_char_args_set(btheme->tv3d.skin_root, 180, 77, 77, 255);
-
+ rgba_char_args_set(btheme->tv3d.gradients.gradient, 0, 0, 0, 0);
+ rgba_char_args_set(btheme->tv3d.gradients.high_gradient, 58, 58, 58, 255);
+ btheme->tv3d.gradients.show_grad = FALSE;
+
/* space buttons */
/* to have something initialized */
btheme->tbuts = btheme->tv3d;
@@ -2116,7 +2129,7 @@ void init_userdef_do_versions(void)
}
}
- if (!MAIN_VERSION_ATLEAST(bmain, 266, 4)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 265, 4)) {
bTheme *btheme;
for (btheme = U.themes.first; btheme; btheme = btheme->next) {
rgba_char_args_set(btheme->text.syntaxd, 50, 0, 140, 255); /* Decorator/Preprocessor Dir. Blue-purple */
@@ -2124,7 +2137,14 @@ void init_userdef_do_versions(void)
rgba_char_args_set(btheme->text.syntaxs, 76, 76, 76, 255); /* Grey (mix between fg/bg) */
}
}
-
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 265, 6)) {
+ bTheme *btheme;
+ for (btheme = U.themes.first; btheme; btheme = btheme->next) {
+ copy_v4_v4_char(btheme->tv3d.gradients.high_gradient, btheme->tv3d.back);
+ }
+ }
+
if (U.pixelsize == 0.0f)
U.pixelsize = 1.0f;
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index d0d631e14a5..41bbed8eb19 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -1694,7 +1694,7 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
/* draw numbers in the appropriate range */
if (dfac > 0.0f) {
- float h = 0.1f*UI_UNIT_Y + (float)(hor.ymin);
+ float h = 0.1f * UI_UNIT_Y + (float)(hor.ymin);
for (; fac < hor.xmax - 0.5f * U.widget_unit; fac += dfac, val += grid->dx) {
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index cc473998340..9236800c16b 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -946,10 +946,10 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, wmEvent *event)
/* As we have only 1D information (magnify value), feed both axes
* with magnify information that is stored in x axis
*/
- fac = 0.01f * (event->x - event->prevx);
+ fac = 0.01f * (event->prevx - event->x);
dx = fac * BLI_rctf_size_x(&v2d->cur) / 10.0f;
if (event->type == MOUSEPAN)
- fac = 0.01f * (event->y - event->prevy);
+ fac = 0.01f * (event->prevy - event->y);
dy = fac * BLI_rctf_size_y(&v2d->cur) / 10.0f;
RNA_float_set(op->ptr, "deltax", dx);
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index 590bcd5939e..5e1d954a2ea 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -1320,7 +1320,7 @@ static void calc_ortho_extent(KnifeTool_OpData *kcd)
{
BMIter iter;
BMVert *v;
- BMesh* bm = kcd->em->bm;
+ BMesh *bm = kcd->em->bm;
float max_xyz = 0.0f;
int i;
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index 48dfe3bf667..38887307a76 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -42,6 +42,7 @@
#include "BKE_displist.h"
#include "BKE_report.h"
#include "BKE_paint.h"
+#include "BKE_mesh.h"
#include "BKE_tessmesh.h"
#include "IMB_imbuf_types.h"
@@ -1370,6 +1371,17 @@ static int edgetag_shortest_path(Scene *scene, BMesh *bm, BMEdge *e_src, BMEdge
/* note, would pass BM_EDGE except we are looping over all edges anyway */
BM_mesh_elem_index_ensure(bm, BM_VERT /* | BM_EDGE */);
+ switch (scene->toolsettings->edge_mode) {
+ case EDGE_MODE_TAG_CREASE:
+ BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(OBACT), ME_CDFLAG_EDGE_CREASE);
+ break;
+ case EDGE_MODE_TAG_BEVEL:
+ BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(OBACT), ME_CDFLAG_EDGE_BWEIGHT);
+ break;
+ default:
+ break;
+ }
+
BM_ITER_MESH_INDEX (e, &eiter, bm, BM_EDGES_OF_MESH, i) {
if (BM_elem_flag_test(e, BM_ELEM_HIDDEN) == FALSE) {
BM_elem_flag_disable(e, BM_ELEM_TAG);
@@ -2274,7 +2286,7 @@ static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *
BMW_FLAG_TEST_HIDDEN,
BMW_NIL_LAY);
- e = BMW_begin(&walker, efa);
+ efa = BMW_begin(&walker, efa);
for (; efa; efa = BMW_step(&walker)) {
BM_face_select_set(bm, efa, sel);
}
@@ -2368,7 +2380,7 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op)
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
- e = BMW_begin(&walker, efa);
+ efa = BMW_begin(&walker, efa);
for (; efa; efa = BMW_step(&walker)) {
BM_face_select_set(bm, efa, TRUE);
}
@@ -2405,8 +2417,9 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op)
}
}
BMW_end(&walker);
+
+ EDBM_selectmode_flush(em);
}
- EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index e8132f5b82b..b95c8a05353 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -550,7 +550,7 @@ void EDBM_select_more(BMEditMesh *em)
BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, use_faces ? TRUE : FALSE);
BMO_op_finish(em->bm, &bmop);
- EDBM_select_flush(em);
+ EDBM_selectmode_flush(em);
}
void EDBM_select_less(BMEditMesh *em)
diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c
index 641d1be7a2e..1d13aa36a6b 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -462,7 +462,7 @@ int ED_mesh_color_add(bContext *C, Scene *UNUSED(scene), Object *UNUSED(ob), Mes
/* copy data from active vertex color layer */
if (layernum) {
const int layernum_dst = CustomData_get_active_layer(&em->bm->ldata, CD_MLOOPCOL);
- BM_data_layer_copy(em->bm, &em->bm->ldata, CD_MLOOPUV, layernum, layernum_dst);
+ BM_data_layer_copy(em->bm, &em->bm->ldata, CD_MLOOPCOL, layernum, layernum_dst);
}
if (active_set || layernum == 0) {
CustomData_set_layer_active(&em->bm->ldata, CD_MLOOPCOL, layernum);
diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c
index c54ac485be6..fc55b2b5915 100644
--- a/source/blender/editors/physics/physics_fluid.c
+++ b/source/blender/editors/physics/physics_fluid.c
@@ -237,7 +237,7 @@ static void init_time(FluidsimSettings *domainSettings, FluidAnimChannels *chann
{
int i;
- channels->timeAtFrame = MEM_callocN((channels->length+1)*sizeof(float), "timeAtFrame channel");
+ channels->timeAtFrame = MEM_callocN((channels->length + 1) * sizeof(float), "timeAtFrame channel");
channels->timeAtFrame[0] = channels->timeAtFrame[1] = domainSettings->animStart; // start at index 1
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index cbc076b3342..7ba6a92e4be 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -43,6 +43,7 @@
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
+#include "DNA_world_types.h"
#include "BKE_context.h"
#include "BKE_global.h"
@@ -192,7 +193,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
}
if ((scene->r.mode & R_OSA) == 0) {
- ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE, FALSE);
+ ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE);
GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, rr->rectf);
}
else {
@@ -206,7 +207,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
BLI_jitter_init(jit_ofs[0], scene->r.osa);
/* first sample buffer, also initializes 'rv3d->persmat' */
- ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE, FALSE);
+ ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE);
GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, accum_buffer);
/* skip the first sample */
@@ -216,7 +217,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
(jit_ofs[j][0] * 2.0f) / sizex,
(jit_ofs[j][1] * 2.0f) / sizey);
- ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat_jitter, TRUE, FALSE);
+ ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat_jitter, TRUE);
GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, accum_tmp);
add_vn_vn(accum_buffer, accum_tmp, sizex * sizey * sizeof(float));
}
@@ -232,7 +233,8 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
else {
/* shouldnt suddenly give errors mid-render but possible */
char err_out[256] = "unknown";
- ImBuf *ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, oglrender->sizex, oglrender->sizey, IB_rectfloat, OB_SOLID, FALSE, TRUE, FALSE, err_out);
+ ImBuf *ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, oglrender->sizex, oglrender->sizey,
+ IB_rectfloat, OB_SOLID, FALSE, TRUE, R_ALPHAPREMUL, err_out);
camera = scene->camera;
if (ibuf_view) {
@@ -243,7 +245,13 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
fprintf(stderr, "%s: failed to get buffer, %s\n", __func__, err_out);
}
}
-
+
+ if (scene->r.alphamode == R_ADDSKY) {
+ float sky_color[3];
+ ED_view3d_offscreen_sky_color_get(scene, sky_color);
+ IMB_alpha_under_color_float(rr->rectf, sizex, sizey, sky_color);
+ }
+
/* note on color management:
*
* OpenGL renders into sRGB colors, but render buffers are expected to be
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 8d748d3ea20..25ad1f61aaf 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -84,6 +84,8 @@
#include "IMB_imbuf_types.h"
#include "IMB_colormanagement.h"
+#include "GPU_extensions.h"
+
#include "BIF_gl.h"
#include "BIF_glutil.h"
@@ -710,7 +712,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
else {
/* validate owner */
//if (ri->rect == NULL)
- // ri->rect= MEM_mallocN(sizeof(int)*ri->pr_rectx*ri->pr_recty, "BIF_previewrender");
+ // ri->rect= MEM_mallocN(sizeof(int) * ri->pr_rectx*ri->pr_recty, "BIF_previewrender");
//RE_ResultGet32(re, ri->rect);
}
@@ -884,7 +886,7 @@ static void icon_preview_startjob(void *customdata, short *stop, short *do_updat
ShaderPreview *sp = customdata;
ID *id = sp->id;
short idtype = GS(id->name);
-
+
if (idtype == ID_IM) {
Image *ima = (Image *)id;
ImBuf *ibuf = NULL;
@@ -1007,8 +1009,27 @@ static void icon_preview_endjob(void *customdata)
{
IconPreview *ip = customdata;
- if (ip->id && GS(ip->id->name) == ID_BR)
- WM_main_add_notifier(NC_BRUSH | NA_EDITED, ip->id);
+ if (ip->id) {
+
+ if (GS(ip->id->name) == ID_BR)
+ WM_main_add_notifier(NC_BRUSH | NA_EDITED, ip->id);
+#if 0
+ if (GS(ip->id->name) == ID_MA) {
+ Material *ma = (Material *)ip->id;
+ PreviewImage *prv_img = ma->preview;
+ int i;
+
+ /* signal to gpu texture */
+ for (i = 0; i < NUM_ICON_SIZES; ++i) {
+ if (prv_img->gputexture[i]) {
+ GPU_texture_free(prv_img->gputexture[i]);
+ prv_img->gputexture[i] = NULL;
+ WM_main_add_notifier(NC_MATERIAL|ND_SHADING_DRAW, ip->id);
+ }
+ }
+ }
+#endif
+ }
}
static void icon_preview_free(void *customdata)
@@ -1044,7 +1065,7 @@ void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *r
/* setup job */
WM_jobs_customdata_set(wm_job, ip, icon_preview_free);
- WM_jobs_timer(wm_job, 0.25, NC_MATERIAL, NC_MATERIAL);
+ WM_jobs_timer(wm_job, 0.1, NC_MATERIAL, NC_MATERIAL);
WM_jobs_callbacks(wm_job, icon_preview_startjob_all_sizes, NULL, NULL, icon_preview_endjob);
WM_jobs_start(CTX_wm_manager(C), wm_job);
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 5af60726f14..cea7b12a27d 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -1584,14 +1584,14 @@ int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco)
if (sa->flag & HEADER_NO_PULLDOWN) {
but = uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, 0,
ICON_DISCLOSURE_TRI_RIGHT,
- xco, yco, U.widget_unit, U.widget_unit*0.9,
+ xco, yco, U.widget_unit, U.widget_unit * 0.9f,
&(sa->flag), 0, 0, 0, 0,
"Show pulldown menus");
}
else {
but = uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, 0,
ICON_DISCLOSURE_TRI_DOWN,
- xco, yco, U.widget_unit, U.widget_unit*0.9,
+ xco, yco, U.widget_unit, U.widget_unit * 0.9f,
&(sa->flag), 0, 0, 0, 0,
"Hide pulldown menus");
}
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index d3947432004..f073fdd5125 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -56,7 +56,7 @@
/* ******************************************** */
/* defined in BIF_gl.h */
-GLubyte stipple_halftone[128] = {
+const GLubyte stipple_halftone[128] = {
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
@@ -83,7 +83,7 @@ GLubyte stipple_halftone[128] = {
* 00000000 */
-GLubyte stipple_quarttone[128] = {
+const GLubyte stipple_quarttone[128] = {
136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0,
136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0,
136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0,
@@ -94,7 +94,7 @@ GLubyte stipple_quarttone[128] = {
136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0};
-GLubyte stipple_diag_stripes_pos[128] = {
+const GLubyte stipple_diag_stripes_pos[128] = {
0x00, 0xff, 0x00, 0xff, 0x01, 0xfe, 0x01, 0xfe,
0x03, 0xfc, 0x03, 0xfc, 0x07, 0xf8, 0x07, 0xf8,
0x0f, 0xf0, 0x0f, 0xf0, 0x1f, 0xe0, 0x1f, 0xe0,
@@ -113,7 +113,7 @@ GLubyte stipple_diag_stripes_pos[128] = {
0xc0, 0x3f, 0xc0, 0x3f, 0x80, 0x7f, 0x80, 0x7f};
-GLubyte stipple_diag_stripes_neg[128] = {
+const GLubyte stipple_diag_stripes_neg[128] = {
0xff, 0x00, 0xff, 0x00, 0xfe, 0x01, 0xfe, 0x01,
0xfc, 0x03, 0xfc, 0x03, 0xf8, 0x07, 0xf8, 0x07,
0xf0, 0x0f, 0xf0, 0x0f, 0xe0, 0x1f, 0xe0, 0x1f,
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index fa8252c824d..d0f8e36e17d 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -6038,7 +6038,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op)
if (w > maxsize) w = maxsize;
if (h > maxsize) h = maxsize;
- ibuf = ED_view3d_draw_offscreen_imbuf(CTX_data_scene(C), CTX_wm_view3d(C), CTX_wm_region(C), w, h, IB_rect, FALSE, FALSE, err_out);
+ ibuf = ED_view3d_draw_offscreen_imbuf(CTX_data_scene(C), CTX_wm_view3d(C), CTX_wm_region(C), w, h, IB_rect, FALSE, R_ALPHAPREMUL, err_out);
if (!ibuf) {
/* Mostly happens when OpenGL offscreen buffer was failed to create, */
/* but could be other reasons. Should be handled in the future. nazgul */
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c
index c30996f03de..dd7412cf3d5 100644
--- a/source/blender/editors/sculpt_paint/paint_image_2d.c
+++ b/source/blender/editors/sculpt_paint/paint_image_2d.c
@@ -391,7 +391,7 @@ int BKE_brush_painter_paint(BrushPainter *painter, BrushFunc func, const float p
double starttime, curtime = time;
/* compute brush spacing adapted to brush size */
- spacing = brush->rate; //radius*brush->spacing*0.01f;
+ spacing = brush->rate; //radius*brush->spacing * 0.01f;
/* setup starting time, direction vector and accumulated time */
starttime = painter->accumtime;
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index 9e702c16e2f..e5d6a1820a2 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -657,8 +657,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
* grid rather than brush alpha */
kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", DKEY, KM_PRESS, KM_SHIFT, 0);
set_brush_rc_props(kmi->ptr, "sculpt", "detail_size", NULL, 0);
- RNA_string_set(kmi->ptr, "data_path_primary",
- "tool_settings.sculpt.detail_size");
+ RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.sculpt.detail_size");
/* multires switch */
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_subdivision_set", PAGEUPKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 54ae2ebf588..2dc4176dde3 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -137,6 +137,11 @@ MultiresModifierData *sculpt_multires_active(Scene *scene, Object *ob)
Mesh *me = (Mesh *)ob->data;
ModifierData *md;
+ if (ob->sculpt && ob->sculpt->bm) {
+ /* can't combine multires and dynamic topology */
+ return NULL;
+ }
+
if (!CustomData_get_layer(&me->ldata, CD_MDISPS)) {
/* multires can't work without displacement layer */
return NULL;
@@ -4585,7 +4590,8 @@ void sculpt_dynamic_topology_disable(bContext *C,
CD_DUPLICATE, unode->bm_enter_totpoly);
mesh_update_customdata_pointers(me, FALSE);
- } else {
+ }
+ else {
sculptsession_bm_to_me(ob, TRUE);
}
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index 3088243d266..04154a27b74 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -82,7 +82,7 @@ int ED_space_clip_view_clip_poll(bContext *C)
{
SpaceClip *sc = CTX_wm_space_clip(C);
- if (sc && sc->clip) {
+ if (sc) {
return sc->view == SC_VIEW_CLIP;
}
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index 4e53f34359e..26bae6e3978 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -382,8 +382,8 @@ static int view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event)
SpaceClip *sc = CTX_wm_space_clip(C);
float offset[2];
- offset[0] = (event->x - event->prevx) / sc->zoom;
- offset[1] = (event->y - event->prevy) / sc->zoom;
+ offset[0] = (event->prevx - event->x) / sc->zoom;
+ offset[1] = (event->prevy - event->y) / sc->zoom;
RNA_float_set_array(op->ptr, "offset", offset);
@@ -515,10 +515,10 @@ static int view_zoom_exec(bContext *C, wmOperator *op)
static int view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
- if (event->type == MOUSEZOOM) {
+ if (event->type == MOUSEZOOM || event->type == MOUSEPAN) {
float delta, factor;
- delta = event->x - event->prevx + event->y - event->prevy;
+ delta = event->prevx - event->x + event->prevy - event->y;
if (U.uiflag & USER_ZOOM_INVERT)
delta *= -1;
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index dc7b6d77c9e..9d0421349d7 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -587,6 +587,7 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "CLIP_OT_view_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "CLIP_OT_view_zoom", MOUSEZOOM, 0, 0, 0);
+ WM_keymap_add_item(keymap, "CLIP_OT_view_zoom", MOUSEPAN, 0, KM_CTRL, 0);
WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_in", WHEELINMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_out", WHEELOUTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 763b18788de..9349abb4d8b 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -28,6 +28,8 @@
* \ingroup spfile
*/
+#include "BLI_blenlib.h"
+#include "BLI_utildefines.h"
#include "BKE_context.h"
#include "BKE_screen.h"
@@ -35,9 +37,6 @@
#include "BKE_report.h"
#include "BKE_main.h"
-#include "BLI_blenlib.h"
-#include "BLI_utildefines.h"
-
#ifdef WIN32
# include "BLI_winstuff.h"
#endif
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 21b0ed99f0b..b92430ce0e9 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -217,7 +217,6 @@ void GRAPH_OT_previewrange_set(wmOperatorType *ot)
static int graphkeys_viewall(bContext *C, const short do_sel_only, const short include_handles)
{
bAnimContext ac;
- float extra;
rctf cur_new;
/* get editor data */
@@ -230,13 +229,7 @@ static int graphkeys_viewall(bContext *C, const short do_sel_only, const short i
&cur_new.ymin, &cur_new.ymax,
do_sel_only, include_handles);
- extra = 0.1f * BLI_rctf_size_x(&cur_new);
- cur_new.xmin -= extra;
- cur_new.xmax += extra;
-
- extra = 0.1f * BLI_rctf_size_y(&cur_new);
- cur_new.ymin -= extra;
- cur_new.ymax += extra;
+ BLI_rctf_scale(&cur_new, 1.1f);
UI_view2d_smooth_view(C, ac.ar, &cur_new);
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index 0534b9f4ffd..7b4814d1ab2 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -514,11 +514,15 @@ static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar,
unsigned char *display_buffer;
void *cache_handle;
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
if (sima->flag & SI_USE_ALPHA) {
fdrawcheckerboard(x, y, x + ibuf->x * zoomx, y + ibuf->y * zoomy);
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+ else {
+ glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+ glRecti(x, y, x + ibuf->x * zoomx, y + ibuf->y * zoomy);
}
display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
@@ -532,8 +536,7 @@ static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar,
IMB_display_buffer_release(cache_handle);
- if (sima->flag & SI_USE_ALPHA)
- glDisable(GL_BLEND);
+ glDisable(GL_BLEND);
}
/* reset zoom */
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index f1662bc254d..eed15425441 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -299,8 +299,8 @@ static int image_view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event)
SpaceImage *sima = CTX_wm_space_image(C);
float offset[2];
- offset[0] = (event->x - event->prevx) / sima->zoom;
- offset[1] = (event->y - event->prevy) / sima->zoom;
+ offset[0] = (event->prevx - event->x) / sima->zoom;
+ offset[1] = (event->prevy - event->y) / sima->zoom;
RNA_float_set_array(op->ptr, "offset", offset);
image_view_pan_exec(C, op);
@@ -464,7 +464,7 @@ static int image_view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &location[0], &location[1]);
- delta = event->x - event->prevx + event->y - event->prevy;
+ delta = event->prevx - event->x + event->prevy - event->y;
if (U.uiflag & USER_ZOOM_INVERT)
delta *= -1;
diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c
index e5f8d6553ed..fc0a7b3b883 100644
--- a/source/blender/editors/space_info/textview.c
+++ b/source/blender/editors/space_info/textview.c
@@ -71,14 +71,14 @@ BLI_INLINE void console_step_sel(ConsoleDrawContext *cdc, const int step)
static void console_draw_sel(const int sel[2], const int xy[2], const int str_len_draw, int cwidth, int lheight)
{
if (sel[0] <= str_len_draw && sel[1] >= 0) {
- int sta = max_ii(sel[0], 0);
- int end = min_ii(sel[1], str_len_draw);
+ const int sta = max_ii(sel[0], 0);
+ const int end = min_ii(sel[1], str_len_draw);
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(stipple_halftone);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glColor4ub(255, 255, 255, 96);
+ glColor4ub(255, 255, 255, 48);
glRecti(xy[0] + (cwidth * sta), xy[1] - 2 + lheight, xy[0] + (cwidth * end), xy[1] - 2);
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 8797cb4a459..981a1775b51 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -1932,9 +1932,9 @@ static void node_composit_buts_hue_sat(uiLayout *layout, bContext *UNUSED(C), Po
static void node_composit_buts_dilateerode(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "type", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "distance", 0, NULL, ICON_NONE);
- switch (RNA_enum_get(ptr, "type")) {
+ switch (RNA_enum_get(ptr, "mode")) {
case CMP_NODE_DILATEERODE_DISTANCE_THRESH:
uiItemR(layout, ptr, "edge", 0, NULL, ICON_NONE);
break;
@@ -3271,10 +3271,18 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode)
}
else {
glPixelZoom(snode->zoom, snode->zoom);
-
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+ glRecti(x, y, x + ibuf->x * snode->zoom, y + ibuf->y * snode->zoom);
+
glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer);
glPixelZoom(1.0f, 1.0f);
+
+ glDisable(GL_BLEND);
}
}
diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c
index 492ff0dcbd4..a69e73c1489 100644
--- a/source/blender/editors/space_node/node_view.c
+++ b/source/blender/editors/space_node/node_view.c
@@ -118,6 +118,9 @@ static int space_node_view_flag(bContext *C, SpaceNode *snode, ARegion *ar, cons
cur_new.xmin = cur_new.xmin - width_new / 2.0f;
cur_new.xmax = cur_new.xmax + width_new / 2.0f;
}
+
+ /* add some padding */
+ BLI_rctf_scale(&cur_new, 1.1f);
}
UI_view2d_smooth_view(C, ar, &cur_new);
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index e3db9c23c41..249ba986fd3 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -924,11 +924,18 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
void *cache_handle = NULL;
const int is_imbuf = ED_space_sequencer_check_show_imbuf(sseq);
- if (G.is_rendering == FALSE) {
+ if (G.is_rendering == FALSE && (scene->r.seq_flag & R_SEQ_GL_PREV) == 0) {
/* stop all running jobs, except screen one. currently previews frustrate Render
* needed to make so sequencer's rendering doesn't conflict with compositor
*/
WM_jobs_kill_type(CTX_wm_manager(C), WM_JOB_TYPE_COMPOSITE);
+
+ if ((scene->r.seq_flag & R_SEQ_GL_PREV) == 0) {
+ /* in case of final rendering used for preview, kill all previews,
+ * otherwise threading conflict will happen in rendering module
+ */
+ WM_jobs_kill_type(CTX_wm_manager(C), WM_JOB_TYPE_RENDER_PREVIEW);
+ }
}
render_size = sseq->render_size;
@@ -1051,6 +1058,10 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
glBegin(GL_QUADS);
if (draw_overlay) {
@@ -1082,6 +1093,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
glEnd();
glBindTexture(GL_TEXTURE_2D, last_texid);
glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
glDeleteTextures(1, &texid);
if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
diff --git a/source/blender/editors/space_view3d/drawanimviz.c b/source/blender/editors/space_view3d/drawanimviz.c
index 0649edc1ac4..57864854734 100644
--- a/source/blender/editors/space_view3d/drawanimviz.c
+++ b/source/blender/editors/space_view3d/drawanimviz.c
@@ -139,35 +139,38 @@ void draw_motion_path_instance(Scene *scene,
short sel = (pchan) ? (pchan->bone->flag & BONE_SELECTED) : (ob->flag & SELECT);
float intensity; /* how faint */
+ int frame = sfra + i;
+ int blend_base = (abs(frame - CFRA) == 1) ? TH_CFRAME : TH_BACK; /* "bleed" cframe color to ease color blending */
+
/* set color
* - more intense for active/selected bones, less intense for unselected bones
* - black for before current frame, green for current frame, blue for after current frame
* - intensity decreases as distance from current frame increases
*/
#define SET_INTENSITY(A, B, C, min, max) (((1.0f - ((C - B) / (C - A))) * (max - min)) + min)
- if ((sfra + i) < CFRA) {
+ if (frame < CFRA) {
/* black - before cfra */
if (sel) {
- // intensity = 0.5f;
+ /* intensity = 0.5f; */
intensity = SET_INTENSITY(sfra, i, CFRA, 0.25f, 0.75f);
}
else {
- //intensity = 0.8f;
+ /* intensity = 0.8f; */
intensity = SET_INTENSITY(sfra, i, CFRA, 0.68f, 0.92f);
}
- UI_ThemeColorBlend(TH_WIRE, TH_BACK, intensity);
+ UI_ThemeColorBlend(TH_WIRE, blend_base, intensity);
}
- else if ((sfra + i) > CFRA) {
+ else if (frame > CFRA) {
/* blue - after cfra */
if (sel) {
- //intensity = 0.5f;
+ /* intensity = 0.5f; */
intensity = SET_INTENSITY(CFRA, i, efra, 0.25f, 0.75f);
}
else {
- //intensity = 0.8f;
+ /* intensity = 0.8f; */
intensity = SET_INTENSITY(CFRA, i, efra, 0.68f, 0.92f);
}
- UI_ThemeColorBlend(TH_BONE_POSE, TH_BACK, intensity);
+ UI_ThemeColorBlend(TH_BONE_POSE, blend_base, intensity);
}
else {
/* green - on cfra */
@@ -232,21 +235,22 @@ void draw_motion_path_instance(Scene *scene,
col[3] = 255;
for (i = 0, mpv = mpv_start; i < len; i += stepsize, mpv += stepsize) {
+ int frame = sfra + i;
char numstr[32];
float co[3];
/* only draw framenum if several consecutive highlighted points don't occur on same point */
if (i == 0) {
- sprintf(numstr, "%d", (i + sfra));
+ sprintf(numstr, " %d", frame);
mul_v3_m4v3(co, ob->imat, mpv->co);
view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col);
}
- else if ((i > stepsize) && (i < len - stepsize)) {
+ else if ((i >= stepsize) && (i < len - stepsize)) {
bMotionPathVert *mpvP = (mpv - stepsize);
bMotionPathVert *mpvN = (mpv + stepsize);
if ((equals_v3v3(mpv->co, mpvP->co) == 0) || (equals_v3v3(mpv->co, mpvN->co) == 0)) {
- sprintf(numstr, "%d", (sfra + i));
+ sprintf(numstr, " %d", frame);
mul_v3_m4v3(co, ob->imat, mpv->co);
view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col);
}
@@ -286,12 +290,13 @@ void draw_motion_path_instance(Scene *scene,
UI_GetThemeColor3ubv(TH_VERTEX_SELECT, col);
col[3] = 255;
- glPointSize(4.0f); // XXX perhaps a bit too big
+ glPointSize(4.0f);
glColor3ubv(col);
glBegin(GL_POINTS);
for (i = 0, mpv = mpv_start; i < len; i++, mpv++) {
- float mframe = (float)(sfra + i);
+ int frame = sfra + i;
+ float mframe = (float)(frame);
if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe))
glVertex3fv(mpv->co);
@@ -309,7 +314,7 @@ void draw_motion_path_instance(Scene *scene,
if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe)) {
char numstr[32];
- sprintf(numstr, "%d", (sfra + i));
+ sprintf(numstr, " %d", (sfra + i));
mul_v3_m4v3(co, ob->imat, mpv->co);
view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col);
}
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index ebb5fd30666..7ef8dc49a5d 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -3493,7 +3493,7 @@ static int drawDispListwire(ListBase *dlbase)
#if 0
/* (ton) this code crashes for me when resolv is 86 or higher... no clue */
- glVertexPointer(3, GL_FLOAT, sizeof(float) * 3 * dl->nr, data + 3*nr);
+ glVertexPointer(3, GL_FLOAT, sizeof(float) * 3 * dl->nr, data + 3 * nr);
if (dl->flag & DL_CYCL_V)
glDrawArrays(GL_LINE_LOOP, 0, dl->parts);
else
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 6a095a8d2b1..ec716284bf3 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -179,32 +179,47 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
BMEdge *eed;
BMIter iter;
- BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
- if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- MVertSkin *vs;
-
- evedef = eve;
- tot++;
- add_v3_v3(&median[LOC_X], eve->co);
-
- vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN);
- if (vs) {
- add_v2_v2(&median[M_SKIN_X], vs->radius); /* Third val not used currently. */
- totskinradius++;
+ const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
+ const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
+
+ if (bm->totvertsel) {
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ evedef = eve;
+ tot++;
+ add_v3_v3(&median[LOC_X], eve->co);
+
+ /* TODO cd_vert_bweight_offset */
+ (void)cd_vert_bweight_offset;
+
+ if (cd_vert_skin_offset != -1) {
+ MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
+ add_v2_v2(&median[M_SKIN_X], vs->radius); /* Third val not used currently. */
+ totskinradius++;
+ }
}
}
}
- BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
- float *f;
+ if ((cd_edge_bweight_offset != -1) ||
+ (cd_edge_crease_offset != -1))
+ {
+ if (bm->totedgesel) {
+ BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
+ if (cd_edge_bweight_offset != -1) {
+ median[M_WEIGHT] += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_bweight_offset);
+ }
- totedgedata++;
- f = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE);
- median[M_CREASE] += f ? *f : 0.0f;
+ if (cd_edge_crease_offset != -1) {
+ median[M_CREASE] += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_crease_offset);
+ }
- f = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT);
- median[M_WEIGHT] += f ? *f : 0.0f;
+ totedgedata++;
+ }
+ }
}
}
@@ -412,14 +427,26 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
/* Meshes... */
if (meshdata) {
if (totedgedata) {
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN,
- totedgedata == 1 ? IFACE_("Crease:") : IFACE_("Mean Crease:"),
- 0, yi -= buth + but_margin, 200, buth,
- &(tfp->ve_median[M_CREASE]), 0.0, 1.0, 1, 3, TIP_("Weight used by SubSurf modifier"));
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN,
- totedgedata == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"),
- 0, yi -= buth + but_margin, 200, buth,
- &(tfp->ve_median[M_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used by Bevel modifier"));
+ Mesh *me = ob->data;
+ BMEditMesh *em = me->edit_btmesh;
+ BMesh *bm = em->bm;
+
+ const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
+
+ if (cd_edge_crease_offset != -1) {
+ uiDefButF(block, NUM, B_OBJECTPANELMEDIAN,
+ totedgedata == 1 ? IFACE_("Crease:") : IFACE_("Mean Crease:"),
+ 0, yi -= buth + but_margin, 200, buth,
+ &(tfp->ve_median[M_CREASE]), 0.0, 1.0, 1, 3, TIP_("Weight used by SubSurf modifier"));
+ }
+
+ if (cd_edge_bweight_offset != -1) {
+ uiDefButF(block, NUM, B_OBJECTPANELMEDIAN,
+ totedgedata == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"),
+ 0, yi -= buth + but_margin, 200, buth,
+ &(tfp->ve_median[M_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used by Bevel modifier"));
+ }
}
if (totskinradius) {
uiDefButF(block, NUM, B_OBJECTPANELMEDIAN,
@@ -502,91 +529,85 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
if (median[M_CREASE] != 0.0f) {
- BMEdge *eed;
+ const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
const float sca = compute_scale_factor(ve_median[M_CREASE], median[M_CREASE]);
+ BMEdge *eed;
if (ELEM(sca, 0.0f, 1.0f)) {
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
- float *crease = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE);
- if (crease) {
- *crease = sca;
- }
+ BM_ELEM_CD_SET_FLOAT(eed, cd_edge_crease_offset, sca);
}
}
}
else if (sca > 0.0f) {
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
- float *crease = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE);
- if (crease) {
- *crease *= sca;
- CLAMP(*crease, 0.0f, 1.0f);
- }
+ float *crease = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_crease_offset);
+ *crease *= sca;
+ CLAMP(*crease, 0.0f, 1.0f);
}
}
}
else {
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
- float *crease = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE);
- if (crease) {
- *crease = 1.0f + ((1.0f - *crease) * sca);
- CLAMP(*crease, 0.0f, 1.0f);
- }
+ float *crease = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_crease_offset);
+ *crease = 1.0f + ((1.0f - *crease) * sca);
+ CLAMP(*crease, 0.0f, 1.0f);
}
}
}
}
if (median[M_WEIGHT] != 0.0f) {
- BMEdge *eed;
+ const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
const float sca = compute_scale_factor(ve_median[M_WEIGHT], median[M_WEIGHT]);
+ BMEdge *eed;
+
+ BLI_assert(cd_edge_bweight_offset != -1);
if (ELEM(sca, 0.0f, 1.0f)) {
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
- float *bweight = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT);
- if (bweight) {
- *bweight = sca;
- }
+ float *bweight = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset);
+ *bweight = sca;
}
}
}
else if (sca > 0.0f) {
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
- float *bweight = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT);
- if (bweight) {
- *bweight *= sca;
- CLAMP(*bweight, 0.0f, 1.0f);
- }
+ float *bweight = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset);
+ *bweight *= sca;
+ CLAMP(*bweight, 0.0f, 1.0f);
}
}
}
else {
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
- float *bweight = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT);
- if (bweight) {
- *bweight = 1.0f + ((1.0f - *bweight) * sca);
- CLAMP(*bweight, 0.0f, 1.0f);
- }
+ float *bweight = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset);
+ *bweight = 1.0f + ((1.0f - *bweight) * sca);
+ CLAMP(*bweight, 0.0f, 1.0f);
}
}
}
}
if (median[M_SKIN_X] != 0.0f) {
- BMVert *eve;
+ const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
/* That one is not clamped to [0.0, 1.0]. */
float sca = ve_median[M_SKIN_X];
+ BMVert *eve;
+
+ BLI_assert(cd_vert_skin_offset != -1);
+
if (ve_median[M_SKIN_X] - median[M_SKIN_X] == 0.0f) {
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN);
- if (vs)
- vs->radius[0] = sca;
+ MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
+ vs->radius[0] = sca;
}
}
}
@@ -594,23 +615,25 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
sca /= (ve_median[M_SKIN_X] - median[M_SKIN_X]);
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN);
- if (vs)
- vs->radius[0] *= sca;
+ MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
+ vs->radius[0] *= sca;
}
}
}
}
if (median[M_SKIN_Y] != 0.0f) {
- BMVert *eve;
+ const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
/* That one is not clamped to [0.0, 1.0]. */
float sca = ve_median[M_SKIN_Y];
+ BMVert *eve;
+
+ BLI_assert(cd_vert_skin_offset != -1);
+
if (ve_median[M_SKIN_Y] - median[M_SKIN_Y] == 0.0f) {
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN);
- if (vs)
- vs->radius[1] = sca;
+ MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
+ vs->radius[1] = sca;
}
}
}
@@ -618,14 +641,12 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
sca /= (ve_median[M_SKIN_Y] - median[M_SKIN_Y]);
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN);
- if (vs)
- vs->radius[1] *= sca;
+ MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
+ vs->radius[1] *= sca;
}
}
}
}
- EDBM_mesh_normals_update(em);
}
else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
Curve *cu = ob->data;
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 4ccf26e12b1..67344a9804b 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -315,7 +315,7 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **
UI_ThemeColor(TH_GRID);
if (unit->system) {
- /* Use GRID_MIN_PX*2 for units because very very small grid
+ /* Use GRID_MIN_PX * 2 for units because very very small grid
* items are less useful when dealing with units */
void *usys;
int len, i;
@@ -381,7 +381,7 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **
drawgrid_draw(ar, wx, wy, x, y, sublines * dx);
}
}
- else { /* start blending out (GRID_MIN_PX < dx < (GRID_MIN_PX*10)) */
+ else { /* start blending out (GRID_MIN_PX < dx < (GRID_MIN_PX * 10)) */
UI_ThemeColorBlend(TH_BACK, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
drawgrid_draw(ar, wx, wy, x, y, dx);
@@ -599,7 +599,7 @@ static void draw_view_axis(RegionView3D *rv3d, rcti *rect)
float startx = k + 1.0f; /* axis center in screen coordinates, x=y */
float starty = k + 1.0f;
float ydisp = 0.0; /* vertical displacement to allow obj info text */
- int bright = 25 * (float)U.rvibright + 5; /* axis alpha (rvibright has range 0-10) */
+ int bright = - 20 * (10 - U.rvibright); /* axis alpha offset (rvibright has range 0-10) */
float vec[3];
float dx, dy;
@@ -937,7 +937,7 @@ static void draw_selected_name(Scene *scene, Object *ob, rcti *rect)
}
/* color depends on whether there is a keyframe */
- if (id_frame_has_keyframe((ID *)ob, /*BKE_scene_frame_get(scene)*/ (float)(CFRA), ANIMFILTER_KEYS_LOCAL))
+ if (id_frame_has_keyframe((ID *)ob, /* BKE_scene_frame_get(scene) */ (float)(CFRA), ANIMFILTER_KEYS_LOCAL))
UI_ThemeColor(TH_VERTEX_SELECT);
else
UI_ThemeColor(TH_TEXT_HI);
@@ -2393,7 +2393,7 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d)
invert_m4_m4(rv3d.persinv, rv3d.viewinv);
/* no need to call ED_view3d_draw_offscreen_init since shadow buffers were already updated */
- ED_view3d_draw_offscreen(scene, v3d, &ar, winsize, winsize, viewmat, winmat, FALSE, FALSE);
+ ED_view3d_draw_offscreen(scene, v3d, &ar, winsize, winsize, viewmat, winmat, FALSE);
GPU_lamp_shadow_buffer_unbind(shadow->lamp);
v3d->drawtype = drawtype;
@@ -2540,13 +2540,11 @@ void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d)
/* ED_view3d_draw_offscreen_init should be called before this to initialize
* stuff like shadow buffers
*/
-void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
- int winx, int winy, float viewmat[4][4], float winmat[4][4],
- int do_bgpic, int colormanage_background)
+void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, int winy,
+ float viewmat[4][4], float winmat[4][4], int do_bgpic)
{
RegionView3D *rv3d = ar->regiondata;
Base *base;
- float backcol[3];
int bwinx, bwiny;
rcti brect;
@@ -2574,34 +2572,7 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
* warning! can be slow so only free animated images - campbell */
GPU_free_images_anim();
- /* set background color, fallback on the view background color
- * (if active clip is set but frame is failed to load fallback to horizon color as background) */
- if (scene->world) {
- /* NOTE: currently OpenGL is supposed to always work in sRGB space and do not
- * apply any tonemaps since it's really tricky to support for all features (GLSL, textures, etc)
- * but due to compatibility issues background is being affected display transform, so we can
- * emulate behavior of disabled color management
- * but this function is also used for sequencer's scene strips which shouldn't be affected by
- * tonemaps now and should be purely sRGB, that's why we've got this colormanage_background
- * we can drop this flag in cost of some compatibility loss -- background wouldn't be
- * color managed in 3d viewport
- * same goes to opengl rendering, where color profile should be applied as very final step
- */
-
- if (colormanage_background) {
- IMB_colormanagement_pixel_to_display_space_v3(backcol, &scene->world->horr, &scene->view_settings,
- &scene->display_settings);
- }
- else {
- linearrgb_to_srgb_v3_v3(backcol, &scene->world->horr);
- }
-
- glClearColor(backcol[0], backcol[1], backcol[2], 0.0f);
- }
- else {
- UI_ThemeClearColor(TH_BACK);
- }
-
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -2703,10 +2674,30 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
G.f &= ~G_RENDER_OGL;
}
+/* get a color used for offscreen sky, returns color in sRGB space */
+void ED_view3d_offscreen_sky_color_get(Scene *scene, float sky_color[3])
+{
+ if (scene->world)
+ linearrgb_to_srgb_v3_v3(sky_color, &scene->world->horr);
+ else
+ UI_GetThemeColor3fv(TH_BACK, sky_color);
+}
+
+static void offscreen_imbuf_add_sky(ImBuf *ibuf, Scene *scene)
+{
+ float sky_color[3];
+
+ ED_view3d_offscreen_sky_color_get(scene, sky_color);
+
+ if (ibuf->rect_float)
+ IMB_alpha_under_color_float(ibuf->rect_float, ibuf->x, ibuf->y, sky_color);
+ else
+ IMB_alpha_under_color_byte((unsigned char *) ibuf->rect, ibuf->x, ibuf->y, sky_color);
+}
+
/* utility func for ED_view3d_draw_offscreen */
-ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar,
- int sizex, int sizey, unsigned int flag, int draw_background,
- int colormanage_background, char err_out[256])
+ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, int sizex, int sizey, unsigned int flag,
+ int draw_background, int alpha_mode, char err_out[256])
{
RegionView3D *rv3d = ar->regiondata;
ImBuf *ibuf;
@@ -2733,10 +2724,10 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar,
BKE_camera_params_compute_viewplane(&params, sizex, sizey, scene->r.xasp, scene->r.yasp);
BKE_camera_params_compute_matrix(&params);
- ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, params.winmat, draw_background, colormanage_background);
+ ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, params.winmat, draw_background);
}
else {
- ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, NULL, draw_background, colormanage_background);
+ ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, NULL, draw_background);
}
/* read in pixels & stamp */
@@ -2747,6 +2738,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar,
else if (ibuf->rect)
GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, ibuf->rect);
+ if (alpha_mode == R_ADDSKY)
+ offscreen_imbuf_add_sky(ibuf, scene);
+
/* unbind */
GPU_offscreen_unbind(ofs);
GPU_offscreen_free(ofs);
@@ -2760,9 +2754,8 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar,
}
/* creates own 3d views, used by the sequencer */
-ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int width, int height,
- unsigned int flag, int drawtype, int use_solid_tex, int draw_background,
- int colormanage_background, char err_out[256])
+ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int width, int height, unsigned int flag, int drawtype,
+ int use_solid_tex, int draw_background, int alpha_mode, char err_out[256])
{
View3D v3d = {NULL};
ARegion ar = {NULL};
@@ -2805,7 +2798,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int w
invert_m4_m4(rv3d.persinv, rv3d.viewinv);
return ED_view3d_draw_offscreen_imbuf(scene, &v3d, &ar, width, height, flag,
- draw_background, colormanage_background, err_out);
+ draw_background, alpha_mode, err_out);
// seq_view3d_cb(scene, cfra, render_size, seqrectx, seqrecty);
}
@@ -2974,6 +2967,169 @@ static void view3d_main_area_draw_engine_info(RegionView3D *rv3d, ARegion *ar)
ED_region_info_draw(ar, rv3d->render_engine->text, 1, 0.25);
}
+/*
+ * Function to clear the view
+ */
+static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
+{
+ /* clear background */
+ if (scene->world && (v3d->flag2 & V3D_RENDER_OVERRIDE)) { /* clear with solid color */
+ if (scene->world->skytype & WO_SKYBLEND) { /* blend sky */
+ int x, y;
+ float col_hor[3];
+ float col_zen[3];
+
+#define VIEWGRAD_RES_X 16
+#define VIEWGRAD_RES_Y 16
+
+ GLubyte grid_col[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][4];
+ static float grid_pos[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][2];
+ static GLushort indices[VIEWGRAD_RES_X - 1][VIEWGRAD_RES_X - 1][4];
+ static char buf_calculated = FALSE;
+
+ IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings,
+ &scene->display_settings);
+ IMB_colormanagement_pixel_to_display_space_v3(col_zen, &scene->world->zenr, &scene->view_settings,
+ &scene->display_settings);
+
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glShadeModel(GL_SMOOTH);
+
+ /* calculate buffers the first time only */
+ if (!buf_calculated) {
+ for (x = 0; x < VIEWGRAD_RES_X; x++) {
+ for (y = 0; y < VIEWGRAD_RES_Y; y++) {
+ const float xf = (float)x / (float)(VIEWGRAD_RES_X - 1);
+ const float yf = (float)y / (float)(VIEWGRAD_RES_Y - 1);
+
+ /* -1..1 range */
+ grid_pos[x][y][0] = (xf - 0.5f) * 2.0f;
+ grid_pos[x][y][1] = (yf - 0.5f) * 2.0f;
+ }
+ }
+
+ for (x = 0; x < VIEWGRAD_RES_X - 1; x++) {
+ for (y = 0; y < VIEWGRAD_RES_Y - 1; y++) {
+ indices[x][y][0] = x * VIEWGRAD_RES_X + y;
+ indices[x][y][1] = x * VIEWGRAD_RES_X + y + 1;
+ indices[x][y][2] = (x + 1) * VIEWGRAD_RES_X + y + 1;
+ indices[x][y][3] = (x + 1) * VIEWGRAD_RES_X + y;
+ }
+ }
+
+ buf_calculated = TRUE;
+ }
+
+ for (x = 0; x < VIEWGRAD_RES_X; x++) {
+ for (y = 0; y < VIEWGRAD_RES_Y; y++) {
+ const float xf = (float)x / (float)(VIEWGRAD_RES_X - 1);
+ const float yf = (float)y / (float)(VIEWGRAD_RES_Y - 1);
+ const float mval[2] = {xf * (float)ar->winx, yf * ar->winy};
+ const float z_up[3] = {0.0f, 0.0f, 1.0f};
+ float out[3];
+ GLubyte *col_ub = grid_col[x][y];
+
+ float col_fac;
+ float col_fl[3];
+
+ ED_view3d_win_to_vector(ar, mval, out);
+
+ if (scene->world->skytype & WO_SKYPAPER) {
+ if (scene->world->skytype & WO_SKYREAL) {
+ col_fac = fabsf(((float)y / (float)VIEWGRAD_RES_Y) - 0.5f) * 2.0f;
+ }
+ else {
+ col_fac = (float)y / (float)VIEWGRAD_RES_Y;
+ }
+ }
+ else {
+ if (scene->world->skytype & WO_SKYREAL) {
+ col_fac = fabsf((angle_normalized_v3v3(z_up, out) / (float)M_PI) - 0.5f) * 2.0f;
+ }
+ else {
+ col_fac = 1.0f - (angle_normalized_v3v3(z_up, out) / (float)M_PI);
+ }
+ }
+
+ interp_v3_v3v3(col_fl, col_hor, col_zen, col_fac);
+
+ rgb_float_to_uchar(col_ub, col_fl);
+ col_ub[3] = 0;
+ }
+ }
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+ glVertexPointer(2, GL_FLOAT, 0, grid_pos);
+ glColorPointer(4, GL_UNSIGNED_BYTE, 0, grid_col);
+
+ glDrawElements(GL_QUADS, (VIEWGRAD_RES_X - 1) * (VIEWGRAD_RES_Y - 1) * 4, GL_UNSIGNED_SHORT, indices);
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+
+ glShadeModel(GL_FLAT);
+
+#undef VIEWGRAD_RES_X
+#undef VIEWGRAD_RES_Y
+ }
+ else { /* solid sky */
+ float col_hor[3];
+ IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings,
+ &scene->display_settings);
+
+ glClearColor(col_hor[0], col_hor[1], col_hor[2], 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ }
+ }
+ else {
+ if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) {
+ /* only clear depth buffer here */
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glShadeModel(GL_SMOOTH);
+ glBegin(GL_QUADS);
+ UI_ThemeColor(TH_LOW_GRAD);
+ glVertex2f(-1.0, -1.0);
+ glVertex2f(1.0, -1.0);
+ UI_ThemeColor(TH_HIGH_GRAD);
+ glVertex2f(1.0, 1.0);
+ glVertex2f(-1.0, 1.0);
+ glEnd();
+ glShadeModel(GL_FLAT);
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+ }
+ else {
+ UI_ThemeClearColor(TH_HIGH_GRAD);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ }
+ }
+}
+
/* warning: this function has duplicate drawing in ED_view3d_draw_offscreen() */
static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const char **grid_unit)
{
@@ -2981,7 +3137,6 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
Base *base;
- float backcol[3];
unsigned int lay_used;
/* shadow buffers, before we setup matrices */
@@ -2994,21 +3149,12 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const
GPU_default_lights();
}
- /* clear background */
- if ((v3d->flag2 & V3D_RENDER_OVERRIDE) && scene->world) {
- IMB_colormanagement_pixel_to_display_space_v3(backcol, &scene->world->horr, &scene->view_settings,
- &scene->display_settings);
-
- glClearColor(backcol[0], backcol[1], backcol[2], 0.0);
- }
- else
- UI_ThemeClearColor(TH_BACK);
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
/* setup view matrices */
view3d_main_area_setup_view(scene, v3d, ar, NULL, NULL);
+ /* clear the background */
+ view3d_main_area_clear(scene, v3d, ar);
+
ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
if (rv3d->rflag & RV3D_CLIPPING)
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index e984a3f5cfd..a1e132c6601 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -2101,16 +2101,15 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
else {
if (event->type == MOUSEZOOM || event->type == MOUSEPAN) {
- /* Bypass Zoom invert flag for track pads (pass FALSE always) */
if (U.uiflag & USER_ZOOM_HORIZ) {
vod->origx = vod->oldx = event->x;
- viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) == 0);
+ viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) != 0);
}
else {
/* Set y move = x move as MOUSEZOOM uses only x axis to pass magnification value */
vod->origy = vod->oldy = vod->origy + event->x - event->prevx;
- viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) == 0);
+ viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) != 0);
}
ED_view3d_depth_tag_update(vod->rv3d);
diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c
index f8c9497a686..c2e75a1c5d9 100644
--- a/source/blender/editors/space_view3d/view3d_fly.c
+++ b/source/blender/editors/space_view3d/view3d_fly.c
@@ -76,7 +76,8 @@ enum {
FLY_MODAL_PRECISION_ENABLE,
FLY_MODAL_PRECISION_DISABLE,
FLY_MODAL_FREELOOK_ENABLE,
- FLY_MODAL_FREELOOK_DISABLE
+ FLY_MODAL_FREELOOK_DISABLE,
+ FLY_MODAL_SPEED, /* mousepan typically */
};
@@ -132,6 +133,8 @@ void fly_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_add_item(keymap, WHEELUPMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_ACCELERATE);
WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_DECELERATE);
+ WM_modalkeymap_add_item(keymap, MOUSEPAN, 0, 0, 0, FLY_MODAL_SPEED);
+
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_PAN_ENABLE);
/* XXX - Bug in the event system, middle mouse release doesnt work */
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, FLY_MODAL_PAN_DISABLE);
@@ -544,7 +547,22 @@ static void flyEvent(FlyInfo *fly, wmEvent *event)
case FLY_MODAL_CONFIRM:
fly->state = FLY_CONFIRM;
break;
-
+
+ /* speed adjusting with mousepan (trackpad) */
+ case FLY_MODAL_SPEED:
+ {
+ float fac = 0.02f * (event->prevy - event->y);
+
+ /* allowing to brake immediate */
+ if (fac > 0.0f && fly->speed < 0.0f)
+ fly->speed = 0.0f;
+ else if (fac < 0.0f && fly->speed > 0.0f)
+ fly->speed = 0.0f;
+ else
+ fly->speed += fly->grid * fac;
+
+ break;
+ }
case FLY_MODAL_ACCELERATE:
{
double time_currwheel;
@@ -816,7 +834,7 @@ static int flyApply(bContext *C, FlyInfo *fly)
/* scale the mouse movement by this value - scales mouse movement to the view size
- * moffset[0]/(ar->winx-xmargin*2) - window size minus margin (same for y)
+ * moffset[0] / (ar->winx-xmargin * 2) - window size minus margin (same for y)
*
* the mouse moves isn't linear */
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 3b443e8bbac..5b5e5206e9c 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -462,7 +462,10 @@ static void viewRedrawForce(const bContext *C, TransInfo *t)
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
else
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
-
+
+ if (t->mode == TFM_EDGE_SLIDE && (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT))
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL);
+
/* for realtime animation record - send notifiers recognised by animation editors */
// XXX: is this notifier a lame duck?
if ((t->animtimer) && IS_AUTOKEY_ON(t->scene))
@@ -5262,7 +5265,7 @@ static int createSlideVerts(TransInfo *t)
if (dot_v3v3(loop_dir[l_nr], dir) < 0.0f) {
swap_v3_v3(sv_array->upvec, sv_array->downvec);
SWAP(BMVert, sv_array->vup, sv_array->vdown);
- SWAP(BMVert*, sv_array->up, sv_array->down);
+ SWAP(BMVert *, sv_array->up, sv_array->down);
}
}
@@ -5424,7 +5427,7 @@ void projectSVData(TransInfo *t, int final)
}
}
-
+
if (!affected)
continue;
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 12b0341d395..d38bdb178fb 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -127,30 +127,24 @@ static short constraints_list_needinv(TransInfo *t, ListBase *list);
/* ************************** Functions *************************** */
-static int trans_data_compare_dist(const void *A, const void *B)
+static int trans_data_compare_dist(const void *a, const void *b)
{
- const TransData *td_A = (const TransData*)A;
- const TransData *td_B = (const TransData*)B;
+ const TransData *td_a = (const TransData *)a;
+ const TransData *td_b = (const TransData *)b;
- if (td_A->dist < td_B->dist)
- return -1;
- else if (td_A->dist > td_B->dist)
- return 1;
-
- return 0;
+ if (td_a->dist < td_b->dist) return -1;
+ else if (td_a->dist > td_b->dist) return 1;
+ else return 0;
}
-static int trans_data_compare_rdist(const void *A, const void *B)
+static int trans_data_compare_rdist(const void *a, const void *b)
{
- const TransData *td_A = (const TransData*)A;
- const TransData *td_B = (const TransData*)B;
+ const TransData *td_a = (const TransData *)a;
+ const TransData *td_b = (const TransData *)b;
- if (td_A->rdist < td_B->rdist)
- return -1;
- else if (td_A->rdist > td_B->rdist)
- return 1;
-
- return 0;
+ if (td_a->rdist < td_b->rdist) return -1;
+ else if (td_a->rdist > td_b->rdist) return 1;
+ else return 0;
}
void sort_trans_data_dist(TransInfo *t)
@@ -295,6 +289,7 @@ static void createTransEdge(TransInfo *t)
float mtx[3][3], smtx[3][3];
int count = 0, countsel = 0;
int propmode = t->flag & T_PROP_EDIT;
+ int cd_edge_float_offset;
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
@@ -318,8 +313,22 @@ static void createTransEdge(TransInfo *t)
copy_m3_m4(mtx, t->obedit->obmat);
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
+ /* create data we need */
+ if (t->mode == TFM_BWEIGHT) {
+ BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(t->obedit), ME_CDFLAG_EDGE_BWEIGHT);
+ cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_BWEIGHT);
+ }
+ else { //if (t->mode == TFM_CREASE) {
+ BLI_assert(t->mode == TFM_CREASE);
+ BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(t->obedit), ME_CDFLAG_EDGE_CREASE);
+ cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_CREASE);
+ }
+
+ BLI_assert(cd_edge_float_offset != -1);
+
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && (BM_elem_flag_test(eed, BM_ELEM_SELECT) || propmode)) {
+ float *fl_ptr;
/* need to set center for center calculations */
mid_v3_v3v3(td->center, eed->v1->co, eed->v2->co);
@@ -333,17 +342,10 @@ static void createTransEdge(TransInfo *t)
copy_m3_m3(td->mtx, mtx);
td->ext = NULL;
- if (t->mode == TFM_BWEIGHT) {
- float *bweight = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_BWEIGHT);
- td->val = bweight;
- td->ival = bweight ? *bweight : 1.0f;
- }
- else {
- float *crease = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_CREASE);
- BLI_assert(t->mode == TFM_CREASE);
- td->val = crease;
- td->ival = crease ? *crease : 0.0f;
- }
+
+ fl_ptr = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_float_offset);
+ td->val = fl_ptr;
+ td->ival = *fl_ptr;
td++;
}
@@ -1913,8 +1915,8 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx
td->val = NULL;
td->extra = NULL;
if (t->mode == TFM_BWEIGHT) {
- td->val = bweight;
- td->ival = bweight ? *(bweight) : 1.0f;
+ td->val = bweight;
+ td->ival = *bweight;
}
else if (t->mode == TFM_SKIN_RESIZE) {
MVertSkin *vs = CustomData_bmesh_get(&em->bm->vdata,
@@ -1950,6 +1952,7 @@ static void createTransEditVerts(TransInfo *t)
int mirror = 0;
char *selstate = NULL;
short selectmode = ts->selectmode;
+ int cd_vert_bweight_offset = -1;
if (t->flag & T_MIRROR) {
EDBM_verts_mirror_cache_begin(em, TRUE);
@@ -2031,6 +2034,10 @@ static void createTransEditVerts(TransInfo *t)
}
}
+ if (t->mode == TFM_BWEIGHT) {
+ BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(t->obedit), ME_CDFLAG_VERT_BWEIGHT);
+ cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ }
if (propmode) {
t->total = count;
@@ -2097,11 +2104,10 @@ static void createTransEditVerts(TransInfo *t)
}
}
- eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL);
- for (a = 0; eve; eve = BM_iter_step(&iter), a++) {
+ BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) {
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
if (propmode || selstate[a]) {
- float *bweight = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_BWEIGHT);
+ float *bweight = (cd_vert_bweight_offset != -1) ? BM_ELEM_CD_GET_VOID_P(eve, cd_vert_bweight_offset) : NULL;
VertsToTransData(t, tob, tx, em, eve, bweight);
if (tx)
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index 607640090aa..023f281aea9 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -194,8 +194,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len);
totarea += BM_face_calc_area(efa);
- //totuvarea += tf_area(tf, efa->v4!=0);
- totuvarea += uv_poly_area(tf_uv, efa->len);
+ totuvarea += area_poly_v2(efa->len, tf_uv);
if (uvedit_face_visible_test(scene, ima, efa, tf)) {
BM_elem_flag_enable(efa, BM_ELEM_TAG);
@@ -238,8 +237,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len);
- //uvarea = tf_area(tf, efa->v4!=0) / totuvarea;
- uvarea = uv_poly_area(tf_uv, efa->len) / totuvarea;
+ uvarea = area_poly_v2(efa->len, tf_uv) / totuvarea;
if (area < FLT_EPSILON || uvarea < FLT_EPSILON)
areadiff = 1.0f;
diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h
index 4d52282d540..b6d82451d2f 100644
--- a/source/blender/editors/uvedit/uvedit_intern.h
+++ b/source/blender/editors/uvedit/uvedit_intern.h
@@ -50,7 +50,6 @@ struct BMVert;
int uvedit_face_visible_nolocal(struct Scene *scene, struct BMFace *efa);
/* geometric utilities */
-float uv_poly_area(float uv[][2], int len);
void uv_poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy, int len);
void uv_poly_center(struct BMEditMesh *em, struct BMFace *f, float r_cent[2]);
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 4336eb02752..2194ce28353 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -575,19 +575,6 @@ void uv_poly_center(BMEditMesh *em, BMFace *f, float r_cent[2])
mul_v2_fl(r_cent, 1.0f / (float)f->len);
}
-float uv_poly_area(float uv[][2], int len)
-{
- //BMESH_TODO: make this not suck
- //maybe use scanfill? I dunno.
-
- if (len >= 4)
- return area_tri_v2(uv[0], uv[1], uv[2]) + area_tri_v2(uv[0], uv[2], uv[3]);
- else
- return area_tri_v2(uv[0], uv[1], uv[2]);
-
- return 1.0;
-}
-
void uv_poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy, int len)
{
int i;
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index 8c3eaa1192f..b1bb5c85e50 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -799,7 +799,7 @@ static void stitch_validate_edge_stichability(UvEdge *edge, StitchState *state,
}
-static void stitch_propagate_uv_final_position (UvElement *element, int index, PreviewPosition *preview_position, UVVertAverage *final_position, StitchState *state, char final, Scene* scene)
+static void stitch_propagate_uv_final_position(UvElement *element, int index, PreviewPosition *preview_position, UVVertAverage *final_position, StitchState *state, char final, Scene *scene)
{
StitchPreviewer *preview = state->stitch_preview;
@@ -1273,7 +1273,8 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
UvElement *element = state->selection_stack[i];
stitch_propagate_uv_final_position (element, i, preview_position, final_position, state, final, scene);
- } else {
+ }
+ else {
UvEdge *edge = state->selection_stack[i];
stitch_propagate_uv_final_position (state->uvs[edge->uv1], edge->uv1, preview_position, final_position, state, final, scene);
@@ -1391,7 +1392,7 @@ static void stitch_switch_selection_mode(StitchState *state)
if (state->mode == STITCH_VERT) {
int i;
- state->selection_stack = MEM_mallocN(state->total_separate_edges*sizeof(*state->selection_stack),
+ state->selection_stack = MEM_mallocN(state->total_separate_edges * sizeof(*state->selection_stack),
"stitch_new_edge_selection_stack");
/* check if both elements of an edge are selected */
@@ -1414,7 +1415,7 @@ static void stitch_switch_selection_mode(StitchState *state)
}
else {
int i;
- state->selection_stack = MEM_mallocN(state->total_separate_uvs*sizeof(*state->selection_stack),
+ state->selection_stack = MEM_mallocN(state->total_separate_uvs * sizeof(*state->selection_stack),
"stitch_new_vert_selection_stack");
for (i = 0; i < old_selection_size; i++) {
@@ -1501,11 +1502,11 @@ static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *ar
else {
UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE);
glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable);
- glDrawArrays(GL_LINES, 0, 2*stitch_preview->num_stitchable);
+ glDrawArrays(GL_LINES, 0, 2 * stitch_preview->num_stitchable);
UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE);
glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable);
- glDrawArrays(GL_LINES, 0, 2*stitch_preview->num_unstitchable);
+ glDrawArrays(GL_LINES, 0, 2 * stitch_preview->num_unstitchable);
}
glPopClientAttrib();
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index 850060ef4d5..a19433dbd2f 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -373,8 +373,6 @@ void IMB_rect_from_float(struct ImBuf *ibuf);
* Changed part will be stored in buffer. This is expected to be used for texture painting updates */
void IMB_partial_rect_from_float(struct ImBuf *ibuf, float *buffer, int x, int y, int w, int h, int is_data);
void IMB_float_from_rect(struct ImBuf *ibuf);
-/* note, check that the conversion exists, only some are supported */
-float *IMB_float_profile_ensure(struct ImBuf *ibuf, int profile, int *alloc);
void IMB_color_to_bw(struct ImBuf *ibuf);
void IMB_saturation(struct ImBuf *ibuf, float sat);
@@ -416,6 +414,9 @@ void nearest_interpolation_color(struct ImBuf *in, unsigned char col[4], float c
void bilinear_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
+void IMB_alpha_under_color_float(float *rect_float, int x, int y, float backcol[3]);
+void IMB_alpha_under_color_byte(unsigned char *rect, int x, int y, float backcol[3]);
+
/**
*
* \attention defined in readimage.c
diff --git a/source/blender/imbuf/IMB_thumbs.h b/source/blender/imbuf/IMB_thumbs.h
index a6f38516a14..9fc075e4e8b 100644
--- a/source/blender/imbuf/IMB_thumbs.h
+++ b/source/blender/imbuf/IMB_thumbs.h
@@ -58,7 +58,7 @@ typedef enum ThumbSource {
} ThumbSource;
/* don't generate thumbs for images bigger then this (100mb) */
-#define THUMB_SIZE_MAX (100 * 1024*1024)
+#define THUMB_SIZE_MAX (100 * 1024 * 1024)
// IB_metadata
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index bcfddfe425a..2c6e46cb664 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -351,9 +351,9 @@ static unsigned char *colormanage_cache_get(ImBuf *ibuf, const ColormanageCacheV
if (cache_data->exposure != view_settings->exposure ||
cache_data->gamma != view_settings->gamma ||
- cache_data->flag != view_settings->flag ||
- cache_data->curve_mapping != curve_mapping ||
- cache_data->curve_mapping_timestamp != curve_mapping_timestamp)
+ cache_data->flag != view_settings->flag ||
+ cache_data->curve_mapping != curve_mapping ||
+ cache_data->curve_mapping_timestamp != curve_mapping_timestamp)
{
*cache_handle = NULL;
@@ -681,7 +681,7 @@ static ColorSpace *display_transform_get_colorspace(const ColorManagedViewSettin
}
static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *view_transform, const char *display,
- float exposure, float gamma)
+ float exposure, float gamma)
{
OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig();
OCIO_DisplayTransformRcPtr *dt;
@@ -698,7 +698,7 @@ static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *vie
if (exposure != 0.0f) {
OCIO_MatrixTransformRcPtr *mt;
float gain = powf(2.0f, exposure);
- const float scale4f[] = {gain, gain, gain, gain};
+ const float scale4f[] = {gain, gain, gain, 1.0f};
float m44[16], offset4[4];
OCIO_matrixTransformScale(m44, offset4, scale4f);
@@ -731,7 +731,7 @@ static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *vie
}
static OCIO_ConstProcessorRcPtr *create_colorspace_transform_processor(const char *from_colorspace,
- const char *to_colorspace)
+ const char *to_colorspace)
{
OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig();
OCIO_ConstProcessorRcPtr *processor;
@@ -1591,14 +1591,14 @@ void IMB_colormanagement_colorspace_to_scene_linear(float *buffer, int width, in
OCIO_PackedImageDesc *img;
img = OCIO_createOCIO_PackedImageDesc(buffer, width, height, channels, sizeof(float),
- channels * sizeof(float), channels * sizeof(float) * width);
+ channels * sizeof(float), channels * sizeof(float) * width);
if (predivide)
OCIO_processorApply_predivide(processor, img);
else
OCIO_processorApply(processor, img);
- OCIO_OCIO_PackedImageDescRelease(img);
+ OCIO_PackedImageDescRelease(img);
}
}
@@ -2538,14 +2538,14 @@ void IMB_colormanagement_processor_apply(ColormanageProcessor *cm_processor, flo
/* apply OCIO processor */
img = OCIO_createOCIO_PackedImageDesc(buffer, width, height, channels, sizeof(float),
- channels * sizeof(float), channels * sizeof(float) * width);
+ channels * sizeof(float), channels * sizeof(float) * width);
if (predivide)
OCIO_processorApply_predivide(cm_processor->processor, img);
else
OCIO_processorApply(cm_processor->processor, img);
- OCIO_OCIO_PackedImageDescRelease(img);
+ OCIO_PackedImageDescRelease(img);
}
}
diff --git a/source/blender/imbuf/intern/dds/ColorBlock.h b/source/blender/imbuf/intern/dds/ColorBlock.h
index f0864f06e6f..730a19d84fd 100644
--- a/source/blender/imbuf/intern/dds/ColorBlock.h
+++ b/source/blender/imbuf/intern/dds/ColorBlock.h
@@ -69,7 +69,7 @@ struct ColorBlock
private:
- Color32 m_color[4*4];
+ Color32 m_color[4 * 4];
};
diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.h b/source/blender/imbuf/intern/dds/DirectDrawSurface.h
index 72a524daba2..11e6d4a5708 100644
--- a/source/blender/imbuf/intern/dds/DirectDrawSurface.h
+++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.h
@@ -172,7 +172,7 @@ public:
void setUserVersion(int version);
void mipmap(Image * img, uint f, uint m);
- void* readData(uint &size);
+ void *readData(uint &size);
// void mipmap(FloatImage * img, uint f, uint m);
void printInfo() const;
diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c
index f0d8b7cac72..84339b51721 100644
--- a/source/blender/imbuf/intern/divers.c
+++ b/source/blender/imbuf/intern/divers.c
@@ -659,53 +659,6 @@ void IMB_float_from_rect(ImBuf *ibuf)
BLI_unlock_thread(LOCK_COLORMANAGE);
}
-/* use when you need to get a buffer with a certain profile
- * if the return */
-
-/* OCIO_TODO: used only by Cineon/DPX exporter which is still broken, so can not guarantee
- * this function is working properly
- */
-float *IMB_float_profile_ensure(ImBuf *ibuf, int profile, int *alloc)
-{
- int profile_from = IB_PROFILE_LINEAR_RGB;
- int profile_to;
-
- /* determine profile */
- if (profile == IB_PROFILE_NONE)
- profile_to = IB_PROFILE_LINEAR_RGB;
- else
- profile_to = IB_PROFILE_SRGB;
-
- if (profile_from == profile_to) {
- /* simple case, just allocate the buffer and return */
- *alloc = 0;
-
- if (ibuf->rect_float == NULL)
- IMB_float_from_rect(ibuf);
-
- return ibuf->rect_float;
- }
- else {
- /* conversion is needed, first check */
- float *fbuf = MEM_mallocN(ibuf->x * ibuf->y * sizeof(float) * 4, "IMB_float_profile_ensure");
- *alloc = 1;
-
- if (ibuf->rect_float == NULL) {
- IMB_buffer_float_from_byte(fbuf, (uchar *)ibuf->rect,
- profile_to, profile_from, FALSE,
- ibuf->x, ibuf->y, ibuf->x, ibuf->x);
- IMB_premultiply_rect_float(ibuf->rect_float, ibuf->planes, ibuf->x, ibuf->y);
- }
- else {
- IMB_buffer_float_from_float(fbuf, ibuf->rect_float,
- 4, profile_to, profile_from, TRUE,
- ibuf->x, ibuf->y, ibuf->x, ibuf->x);
- }
-
- return fbuf;
- }
-}
-
/**************************** Color to Grayscale *****************************/
/* no profile conversion */
diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c
index 1eac6236829..59282c9d207 100644
--- a/source/blender/imbuf/intern/imageprocess.c
+++ b/source/blender/imbuf/intern/imageprocess.c
@@ -327,3 +327,53 @@ void IMB_processor_apply_threaded(int buffer_lines, int handle_size, void *init_
MEM_freeN(handles);
}
+
+/* Alpha-under */
+
+void IMB_alpha_under_color_float(float *rect_float, int x, int y, float backcol[3])
+{
+ int a = x * y;
+ float *fp = rect_float;
+
+ while (a--) {
+ if (fp[3] == 0.0f) {
+ copy_v3_v3(fp, backcol);
+ }
+ else {
+ float mul = 1.0f - fp[3];
+
+ fp[0] += mul * backcol[0];
+ fp[1] += mul * backcol[1];
+ fp[2] += mul * backcol[2];
+ }
+
+ fp[3] = 1.0f;
+
+ fp += 4;
+ }
+}
+
+void IMB_alpha_under_color_byte(unsigned char *rect, int x, int y, float backcol[3])
+{
+ int a = x * y;
+ unsigned char *cp = rect;
+
+ while (a--) {
+ if (cp[3] == 0) {
+ cp[0] = backcol[0] * 255;
+ cp[1] = backcol[1] * 255;
+ cp[2] = backcol[2] * 255;
+ }
+ else {
+ int mul = 255 - cp[3];
+
+ cp[0] += mul * backcol[0] / 255;
+ cp[1] += mul * backcol[1] / 255;
+ cp[2] += mul * backcol[2] / 255;
+ }
+
+ cp[3] = 255;
+
+ cp += 4;
+ }
+}
diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h
index 03b23c5137a..da666059601 100644
--- a/source/blender/makesdna/DNA_mesh_types.h
+++ b/source/blender/makesdna/DNA_mesh_types.h
@@ -119,7 +119,10 @@ typedef struct Mesh {
short texflag, drawflag;
short smoothresh, flag;
- short subdiv DNA_DEPRECATED, subdivr DNA_DEPRECATED;
+ /* customdata flag, for bevel-weight and crease, which are now optional */
+ char cd_flag, pad;
+
+ char subdiv DNA_DEPRECATED, subdivr DNA_DEPRECATED;
char subsurftype DNA_DEPRECATED; /* only kept for backwards compat, not used anymore */
char editflag;
@@ -172,6 +175,11 @@ typedef struct TFace {
#define ME_DS_EXPAND 512
#define ME_SCULPT_DYNAMIC_TOPOLOGY 1024
+/* me->cd_flag */
+#define ME_CDFLAG_VERT_BWEIGHT (1 << 0)
+#define ME_CDFLAG_EDGE_BWEIGHT (1 << 1)
+#define ME_CDFLAG_EDGE_CREASE (1 << 2)
+
/* me->drawflag, short */
#define ME_DRAWEDGES (1 << 0)
#define ME_DRAWFACES (1 << 1)
diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h
index af1981ae07d..b85bdecee02 100644
--- a/source/blender/makesdna/DNA_meshdata_types.h
+++ b/source/blender/makesdna/DNA_meshdata_types.h
@@ -167,7 +167,7 @@ typedef struct MIntProperty {
int i;
} MIntProperty;
typedef struct MStringProperty {
- char s[256];
+ char s[255], s_len;
} MStringProperty;
typedef struct OrigSpaceFace {
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 89328c33674..559ba446740 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -178,7 +178,7 @@ typedef struct Object {
short ipoflag; // xxx deprecated... old animation system
short scaflag; /* ui state for game logic */
char scavisflag; /* more display settings for game logic */
- char pad5;
+ char depsflag;
int dupon, dupoff, dupsta, dupend;
@@ -530,6 +530,10 @@ typedef struct DupliObject {
#define OB_BODY_TYPE_NAVMESH 7
#define OB_BODY_TYPE_CHARACTER 8
+/* ob->depsflag */
+#define OB_DEPS_EXTRA_OB_RECALC 1
+#define OB_DEPS_EXTRA_DATA_RECALC 2
+
/* ob->scavisflag */
#define OB_VIS_SENS 1
#define OB_VIS_CONT 2
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index e7f27834c85..96bf4a10dda 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -149,6 +149,13 @@ typedef struct uiPanelColors {
int pad;
} uiPanelColors;
+typedef struct uiGradientColors {
+ char gradient[4];
+ char high_gradient[4];
+ int show_grad;
+ int pad2;
+} uiGradientColors;
+
typedef struct ThemeUI {
/* Interface Elements (buttons, menus, icons) */
uiWidgetColors wcol_regular, wcol_tool, wcol_text;
@@ -210,7 +217,9 @@ typedef struct ThemeSpace {
/* note, cannot use name 'panel' because of DNA mapping old files */
uiPanelColors panelcolors;
-
+
+ uiGradientColors gradients;
+
char shade1[4];
char shade2[4];
@@ -440,6 +449,7 @@ typedef struct UserDef {
int ndof_flag; /* flags for 3D mouse */
short ogl_multisamples; /* amount of samples for OpenGL FSA, if zero no FSA */
+
short pad4;
float glalphaclip;
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 8956e9d9005..af182c467be 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -610,6 +610,7 @@ extern StructRNA RNA_ThemeOutliner;
extern StructRNA RNA_ThemeProperties;
extern StructRNA RNA_ThemeSequenceEditor;
extern StructRNA RNA_ThemeSpaceGeneric;
+extern StructRNA RNA_ThemeSpaceGradient;
extern StructRNA RNA_ThemeSpaceListGeneric;
extern StructRNA RNA_ThemeStyle;
extern StructRNA RNA_ThemeTextEditor;
diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h
index 9939d0839e6..463e0e04679 100644
--- a/source/blender/makesrna/RNA_define.h
+++ b/source/blender/makesrna/RNA_define.h
@@ -49,6 +49,7 @@ void RNA_exit(void);
/* Struct */
+StructRNA *RNA_def_struct_ptr(BlenderRNA *brna, const char *identifier, StructRNA *srnafrom);
StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from);
void RNA_def_struct_sdna(StructRNA *srna, const char *structname);
void RNA_def_struct_sdna_from(StructRNA *srna, const char *structname, const char *propname);
@@ -91,7 +92,6 @@ PropertyRNA *RNA_def_string_translate(StructOrFunctionRNA *cont, const char *ide
PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description);
PropertyRNA *RNA_def_enum_flag(StructOrFunctionRNA *cont, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description);
void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc);
-void RNA_def_enum_py_data(PropertyRNA *prop, void *py_data);
PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax);
PropertyRNA *RNA_def_float_vector(StructOrFunctionRNA *cont, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax);
@@ -177,6 +177,17 @@ void RNA_def_property_collection_funcs(PropertyRNA *prop, const char *begin, con
void RNA_def_property_srna(PropertyRNA *prop, const char *type);
void RNA_def_py_data(PropertyRNA *prop, void *py_data);
+void RNA_def_property_boolean_funcs_runtime(PropertyRNA *prop, BooleanPropertyGetFunc getfunc, BooleanPropertySetFunc setfunc);
+void RNA_def_property_boolean_array_funcs_runtime(PropertyRNA *prop, BooleanArrayPropertyGetFunc getfunc, BooleanArrayPropertySetFunc setfunc);
+void RNA_def_property_int_funcs_runtime(PropertyRNA *prop, IntPropertyGetFunc getfunc, IntPropertySetFunc setfunc, IntPropertyRangeFunc rangefunc);
+void RNA_def_property_int_array_funcs_runtime(PropertyRNA *prop, IntArrayPropertyGetFunc getfunc, IntArrayPropertySetFunc setfunc, IntPropertyRangeFunc rangefunc);
+void RNA_def_property_float_funcs_runtime(PropertyRNA *prop, FloatPropertyGetFunc getfunc, FloatPropertySetFunc setfunc, FloatPropertyRangeFunc rangefunc);
+void RNA_def_property_float_array_funcs_runtime(PropertyRNA *prop, FloatArrayPropertyGetFunc getfunc, FloatArrayPropertySetFunc setfunc, FloatPropertyRangeFunc rangefunc);
+void RNA_def_property_enum_funcs_runtime(PropertyRNA *prop, EnumPropertyGetFunc getfunc, EnumPropertySetFunc setfunc, EnumPropertyItemFunc itemfunc);
+void RNA_def_property_string_funcs_runtime(PropertyRNA *prop, StringPropertyGetFunc getfunc, StringPropertyLengthFunc lengthfunc, StringPropertySetFunc setfunc);
+
+void RNA_def_property_enum_py_data(PropertyRNA *prop, void *py_data);
+
void RNA_def_property_translation_context(PropertyRNA *prop, const char *context);
/* Function */
diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h
index dacb2fee212..c76f9824c73 100644
--- a/source/blender/makesrna/RNA_types.h
+++ b/source/blender/makesrna/RNA_types.h
@@ -269,7 +269,27 @@ typedef struct EnumPropertyItem {
const char *description;
} EnumPropertyItem;
-/* this is a copy of 'PropEnumItemFunc' defined in rna_internal_types.h */
+/* extended versions with PropertyRNA argument */
+typedef int (*BooleanPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*BooleanPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value);
+typedef void (*BooleanArrayPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values);
+typedef void (*BooleanArrayPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values);
+typedef int (*IntPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*IntPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value);
+typedef void (*IntArrayPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values);
+typedef void (*IntArrayPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values);
+typedef void (*IntPropertyRangeFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *min, int *max, int *softmin, int *softmax);
+typedef float (*FloatPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*FloatPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, float value);
+typedef void (*FloatArrayPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, float *values);
+typedef void (*FloatArrayPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, const float *values);
+typedef void (*FloatPropertyRangeFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, float *min, float *max, float *softmin, float *softmax);
+typedef void (*StringPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, char *value);
+typedef int (*StringPropertyLengthFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*StringPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, const char *value);
+typedef int (*EnumPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*EnumPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value);
+/* same as PropEnumItemFunc */
typedef EnumPropertyItem *(*EnumPropertyItemFunc)(struct bContext *C, PointerRNA *ptr, struct PropertyRNA *prop, int *free);
typedef struct PropertyRNA PropertyRNA;
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index a9cb6cdf77e..0992153560f 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -2947,11 +2947,15 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
case PROP_BOOLEAN:
{
BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
- fprintf(f, "\t%s, %s, %s, %s, %d, ",
+ fprintf(f, "\t%s, %s, %s, %s, %s, %s, %s, %s, %d, ",
rna_function_string(bprop->get),
rna_function_string(bprop->set),
rna_function_string(bprop->getarray),
rna_function_string(bprop->setarray),
+ rna_function_string(bprop->get_ex),
+ rna_function_string(bprop->set_ex),
+ rna_function_string(bprop->getarray_ex),
+ rna_function_string(bprop->setarray_ex),
bprop->defaultvalue);
if (prop->arraydimension && prop->totarraylength)
fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier);
@@ -2961,12 +2965,17 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
case PROP_INT:
{
IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
- fprintf(f, "\t%s, %s, %s, %s, %s,\n\t",
+ fprintf(f, "\t%s, %s, %s, %s, %s, %s, %s, %s, %s, %s,\n\t",
rna_function_string(iprop->get),
rna_function_string(iprop->set),
rna_function_string(iprop->getarray),
rna_function_string(iprop->setarray),
- rna_function_string(iprop->range));
+ rna_function_string(iprop->range),
+ rna_function_string(iprop->get_ex),
+ rna_function_string(iprop->set_ex),
+ rna_function_string(iprop->getarray_ex),
+ rna_function_string(iprop->setarray_ex),
+ rna_function_string(iprop->range_ex));
rna_int_print(f, iprop->softmin); fprintf(f, ", ");
rna_int_print(f, iprop->softmax); fprintf(f, ", ");
rna_int_print(f, iprop->hardmin); fprintf(f, ", ");
@@ -2981,12 +2990,17 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
case PROP_FLOAT:
{
FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
- fprintf(f, "\t%s, %s, %s, %s, %s, ",
+ fprintf(f, "\t%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, ",
rna_function_string(fprop->get),
rna_function_string(fprop->set),
rna_function_string(fprop->getarray),
rna_function_string(fprop->setarray),
- rna_function_string(fprop->range));
+ rna_function_string(fprop->range),
+ rna_function_string(fprop->get_ex),
+ rna_function_string(fprop->set_ex),
+ rna_function_string(fprop->getarray_ex),
+ rna_function_string(fprop->setarray_ex),
+ rna_function_string(fprop->range_ex));
rna_float_print(f, fprop->softmin); fprintf(f, ", ");
rna_float_print(f, fprop->softmax); fprintf(f, ", ");
rna_float_print(f, fprop->hardmin); fprintf(f, ", ");
@@ -3002,10 +3016,13 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
case PROP_STRING:
{
StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
- fprintf(f, "\t%s, %s, %s, %d, ",
+ fprintf(f, "\t%s, %s, %s, %s, %s, %s, %d, ",
rna_function_string(sprop->get),
rna_function_string(sprop->length),
rna_function_string(sprop->set),
+ rna_function_string(sprop->get_ex),
+ rna_function_string(sprop->length_ex),
+ rna_function_string(sprop->set_ex),
sprop->maxlength);
rna_print_c_string(f, sprop->defaultvalue); fprintf(f, "\n");
break;
@@ -3013,10 +3030,12 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
case PROP_ENUM:
{
EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
- fprintf(f, "\t%s, %s, %s, NULL, ",
+ fprintf(f, "\t%s, %s, %s, %s, %s, NULL, ",
rna_function_string(eprop->get),
rna_function_string(eprop->set),
- rna_function_string(eprop->itemf));
+ rna_function_string(eprop->itemf),
+ rna_function_string(eprop->get_ex),
+ rna_function_string(eprop->set_ex));
if (eprop->item)
fprintf(f, "rna_%s%s_%s_items, ", srna->identifier, strnest, prop->identifier);
else
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index 092c9eb2b17..18281d4d251 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -257,7 +257,7 @@ StructRNA *rna_PropertyGroup_register(Main *UNUSED(bmain), ReportList *reports,
return NULL;
}
- return RNA_def_struct(&BLENDER_RNA, identifier, "PropertyGroup"); /* XXX */
+ return RNA_def_struct_ptr(&BLENDER_RNA, identifier, &RNA_PropertyGroup); /* XXX */
}
StructRNA *rna_PropertyGroup_refine(PointerRNA *ptr)
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 0048e1c60c2..59bcb1506af 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -40,6 +40,7 @@
#include "BLI_utildefines.h"
#include "BLI_dynstr.h"
#include "BLI_ghash.h"
+#include "BLI_math.h"
#include "BLF_api.h"
#include "BLF_translation.h"
@@ -937,6 +938,12 @@ void RNA_property_int_range(PointerRNA *ptr, PropertyRNA *prop, int *hardmin, in
iprop->range(ptr, hardmin, hardmax, &softmin, &softmax);
}
+ else if (iprop->range_ex) {
+ *hardmin = INT_MIN;
+ *hardmax = INT_MAX;
+
+ iprop->range_ex(ptr, prop, hardmin, hardmax, &softmin, &softmax);
+ }
else {
*hardmin = iprop->hardmin;
*hardmax = iprop->hardmax;
@@ -977,8 +984,17 @@ void RNA_property_int_ui_range(PointerRNA *ptr, PropertyRNA *prop, int *softmin,
iprop->range(ptr, &hardmin, &hardmax, softmin, softmax);
- *softmin = MAX2(*softmin, hardmin);
- *softmax = MIN2(*softmax, hardmax);
+ *softmin = max_ii(*softmin, hardmin);
+ *softmax = min_ii(*softmax, hardmax);
+ }
+ else if (iprop->range_ex) {
+ hardmin = INT_MIN;
+ hardmax = INT_MAX;
+
+ iprop->range_ex(ptr, prop, &hardmin, &hardmax, softmin, softmax);
+
+ *softmin = max_ii(*softmin, hardmin);
+ *softmax = min_ii(*softmax, hardmax);
}
*step = iprop->step;
@@ -1012,6 +1028,12 @@ void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin
fprop->range(ptr, hardmin, hardmax, &softmin, &softmax);
}
+ else if (fprop->range_ex) {
+ *hardmin = -FLT_MAX;
+ *hardmax = FLT_MAX;
+
+ fprop->range_ex(ptr, prop, hardmin, hardmax, &softmin, &softmax);
+ }
else {
*hardmin = fprop->hardmin;
*hardmax = fprop->hardmax;
@@ -1056,8 +1078,17 @@ void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *soft
fprop->range(ptr, &hardmin, &hardmax, softmin, softmax);
- *softmin = MAX2(*softmin, hardmin);
- *softmax = MIN2(*softmax, hardmax);
+ *softmin = max_ff(*softmin, hardmin);
+ *softmax = min_ff(*softmax, hardmax);
+ }
+ else if (fprop->range_ex) {
+ hardmin = -FLT_MAX;
+ hardmax = FLT_MAX;
+
+ fprop->range_ex(ptr, prop, &hardmin, &hardmax, softmin, softmax);
+
+ *softmin = max_ff(*softmin, hardmin);
+ *softmax = min_ff(*softmax, hardmax);
}
*step = fprop->step;
@@ -1645,6 +1676,8 @@ int RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
return IDP_Int(idprop);
else if (bprop->get)
return bprop->get(ptr);
+ else if (bprop->get_ex)
+ return bprop->get_ex(ptr, prop);
else
return bprop->defaultvalue;
}
@@ -1667,6 +1700,9 @@ void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, int value)
else if (bprop->set) {
bprop->set(ptr, value);
}
+ else if (bprop->set_ex) {
+ bprop->set_ex(ptr, prop, value);
+ }
else if (prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val = {0};
IDProperty *group;
@@ -1697,6 +1733,8 @@ void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, int *val
values[0] = RNA_property_boolean_get(ptr, prop);
else if (bprop->getarray)
bprop->getarray(ptr, values);
+ else if (bprop->getarray_ex)
+ bprop->getarray_ex(ptr, prop, values);
else if (bprop->defaultarray)
memcpy(values, bprop->defaultarray, sizeof(int) * prop->totarraylength);
else
@@ -1747,6 +1785,8 @@ void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const in
RNA_property_boolean_set(ptr, prop, values[0]);
else if (bprop->setarray)
bprop->setarray(ptr, values);
+ else if (bprop->setarray_ex)
+ bprop->setarray_ex(ptr, prop, values);
else if (prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val = {0};
IDProperty *group;
@@ -1848,6 +1888,8 @@ int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
return IDP_Int(idprop);
else if (iprop->get)
return iprop->get(ptr);
+ else if (iprop->get_ex)
+ return iprop->get_ex(ptr, prop);
else
return iprop->defaultvalue;
}
@@ -1868,6 +1910,8 @@ void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
}
else if (iprop->set)
iprop->set(ptr, value);
+ else if (iprop->set_ex)
+ iprop->set_ex(ptr, prop, value);
else if (prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val = {0};
IDProperty *group;
@@ -1900,6 +1944,8 @@ void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
values[0] = RNA_property_int_get(ptr, prop);
else if (iprop->getarray)
iprop->getarray(ptr, values);
+ else if (iprop->getarray_ex)
+ iprop->getarray_ex(ptr, prop, values);
else if (iprop->defaultarray)
memcpy(values, iprop->defaultarray, sizeof(int) * prop->totarraylength);
else
@@ -1987,6 +2033,8 @@ void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *v
RNA_property_int_set(ptr, prop, values[0]);
else if (iprop->setarray)
iprop->setarray(ptr, values);
+ else if (iprop->setarray_ex)
+ iprop->setarray_ex(ptr, prop, values);
else if (prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val = {0};
IDProperty *group;
@@ -2087,6 +2135,8 @@ float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
}
else if (fprop->get)
return fprop->get(ptr);
+ else if (fprop->get_ex)
+ return fprop->get_ex(ptr, prop);
else
return fprop->defaultvalue;
}
@@ -2112,6 +2162,9 @@ void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
else if (fprop->set) {
fprop->set(ptr, value);
}
+ else if (fprop->set_ex) {
+ fprop->set_ex(ptr, prop, value);
+ }
else if (prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val = {0};
IDProperty *group;
@@ -2150,6 +2203,8 @@ void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *val
values[0] = RNA_property_float_get(ptr, prop);
else if (fprop->getarray)
fprop->getarray(ptr, values);
+ else if (fprop->getarray_ex)
+ fprop->getarray_ex(ptr, prop, values);
else if (fprop->defaultarray)
memcpy(values, fprop->defaultarray, sizeof(float) * prop->totarraylength);
else
@@ -2249,6 +2304,9 @@ void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const floa
else if (fprop->setarray) {
fprop->setarray(ptr, values);
}
+ else if (fprop->setarray_ex) {
+ fprop->setarray_ex(ptr, prop, values);
+ }
else if (prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val = {0};
IDProperty *group;
@@ -2361,6 +2419,9 @@ void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value)
else if (sprop->get) {
sprop->get(ptr, value);
}
+ else if (sprop->get_ex) {
+ sprop->get_ex(ptr, prop, value);
+ }
else {
strcpy(value, sprop->defaultvalue);
}
@@ -2421,6 +2482,8 @@ int RNA_property_string_length(PointerRNA *ptr, PropertyRNA *prop)
}
else if (sprop->length)
return sprop->length(ptr);
+ else if (sprop->length_ex)
+ return sprop->length_ex(ptr, prop);
else
return strlen(sprop->defaultvalue);
}
@@ -2439,6 +2502,8 @@ void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *val
}
else if (sprop->set)
sprop->set(ptr, value); /* set function needs to clamp its self */
+ else if (sprop->set_ex)
+ sprop->set_ex(ptr, prop, value); /* set function needs to clamp its self */
else if (prop->flag & PROP_EDITABLE) {
IDProperty *group;
@@ -2497,6 +2562,8 @@ int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
return IDP_Int(idprop);
else if (eprop->get)
return eprop->get(ptr);
+ else if (eprop->get_ex)
+ return eprop->get_ex(ptr, prop);
else
return eprop->defaultvalue;
}
@@ -2515,6 +2582,9 @@ void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
else if (eprop->set) {
eprop->set(ptr, value);
}
+ else if (eprop->set_ex) {
+ eprop->set_ex(ptr, prop, value);
+ }
else if (prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val = {0};
IDProperty *group;
@@ -4034,8 +4104,9 @@ static char *rna_idp_path(PointerRNA *ptr, IDProperty *haystack, IDProperty *nee
else {
if (iter->type == IDP_GROUP) {
/* ensure this is RNA */
- PointerRNA child_ptr = RNA_pointer_get(ptr, iter->name);
- if (child_ptr.type) {
+ PropertyRNA *prop = RNA_struct_find_property(ptr, iter->name);
+ if (prop && prop->type == PROP_POINTER) {
+ PointerRNA child_ptr = RNA_property_pointer_get(ptr, prop);
link.name = iter->name;
link.index = -1;
if ((path = rna_idp_path(&child_ptr, iter, needle, &link))) {
diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c
index 402d05a20b6..d6ea53f6ab3 100644
--- a/source/blender/makesrna/intern/rna_animation.c
+++ b/source/blender/makesrna/intern/rna_animation.c
@@ -198,6 +198,8 @@ static void rna_KeyingSetInfo_unregister(Main *bmain, StructRNA *type)
RNA_struct_free_extension(type, &ksi->ext);
RNA_struct_free(&BLENDER_RNA, type);
+ WM_main_add_notifier(NC_WINDOW, NULL);
+
/* unlink Blender-side data */
ANIM_keyingset_info_unregister(bmain, ksi);
}
@@ -234,7 +236,7 @@ static StructRNA *rna_KeyingSetInfo_register(Main *bmain, ReportList *reports, v
memcpy(ksi, &dummyksi, sizeof(KeyingSetInfo));
/* set RNA-extensions info */
- ksi->ext.srna = RNA_def_struct(&BLENDER_RNA, ksi->idname, "KeyingSetInfo");
+ ksi->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ksi->idname, &RNA_KeyingSetInfo);
ksi->ext.data = data;
ksi->ext.call = call;
ksi->ext.free = free;
@@ -249,6 +251,8 @@ static StructRNA *rna_KeyingSetInfo_register(Main *bmain, ReportList *reports, v
/* add and register with other info as needed */
ANIM_keyingset_info_register(ksi);
+ WM_main_add_notifier(NC_WINDOW, NULL);
+
/* return the struct-rna added */
return ksi->ext.srna;
}
@@ -577,7 +581,7 @@ static void rna_def_keyingset_info(BlenderRNA *brna)
RNA_def_struct_name_property(srna, prop);
RNA_def_property_flag(prop, PROP_REGISTER);
- prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE);
+ prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "description");
RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
@@ -777,7 +781,7 @@ static void rna_def_keyingset(BlenderRNA *brna)
RNA_def_struct_name_property(srna, prop);
RNA_def_property_update(prop, NC_SCENE | ND_KEYINGSET | NA_RENAME, NULL);
- prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE);
+ prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "description");
RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index 36d5a575ab4..bc4194ebffb 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -462,7 +462,7 @@ static void rna_ColorManagedViewSettings_view_transform_set(PointerRNA *ptr, int
}
}
-static EnumPropertyItem* rna_ColorManagedViewSettings_view_transform_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free)
+static EnumPropertyItem *rna_ColorManagedViewSettings_view_transform_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free)
{
Scene *scene = CTX_data_scene(C);
EnumPropertyItem *items = NULL;
diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c
index 727b1e44931..b94d7eb691f 100644
--- a/source/blender/makesrna/intern/rna_define.c
+++ b/source/blender/makesrna/intern/rna_define.c
@@ -623,13 +623,12 @@ static StructDefRNA *rna_find_def_struct(StructRNA *srna)
}
/* Struct Definition */
-
-StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from)
+StructRNA *RNA_def_struct_ptr(BlenderRNA *brna, const char *identifier, StructRNA *srnafrom)
{
- StructRNA *srna, *srnafrom = NULL;
+ StructRNA *srna;
StructDefRNA *ds = NULL, *dsfrom = NULL;
PropertyRNA *prop;
-
+
if (DefRNA.preprocess) {
char error[512];
@@ -638,18 +637,6 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *
DefRNA.error = 1;
}
}
-
- if (from) {
- /* find struct to derive from */
- for (srnafrom = brna->structs.first; srnafrom; srnafrom = srnafrom->cont.next)
- if (strcmp(srnafrom->identifier, from) == 0)
- break;
-
- if (!srnafrom) {
- fprintf(stderr, "%s: struct %s not found to define %s.\n", __func__, from, identifier);
- DefRNA.error = 1;
- }
- }
srna = MEM_callocN(sizeof(StructRNA), "StructRNA");
DefRNA.laststruct = srna;
@@ -670,7 +657,7 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *
else
srna->base = srnafrom;
}
-
+
srna->identifier = identifier;
srna->name = identifier; /* may be overwritten later RNA_def_struct_ui_text */
srna->description = "";
@@ -741,6 +728,28 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *
return srna;
}
+StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from)
+{
+ StructRNA *srnafrom = NULL;
+
+ /* only use RNA_def_struct() while pre-processing, otherwise use RNA_def_struct_ptr() */
+ BLI_assert(DefRNA.preprocess);
+
+ if (from) {
+ /* find struct to derive from */
+ for (srnafrom = brna->structs.first; srnafrom; srnafrom = srnafrom->cont.next)
+ if (strcmp(srnafrom->identifier, from) == 0)
+ break;
+
+ if (!srnafrom) {
+ fprintf(stderr, "%s: struct %s not found to define %s.\n", __func__, from, identifier);
+ DefRNA.error = 1;
+ }
+ }
+
+ return RNA_def_struct_ptr(brna, identifier, srnafrom);
+}
+
void RNA_def_struct_sdna(StructRNA *srna, const char *structname)
{
StructDefRNA *ds;
@@ -2017,6 +2026,38 @@ void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const ch
}
}
+void RNA_def_property_boolean_funcs_runtime(PropertyRNA *prop, BooleanPropertyGetFunc getfunc, BooleanPropertySetFunc setfunc)
+{
+ BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
+
+ if (getfunc) bprop->get_ex = getfunc;
+ if (setfunc) bprop->set_ex = setfunc;
+
+ if (getfunc || setfunc) {
+ /* don't save in id properties */
+ prop->flag &= ~PROP_IDPROPERTY;
+
+ if (!setfunc)
+ prop->flag &= ~PROP_EDITABLE;
+ }
+}
+
+void RNA_def_property_boolean_array_funcs_runtime(PropertyRNA *prop, BooleanArrayPropertyGetFunc getfunc, BooleanArrayPropertySetFunc setfunc)
+{
+ BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
+
+ if (getfunc) bprop->getarray_ex = getfunc;
+ if (setfunc) bprop->setarray_ex = setfunc;
+
+ if (getfunc || setfunc) {
+ /* don't save in id properties */
+ prop->flag &= ~PROP_IDPROPERTY;
+
+ if (!setfunc)
+ prop->flag &= ~PROP_EDITABLE;
+ }
+}
+
void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range)
{
StructRNA *srna = DefRNA.laststruct;
@@ -2049,6 +2090,38 @@ void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char *
}
}
+void RNA_def_property_int_funcs_runtime(PropertyRNA *prop, IntPropertyGetFunc getfunc, IntPropertySetFunc setfunc, IntPropertyRangeFunc rangefunc)
+{
+ IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
+
+ if (getfunc) iprop->get_ex = getfunc;
+ if (setfunc) iprop->set_ex = setfunc;
+
+ if (getfunc || setfunc) {
+ /* don't save in id properties */
+ prop->flag &= ~PROP_IDPROPERTY;
+
+ if (!setfunc)
+ prop->flag &= ~PROP_EDITABLE;
+ }
+}
+
+void RNA_def_property_int_array_funcs_runtime(PropertyRNA *prop, IntArrayPropertyGetFunc getfunc, IntArrayPropertySetFunc setfunc, IntPropertyRangeFunc rangefunc)
+{
+ IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
+
+ if (getfunc) iprop->getarray_ex = getfunc;
+ if (setfunc) iprop->setarray_ex = setfunc;
+
+ if (getfunc || setfunc) {
+ /* don't save in id properties */
+ prop->flag &= ~PROP_IDPROPERTY;
+
+ if (!setfunc)
+ prop->flag &= ~PROP_EDITABLE;
+ }
+}
+
void RNA_def_property_float_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range)
{
StructRNA *srna = DefRNA.laststruct;
@@ -2081,6 +2154,40 @@ void RNA_def_property_float_funcs(PropertyRNA *prop, const char *get, const char
}
}
+void RNA_def_property_float_funcs_runtime(PropertyRNA *prop, FloatPropertyGetFunc getfunc, FloatPropertySetFunc setfunc, FloatPropertyRangeFunc rangefunc)
+{
+ FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
+
+ if (getfunc) fprop->get_ex = getfunc;
+ if (setfunc) fprop->set_ex = setfunc;
+ if (rangefunc) fprop->range_ex = rangefunc;
+
+ if (getfunc || setfunc) {
+ /* don't save in id properties */
+ prop->flag &= ~PROP_IDPROPERTY;
+
+ if (!setfunc)
+ prop->flag &= ~PROP_EDITABLE;
+ }
+}
+
+void RNA_def_property_float_array_funcs_runtime(PropertyRNA *prop, FloatArrayPropertyGetFunc getfunc, FloatArrayPropertySetFunc setfunc, FloatPropertyRangeFunc rangefunc)
+{
+ FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
+
+ if (getfunc) fprop->getarray_ex = getfunc;
+ if (setfunc) fprop->setarray_ex = setfunc;
+ if (rangefunc) fprop->range_ex = rangefunc;
+
+ if (getfunc || setfunc) {
+ /* don't save in id properties */
+ prop->flag &= ~PROP_IDPROPERTY;
+
+ if (!setfunc)
+ prop->flag &= ~PROP_EDITABLE;
+ }
+}
+
void RNA_def_property_enum_funcs(PropertyRNA *prop, const char *get, const char *set, const char *item)
{
StructRNA *srna = DefRNA.laststruct;
@@ -2107,6 +2214,29 @@ void RNA_def_property_enum_funcs(PropertyRNA *prop, const char *get, const char
}
}
+void RNA_def_property_enum_funcs_runtime(PropertyRNA *prop, EnumPropertyGetFunc getfunc, EnumPropertySetFunc setfunc, EnumPropertyItemFunc itemfunc)
+{
+ EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
+
+ if (getfunc) eprop->get_ex = getfunc;
+ if (setfunc) eprop->set_ex = setfunc;
+ if (itemfunc) eprop->itemf = itemfunc;
+
+ if (getfunc || setfunc) {
+ /* don't save in id properties */
+ prop->flag &= ~PROP_IDPROPERTY;
+
+ if (!setfunc)
+ prop->flag &= ~PROP_EDITABLE;
+ }
+}
+
+void RNA_def_property_enum_py_data(PropertyRNA *prop, void *py_data)
+{
+ EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
+ eprop->py_data = py_data;
+}
+
void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const char *length, const char *set)
{
StructRNA *srna = DefRNA.laststruct;
@@ -2133,6 +2263,23 @@ void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const cha
}
}
+void RNA_def_property_string_funcs_runtime(PropertyRNA *prop, StringPropertyGetFunc getfunc, StringPropertyLengthFunc lengthfunc, StringPropertySetFunc setfunc)
+{
+ StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
+
+ if (getfunc) sprop->get_ex = getfunc;
+ if (lengthfunc) sprop->length_ex = lengthfunc;
+ if (setfunc) sprop->set_ex = setfunc;
+
+ if (getfunc || setfunc) {
+ /* don't save in id properties */
+ prop->flag &= ~PROP_IDPROPERTY;
+
+ if (!setfunc)
+ prop->flag &= ~PROP_EDITABLE;
+ }
+}
+
void RNA_def_property_pointer_funcs(PropertyRNA *prop, const char *get, const char *set,
const char *typef, const char *poll)
{
@@ -2447,12 +2594,6 @@ void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc)
eprop->itemf = itemfunc;
}
-void RNA_def_enum_py_data(PropertyRNA *prop, void *py_data)
-{
- EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
- eprop->py_data = py_data;
-}
-
PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value,
float hardmin, float hardmax, const char *ui_name, const char *ui_description,
float softmin, float softmax)
diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h
index ccfb83b61e3..43ec09de010 100644
--- a/source/blender/makesrna/intern/rna_internal_types.h
+++ b/source/blender/makesrna/intern/rna_internal_types.h
@@ -30,6 +30,8 @@
#include "DNA_listBase.h"
+#include "RNA_types.h"
+
struct BlenderRNA;
struct ContainerRNA;
struct StructRNA;
@@ -64,7 +66,7 @@ typedef void (*ContextPropUpdateFunc)(struct bContext *C, struct PointerRNA *ptr
typedef void (*ContextUpdateFunc)(struct bContext *C, struct PointerRNA *ptr);
typedef int (*EditableFunc)(struct PointerRNA *ptr);
typedef int (*ItemEditableFunc)(struct PointerRNA *ptr, int index);
-typedef struct IDProperty* (*IDPropertiesFunc)(struct PointerRNA *ptr, int create);
+typedef struct IDProperty *(*IDPropertiesFunc)(struct PointerRNA *ptr, int create);
typedef struct StructRNA *(*StructRefineFunc)(struct PointerRNA *ptr);
typedef char *(*StructPathFunc)(struct PointerRNA *ptr);
@@ -91,7 +93,7 @@ typedef void (*PropEnumSetFunc)(struct PointerRNA *ptr, int value);
typedef EnumPropertyItem *(*PropEnumItemFunc)(struct bContext *C, struct PointerRNA *ptr,
struct PropertyRNA *prop, int *free);
typedef PointerRNA (*PropPointerGetFunc)(struct PointerRNA *ptr);
-typedef StructRNA* (*PropPointerTypeFunc)(struct PointerRNA *ptr);
+typedef StructRNA *(*PropPointerTypeFunc)(struct PointerRNA *ptr);
typedef void (*PropPointerSetFunc)(struct PointerRNA *ptr, const PointerRNA value);
typedef int (*PropPointerPollFunc)(struct PointerRNA *ptr, const PointerRNA value);
typedef void (*PropCollectionBeginFunc)(struct CollectionPropertyIterator *iter, struct PointerRNA *ptr);
@@ -103,6 +105,27 @@ typedef int (*PropCollectionLookupIntFunc)(struct PointerRNA *ptr, int key, stru
typedef int (*PropCollectionLookupStringFunc)(struct PointerRNA *ptr, const char *key, struct PointerRNA *r_ptr);
typedef int (*PropCollectionAssignIntFunc)(struct PointerRNA *ptr, int key, const struct PointerRNA *assign_ptr);
+/* extended versions with PropertyRNA argument */
+typedef int (*PropBooleanGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*PropBooleanSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value);
+typedef void (*PropBooleanArrayGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values);
+typedef void (*PropBooleanArraySetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values);
+typedef int (*PropIntGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*PropIntSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value);
+typedef void (*PropIntArrayGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values);
+typedef void (*PropIntArraySetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values);
+typedef void (*PropIntRangeFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *min, int *max, int *softmin, int *softmax);
+typedef float (*PropFloatGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*PropFloatSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, float value);
+typedef void (*PropFloatArrayGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, float *values);
+typedef void (*PropFloatArraySetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, const float *values);
+typedef void (*PropFloatRangeFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, float *min, float *max, float *softmin, float *softmax);
+typedef void (*PropStringGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, char *value);
+typedef int (*PropStringLengthFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*PropStringSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, const char *value);
+typedef int (*PropEnumGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*PropEnumSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value);
+
/* Container - generic abstracted container of RNA properties */
typedef struct ContainerRNA {
void *next, *prev;
@@ -193,10 +216,14 @@ typedef struct BoolPropertyRNA {
PropBooleanGetFunc get;
PropBooleanSetFunc set;
-
PropBooleanArrayGetFunc getarray;
PropBooleanArraySetFunc setarray;
+ PropBooleanGetFuncEx get_ex;
+ PropBooleanSetFuncEx set_ex;
+ PropBooleanArrayGetFuncEx getarray_ex;
+ PropBooleanArraySetFuncEx setarray_ex;
+
int defaultvalue;
const int *defaultarray;
} BoolPropertyRNA;
@@ -206,12 +233,16 @@ typedef struct IntPropertyRNA {
PropIntGetFunc get;
PropIntSetFunc set;
-
PropIntArrayGetFunc getarray;
PropIntArraySetFunc setarray;
-
PropIntRangeFunc range;
+ PropIntGetFuncEx get_ex;
+ PropIntSetFuncEx set_ex;
+ PropIntArrayGetFuncEx getarray_ex;
+ PropIntArraySetFuncEx setarray_ex;
+ PropIntRangeFuncEx range_ex;
+
int softmin, softmax;
int hardmin, hardmax;
int step;
@@ -225,12 +256,16 @@ typedef struct FloatPropertyRNA {
PropFloatGetFunc get;
PropFloatSetFunc set;
-
PropFloatArrayGetFunc getarray;
PropFloatArraySetFunc setarray;
-
PropFloatRangeFunc range;
+ PropFloatGetFuncEx get_ex;
+ PropFloatSetFuncEx set_ex;
+ PropFloatArrayGetFuncEx getarray_ex;
+ PropFloatArraySetFuncEx setarray_ex;
+ PropFloatRangeFuncEx range_ex;
+
float softmin, softmax;
float hardmin, hardmax;
float step;
@@ -247,6 +282,10 @@ typedef struct StringPropertyRNA {
PropStringLengthFunc length;
PropStringSetFunc set;
+ PropStringGetFuncEx get_ex;
+ PropStringLengthFuncEx length_ex;
+ PropStringSetFuncEx set_ex;
+
int maxlength; /* includes string terminator! */
const char *defaultvalue;
@@ -258,6 +297,9 @@ typedef struct EnumPropertyRNA {
PropEnumGetFunc get;
PropEnumSetFunc set;
PropEnumItemFunc itemf;
+
+ PropEnumGetFuncEx get_ex;
+ PropEnumSetFuncEx set_ex;
void *py_data; /* store py callback here */
EnumPropertyItem *item;
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index 31e27ebc982..8c8b7b4f637 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -1233,6 +1233,26 @@ static char *rna_MeshStringProperty_path(PointerRNA *ptr)
return rna_PolyCustomData_data_path(ptr, "layers_string", CD_PROP_STR);
}
+/* XXX, we dont have propper byte string support yet, so for now use the (bytes + 1)
+ * bmesh API exposes correct python/bytestring access */
+void rna_MeshStringProperty_s_get(PointerRNA *ptr, char *value)
+{
+ MStringProperty *ms = (MStringProperty *)ptr->data;
+ BLI_strncpy(value, ms->s, (int)ms->s_len + 1);
+}
+
+int rna_MeshStringProperty_s_length(PointerRNA *ptr)
+{
+ MStringProperty *ms = (MStringProperty *)ptr->data;
+ return (int)ms->s_len + 1;
+}
+
+void rna_MeshStringProperty_s_set(PointerRNA *ptr, const char *value)
+{
+ MStringProperty *ms = (MStringProperty *)ptr->data;
+ BLI_strncpy(ms->s, value, sizeof(ms->s));
+}
+
static int rna_Mesh_tot_vert_get(PointerRNA *ptr)
{
Mesh *me = rna_mesh(ptr);
@@ -2182,6 +2202,7 @@ static void rna_def_mproperties(BlenderRNA *brna)
/* low level mesh data access, treat as bytes */
prop = RNA_def_property(srna, "value", PROP_STRING, PROP_BYTESTRING);
RNA_def_property_string_sdna(prop, NULL, "s");
+ RNA_def_property_string_funcs(prop, "rna_MeshStringProperty_s_get", "rna_MeshStringProperty_s_length", "rna_MeshStringProperty_s_set");
RNA_def_property_ui_text(prop, "Value", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
}
@@ -3010,6 +3031,22 @@ static void rna_def_mesh(BlenderRNA *brna)
RNA_def_property_ui_icon(prop, ICON_VERTEXSEL, 0);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_Mesh_update_vertmask");
+
+
+ /* customdata flags */
+ prop = RNA_def_property(srna, "use_customdata_vertex_bevel", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "cd_flag", ME_CDFLAG_VERT_BWEIGHT);
+ RNA_def_property_ui_text(prop, "Store Vertex Bevel Weight", "");
+
+ prop = RNA_def_property(srna, "use_customdata_edge_bevel", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "cd_flag", ME_CDFLAG_EDGE_BWEIGHT);
+ RNA_def_property_ui_text(prop, "Store Edge Bevel Weight", "");
+
+ prop = RNA_def_property(srna, "use_customdata_edge_crease", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "cd_flag", ME_CDFLAG_EDGE_CREASE);
+ RNA_def_property_ui_text(prop, "Store Edge Crease", "");
+
+
/* readonly editmesh info - use for extrude menu */
prop = RNA_def_property(srna, "total_vert_sel", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_funcs(prop, "rna_Mesh_tot_vert_get", NULL, NULL);
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 18dfd8aa6f9..eecdf13813c 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -288,6 +288,47 @@ static const char *rna_Node_get_node_type(StructRNA *type)
return "";
}
+static void rna_Node_parent_set(PointerRNA *ptr, PointerRNA value)
+{
+ bNode *node = ptr->data;
+ bNode *parent = value.data;
+
+ if (parent) {
+ /* XXX only Frame node allowed for now,
+ * in the future should have a poll function or so to test possible attachment.
+ */
+ if (parent->type != NODE_FRAME)
+ return;
+
+ /* make sure parent is not attached to the node */
+ if (nodeAttachNodeCheck(parent, node))
+ return;
+ }
+
+ nodeDetachNode(node);
+ if (parent) {
+ nodeAttachNode(node, parent);
+ }
+}
+
+static int rna_Node_parent_poll(PointerRNA *ptr, PointerRNA value)
+{
+ bNode *node = ptr->data;
+ bNode *parent = value.data;
+
+ /* XXX only Frame node allowed for now,
+ * in the future should have a poll function or so to test possible attachment.
+ */
+ if (parent->type != NODE_FRAME)
+ return FALSE;
+
+ /* make sure parent is not attached to the node */
+ if (nodeAttachNodeCheck(parent, node))
+ return FALSE;
+
+ return TRUE;
+}
+
static StructRNA *rna_NodeSocket_refine(PointerRNA *ptr)
{
bNodeSocket *sock = (bNodeSocket *)ptr->data;
@@ -2480,7 +2521,7 @@ static void def_cmp_dilate_erode(StructRNA *srna)
{
PropertyRNA *prop;
- static EnumPropertyItem type_items[] = {
+ static EnumPropertyItem mode_items[] = {
{CMP_NODE_DILATEERODE_STEP, "STEP", 0, "Step", ""},
{CMP_NODE_DILATEERODE_DISTANCE_THRESH, "THRESHOLD", 0, "Threshold", ""},
{CMP_NODE_DILATEERODE_DISTANCE, "DISTANCE", 0, "Distance", ""},
@@ -2488,10 +2529,10 @@ static void def_cmp_dilate_erode(StructRNA *srna)
{0, NULL, 0, NULL, NULL}
};
- prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
+ prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
- RNA_def_property_enum_items(prop, type_items);
- RNA_def_property_ui_text(prop, "Distance", "Distance to grow/shrink (number of iterations)");
+ RNA_def_property_enum_items(prop, mode_items);
+ RNA_def_property_ui_text(prop, "Mode", "Growing/shrinking mode");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "distance", PROP_INT, PROP_NONE);
@@ -4689,8 +4730,9 @@ static void rna_def_node(BlenderRNA *brna)
prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "parent");
+ RNA_def_property_pointer_funcs(prop, NULL, "rna_Node_parent_set", NULL, "rna_Node_parent_poll");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "Node");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Parent", "Parent this node is attached to");
prop = RNA_def_property(srna, "use_custom_color", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 80d74c3a9fe..a617c78019f 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -2469,6 +2469,15 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Slow Parent Offset", "Delay in the parent relationship");
RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update");
+ /* depsgraph hack */
+ prop = RNA_def_property(srna, "extra_recalc_object", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "depsflag", OB_DEPS_EXTRA_OB_RECALC);
+ RNA_def_property_ui_text(prop, "Extra Object Update", "Refresh this object again on frame changes, dependency graph hack");
+
+ prop = RNA_def_property(srna, "extra_recalc_data", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "depsflag", OB_DEPS_EXTRA_DATA_RECALC);
+ RNA_def_property_ui_text(prop, "Extra Data Update", "Refresh this object's data again on frame changes, dependency graph hack");
+
/* duplicates */
prop = RNA_def_property(srna, "dupli_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "transflag");
diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index d7115256fe5..40b8d4cce66 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -129,9 +129,6 @@ static Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int
DerivedMesh *derivedFinal = NULL;
int uv_from_orco;
- int (*orco_index)[4] = NULL;
- float (*orco)[3] = NULL;
-
/* copies object and modifiers (but not the data) */
tmpobj = BKE_object_copy_with_caches(ob);
tmpcu = (Curve *)tmpobj->data;
@@ -158,38 +155,12 @@ static Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int
tmpobj->derivedFinal = derivedFinal;
- uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0;
-
- if (uv_from_orco) {
- /* before curve conversion */
- orco = (float (*)[3])BKE_curve_make_orco(sce, tmpobj);
- }
-
/* convert object type to mesh */
- BKE_mesh_from_nurbs_displist(tmpobj, &dispbase, uv_from_orco ? (int **)&orco_index : NULL);
+ uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0;
+ BKE_mesh_from_nurbs_displist(tmpobj, &dispbase, uv_from_orco);
tmpmesh = tmpobj->data;
- if (uv_from_orco && orco && orco_index) {
- const char *uvname = "Orco";
- /* add UV's */
- MTexPoly *mtpoly = CustomData_add_layer_named(&tmpmesh->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, tmpmesh->totpoly, uvname);
- MLoopUV *mloopuvs = CustomData_add_layer_named(&tmpmesh->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, tmpmesh->totloop, uvname);
-
- BKE_mesh_nurbs_to_mdata_orco(tmpmesh->mpoly, tmpmesh->totpoly,
- tmpmesh->mloop, mloopuvs,
- orco, orco_index);
-
- (void)mtpoly;
- }
-
- if (orco_index) {
- MEM_freeN(orco_index);
- }
- if (orco) {
- MEM_freeN(orco);
- }
-
BKE_displist_free(&dispbase);
/* BKE_mesh_from_nurbs changes the type to a mesh, check it worked */
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index be3cbfaece3..4a520cdc729 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -492,7 +492,7 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, P
if (n_mcol && ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) {
if (num != DMCACHE_NOTFOUND) {
MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE);
- MCol *mc = (MCol*)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, vcol_no);
+ MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, vcol_no);
mc += num * 4;
psys_interpolate_mcol(mc, mface->v4, particle->fuv, &mcol);
@@ -517,7 +517,7 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, P
if (n_mcol && ELEM(PART_FROM_FACE, PART_FROM_FACE, PART_FROM_VOLUME)) {
if (cpa->num != DMCACHE_NOTFOUND) {
MFace *mface = modifier->dm->getTessFaceData(modifier->dm, cpa->num, CD_MFACE);
- MCol *mc = (MCol*)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, 0);
+ MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, 0);
mc += cpa->num * 4;
psys_interpolate_mcol(mc, mface->v4, cpa->fuv, &mcol);
@@ -543,7 +543,7 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, P
if (n_mcol && ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) {
if (num != DMCACHE_NOTFOUND) {
MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE);
- MCol *mc = (MCol*)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, 0);
+ MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, 0);
mc += num * 4;
psys_interpolate_mcol(mc, mface->v4, parent->fuv, &mcol);
@@ -1545,9 +1545,9 @@ static void rna_def_fluid_settings(BlenderRNA *brna)
/* Double density relaxation */
prop = RNA_def_property(srna, "stiffness", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "stiffness_k");
- RNA_def_property_range(prop, 0.0f, 100000.0f);
+ RNA_def_property_range(prop, 0.0f, 1000.0f);
RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3);
- RNA_def_property_ui_text(prop, "Stiffness", "How incompressible the fluid is");
+ RNA_def_property_ui_text(prop, "Stiffness", "How incompressible the fluid is (speed of sound)");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
prop = RNA_def_property(srna, "repulsion", PROP_FLOAT, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c
index 93c5b45e642..5931440b422 100644
--- a/source/blender/makesrna/intern/rna_render.c
+++ b/source/blender/makesrna/intern/rna_render.c
@@ -196,7 +196,7 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo
et = MEM_callocN(sizeof(RenderEngineType), "python render engine");
memcpy(et, &dummyet, sizeof(dummyet));
- et->ext.srna = RNA_def_struct(&BLENDER_RNA, et->idname, "RenderEngine");
+ et->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, et->idname, &RNA_RenderEngine);
et->ext.data = data;
et->ext.call = call;
et->ext.free = free;
@@ -415,7 +415,7 @@ static void rna_def_render_engine(BlenderRNA *brna)
RNA_def_property_string_sdna(prop, NULL, "type->idname");
RNA_def_property_flag(prop, PROP_REGISTER | PROP_NEVER_CLAMP);
- prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_TRANSLATE);
+ prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->name");
RNA_def_property_flag(prop, PROP_REGISTER);
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 8d99cecd9fa..f4059bc5846 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -278,9 +278,11 @@ EnumPropertyItem image_color_mode_items[] = {
{0, NULL, 0, NULL, NULL}
};
+#ifdef RNA_RUNTIME
#define IMAGE_COLOR_MODE_BW image_color_mode_items[0]
#define IMAGE_COLOR_MODE_RGB image_color_mode_items[1]
#define IMAGE_COLOR_MODE_RGBA image_color_mode_items[2]
+#endif
EnumPropertyItem image_color_depth_items[] = {
/* 1 (monochrome) not used */
diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c
index 17edf2944aa..cc1895541df 100644
--- a/source/blender/makesrna/intern/rna_sculpt_paint.c
+++ b/source/blender/makesrna/intern/rna_sculpt_paint.c
@@ -222,7 +222,7 @@ static void rna_Sculpt_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNU
if (ob->sculpt) {
ob->sculpt->bm_smooth_shading = (scene->toolsettings->sculpt->flags &
- SCULPT_DYNTOPO_SMOOTH_SHADING);
+ SCULPT_DYNTOPO_SMOOTH_SHADING);
}
}
}
diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c
index 69d35a3c2f0..386263c784e 100644
--- a/source/blender/makesrna/intern/rna_sequencer_api.c
+++ b/source/blender/makesrna/intern/rna_sequencer_api.c
@@ -82,14 +82,14 @@ static void rna_Sequence_swap_internal(Sequence *seq_self, ReportList *reports,
BKE_report(reports, RPT_ERROR, error_msg);
}
-static Sequence *alloc_generic_sequence(Editing *ed, const char *name, int start_frame,
+static Sequence *alloc_generic_sequence(Editing *ed, const char *name, int frame_start,
int channel, int type, const char *file)
{
Sequence *seq;
Strip *strip;
StripElem *se;
- seq = BKE_sequence_alloc(ed->seqbasep, start_frame, channel);
+ seq = BKE_sequence_alloc(ed->seqbasep, frame_start, channel);
seq->type = type;
BLI_strncpy(seq->name + 2, name, sizeof(seq->name) - 2);
@@ -113,12 +113,12 @@ static Sequence *alloc_generic_sequence(Editing *ed, const char *name, int start
static Sequence *rna_Sequences_new_clip(ID *id, Editing *ed,
const char *name, MovieClip *clip, int channel,
- int start_frame)
+ int frame_start)
{
Scene *scene = (Scene *)id;
Sequence *seq;
- seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_MOVIECLIP, clip->name);
+ seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_MOVIECLIP, clip->name);
seq->clip = clip;
seq->len = BKE_movieclip_get_duration(clip);
id_us_plus((ID *)clip);
@@ -132,12 +132,12 @@ static Sequence *rna_Sequences_new_clip(ID *id, Editing *ed,
static Sequence *rna_Sequences_new_mask(ID *id, Editing *ed,
const char *name, Mask *mask, int channel,
- int start_frame)
+ int frame_start)
{
Scene *scene = (Scene *)id;
Sequence *seq;
- seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_MASK, mask->id.name);
+ seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_MASK, mask->id.name);
seq->mask = mask;
seq->len = BKE_mask_get_duration(mask);
id_us_plus((ID *)mask);
@@ -151,15 +151,15 @@ static Sequence *rna_Sequences_new_mask(ID *id, Editing *ed,
static Sequence *rna_Sequences_new_scene(ID *id, Editing *ed,
const char *name, Scene *sce_seq, int channel,
- int start_frame)
+ int frame_start)
{
Scene *scene = (Scene *)id;
Sequence *seq;
- seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_SCENE, NULL);
+ seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_SCENE, NULL);
seq->scene = sce_seq;
seq->len = sce_seq->r.efra - sce_seq->r.sfra + 1;
- seq->scene_sound = sound_scene_add_scene_sound(scene, seq, start_frame, start_frame + seq->len, 0);
+ seq->scene_sound = sound_scene_add_scene_sound(scene, seq, frame_start, frame_start + seq->len, 0);
id_us_plus((ID *)sce_seq);
BKE_sequence_calc_disp(scene, seq);
@@ -171,12 +171,12 @@ static Sequence *rna_Sequences_new_scene(ID *id, Editing *ed,
static Sequence *rna_Sequences_new_image(ID *id, Editing *ed, ReportList *reports,
const char *name, const char *file, int channel,
- int start_frame)
+ int frame_start)
{
Scene *scene = (Scene *)id;
Sequence *seq;
- seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_IMAGE, file);
+ seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_IMAGE, file);
seq->len = 1;
if (seq->strip->stripdata->name[0] == '\0') {
@@ -195,12 +195,11 @@ static Sequence *rna_Sequences_new_image(ID *id, Editing *ed, ReportList *report
static Sequence *rna_Sequences_new_movie(ID *id, Editing *ed, ReportList *reports,
const char *name, const char *file, int channel,
- int start_frame)
+ int frame_start)
{
Scene *scene = (Scene *)id;
Sequence *seq;
- /* OCIO_TODO: support configurable color spaces for strips */
struct anim *an = openanim(file, IB_rect, 0, NULL);
if (an == NULL) {
@@ -208,7 +207,7 @@ static Sequence *rna_Sequences_new_movie(ID *id, Editing *ed, ReportList *report
return NULL;
}
- seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_MOVIE, file);
+ seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_MOVIE, file);
seq->anim = an;
seq->anim_preseek = IMB_anim_get_preseek(an);
seq->len = IMB_anim_get_duration(an, IMB_TC_RECORD_RUN);
@@ -222,7 +221,7 @@ static Sequence *rna_Sequences_new_movie(ID *id, Editing *ed, ReportList *report
#ifdef WITH_AUDASPACE
static Sequence *rna_Sequences_new_sound(ID *id, Editing *ed, Main *bmain, ReportList *reports,
- const char *name, const char *file, int channel, int start_frame)
+ const char *name, const char *file, int channel, int frame_start)
{
Scene *scene = (Scene *)id;
Sequence *seq;
@@ -234,11 +233,11 @@ static Sequence *rna_Sequences_new_sound(ID *id, Editing *ed, Main *bmain, Repor
return NULL;
}
- seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_SOUND_RAM, sound->name);
+ seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_SOUND_RAM, sound->name);
seq->sound = sound;
seq->len = ceil((double)sound_get_length(sound) * FPS);
- seq->scene_sound = sound_add_scene_sound(scene, seq, start_frame, start_frame + seq->len, 0);
+ seq->scene_sound = sound_add_scene_sound(scene, seq, frame_start, frame_start + seq->len, 0);
BKE_sequence_calc_disp(scene, seq);
@@ -249,7 +248,7 @@ static Sequence *rna_Sequences_new_sound(ID *id, Editing *ed, Main *bmain, Repor
#else /* WITH_AUDASPACE */
static Sequence *rna_Sequences_new_sound(ID *UNUSED(id), Editing *UNUSED(ed), Main *UNUSED(bmain), ReportList *reports,
const char *UNUSED(name), const char *UNUSED(file), int UNUSED(channel),
- int UNUSED(start_frame))
+ int UNUSED(frame_start))
{
BKE_report(reports, RPT_ERROR, "Blender compiled without Audaspace support");
return NULL;
@@ -258,7 +257,7 @@ static Sequence *rna_Sequences_new_sound(ID *UNUSED(id), Editing *UNUSED(ed), Ma
static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *reports,
const char *name, int type, int channel,
- int start_frame, int end_frame,
+ int frame_start, int frame_end,
Sequence *seq1, Sequence *seq2, Sequence *seq3)
{
Scene *scene = (Scene *)id;
@@ -268,7 +267,7 @@ static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *repor
switch (num_inputs) {
case 0:
- if (end_frame <= start_frame) {
+ if (frame_end <= frame_start) {
BKE_report(reports, RPT_ERROR, "Sequences.new_effect: end frame not set");
return NULL;
}
@@ -298,7 +297,7 @@ static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *repor
return NULL;
}
- seq = alloc_generic_sequence(ed, name, start_frame, channel, type, NULL);
+ seq = alloc_generic_sequence(ed, name, frame_start, channel, type, NULL);
sh = BKE_sequence_get_effect(seq);
@@ -310,7 +309,7 @@ static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *repor
if (!seq1) { /* effect has no deps */
seq->len = 1;
- BKE_sequence_tx_set_final_right(seq, end_frame);
+ BKE_sequence_tx_set_final_right(seq, frame_end);
}
seq->flag |= SEQ_USE_EFFECT_DEFAULT_FADE;
@@ -488,7 +487,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
"The channel for the new sequence", 0, MAXSEQ - 1);
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "",
+ parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "",
"The start frame for the new sequence", -MAXFRAME, MAXFRAME);
RNA_def_property_flag(parm, PROP_REQUIRED);
/* return type */
@@ -505,7 +504,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
"The channel for the new sequence", 0, MAXSEQ - 1);
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "",
+ parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "",
"The start frame for the new sequence", -MAXFRAME, MAXFRAME);
RNA_def_property_flag(parm, PROP_REQUIRED);
/* return type */
@@ -522,7 +521,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
"The channel for the new sequence", 0, MAXSEQ - 1);
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "",
+ parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "",
"The start frame for the new sequence", -MAXFRAME, MAXFRAME);
RNA_def_property_flag(parm, PROP_REQUIRED);
/* return type */
@@ -539,7 +538,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
"The channel for the new sequence", 0, MAXSEQ - 1);
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "",
+ parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "",
"The start frame for the new sequence", -MAXFRAME, MAXFRAME);
RNA_def_property_flag(parm, PROP_REQUIRED);
/* return type */
@@ -556,7 +555,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
"The channel for the new sequence", 0, MAXSEQ - 1);
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "",
+ parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "",
"The start frame for the new sequence", -MAXFRAME, MAXFRAME);
RNA_def_property_flag(parm, PROP_REQUIRED);
/* return type */
@@ -573,7 +572,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
"The channel for the new sequence", 0, MAXSEQ - 1);
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "",
+ parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "",
"The start frame for the new sequence", -MAXFRAME, MAXFRAME);
RNA_def_property_flag(parm, PROP_REQUIRED);
/* return type */
@@ -590,12 +589,13 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_flag(parm, PROP_REQUIRED);
parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
"The channel for the new sequence", 0, MAXSEQ - 1);
+ /* don't use MAXFRAME since it makes importer scripts fail */
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "",
- "The start frame for the new sequence", -MAXFRAME, MAXFRAME);
+ parm = RNA_def_int(func, "frame_start", 0, INT_MIN, INT_MAX, "",
+ "The start frame for the new sequence", INT_MIN, INT_MAX);
RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_def_int(func, "end_frame", 0, -MAXFRAME, MAXFRAME, "",
- "The end frame for the new sequence", -MAXFRAME, MAXFRAME);
+ RNA_def_int(func, "frame_end", 0, INT_MIN, INT_MAX, "",
+ "The end frame for the new sequence", INT_MIN, INT_MAX);
RNA_def_pointer(func, "seq1", "Sequence", "", "Sequence 1 for effect");
RNA_def_pointer(func, "seq2", "Sequence", "", "Sequence 2 for effect");
RNA_def_pointer(func, "seq3", "Sequence", "", "Sequence 3 for effect");
diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c
index 7cc57947671..cd646f4849c 100644
--- a/source/blender/makesrna/intern/rna_tracking.c
+++ b/source/blender/makesrna/intern/rna_tracking.c
@@ -402,39 +402,52 @@ static void rna_trackingDopesheet_tagUpdate(Main *UNUSED(bmain), Scene *scene, P
/* API */
-static void add_tracks_to_base(MovieClip *clip, MovieTracking *tracking, ListBase *tracksbase, int frame, int number)
+static MovieTrackingTrack *add_track_to_base(MovieClip *clip, MovieTracking *tracking, ListBase *tracksbase, const char *name, int frame)
{
- int a, width, height;
+ int width, height;
MovieClipUser user = {0};
+ MovieTrackingTrack *track;
user.framenr = 1;
BKE_movieclip_get_size(clip, &user, &width, &height);
- for (a = 0; a < number; a++)
- BKE_tracking_track_add(tracking, tracksbase, 0, 0, frame, width, height);
+ track = BKE_tracking_track_add(tracking, tracksbase, 0, 0, frame, width, height);
+
+ if (name && name[0]) {
+ BLI_strncpy(track->name, name, sizeof(track->name));
+ BKE_tracking_track_unique_name(tracksbase, track);
+ }
+
+ return track;
}
-static void rna_trackingTracks_add(ID *id, MovieTracking *tracking, int frame, int number)
+static MovieTrackingTrack *rna_trackingTracks_new(ID *id, MovieTracking *tracking, const char *name, int frame)
{
MovieClip *clip = (MovieClip *) id;
+ MovieTrackingTrack *track;
- add_tracks_to_base(clip, tracking, &tracking->tracks, frame, number);
+ track = add_track_to_base(clip, tracking, &tracking->tracks, name, frame);
WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, clip);
+
+ return track;
}
-static void rna_trackingObject_tracks_add(ID *id, MovieTrackingObject *object, int frame, int number)
+static MovieTrackingTrack *rna_trackingObject_tracks_new(ID *id, MovieTrackingObject *object, const char *name, int frame)
{
MovieClip *clip = (MovieClip *) id;
ListBase *tracksbase = &object->tracks;
+ MovieTrackingTrack *track;
if (object->flag & TRACKING_OBJECT_CAMERA)
tracksbase = &clip->tracking.tracks;
- add_tracks_to_base(clip, &clip->tracking, tracksbase, frame, number);
+ track = add_track_to_base(clip, &clip->tracking, tracksbase, name, frame);
WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, NULL);
+
+ return track;
}
static MovieTrackingObject *rna_trackingObject_new(MovieTracking *tracking, const char *name)
@@ -475,6 +488,14 @@ static MovieTrackingMarker *rna_trackingMarkers_insert_frame(MovieTrackingTrack
marker.framenr = framenr;
copy_v2_v2(marker.pos, co);
+ /* a bit arbitrary, but better than creating markers with zero pattern
+ * which is forbidden actually
+ */
+ copy_v2_v2(marker.pattern_corners[0], track->markers[0].pattern_corners[0]);
+ copy_v2_v2(marker.pattern_corners[1], track->markers[0].pattern_corners[1]);
+ copy_v2_v2(marker.pattern_corners[2], track->markers[0].pattern_corners[2]);
+ copy_v2_v2(marker.pattern_corners[3], track->markers[0].pattern_corners[3]);
+
new_marker = BKE_tracking_marker_insert(track, &marker);
WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, NULL);
@@ -1318,16 +1339,19 @@ static void rna_def_trackingTracks(BlenderRNA *brna)
StructRNA *srna;
FunctionRNA *func;
PropertyRNA *prop;
+ PropertyRNA *parm;
srna = RNA_def_struct(brna, "MovieTrackingTracks", NULL);
RNA_def_struct_sdna(srna, "MovieTracking");
RNA_def_struct_ui_text(srna, "Movie Tracks", "Collection of movie tracking tracks");
- func = RNA_def_function(srna, "add", "rna_trackingTracks_add");
+ func = RNA_def_function(srna, "new", "rna_trackingTracks_new");
RNA_def_function_flag(func, FUNC_USE_SELF_ID);
- RNA_def_function_ui_description(func, "Add a number of tracks to this movie clip");
- RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "Frame number to add tracks on", MINFRAME, MAXFRAME);
- RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of tracks to add to the movie clip", 0, INT_MAX);
+ RNA_def_function_ui_description(func, "Create new motion track in this movie clip");
+ RNA_def_string(func, "name", "", 0, "", "Name of new track");
+ RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "Frame number to add track on", MINFRAME, MAXFRAME);
+ parm = RNA_def_pointer(func, "track", "MovieTrackingTrack", "", "Newly created track");
+ RNA_def_function_return(func, parm);
/* active track */
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
@@ -1342,16 +1366,19 @@ static void rna_def_trackingObjectTracks(BlenderRNA *brna)
StructRNA *srna;
FunctionRNA *func;
PropertyRNA *prop;
+ PropertyRNA *parm;
srna = RNA_def_struct(brna, "MovieTrackingObjectTracks", NULL);
RNA_def_struct_sdna(srna, "MovieTrackingObject");
RNA_def_struct_ui_text(srna, "Movie Tracks", "Collection of movie tracking tracks");
- func = RNA_def_function(srna, "add", "rna_trackingObject_tracks_add");
+ func = RNA_def_function(srna, "new", "rna_trackingObject_tracks_new");
RNA_def_function_flag(func, FUNC_USE_SELF_ID);
- RNA_def_function_ui_description(func, "Add a number of tracks to this movie clip");
+ RNA_def_function_ui_description(func, "create new motion track in this movie clip");
+ RNA_def_string(func, "name", "", 0, "", "Name of new track");
RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "Frame number to add tracks on", MINFRAME, MAXFRAME);
- RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of tracks to add to the movie clip", 0, INT_MAX);
+ parm = RNA_def_pointer(func, "track", "MovieTrackingTrack", "", "Newly created track");
+ RNA_def_function_return(func, parm);
/* active track */
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c
index 14789a437b7..00124a82dd1 100644
--- a/source/blender/makesrna/intern/rna_ui.c
+++ b/source/blender/makesrna/intern/rna_ui.c
@@ -165,7 +165,7 @@ static void panel_draw_header(const bContext *C, Panel *pnl)
RNA_parameter_list_free(&list);
}
-static void rna_Panel_unregister(Main *UNUSED(bmain), StructRNA *type)
+static void rna_Panel_unregister(Main *bmain, StructRNA *type)
{
ARegionType *art;
PanelType *pt = RNA_struct_blender_type_get(type);
@@ -181,7 +181,7 @@ static void rna_Panel_unregister(Main *UNUSED(bmain), StructRNA *type)
RNA_struct_free(&BLENDER_RNA, type);
/* update while blender is running */
- WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_WINDOW, NULL);
}
static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
@@ -225,7 +225,7 @@ static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *dat
pt = MEM_callocN(sizeof(PanelType), "python buttons panel");
memcpy(pt, &dummypt, sizeof(dummypt));
- pt->ext.srna = RNA_def_struct(&BLENDER_RNA, pt->idname, "Panel");
+ pt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, pt->idname, &RNA_Panel);
pt->ext.data = data;
pt->ext.call = call;
pt->ext.free = free;
@@ -251,7 +251,7 @@ static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *dat
BLI_addtail(&art->paneltypes, pt);
/* update while blender is running */
- WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_WINDOW, NULL);
return pt->ext.srna;
}
@@ -303,7 +303,7 @@ static void rna_UIList_unregister(Main *UNUSED(bmain), StructRNA *type)
RNA_struct_free(&BLENDER_RNA, type);
/* update while blender is running */
- WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_WINDOW, NULL);
}
static StructRNA *rna_UIList_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
@@ -338,7 +338,7 @@ static StructRNA *rna_UIList_register(Main *bmain, ReportList *reports, void *da
ult = MEM_callocN(sizeof(uiListType) + over_alloc, "python uilist");
memcpy(ult, &dummyult, sizeof(dummyult));
- ult->ext.srna = RNA_def_struct(&BLENDER_RNA, ult->idname, "UIList");
+ ult->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ult->idname, &RNA_UIList);
ult->ext.data = data;
ult->ext.call = call;
ult->ext.free = free;
@@ -350,7 +350,7 @@ static StructRNA *rna_UIList_register(Main *bmain, ReportList *reports, void *da
WM_uilisttype_add(ult);
/* update while blender is running */
- WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_WINDOW, NULL);
return ult->ext.srna;
}
@@ -397,7 +397,7 @@ static void rna_Header_unregister(Main *UNUSED(bmain), StructRNA *type)
RNA_struct_free(&BLENDER_RNA, type);
/* update while blender is running */
- WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_WINDOW, NULL);
}
static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
@@ -439,7 +439,7 @@ static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *da
ht = MEM_callocN(sizeof(HeaderType), "python buttons header");
memcpy(ht, &dummyht, sizeof(dummyht));
- ht->ext.srna = RNA_def_struct(&BLENDER_RNA, ht->idname, "Header");
+ ht->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ht->idname, &RNA_Header);
ht->ext.data = data;
ht->ext.call = call;
ht->ext.free = free;
@@ -450,7 +450,7 @@ static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *da
BLI_addtail(&art->headertypes, ht);
/* update while blender is running */
- WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_WINDOW, NULL);
return ht->ext.srna;
}
@@ -520,7 +520,7 @@ static void rna_Menu_unregister(Main *UNUSED(bmain), StructRNA *type)
RNA_struct_free(&BLENDER_RNA, type);
/* update while blender is running */
- WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_WINDOW, NULL);
}
static char _menu_descr[RNA_DYN_DESCR_MAX];
@@ -572,7 +572,7 @@ static StructRNA *rna_Menu_register(Main *bmain, ReportList *reports, void *data
mt->description = buf;
}
- mt->ext.srna = RNA_def_struct(&BLENDER_RNA, mt->idname, "Menu");
+ mt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, mt->idname, &RNA_Menu);
mt->ext.data = data;
mt->ext.call = call;
mt->ext.free = free;
@@ -585,7 +585,7 @@ static StructRNA *rna_Menu_register(Main *bmain, ReportList *reports, void *data
WM_menutype_add(mt);
/* update while blender is running */
- WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_WINDOW, NULL);
return mt->ext.srna;
}
@@ -1000,7 +1000,7 @@ static void rna_def_menu(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_REGISTER);
RNA_def_property_ui_text(prop, "Label", "The menu label");
- prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE);
+ prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->description");
RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Menu_bl_description_set");
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 7474ff40e32..f53b67c0e92 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -345,6 +345,11 @@ static PointerRNA rna_Theme_space_generic_get(PointerRNA *ptr)
return rna_pointer_inherit_refine(ptr, &RNA_ThemeSpaceGeneric, ptr->data);
}
+static PointerRNA rna_Theme_space_gradient_get(PointerRNA *ptr)
+{
+ return rna_pointer_inherit_refine(ptr, &RNA_ThemeSpaceGradient, ptr->data);
+}
+
static PointerRNA rna_Theme_space_list_generic_get(PointerRNA *ptr)
{
return rna_pointer_inherit_refine(ptr, &RNA_ThemeSpaceListGeneric, ptr->data);
@@ -471,7 +476,7 @@ static void rna_AddonPref_unregister(Main *UNUSED(bmain), StructRNA *type)
RNA_struct_free(&BLENDER_RNA, type);
/* update while blender is running */
- WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_WINDOW, NULL);
}
static StructRNA *rna_AddonPref_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
@@ -509,7 +514,7 @@ static StructRNA *rna_AddonPref_register(Main *bmain, ReportList *reports, void
memcpy(apt, &dummyapt, sizeof(dummyapt));
BKE_addon_pref_type_add(apt);
- apt->ext.srna = RNA_def_struct(&BLENDER_RNA, identifier, "AddonPreferences");
+ apt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, identifier, &RNA_AddonPreferences);
apt->ext.data = data;
apt->ext.call = call;
apt->ext.free = free;
@@ -518,7 +523,7 @@ static StructRNA *rna_AddonPref_register(Main *bmain, ReportList *reports, void
// apt->draw = (have_function[0]) ? header_draw : NULL;
/* update while blender is running */
- WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_WINDOW, NULL);
return apt->ext.srna;
}
@@ -758,6 +763,32 @@ static void rna_def_userdef_theme_ui_panel(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_userdef_update");
}
+static void rna_def_userdef_theme_ui_gradient(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "ThemeGradientColors", NULL);
+ RNA_def_struct_sdna(srna, "uiGradientColors");
+ RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
+ RNA_def_struct_ui_text(srna, "Theme Background Color", "Theme settings for background colors and gradient");
+
+ prop = RNA_def_property(srna, "show_grad", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Use Gradient",
+ "Do a gradient for the background of the viewport working area");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "gradient", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Gradient Low", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "high_gradient", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Gradient High/Off", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+}
+
static void rna_def_userdef_theme_ui(BlenderRNA *brna)
{
StructRNA *srna;
@@ -766,7 +797,8 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
rna_def_userdef_theme_ui_wcol(brna);
rna_def_userdef_theme_ui_wcol_state(brna);
rna_def_userdef_theme_ui_panel(brna);
-
+ rna_def_userdef_theme_ui_gradient(brna);
+
srna = RNA_def_struct(brna, "ThemeUserInterface", NULL);
RNA_def_struct_sdna(srna, "ThemeUI");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
@@ -976,6 +1008,83 @@ static void rna_def_userdef_theme_space_generic(BlenderRNA *brna)
/* } */
}
+static void rna_def_userdef_theme_space_gradient(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "ThemeSpaceGradient", NULL);
+ RNA_def_struct_sdna(srna, "ThemeSpace");
+ RNA_def_struct_ui_text(srna, "Theme Space Settings", "");
+
+ /* window */
+ prop = RNA_def_property(srna, "title", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Title", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "text", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Text", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "text_hi", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Text Highlight", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ /* header */
+ prop = RNA_def_property(srna, "header", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Header", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "header_text", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Header Text", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "header_text_hi", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Header Text Highlight", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ /* panel settings */
+ prop = RNA_def_property(srna, "panelcolors", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_ui_text(prop, "Panel Colors", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ /* gradient/background settings */
+ prop = RNA_def_property(srna, "gradients", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_ui_text(prop, "Gradient Colors", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ /* buttons */
+/* if (! ELEM(spacetype, SPACE_BUTS, SPACE_OUTLINER)) { */
+ prop = RNA_def_property(srna, "button", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_ui_text(prop, "Region Background", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "button_title", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Region Text Titles", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "button_text", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Region Text", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "button_text_hi", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Region Text Highlight", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+/* } */
+}
+
/* list / channels */
static void rna_def_userdef_theme_space_list_generic(BlenderRNA *brna)
{
@@ -1018,6 +1127,17 @@ static void rna_def_userdef_theme_spaces_main(StructRNA *srna)
RNA_def_property_ui_text(prop, "Theme Space", "Settings for space");
}
+static void rna_def_userdef_theme_spaces_gradient(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ prop = RNA_def_property(srna, "space", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_struct_type(prop, "ThemeSpaceGradient");
+ RNA_def_property_pointer_funcs(prop, "rna_Theme_space_gradient_get", NULL, NULL, NULL);
+ RNA_def_property_ui_text(prop, "Theme Space", "Settings for space");
+}
+
static void rna_def_userdef_theme_spaces_list_main(StructRNA *srna)
{
PropertyRNA *prop;
@@ -1236,7 +1356,7 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna)
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme 3D View", "Theme settings for the 3D View");
- rna_def_userdef_theme_spaces_main(srna);
+ rna_def_userdef_theme_spaces_gradient(srna);
prop = RNA_def_property(srna, "grid", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 3);
@@ -2550,6 +2670,7 @@ static void rna_def_userdef_dothemes(BlenderRNA *brna)
rna_def_userdef_theme_ui(brna);
rna_def_userdef_theme_space_generic(brna);
+ rna_def_userdef_theme_space_gradient(brna);
rna_def_userdef_theme_space_list_generic(brna);
rna_def_userdef_theme_space_view3d(brna);
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index f123b564f8d..f416d3403ad 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -1138,7 +1138,7 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *
* for now just remove from dir(bpy.types) */
/* create a new operator type */
- dummyot.ext.srna = RNA_def_struct(&BLENDER_RNA, dummyot.idname, "Operator");
+ dummyot.ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, dummyot.idname, &RNA_Operator);
RNA_def_struct_flag(dummyot.ext.srna, STRUCT_NO_IDPROPERTIES); /* operator properties are registered separately */
dummyot.ext.data = data;
dummyot.ext.call = call;
@@ -1219,7 +1219,7 @@ static StructRNA *rna_MacroOperator_register(Main *bmain, ReportList *reports, v
* for now just remove from dir(bpy.types) */
/* create a new operator type */
- dummyot.ext.srna = RNA_def_struct(&BLENDER_RNA, dummyot.idname, "Operator");
+ dummyot.ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, dummyot.idname, &RNA_Operator);
dummyot.ext.data = data;
dummyot.ext.call = call;
dummyot.ext.free = free;
@@ -1340,7 +1340,7 @@ static void rna_def_operator(BlenderRNA *brna)
/* RNA_def_property_clear_flag(prop, PROP_EDITABLE); */
RNA_def_property_flag(prop, PROP_REGISTER);
- prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE);
+ prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->description");
RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Operator_bl_description_set");
@@ -1407,7 +1407,7 @@ static void rna_def_macro_operator(BlenderRNA *brna)
/* RNA_def_property_clear_flag(prop, PROP_EDITABLE); */
RNA_def_property_flag(prop, PROP_REGISTER);
- prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE);
+ prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->description");
RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Operator_bl_description_set");
diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c
index a84b1124d44..7a94566c6ee 100644
--- a/source/blender/makesrna/intern/rna_world.c
+++ b/source/blender/makesrna/intern/rna_world.c
@@ -529,7 +529,7 @@ void RNA_def_world(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "zenr");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Zenith Color", "Color at the zenith");
- RNA_def_property_update(prop, 0, "rna_World_update");
+ RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update");
prop = RNA_def_property(srna, "ambient_color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "ambr");
@@ -554,17 +554,17 @@ void RNA_def_world(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_sky_blend", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "skytype", WO_SKYBLEND);
RNA_def_property_ui_text(prop, "Blend Sky", "Render background with natural progression from horizon to zenith");
- RNA_def_property_update(prop, 0, "rna_World_update");
+ RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update");
prop = RNA_def_property(srna, "use_sky_paper", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "skytype", WO_SKYPAPER);
RNA_def_property_ui_text(prop, "Paper Sky", "Flatten blend or texture coordinates");
- RNA_def_property_update(prop, 0, "rna_World_update");
+ RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update");
prop = RNA_def_property(srna, "use_sky_real", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "skytype", WO_SKYREAL);
RNA_def_property_ui_text(prop, "Real Sky", "Render background with a real horizon, relative to the camera angle");
- RNA_def_property_update(prop, 0, "rna_World_update");
+ RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update");
/* nested structs */
prop = RNA_def_property(srna, "light_settings", PROP_POINTER, PROP_NONE);
diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c
index ff88cd97197..1021620e04f 100644
--- a/source/blender/modifiers/intern/MOD_screw.c
+++ b/source/blender/modifiers/intern/MOD_screw.c
@@ -274,7 +274,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
step_tot = ((step_tot + 1) * ltmd->iter) - (ltmd->iter - 1);
/* will the screw be closed?
- * Note! smaller then FLT_EPSILON*100 gives problems with float precision so its never closed. */
+ * Note! smaller then FLT_EPSILON * 100 gives problems with float precision so its never closed. */
if (fabsf(screw_ofs) <= (FLT_EPSILON * 100.0f) &&
fabsf(fabsf(angle) - ((float)M_PI * 2.0f)) <= (FLT_EPSILON * 100.0f))
{
diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h
index 9bd45d2b759..13cb11d1301 100644
--- a/source/blender/python/BPY_extern.h
+++ b/source/blender/python/BPY_extern.h
@@ -66,7 +66,7 @@ void BPY_python_end(void);
/* 2.5 UI Scripts */
int BPY_filepath_exec(struct bContext *C, const char *filepath, struct ReportList *reports);
-int BPY_text_exec(struct bContext *C, struct Text *text, struct ReportList *reports, const short do_jump);
+int BPY_text_exec(struct bContext *C, struct Text *text, struct ReportList *reports, const bool do_jump);
void BPY_text_free_code(struct Text *text);
void BPY_modules_update(struct bContext *C); // XXX - annoying, need this for pointers that get out of date
void BPY_modules_load_user(struct bContext *C);
diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c
index ded35363287..32315195072 100644
--- a/source/blender/python/bmesh/bmesh_py_ops_call.c
+++ b/source/blender/python/bmesh/bmesh_py_ops_call.c
@@ -523,7 +523,7 @@ static int bpy_slot_from_py(BMesh *bm, BMOperator *bmop, BMOpSlot *slot, PyObjec
*
* \note Don't throw any exceptions and should always return a valid (PyObject *).
*/
-static PyObject* bpy_slot_to_py(BMesh *bm, BMOpSlot *slot)
+static PyObject *bpy_slot_to_py(BMesh *bm, BMOpSlot *slot)
{
PyObject *item = NULL;
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c
index f39e170c481..37376cc7610 100644
--- a/source/blender/python/bmesh/bmesh_py_types.c
+++ b/source/blender/python/bmesh/bmesh_py_types.c
@@ -1631,6 +1631,21 @@ static PyObject *bpy_bmface_normal_update(BPy_BMFace *self)
}
+PyDoc_STRVAR(bpy_bmface_normal_flip_doc,
+".. method:: normal_flip()\n"
+"\n"
+" Reverses winding of a face, which flips its normal.\n"
+);
+static PyObject *bpy_bmface_normal_flip(BPy_BMFace *self)
+{
+ BPY_BM_CHECK_OBJ(self);
+
+ BM_face_normal_flip(self->bm, self->f);
+
+ Py_RETURN_NONE;
+}
+
+
/* Loop
* ---- */
@@ -2439,6 +2454,7 @@ static struct PyMethodDef bpy_bmface_methods[] = {
{"calc_center_bounds", (PyCFunction)bpy_bmface_calc_center_bounds, METH_NOARGS, bpy_bmface_calc_center_bounds_doc},
{"normal_update", (PyCFunction)bpy_bmface_normal_update, METH_NOARGS, bpy_bmface_normal_update_doc},
+ {"normal_flip", (PyCFunction)bpy_bmface_normal_flip, METH_NOARGS, bpy_bmface_normal_flip_doc},
{NULL, NULL, 0, NULL}
};
diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c
index fd31f3c40cc..4a8f8d49f35 100644
--- a/source/blender/python/bmesh/bmesh_py_types_customdata.c
+++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c
@@ -981,7 +981,7 @@ PyObject *BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer)
case CD_PROP_STR:
{
MStringProperty *mstring = value;
- ret = PyBytes_FromStringAndSize(mstring->s, BLI_strnlen(mstring->s, sizeof(mstring->s)));
+ ret = PyBytes_FromStringAndSize(mstring->s, mstring->s_len);
break;
}
case CD_MTEXPOLY:
@@ -1067,13 +1067,17 @@ int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObj
case CD_PROP_STR:
{
MStringProperty *mstring = value;
- const char *tmp_val = PyBytes_AsString(py_value);
- if (UNLIKELY(tmp_val == NULL)) {
+ char *tmp_val;
+ Py_ssize_t tmp_val_len;
+ if (UNLIKELY(PyBytes_AsStringAndSize(py_value, &tmp_val, &tmp_val_len) == -1)) {
PyErr_Format(PyExc_TypeError, "expected bytes, not a %.200s", Py_TYPE(py_value)->tp_name);
ret = -1;
}
else {
- BLI_strncpy(mstring->s, tmp_val, min_ii(PyBytes_Size(py_value), sizeof(mstring->s)));
+ if (tmp_val_len > sizeof(mstring->s))
+ tmp_val_len = sizeof(mstring->s);
+ memcpy(mstring->s, tmp_val, tmp_val_len);
+ mstring->s_len = tmp_val_len;
}
break;
}
diff --git a/source/blender/python/generic/bpy_internal_import.h b/source/blender/python/generic/bpy_internal_import.h
index 1592ec52b4c..56cdf677ccb 100644
--- a/source/blender/python/generic/bpy_internal_import.h
+++ b/source/blender/python/generic/bpy_internal_import.h
@@ -48,9 +48,9 @@ struct Text;
void bpy_import_init(PyObject *builtins);
-PyObject* bpy_text_import(struct Text *text);
-PyObject* bpy_text_import_name(const char *name, int *found);
-PyObject* bpy_text_reimport(PyObject *module, int *found);
+PyObject *bpy_text_import(struct Text *text);
+PyObject *bpy_text_import_name(const char *name, int *found);
+PyObject *bpy_text_reimport(PyObject *module, int *found);
/* void bpy_text_clear_modules(int clear_all);*/ /* Clear user modules */
void bpy_text_filename_get(char *fn, size_t fn_len, struct Text *text);
diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c
index 9a064923736..56d9e2ac0dd 100644
--- a/source/blender/python/generic/py_capi_utils.c
+++ b/source/blender/python/generic/py_capi_utils.c
@@ -33,6 +33,8 @@
#include <Python.h>
#include <frameobject.h>
+#include "BLI_utildefines.h" /* for bool */
+
#include "py_capi_utils.h"
/* only for BLI_strncpy_wchar_from_utf8, should replace with py funcs but too late in release now */
@@ -44,7 +46,7 @@
/* array utility function */
int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length,
- const PyTypeObject *type, const short is_double, const char *error_prefix)
+ const PyTypeObject *type, const bool is_double, const char *error_prefix)
{
PyObject *value_fast;
Py_ssize_t value_len;
@@ -112,6 +114,54 @@ int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length,
return 0;
}
+/* array utility function */
+PyObject *PyC_FromArray(const void *array, int length, const PyTypeObject *type,
+ const bool is_double, const char *error_prefix)
+{
+ PyObject *tuple;
+ int i;
+
+ tuple = PyTuple_New(length);
+
+ /* for each type */
+ if (type == &PyFloat_Type) {
+ if (is_double) {
+ const double *array_double = array;
+ for (i = 0; i < length; ++i) {
+ PyTuple_SET_ITEM(tuple, i, PyFloat_FromDouble(array_double[i]));
+ }
+ }
+ else {
+ const float *array_float = array;
+ for (i = 0; i < length; ++i) {
+ PyTuple_SET_ITEM(tuple, i, PyFloat_FromDouble(array_float[i]));
+ }
+ }
+ }
+ else if (type == &PyLong_Type) {
+ /* could use is_double for 'long int' but no use now */
+ const int *array_int = array;
+ for (i = 0; i < length; ++i) {
+ PyTuple_SET_ITEM(tuple, i, PyLong_FromLong(array_int[i]));
+ }
+ }
+ else if (type == &PyBool_Type) {
+ const int *array_bool = array;
+ for (i = 0; i < length; ++i) {
+ PyTuple_SET_ITEM(tuple, i, PyBool_FromLong(array_bool[i]));
+ }
+ }
+ else {
+ Py_DECREF(tuple);
+ PyErr_Format(PyExc_TypeError,
+ "%s: internal error %s is invalid",
+ error_prefix, type->tp_name);
+ return NULL;
+ }
+
+ return tuple;
+}
+
/* for debugging */
void PyC_ObSpit(const char *name, PyObject *var)
diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h
index db582bd7086..239858032de 100644
--- a/source/blender/python/generic/py_capi_utils.h
+++ b/source/blender/python/generic/py_capi_utils.h
@@ -38,7 +38,9 @@ PyObject * PyC_Err_Format_Prefix(PyObject *exception_type_prefix, const char *f
void PyC_FileAndNum(const char **filename, int *lineno);
void PyC_FileAndNum_Safe(const char **filename, int *lineno); /* checks python is running */
int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length,
- const PyTypeObject *type, const short is_double, const char *error_prefix);
+ const PyTypeObject *type, const bool is_double, const char *error_prefix);
+PyObject * PyC_FromArray(const void *array, int length, const PyTypeObject *type,
+ const bool is_double, const char *error_prefix);
/* follow http://www.python.org/dev/peps/pep-0383/ */
PyObject * PyC_UnicodeFromByte(const char *str);
diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c
index c4d8f8ee9b8..1f8385288bd 100644
--- a/source/blender/python/intern/bpy.c
+++ b/source/blender/python/intern/bpy.c
@@ -35,19 +35,19 @@
#include "RNA_types.h"
#include "RNA_access.h"
-#include "bpy.h"
-#include "bpy_util.h"
+#include "BLI_path_util.h"
+#include "BLI_string.h"
+#include "BKE_bpath.h"
+#include "BLI_utildefines.h"
+
+#include "bpy.h"
+#include "bpy_util.h"
#include "bpy_rna.h"
#include "bpy_app.h"
#include "bpy_props.h"
#include "bpy_library.h"
#include "bpy_operator.h"
-#include "BLI_path_util.h"
-#include "BLI_string.h"
-#include "BKE_bpath.h"
-#include "BLI_utildefines.h"
-
#include "BKE_main.h"
#include "BKE_global.h" /* XXX, G.main only */
#include "BKE_blender.h"
@@ -98,7 +98,7 @@ static int bpy_blend_paths_visit_cb(void *userdata, char *UNUSED(path_dst), cons
PyObject *item = PyUnicode_DecodeFSDefault(path_src);
PyList_Append(list, item);
Py_DECREF(item);
- return FALSE; /* never edits the path */
+ return false; /* never edits the path */
}
PyDoc_STRVAR(bpy_blend_paths_doc,
@@ -120,9 +120,9 @@ static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObjec
int flag = 0;
PyObject *list;
- int absolute = FALSE;
- int packed = FALSE;
- int local = FALSE;
+ int absolute = false;
+ int packed = false;
+ int local = false;
static const char *kwlist[] = {"absolute", "packed", "local", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kw, "|iii:blend_paths",
@@ -209,7 +209,7 @@ static PyObject *bpy_resource_path(PyObject *UNUSED(self), PyObject *args, PyObj
return NULL;
}
- path = BLI_get_folder_version(folder_id, (major * 100) + minor, FALSE);
+ path = BLI_get_folder_version(folder_id, (major * 100) + minor, false);
return PyUnicode_DecodeFSDefault(path ? path : "");
}
diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c
index 784ce2f93e0..65568e9a0c1 100644
--- a/source/blender/python/intern/bpy_app.c
+++ b/source/blender/python/intern/bpy_app.c
@@ -182,7 +182,7 @@ static int bpy_app_debug_set(PyObject *UNUSED(self), PyObject *value, void *clos
const int flag = GET_INT_FROM_POINTER(closure);
const int param = PyObject_IsTrue(value);
- if (param < 0) {
+ if (param == -1) {
PyErr_SetString(PyExc_TypeError, "bpy.app.debug can only be True/False");
return -1;
}
diff --git a/source/blender/python/intern/bpy_app_ffmpeg.c b/source/blender/python/intern/bpy_app_ffmpeg.c
index 5ae2a11710a..3bf3dec3872 100644
--- a/source/blender/python/intern/bpy_app_ffmpeg.c
+++ b/source/blender/python/intern/bpy_app_ffmpeg.c
@@ -41,16 +41,16 @@ static PyTypeObject BlenderAppFFmpegType;
#define DEF_FFMPEG_LIB_VERSION(lib) \
{(char *)(#lib "_version"), (char *)("The " #lib " version as a tuple of 3 numbers")}, \
- {(char *)(#lib "_version_string"), (char *)("The " #lib " version formatted as a string")},
+ {(char *)(#lib "_version_string"), (char *)("The " #lib " version formatted as a string")}
static PyStructSequence_Field app_ffmpeg_info_fields[] = {
{(char *)"supported", (char *)("Boolean, True when Blender is built with FFmpeg support")},
- DEF_FFMPEG_LIB_VERSION(avcodec)
- DEF_FFMPEG_LIB_VERSION(avdevice)
- DEF_FFMPEG_LIB_VERSION(avformat)
- DEF_FFMPEG_LIB_VERSION(avutil)
- DEF_FFMPEG_LIB_VERSION(swscale)
+ DEF_FFMPEG_LIB_VERSION(avcodec),
+ DEF_FFMPEG_LIB_VERSION(avdevice),
+ DEF_FFMPEG_LIB_VERSION(avformat),
+ DEF_FFMPEG_LIB_VERSION(avutil),
+ DEF_FFMPEG_LIB_VERSION(swscale),
{NULL}
};
diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c
index 9a79616c23b..c49794ad37a 100644
--- a/source/blender/python/intern/bpy_driver.c
+++ b/source/blender/python/intern/bpy_driver.c
@@ -122,7 +122,7 @@ static void bpy_pydriver_update_dict(const float evaltime)
void BPY_driver_reset(void)
{
PyGILState_STATE gilstate;
- int use_gil = TRUE; /* !PYC_INTERPRETER_ACTIVE; */
+ bool use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
if (use_gil)
gilstate = PyGILState_Ensure();
@@ -175,7 +175,7 @@ float BPY_driver_exec(ChannelDriver *driver, const float evaltime)
PyObject *expr_vars; /* speed up by pre-hashing string & avoids re-converting unicode strings for every execution */
PyObject *expr_code;
PyGILState_STATE gilstate;
- int use_gil;
+ bool use_gil;
DriverVar *dvar;
double result = 0.0; /* default return */
@@ -193,7 +193,7 @@ float BPY_driver_exec(ChannelDriver *driver, const float evaltime)
return 0.0f;
}
- use_gil = TRUE; /* !PYC_INTERPRETER_ACTIVE; */
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
if (use_gil)
gilstate = PyGILState_Ensure();
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index 7bce8673943..e9fa00c7868 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -39,6 +39,15 @@
#include "MEM_guardedalloc.h"
+#include "BLI_path_util.h"
+#include "BLI_fileops.h"
+#include "BLI_listbase.h"
+#include "BLI_math_base.h"
+#include "BLI_string.h"
+#include "BLI_string_utf8.h"
+#include "BLI_utildefines.h"
+#include "BLI_threads.h"
+
#include "RNA_types.h"
#include "bpy.h"
@@ -52,15 +61,6 @@
#include "DNA_space_types.h"
#include "DNA_text_types.h"
-#include "BLI_path_util.h"
-#include "BLI_fileops.h"
-#include "BLI_listbase.h"
-#include "BLI_math_base.h"
-#include "BLI_string.h"
-#include "BLI_string_utf8.h"
-#include "BLI_utildefines.h"
-#include "BLI_threads.h"
-
#include "BKE_context.h"
#include "BKE_text.h"
#include "BKE_main.h"
@@ -166,7 +166,7 @@ void BPY_text_free_code(Text *text)
{
if (text->compiled) {
PyGILState_STATE gilstate;
- int use_gil = !PYC_INTERPRETER_ACTIVE;
+ bool use_gil = !PYC_INTERPRETER_ACTIVE;
if (use_gil)
gilstate = PyGILState_Ensure();
@@ -378,8 +378,8 @@ static void python_script_error_jump_text(struct Text *text)
python_script_error_jump(text->id.name + 2, &lineno, &offset);
if (lineno != -1) {
/* select the line with the error */
- txt_move_to(text, lineno - 1, INT_MAX, FALSE);
- txt_move_to(text, lineno - 1, offset, TRUE);
+ txt_move_to(text, lineno - 1, INT_MAX, false);
+ txt_move_to(text, lineno - 1, offset, true);
}
}
@@ -397,7 +397,7 @@ typedef struct {
#endif
static int python_script_exec(bContext *C, const char *fn, struct Text *text,
- struct ReportList *reports, const short do_jump)
+ struct ReportList *reports, const bool do_jump)
{
Main *bmain_old = CTX_data_main(C);
PyObject *main_mod = NULL;
@@ -514,11 +514,11 @@ static int python_script_exec(bContext *C, const char *fn, struct Text *text,
/* Can run a file or text block */
int BPY_filepath_exec(bContext *C, const char *filepath, struct ReportList *reports)
{
- return python_script_exec(C, filepath, NULL, reports, FALSE);
+ return python_script_exec(C, filepath, NULL, reports, false);
}
-int BPY_text_exec(bContext *C, struct Text *text, struct ReportList *reports, const short do_jump)
+int BPY_text_exec(bContext *C, struct Text *text, struct ReportList *reports, const bool do_jump)
{
return python_script_exec(C, NULL, text, reports, do_jump);
}
@@ -719,12 +719,12 @@ void BPY_modules_load_user(bContext *C)
int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *result)
{
PyGILState_STATE gilstate;
- int use_gil = !PYC_INTERPRETER_ACTIVE;
+ bool use_gil = !PYC_INTERPRETER_ACTIVE;
PyObject *pyctx;
PyObject *item;
PointerRNA *ptr = NULL;
- int done = FALSE;
+ bool done = false;
if (use_gil)
gilstate = PyGILState_Ensure();
@@ -743,7 +743,7 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *
//result->ptr = ((BPy_StructRNA *)item)->ptr;
CTX_data_pointer_set(result, ptr->id.data, ptr->type, ptr->data);
- done = TRUE;
+ done = true;
}
else if (PySequence_Check(item)) {
PyObject *seq_fast = PySequence_Fast(item, "bpy_context_get sequence conversion");
@@ -774,7 +774,7 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *
}
Py_DECREF(seq_fast);
- done = TRUE;
+ done = true;
}
}
diff --git a/source/blender/python/intern/bpy_interface_atexit.c b/source/blender/python/intern/bpy_interface_atexit.c
index 13d8cedf907..d1d33a01e55 100644
--- a/source/blender/python/intern/bpy_interface_atexit.c
+++ b/source/blender/python/intern/bpy_interface_atexit.c
@@ -31,13 +31,13 @@
#include <Python.h>
+#include "BLI_utildefines.h"
+
#include "bpy_util.h"
#include "bpy.h" /* own include */
#include "WM_api.h"
-#include "BLI_utildefines.h"
-
static PyObject *bpy_atexit(PyObject *UNUSED(self), PyObject *UNUSED(args), PyObject *UNUSED(kw))
{
/* close down enough of blender at least not to crash */
diff --git a/source/blender/python/intern/bpy_library.c b/source/blender/python/intern/bpy_library.c
index 7571fe0f75e..ec6322a1a11 100644
--- a/source/blender/python/intern/bpy_library.c
+++ b/source/blender/python/intern/bpy_library.c
@@ -244,7 +244,7 @@ static PyObject *bpy_lib_enter(BPy_Library *self, PyObject *UNUSED(args))
self->blo_handle = BLO_blendhandle_from_file(self->abspath, &reports);
if (self->blo_handle == NULL) {
- if (BPy_reports_to_error(&reports, PyExc_IOError, TRUE) != -1) {
+ if (BPy_reports_to_error(&reports, PyExc_IOError, true) != -1) {
PyErr_Format(PyExc_IOError,
"load: %s failed to open blend file",
self->abspath);
diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c
index 55ef217e781..ee885684e03 100644
--- a/source/blender/python/intern/bpy_operator.c
+++ b/source/blender/python/intern/bpy_operator.c
@@ -35,6 +35,9 @@
#include "RNA_types.h"
+#include "BLI_utildefines.h"
+#include "BLI_string.h"
+
#include "BPY_extern.h"
#include "bpy_operator.h"
#include "bpy_operator_wrap.h"
@@ -42,9 +45,6 @@
#include "bpy_util.h"
#include "../generic/bpy_internal_import.h"
-#include "BLI_utildefines.h"
-#include "BLI_string.h"
-
#include "RNA_access.h"
#include "RNA_enum_types.h"
@@ -85,7 +85,7 @@ static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args)
if (!PyArg_ParseTuple(args, "s|Os:_bpy.ops.poll", &opname, &context_dict, &context_str))
return NULL;
- ot = WM_operatortype_find(opname, TRUE);
+ ot = WM_operatortype_find(opname, true);
if (ot == NULL) {
PyErr_Format(PyExc_AttributeError,
@@ -147,7 +147,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
/* note that context is an int, python does the conversion in this case */
int context = WM_OP_EXEC_DEFAULT;
- int is_undo = FALSE;
+ int is_undo = false;
/* XXX Todo, work out a better solution for passing on context,
* could make a tuple from self and pack the name and Context into it... */
@@ -164,7 +164,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
return NULL;
}
- ot = WM_operatortype_find(opname, TRUE);
+ ot = WM_operatortype_find(opname, true);
if (ot == NULL) {
PyErr_Format(PyExc_AttributeError,
@@ -209,7 +209,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
CTX_py_dict_set(C, (void *)context_dict);
Py_XINCREF(context_dict); /* so we done loose it */
- if (WM_operator_poll_context((bContext *)C, ot, context) == FALSE) {
+ if (WM_operator_poll_context((bContext *)C, ot, context) == false) {
const char *msg = CTX_wm_operator_poll_msg_get(C);
PyErr_Format(PyExc_RuntimeError,
"Operator bpy.ops.%.200s.poll() %.200s",
@@ -248,7 +248,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
}
#endif
- error_val = BPy_reports_to_error(reports, PyExc_RuntimeError, FALSE);
+ error_val = BPy_reports_to_error(reports, PyExc_RuntimeError, false);
/* operator output is nice to have in the terminal/console too */
if (reports->list.first) {
@@ -328,7 +328,7 @@ static PyObject *pyop_as_string(PyObject *UNUSED(self), PyObject *args)
if (!PyArg_ParseTuple(args, "s|O!i:_bpy.ops.as_string", &opname, &PyDict_Type, &kw, &all_args))
return NULL;
- ot = WM_operatortype_find(opname, TRUE);
+ ot = WM_operatortype_find(opname, true);
if (ot == NULL) {
PyErr_Format(PyExc_AttributeError,
@@ -392,7 +392,7 @@ static PyObject *pyop_getrna(PyObject *UNUSED(self), PyObject *value)
PyErr_SetString(PyExc_TypeError, "_bpy.ops.get_rna() expects a string argument");
return NULL;
}
- ot = WM_operatortype_find(opname, TRUE);
+ ot = WM_operatortype_find(opname, true);
if (ot == NULL) {
PyErr_Format(PyExc_KeyError, "_bpy.ops.get_rna(\"%s\") not found", opname);
return NULL;
@@ -408,7 +408,7 @@ static PyObject *pyop_getrna(PyObject *UNUSED(self), PyObject *value)
pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr);
#ifdef PYRNA_FREE_SUPPORT
- pyrna->freeptr = TRUE;
+ pyrna->freeptr = true;
#endif
return (PyObject *)pyrna;
}
@@ -425,7 +425,7 @@ static PyObject *pyop_getinstance(PyObject *UNUSED(self), PyObject *value)
PyErr_SetString(PyExc_TypeError, "_bpy.ops.get_instance() expects a string argument");
return NULL;
}
- ot = WM_operatortype_find(opname, TRUE);
+ ot = WM_operatortype_find(opname, true);
if (ot == NULL) {
PyErr_Format(PyExc_KeyError, "_bpy.ops.get_instance(\"%s\") not found", opname);
return NULL;
@@ -444,7 +444,7 @@ static PyObject *pyop_getinstance(PyObject *UNUSED(self), PyObject *value)
pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr);
#ifdef PYRNA_FREE_SUPPORT
- pyrna->freeptr = TRUE;
+ pyrna->freeptr = true;
#endif
op->ptr = &pyrna->ptr;
diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c
index 1caec294aa0..cb2e12ba996 100644
--- a/source/blender/python/intern/bpy_operator_wrap.c
+++ b/source/blender/python/intern/bpy_operator_wrap.c
@@ -112,7 +112,7 @@ PyObject *PYOP_wrap_macro_define(PyObject *UNUSED(self), PyObject *args)
if (!PyArg_ParseTuple(args, "Os:_bpy.ops.macro_define", &macro, &opname))
return NULL;
- if (WM_operatortype_find(opname, TRUE) == NULL) {
+ if (WM_operatortype_find(opname, true) == NULL) {
PyErr_Format(PyExc_ValueError,
"Macro Define: '%s' is not a valid operator id",
opname);
@@ -123,7 +123,7 @@ PyObject *PYOP_wrap_macro_define(PyObject *UNUSED(self), PyObject *args)
srna = srna_from_self(macro, "Macro Define:");
macroname = RNA_struct_identifier(srna);
- ot = WM_operatortype_find(macroname, TRUE);
+ ot = WM_operatortype_find(macroname, true);
if (!ot) {
PyErr_Format(PyExc_ValueError,
diff --git a/source/blender/python/intern/bpy_path.c b/source/blender/python/intern/bpy_path.c
index 8df7ed2364f..1d554b60bbe 100644
--- a/source/blender/python/intern/bpy_path.c
+++ b/source/blender/python/intern/bpy_path.c
@@ -28,6 +28,8 @@
#include <Python.h>
+#include "BLI_utildefines.h"
+
#include "bpy_path.h"
#include "../generic/py_capi_utils.h"
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c
index 57ddee0c8c0..f3fa0c9a0a9 100644
--- a/source/blender/python/intern/bpy_props.c
+++ b/source/blender/python/intern/bpy_props.c
@@ -33,12 +33,12 @@
#include "RNA_types.h"
+#include "BLI_utildefines.h"
+
#include "bpy_props.h"
#include "bpy_rna.h"
#include "bpy_util.h"
-#include "BLI_utildefines.h"
-
#include "BKE_idprop.h"
#include "RNA_access.h"
@@ -50,9 +50,11 @@
#include "../generic/py_capi_utils.h"
/* initial definition of callback slots we'll probably have more then 1 */
-#define BPY_DATA_CB_SLOT_SIZE 1
+#define BPY_DATA_CB_SLOT_SIZE 3
#define BPY_DATA_CB_SLOT_UPDATE 0
+#define BPY_DATA_CB_SLOT_GET 1
+#define BPY_DATA_CB_SLOT_SET 2
extern BPy_StructRNA *bpy_context_module;
@@ -197,7 +199,7 @@ static void bpy_prop_update_cb(struct bContext *C, struct PointerRNA *ptr, struc
BLI_assert(py_data != NULL);
if (!is_write_ok) {
- pyrna_write_set(TRUE);
+ pyrna_write_set(true);
}
bpy_context_set(C, &gilstate);
@@ -230,25 +232,1260 @@ static void bpy_prop_update_cb(struct bContext *C, struct PointerRNA *ptr, struc
bpy_context_clear(C, &gilstate);
if (!is_write_ok) {
- pyrna_write_set(FALSE);
+ pyrna_write_set(false);
+ }
+}
+
+static int bpy_prop_boolean_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int value;
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ value = false;
+ }
+ else {
+ value = PyLong_AsLong(ret);
+
+ if (value == -1 && PyErr_Occurred()) {
+ printf_func_error(py_func);
+ value = false;
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
}
+
+ return value;
}
-static int bpy_prop_callback_check(PyObject *py_func, int argcount)
+static void bpy_prop_boolean_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int value)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_SET];
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ PyTuple_SET_ITEM(args, 1, PyBool_FromLong(value));
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if (ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static void bpy_prop_boolean_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int i, len = RNA_property_array_length(ptr, prop);
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+
+ for (i = 0; i < len; ++i)
+ values[i] = false;
+ }
+ else {
+ if (PyC_AsArray(values, ret, len, &PyBool_Type, false, "BoolVectorProperty get") == -1) {
+ printf_func_error(py_func);
+
+ for (i = 0; i < len; ++i)
+ values[i] = false;
+
+ /* PyC_AsArray decrements refcount internally on error */
+ }
+ else {
+ Py_DECREF(ret);
+ }
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static void bpy_prop_boolean_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyObject *py_values;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int len = RNA_property_array_length(ptr, prop);
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_SET];
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ py_values = PyC_FromArray(values, len, &PyBool_Type, false, "BoolVectorProperty set");
+ if (!py_values) {
+ printf_func_error(py_func);
+ }
+ else
+ PyTuple_SET_ITEM(args, 1, py_values);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if (ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static int bpy_prop_int_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int value;
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ value = 0.0f;
+ }
+ else {
+ value = PyLong_AsLong(ret);
+
+ if (value == -1 && PyErr_Occurred()) {
+ printf_func_error(py_func);
+ value = 0;
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+
+ return value;
+}
+
+static void bpy_prop_int_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int value)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_SET];
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ PyTuple_SET_ITEM(args, 1, PyLong_FromLong(value));
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if (ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static void bpy_prop_int_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int i, len = RNA_property_array_length(ptr, prop);
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+
+ for (i = 0; i < len; ++i)
+ values[i] = 0;
+ }
+ else {
+ if (PyC_AsArray(values, ret, len, &PyLong_Type, false, "IntVectorProperty get") == -1) {
+ printf_func_error(py_func);
+
+ for (i = 0; i < len; ++i)
+ values[i] = 0;
+
+ /* PyC_AsArray decrements refcount internally on error */
+ }
+ else {
+ Py_DECREF(ret);
+ }
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static void bpy_prop_int_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyObject *py_values;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int len = RNA_property_array_length(ptr, prop);
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_SET];
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ py_values = PyC_FromArray(values, len, &PyLong_Type, false, "IntVectorProperty set");
+ if (!py_values) {
+ printf_func_error(py_func);
+ }
+ else
+ PyTuple_SET_ITEM(args, 1, py_values);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if (ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static float bpy_prop_float_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ float value;
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ value = 0.0f;
+ }
+ else {
+ value = PyFloat_AsDouble(ret);
+
+ if (value == -1.0f && PyErr_Occurred()) {
+ printf_func_error(py_func);
+ value = 0.0f;
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+
+ return value;
+}
+
+static void bpy_prop_float_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, float value)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_SET];
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ PyTuple_SET_ITEM(args, 1, PyFloat_FromDouble(value));
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if (ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static void bpy_prop_float_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, float *values)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int i, len = RNA_property_array_length(ptr, prop);
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+
+ for (i = 0; i < len; ++i)
+ values[i] = 0.0f;
+ }
+ else {
+ if (PyC_AsArray(values, ret, len, &PyFloat_Type, false, "FloatVectorProperty get") == -1) {
+ printf_func_error(py_func);
+
+ for (i = 0; i < len; ++i)
+ values[i] = 0.0f;
+
+ /* PyC_AsArray decrements refcount internally on error */
+ }
+ else {
+ Py_DECREF(ret);
+ }
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static void bpy_prop_float_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const float *values)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyObject *py_values;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int len = RNA_property_array_length(ptr, prop);
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_SET];
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ py_values = PyC_FromArray(values, len, &PyFloat_Type, false, "FloatVectorProperty set");
+ if (!py_values) {
+ printf_func_error(py_func);
+ }
+ else
+ PyTuple_SET_ITEM(args, 1, py_values);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if (ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static void bpy_prop_string_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, char *value)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ value[0] = '\0';
+ }
+ else if (!PyUnicode_Check(ret)) {
+ PyErr_Format(PyExc_TypeError,
+ "return value must be a string, not %.200s",
+ Py_TYPE(ret)->tp_name);
+ printf_func_error(py_func);
+ value[0] = '\0';
+ Py_DECREF(ret);
+ }
+ else {
+ Py_ssize_t length;
+ const char *buffer = _PyUnicode_AsStringAndSize(ret, &length);
+ memcpy(value, buffer, length + 1);
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static int bpy_prop_string_length_cb(struct PointerRNA *ptr, struct PropertyRNA *prop)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int length;
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ length = 0;
+ }
+ else if (!PyUnicode_Check(ret)) {
+ PyErr_Format(PyExc_TypeError,
+ "return value must be a string, not %.200s",
+ Py_TYPE(ret)->tp_name);
+ printf_func_error(py_func);
+ length = 0;
+ Py_DECREF(ret);
+ }
+ else {
+ Py_ssize_t length_ssize_t = 0;
+ _PyUnicode_AsStringAndSize(ret, &length_ssize_t);
+ length = length_ssize_t;
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+
+ return length;
+}
+
+static void bpy_prop_string_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const char *value)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ PyObject *py_value;
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_SET];
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ py_value = PyUnicode_FromString(value);
+ if (!py_value) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be a string");
+ printf_func_error(py_func);
+ }
+ else
+ PyTuple_SET_ITEM(args, 1, py_value);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if (ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static int bpy_prop_enum_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int value;
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ value = RNA_property_enum_get_default(ptr, prop);
+ }
+ else {
+ value = PyLong_AsLong(ret);
+
+ if (value == -1 && PyErr_Occurred()) {
+ printf_func_error(py_func);
+ value = RNA_property_enum_get_default(ptr, prop);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+
+ return value;
+}
+
+static void bpy_prop_enum_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int value)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_SET];
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ PyTuple_SET_ITEM(args, 1, PyLong_FromLong(value));
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if (ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+/* utility function we need for parsing int's in an if statement */
+static int py_long_as_int(PyObject *py_long, int *r_int)
+{
+ if (PyLong_CheckExact(py_long)) {
+ *r_int = (int)PyLong_AS_LONG(py_long);
+ return 0;
+ }
+ else {
+ return -1;
+ }
+}
+
+#if 0
+/* copies orig to buf, then sets orig to buf, returns copy length */
+static size_t strswapbufcpy(char *buf, const char **orig)
+{
+ const char *src = *orig;
+ char *dst = buf;
+ size_t i = 0;
+ *orig = buf;
+ while ((*dst = *src)) { dst++; src++; i++; }
+ return i + 1; /* include '\0' */
+}
+#endif
+
+static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, int *defvalue, const short is_enum_flag)
+{
+ EnumPropertyItem *items;
+ PyObject *item;
+ const Py_ssize_t seq_len = PySequence_Fast_GET_SIZE(seq_fast);
+ Py_ssize_t totbuf = 0;
+ int i;
+ short def_used = 0;
+ const char *def_cmp = NULL;
+
+ if (is_enum_flag) {
+ if (seq_len > RNA_ENUM_BITFLAG_SIZE) {
+ PyErr_SetString(PyExc_TypeError,
+ "EnumProperty(...): maximum "
+ STRINGIFY(RNA_ENUM_BITFLAG_SIZE)
+ " members for a ENUM_FLAG type property");
+ return NULL;
+ }
+ if (def && !PySet_Check(def)) {
+ PyErr_Format(PyExc_TypeError,
+ "EnumProperty(...): default option must be a 'set' "
+ "type when ENUM_FLAG is enabled, not a '%.200s'",
+ Py_TYPE(def)->tp_name);
+ return NULL;
+ }
+ }
+ else {
+ if (def) {
+ def_cmp = _PyUnicode_AsString(def);
+ if (def_cmp == NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "EnumProperty(...): default option must be a 'str' "
+ "type when ENUM_FLAG is disabled, not a '%.200s'",
+ Py_TYPE(def)->tp_name);
+ return NULL;
+ }
+ }
+ }
+
+ /* blank value */
+ *defvalue = 0;
+
+ items = MEM_callocN(sizeof(EnumPropertyItem) * (seq_len + 1), "enum_items_from_py1");
+
+ for (i = 0; i < seq_len; i++) {
+ EnumPropertyItem tmp = {0, "", 0, "", ""};
+ Py_ssize_t item_size;
+ Py_ssize_t id_str_size;
+ Py_ssize_t name_str_size;
+ Py_ssize_t desc_str_size;
+
+ item = PySequence_Fast_GET_ITEM(seq_fast, i);
+
+ if ((PyTuple_CheckExact(item)) &&
+ (item_size = PyTuple_GET_SIZE(item)) &&
+ (item_size == 3 || item_size == 4) &&
+ (tmp.identifier = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 0), &id_str_size)) &&
+ (tmp.name = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 1), &name_str_size)) &&
+ (tmp.description = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 2), &desc_str_size)) &&
+ /* TODO, number isn't ensured to be unique from the script author */
+ (item_size < 4 || py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.value) != -1))
+ {
+ if (is_enum_flag) {
+ if (item_size < 4) {
+ tmp.value = 1 << i;
+ }
+
+ if (def && PySet_Contains(def, PyTuple_GET_ITEM(item, 0))) {
+ *defvalue |= tmp.value;
+ def_used++;
+ }
+ }
+ else {
+ if (item_size < 4) {
+ tmp.value = i;
+ }
+
+ if (def && def_used == 0 && strcmp(def_cmp, tmp.identifier) == 0) {
+ *defvalue = tmp.value;
+ def_used++; /* only ever 1 */
+ }
+ }
+
+ items[i] = tmp;
+
+ /* calculate combine string length */
+ totbuf += id_str_size + name_str_size + desc_str_size + 3; /* 3 is for '\0's */
+ }
+ else {
+ MEM_freeN(items);
+ PyErr_SetString(PyExc_TypeError,
+ "EnumProperty(...): expected a tuple containing "
+ "(identifier, name, description) and optionally a "
+ "unique number");
+ return NULL;
+ }
+
+ }
+
+ if (is_enum_flag) {
+ /* strict check that all set members were used */
+ if (def && def_used != PySet_GET_SIZE(def)) {
+ MEM_freeN(items);
+
+ PyErr_Format(PyExc_TypeError,
+ "EnumProperty(..., default={...}): set has %d unused member(s)",
+ PySet_GET_SIZE(def) - def_used);
+ return NULL;
+ }
+ }
+ else {
+ if (def && def_used == 0) {
+ MEM_freeN(items);
+
+ PyErr_Format(PyExc_TypeError,
+ "EnumProperty(..., default=\'%s\'): not found in enum members",
+ def_cmp);
+ return NULL;
+ }
+ }
+
+ /* disabled duplicating strings because the array can still be freed and
+ * the strings from it referenced, for now we can't support dynamically
+ * created strings from python. */
+#if 0
+ /* this would all work perfectly _but_ the python strings may be freed
+ * immediately after use, so we need to duplicate them, ugh.
+ * annoying because it works most of the time without this. */
+ {
+ EnumPropertyItem *items_dup = MEM_mallocN((sizeof(EnumPropertyItem) * (seq_len + 1)) + (sizeof(char) * totbuf),
+ "enum_items_from_py2");
+ EnumPropertyItem *items_ptr = items_dup;
+ char *buf = ((char *)items_dup) + (sizeof(EnumPropertyItem) * (seq_len + 1));
+ memcpy(items_dup, items, sizeof(EnumPropertyItem) * (seq_len + 1));
+ for (i = 0; i < seq_len; i++, items_ptr++) {
+ buf += strswapbufcpy(buf, &items_ptr->identifier);
+ buf += strswapbufcpy(buf, &items_ptr->name);
+ buf += strswapbufcpy(buf, &items_ptr->description);
+ }
+ MEM_freeN(items);
+ items = items_dup;
+ }
+ /* end string duplication */
+#endif
+
+ return items;
+}
+
+static EnumPropertyItem *bpy_prop_enum_itemf_cb(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int *free)
+{
+ PyGILState_STATE gilstate;
+
+ PyObject *py_func = RNA_property_enum_py_data_get(prop);
+ PyObject *self = NULL;
+ PyObject *args;
+ PyObject *items; /* returned from the function call */
+
+ EnumPropertyItem *eitems = NULL;
+ int err = 0;
+
+ bpy_context_set(C, &gilstate);
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ /* now get the context */
+ PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module);
+ Py_INCREF(bpy_context_module);
+
+ items = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (items == NULL) {
+ err = -1;
+ }
+ else {
+ PyObject *items_fast;
+ int defvalue_dummy = 0;
+
+ if (!(items_fast = PySequence_Fast(items, "EnumProperty(...): "
+ "return value from the callback was not a sequence")))
+ {
+ err = -1;
+ }
+ else {
+ eitems = enum_items_from_py(items_fast, NULL, &defvalue_dummy,
+ (RNA_property_flag(prop) & PROP_ENUM_FLAG) != 0);
+
+ Py_DECREF(items_fast);
+
+ if (!eitems) {
+ err = -1;
+ }
+ }
+
+ Py_DECREF(items);
+ }
+
+ if (err != -1) { /* worked */
+ *free = 1;
+ }
+ else {
+ printf_func_error(py_func);
+
+ eitems = DummyRNA_NULL_items;
+ }
+
+
+ bpy_context_clear(C, &gilstate);
+ return eitems;
+}
+
+static int bpy_prop_callback_check(PyObject *py_func, const char *keyword, int argcount)
{
if (py_func && py_func != Py_None) {
if (!PyFunction_Check(py_func)) {
PyErr_Format(PyExc_TypeError,
- "update keyword: expected a function type, not a %.200s",
- Py_TYPE(py_func)->tp_name);
+ "%s keyword: expected a function type, not a %.200s",
+ keyword, Py_TYPE(py_func)->tp_name);
return -1;
}
else {
PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func);
if (f_code->co_argcount != argcount) {
PyErr_Format(PyExc_TypeError,
- "update keyword: expected a function taking %d arguments, not %d",
- argcount, f_code->co_argcount);
+ "%s keyword: expected a function taking %d arguments, not %d",
+ keyword, argcount, f_code->co_argcount);
return -1;
}
}
@@ -257,32 +1494,215 @@ static int bpy_prop_callback_check(PyObject *py_func, int argcount)
return 0;
}
+static PyObject **bpy_prop_py_data_get(struct PropertyRNA *prop)
+{
+ PyObject **py_data = RNA_property_py_data_get(prop);
+ if (!py_data) {
+ py_data = MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, __func__);
+ RNA_def_py_data(prop, py_data);
+ }
+ return py_data;
+}
-static int bpy_prop_callback_assign(struct PropertyRNA *prop, PyObject *update_cb)
+static void bpy_prop_callback_assign_update(struct PropertyRNA *prop, PyObject *update_cb)
{
/* assume this is already checked for type and arg length */
if (update_cb && update_cb != Py_None) {
- PyObject **py_data = MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, __func__);
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
RNA_def_property_update_runtime(prop, (void *)bpy_prop_update_cb);
py_data[BPY_DATA_CB_SLOT_UPDATE] = update_cb;
- RNA_def_py_data(prop, py_data);
RNA_def_property_flag(prop, PROP_CONTEXT_PROPERTY_UPDATE);
}
+}
- return 0;
+static void bpy_prop_callback_assign_boolean(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
+{
+ BooleanPropertyGetFunc rna_get_cb = NULL;
+ BooleanPropertySetFunc rna_set_cb = NULL;
+
+ if (get_cb && get_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_get_cb = bpy_prop_boolean_get_cb;
+ py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
+ }
+
+ if (set_cb && set_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_set_cb = bpy_prop_boolean_set_cb;
+ py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
+ }
+
+ RNA_def_property_boolean_funcs_runtime(prop, rna_get_cb, rna_set_cb);
}
-/* utility function we need for parsing int's in an if statement */
-static int py_long_as_int(PyObject *py_long, int *r_int)
+static void bpy_prop_callback_assign_boolean_array(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
{
- if (PyLong_CheckExact(py_long)) {
- *r_int = (int)PyLong_AS_LONG(py_long);
- return 0;
+ BooleanArrayPropertyGetFunc rna_get_cb = NULL;
+ BooleanArrayPropertySetFunc rna_set_cb = NULL;
+
+ if (get_cb && get_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_get_cb = bpy_prop_boolean_array_get_cb;
+ py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
}
- else {
- return -1;
+
+ if (set_cb && set_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_set_cb = bpy_prop_boolean_array_set_cb;
+ py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
+ }
+
+ RNA_def_property_boolean_array_funcs_runtime(prop, rna_get_cb, rna_set_cb);
+}
+
+static void bpy_prop_callback_assign_int(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
+{
+ IntPropertyGetFunc rna_get_cb = NULL;
+ IntPropertySetFunc rna_set_cb = NULL;
+
+ if (get_cb && get_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_get_cb = bpy_prop_int_get_cb;
+ py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
+ }
+
+ if (set_cb && set_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_set_cb = bpy_prop_int_set_cb;
+ py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
+ }
+
+ RNA_def_property_int_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL);
+}
+
+static void bpy_prop_callback_assign_int_array(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
+{
+ IntArrayPropertyGetFunc rna_get_cb = NULL;
+ IntArrayPropertySetFunc rna_set_cb = NULL;
+
+ if (get_cb && get_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_get_cb = bpy_prop_int_array_get_cb;
+ py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
+ }
+
+ if (set_cb && set_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_set_cb = bpy_prop_int_array_set_cb;
+ py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
+ }
+
+ RNA_def_property_int_array_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL);
+}
+
+static void bpy_prop_callback_assign_float(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
+{
+ FloatPropertyGetFunc rna_get_cb = NULL;
+ FloatPropertySetFunc rna_set_cb = NULL;
+
+ if (get_cb && get_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_get_cb = bpy_prop_float_get_cb;
+ py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
}
+
+ if (set_cb && set_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_set_cb = bpy_prop_float_set_cb;
+ py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
+ }
+
+ RNA_def_property_float_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL);
+}
+
+static void bpy_prop_callback_assign_float_array(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
+{
+ FloatArrayPropertyGetFunc rna_get_cb = NULL;
+ FloatArrayPropertySetFunc rna_set_cb = NULL;
+
+ if (get_cb && get_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_get_cb = bpy_prop_float_array_get_cb;
+ py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
+ }
+
+ if (set_cb && set_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_set_cb = bpy_prop_float_array_set_cb;
+ py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
+ }
+
+ RNA_def_property_float_array_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL);
+}
+
+static void bpy_prop_callback_assign_string(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
+{
+ StringPropertyGetFunc rna_get_cb = NULL;
+ StringPropertyLengthFunc rna_length_cb = NULL;
+ StringPropertySetFunc rna_set_cb = NULL;
+
+ if (get_cb && get_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_get_cb = bpy_prop_string_get_cb;
+ rna_length_cb = bpy_prop_string_length_cb;
+ py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
+ }
+
+ if (set_cb && set_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_set_cb = bpy_prop_string_set_cb;
+ py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
+ }
+
+ RNA_def_property_string_funcs_runtime(prop, rna_get_cb, rna_length_cb, rna_set_cb);
+}
+
+static void bpy_prop_callback_assign_enum(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb, PyObject *itemf_cb)
+{
+ EnumPropertyGetFunc rna_get_cb = NULL;
+ EnumPropertyItemFunc rna_itemf_cb = NULL;
+ EnumPropertySetFunc rna_set_cb = NULL;
+
+ if (get_cb && get_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_get_cb = bpy_prop_enum_get_cb;
+ py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
+ }
+
+ if (set_cb && set_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_set_cb = bpy_prop_enum_set_cb;
+ py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
+ }
+
+ if (itemf_cb && itemf_cb != Py_None) {
+ rna_itemf_cb = bpy_prop_enum_itemf_cb;
+ RNA_def_property_enum_py_data(prop, (void *)itemf_cb);
+
+ /* watch out!, if a user is tricky they can probably crash blender
+ * if they manage to free the callback, take care! */
+ /* Py_INCREF(itemf_cb); */
+ }
+
+ RNA_def_property_enum_funcs_runtime(prop, rna_get_cb, rna_set_cb, rna_itemf_cb);
}
/* this define runs at the start of each function and deals with
@@ -386,7 +1806,9 @@ PyDoc_STRVAR(BPy_BoolProperty_doc,
"default=False, "
"options={'ANIMATABLE'}, "
"subtype='NONE', "
- "update=None)\n"
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
"\n"
" Returns a new boolean property definition.\n"
"\n"
@@ -406,7 +1828,7 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
if (srna) {
static const char *kwlist[] = {"attr", "name", "description", "default",
- "options", "subtype", "update", NULL};
+ "options", "subtype", "update", "get", "set", NULL};
const char *id = NULL, *name = NULL, *description = "";
int id_len;
int def = 0;
@@ -416,20 +1838,28 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
char *pysubtype = NULL;
int subtype = PROP_NONE;
PyObject *update_cb = NULL;
+ PyObject *get_cb = NULL;
+ PyObject *set_cb = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|ssiO!sO:BoolProperty",
+ "s#|ssiO!sOOO:BoolProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &def,
&PySet_Type, &pyopts, &pysubtype,
- &update_cb))
+ &update_cb, &get_cb, &set_cb))
{
return NULL;
}
BPY_PROPDEF_SUBTYPE_CHECK(BoolProperty, property_flag_items, property_subtype_number_items);
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
return NULL;
}
@@ -443,7 +1873,8 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
+ bpy_prop_callback_assign_boolean(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
@@ -457,7 +1888,9 @@ PyDoc_STRVAR(BPy_BoolVectorProperty_doc,
"options={'ANIMATABLE'}, "
"subtype='NONE', "
"size=3, "
- "update=None)\n"
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
"\n"
" Returns a new vector boolean property definition.\n"
"\n"
@@ -483,7 +1916,7 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
if (srna) {
static const char *kwlist[] = {"attr", "name", "description", "default",
- "options", "subtype", "size", "update", NULL};
+ "options", "subtype", "size", "update", "get", "set", NULL};
const char *id = NULL, *name = NULL, *description = "";
int id_len;
int def[PYRNA_STACK_ARRAY] = {0};
@@ -495,13 +1928,15 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
char *pysubtype = NULL;
int subtype = PROP_NONE;
PyObject *update_cb = NULL;
+ PyObject *get_cb = NULL;
+ PyObject *set_cb = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|ssOO!siO:BoolVectorProperty",
+ "s#|ssOO!siOOO:BoolVectorProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &pydef,
&PySet_Type, &pyopts, &pysubtype, &size,
- &update_cb))
+ &update_cb, &get_cb, &set_cb))
{
return NULL;
}
@@ -515,10 +1950,16 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
return NULL;
}
- if (pydef && PyC_AsArray(def, pydef, size, &PyBool_Type, FALSE, "BoolVectorProperty(default=sequence)") < 0)
+ if (pydef && PyC_AsArray(def, pydef, size, &PyBool_Type, false, "BoolVectorProperty(default=sequence)") == -1)
return NULL;
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
return NULL;
}
@@ -534,7 +1975,8 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
+ bpy_prop_callback_assign_boolean_array(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
@@ -550,7 +1992,9 @@ PyDoc_STRVAR(BPy_IntProperty_doc,
"step=1, "
"options={'ANIMATABLE'}, "
"subtype='NONE', "
- "update=None)\n"
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
"\n"
" Returns a new int property definition.\n"
"\n"
@@ -571,7 +2015,7 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
if (srna) {
static const char *kwlist[] = {"attr", "name", "description", "default",
"min", "max", "soft_min", "soft_max",
- "step", "options", "subtype", "update", NULL};
+ "step", "options", "subtype", "update", "get", "set", NULL};
const char *id = NULL, *name = NULL, *description = "";
int id_len;
int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1, def = 0;
@@ -581,21 +2025,29 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
char *pysubtype = NULL;
int subtype = PROP_NONE;
PyObject *update_cb = NULL;
+ PyObject *get_cb = NULL;
+ PyObject *set_cb = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|ssiiiiiiO!sO:IntProperty",
+ "s#|ssiiiiiiO!sOOO:IntProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &def,
&min, &max, &soft_min, &soft_max,
&step, &PySet_Type, &pyopts, &pysubtype,
- &update_cb))
+ &update_cb, &get_cb, &set_cb))
{
return NULL;
}
BPY_PROPDEF_SUBTYPE_CHECK(IntProperty, property_flag_items, property_subtype_number_items);
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
return NULL;
}
@@ -611,7 +2063,8 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
+ bpy_prop_callback_assign_int(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
@@ -626,7 +2079,9 @@ PyDoc_STRVAR(BPy_IntVectorProperty_doc,
"options={'ANIMATABLE'}, "
"subtype='NONE', "
"size=3, "
- "update=None)\n"
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
"\n"
" Returns a new vector int property definition.\n"
"\n"
@@ -653,7 +2108,7 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
if (srna) {
static const char *kwlist[] = {"attr", "name", "description", "default",
"min", "max", "soft_min", "soft_max",
- "step", "options", "subtype", "size", "update", NULL};
+ "step", "options", "subtype", "size", "update", "get", "set", NULL};
const char *id = NULL, *name = NULL, *description = "";
int id_len;
int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1;
@@ -666,15 +2121,17 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
char *pysubtype = NULL;
int subtype = PROP_NONE;
PyObject *update_cb = NULL;
+ PyObject *get_cb = NULL;
+ PyObject *set_cb = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|ssOiiiiiO!siO:IntVectorProperty",
+ "s#|ssOiiiiiO!siOOO:IntVectorProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &pydef,
&min, &max, &soft_min, &soft_max,
&step, &PySet_Type, &pyopts,
&pysubtype, &size,
- &update_cb))
+ &update_cb, &get_cb, &set_cb))
{
return NULL;
}
@@ -688,10 +2145,16 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
return NULL;
}
- if (pydef && PyC_AsArray(def, pydef, size, &PyLong_Type, FALSE, "IntVectorProperty(default=sequence)") < 0)
+ if (pydef && PyC_AsArray(def, pydef, size, &PyLong_Type, false, "IntVectorProperty(default=sequence)") == -1)
return NULL;
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
return NULL;
}
@@ -708,7 +2171,8 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
+ bpy_prop_callback_assign_int_array(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
@@ -726,7 +2190,9 @@ PyDoc_STRVAR(BPy_FloatProperty_doc,
"options={'ANIMATABLE'}, "
"subtype='NONE', "
"unit='NONE', "
- "update=None)\n"
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
"\n"
" Returns a new float property definition.\n"
"\n"
@@ -748,7 +2214,8 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
if (srna) {
static const char *kwlist[] = {"attr", "name", "description", "default",
"min", "max", "soft_min", "soft_max",
- "step", "precision", "options", "subtype", "unit", "update", NULL};
+ "step", "precision", "options", "subtype",
+ "unit", "update", "get", "set", NULL};
const char *id = NULL, *name = NULL, *description = "";
int id_len;
float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3, def = 0.0f;
@@ -761,15 +2228,17 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
char *pyunit = NULL;
int unit = PROP_UNIT_NONE;
PyObject *update_cb = NULL;
+ PyObject *get_cb = NULL;
+ PyObject *set_cb = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|ssffffffiO!ssO:FloatProperty",
+ "s#|ssffffffiO!ssOOO:FloatProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &def,
&min, &max, &soft_min, &soft_max,
&step, &precision, &PySet_Type,
&pyopts, &pysubtype, &pyunit,
- &update_cb))
+ &update_cb, &get_cb, &set_cb))
{
return NULL;
}
@@ -781,7 +2250,13 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
return NULL;
}
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
return NULL;
}
@@ -797,7 +2272,8 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
+ bpy_prop_callback_assign_float(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
@@ -814,7 +2290,9 @@ PyDoc_STRVAR(BPy_FloatVectorProperty_doc,
"options={'ANIMATABLE'}, "
"subtype='NONE', "
"size=3, "
- "update=None)\n"
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
"\n"
" Returns a new vector float property definition.\n"
"\n"
@@ -842,7 +2320,8 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
if (srna) {
static const char *kwlist[] = {"attr", "name", "description", "default",
"min", "max", "soft_min", "soft_max",
- "step", "precision", "options", "subtype", "unit", "size", "update", NULL};
+ "step", "precision", "options", "subtype",
+ "unit", "size", "update", "get", "set", NULL};
const char *id = NULL, *name = NULL, *description = "";
int id_len;
float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3;
@@ -857,15 +2336,17 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
char *pyunit = NULL;
int unit = PROP_UNIT_NONE;
PyObject *update_cb = NULL;
+ PyObject *get_cb = NULL;
+ PyObject *set_cb = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|ssOfffffiO!ssiO:FloatVectorProperty",
+ "s#|ssOfffffiO!ssiOOO:FloatVectorProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &pydef,
&min, &max, &soft_min, &soft_max,
&step, &precision, &PySet_Type,
&pyopts, &pysubtype, &pyunit, &size,
- &update_cb))
+ &update_cb, &get_cb, &set_cb))
{
return NULL;
}
@@ -884,10 +2365,16 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
return NULL;
}
- if (pydef && PyC_AsArray(def, pydef, size, &PyFloat_Type, FALSE, "FloatVectorProperty(default=sequence)") < 0)
+ if (pydef && PyC_AsArray(def, pydef, size, &PyFloat_Type, false, "FloatVectorProperty(default=sequence)") == -1)
return NULL;
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
return NULL;
}
@@ -904,7 +2391,8 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
+ bpy_prop_callback_assign_float_array(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
@@ -917,7 +2405,9 @@ PyDoc_STRVAR(BPy_StringProperty_doc,
"maxlen=0, "
"options={'ANIMATABLE'}, "
"subtype='NONE', "
- "update=None)\n"
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
"\n"
" Returns a new string property definition.\n"
"\n"
@@ -937,7 +2427,7 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw
if (srna) {
static const char *kwlist[] = {"attr", "name", "description", "default",
- "maxlen", "options", "subtype", "update", NULL};
+ "maxlen", "options", "subtype", "update", "get", "set", NULL};
const char *id = NULL, *name = NULL, *description = "", *def = "";
int id_len;
int maxlen = 0;
@@ -947,20 +2437,28 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw
char *pysubtype = NULL;
int subtype = PROP_NONE;
PyObject *update_cb = NULL;
+ PyObject *get_cb = NULL;
+ PyObject *set_cb = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|sssiO!sO:StringProperty",
+ "s#|sssiO!sOOO:StringProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &def,
&maxlen, &PySet_Type, &pyopts, &pysubtype,
- &update_cb))
+ &update_cb, &get_cb, &set_cb))
{
return NULL;
}
BPY_PROPDEF_SUBTYPE_CHECK(StringProperty, property_flag_items, property_subtype_string_items);
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
return NULL;
}
@@ -975,246 +2473,22 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
+ bpy_prop_callback_assign_string(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
}
-#if 0
-/* copies orig to buf, then sets orig to buf, returns copy length */
-static size_t strswapbufcpy(char *buf, const char **orig)
-{
- const char *src = *orig;
- char *dst = buf;
- size_t i = 0;
- *orig = buf;
- while ((*dst = *src)) { dst++; src++; i++; }
- return i + 1; /* include '\0' */
-}
-#endif
-
-static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, int *defvalue, const short is_enum_flag)
-{
- EnumPropertyItem *items;
- PyObject *item;
- const Py_ssize_t seq_len = PySequence_Fast_GET_SIZE(seq_fast);
- Py_ssize_t totbuf = 0;
- int i;
- short def_used = 0;
- const char *def_cmp = NULL;
-
- if (is_enum_flag) {
- if (seq_len > RNA_ENUM_BITFLAG_SIZE) {
- PyErr_SetString(PyExc_TypeError,
- "EnumProperty(...): maximum "
- STRINGIFY(RNA_ENUM_BITFLAG_SIZE)
- " members for a ENUM_FLAG type property");
- return NULL;
- }
- if (def && !PySet_Check(def)) {
- PyErr_Format(PyExc_TypeError,
- "EnumProperty(...): default option must be a 'set' "
- "type when ENUM_FLAG is enabled, not a '%.200s'",
- Py_TYPE(def)->tp_name);
- return NULL;
- }
- }
- else {
- if (def) {
- def_cmp = _PyUnicode_AsString(def);
- if (def_cmp == NULL) {
- PyErr_Format(PyExc_TypeError,
- "EnumProperty(...): default option must be a 'str' "
- "type when ENUM_FLAG is disabled, not a '%.200s'",
- Py_TYPE(def)->tp_name);
- return NULL;
- }
- }
- }
-
- /* blank value */
- *defvalue = 0;
-
- items = MEM_callocN(sizeof(EnumPropertyItem) * (seq_len + 1), "enum_items_from_py1");
-
- for (i = 0; i < seq_len; i++) {
- EnumPropertyItem tmp = {0, "", 0, "", ""};
- Py_ssize_t item_size;
- Py_ssize_t id_str_size;
- Py_ssize_t name_str_size;
- Py_ssize_t desc_str_size;
-
- item = PySequence_Fast_GET_ITEM(seq_fast, i);
-
- if ((PyTuple_CheckExact(item)) &&
- (item_size = PyTuple_GET_SIZE(item)) &&
- (item_size == 3 || item_size == 4) &&
- (tmp.identifier = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 0), &id_str_size)) &&
- (tmp.name = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 1), &name_str_size)) &&
- (tmp.description = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 2), &desc_str_size)) &&
- /* TODO, number isn't ensured to be unique from the script author */
- (item_size < 4 || py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.value) != -1))
- {
- if (is_enum_flag) {
- if (item_size < 4) {
- tmp.value = 1 << i;
- }
-
- if (def && PySet_Contains(def, PyTuple_GET_ITEM(item, 0))) {
- *defvalue |= tmp.value;
- def_used++;
- }
- }
- else {
- if (item_size < 4) {
- tmp.value = i;
- }
-
- if (def && def_used == 0 && strcmp(def_cmp, tmp.identifier) == 0) {
- *defvalue = tmp.value;
- def_used++; /* only ever 1 */
- }
- }
-
- items[i] = tmp;
-
- /* calculate combine string length */
- totbuf += id_str_size + name_str_size + desc_str_size + 3; /* 3 is for '\0's */
- }
- else {
- MEM_freeN(items);
- PyErr_SetString(PyExc_TypeError,
- "EnumProperty(...): expected a tuple containing "
- "(identifier, name, description) and optionally a "
- "unique number");
- return NULL;
- }
-
- }
-
- if (is_enum_flag) {
- /* strict check that all set members were used */
- if (def && def_used != PySet_GET_SIZE(def)) {
- MEM_freeN(items);
-
- PyErr_Format(PyExc_TypeError,
- "EnumProperty(..., default={...}): set has %d unused member(s)",
- PySet_GET_SIZE(def) - def_used);
- return NULL;
- }
- }
- else {
- if (def && def_used == 0) {
- MEM_freeN(items);
-
- PyErr_Format(PyExc_TypeError,
- "EnumProperty(..., default=\'%s\'): not found in enum members",
- def_cmp);
- return NULL;
- }
- }
-
- /* disabled duplicating strings because the array can still be freed and
- * the strings from it referenced, for now we can't support dynamically
- * created strings from python. */
-#if 0
- /* this would all work perfectly _but_ the python strings may be freed
- * immediately after use, so we need to duplicate them, ugh.
- * annoying because it works most of the time without this. */
- {
- EnumPropertyItem *items_dup = MEM_mallocN((sizeof(EnumPropertyItem) * (seq_len + 1)) + (sizeof(char) * totbuf),
- "enum_items_from_py2");
- EnumPropertyItem *items_ptr = items_dup;
- char *buf = ((char *)items_dup) + (sizeof(EnumPropertyItem) * (seq_len + 1));
- memcpy(items_dup, items, sizeof(EnumPropertyItem) * (seq_len + 1));
- for (i = 0; i < seq_len; i++, items_ptr++) {
- buf += strswapbufcpy(buf, &items_ptr->identifier);
- buf += strswapbufcpy(buf, &items_ptr->name);
- buf += strswapbufcpy(buf, &items_ptr->description);
- }
- MEM_freeN(items);
- items = items_dup;
- }
- /* end string duplication */
-#endif
-
- return items;
-}
-
-static EnumPropertyItem *bpy_props_enum_itemf(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int *free)
-{
- PyGILState_STATE gilstate;
-
- PyObject *py_func = RNA_property_enum_py_data_get(prop);
- PyObject *self = NULL;
- PyObject *args;
- PyObject *items; /* returned from the function call */
-
- EnumPropertyItem *eitems = NULL;
- int err = 0;
-
- bpy_context_set(C, &gilstate);
-
- args = PyTuple_New(2);
- self = pyrna_struct_as_instance(ptr);
- PyTuple_SET_ITEM(args, 0, self);
-
- /* now get the context */
- PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module);
- Py_INCREF(bpy_context_module);
-
- items = PyObject_CallObject(py_func, args);
-
- Py_DECREF(args);
-
- if (items == NULL) {
- err = -1;
- }
- else {
- PyObject *items_fast;
- int defvalue_dummy = 0;
-
- if (!(items_fast = PySequence_Fast(items, "EnumProperty(...): "
- "return value from the callback was not a sequence")))
- {
- err = -1;
- }
- else {
- eitems = enum_items_from_py(items_fast, NULL, &defvalue_dummy,
- (RNA_property_flag(prop) & PROP_ENUM_FLAG) != 0);
-
- Py_DECREF(items_fast);
-
- if (!eitems) {
- err = -1;
- }
- }
-
- Py_DECREF(items);
- }
-
- if (err != -1) { /* worked */
- *free = 1;
- }
- else {
- printf_func_error(py_func);
-
- eitems = DummyRNA_NULL_items;
- }
-
-
- bpy_context_clear(C, &gilstate);
- return eitems;
-}
-
PyDoc_STRVAR(BPy_EnumProperty_doc,
".. function:: EnumProperty(items, "
"name=\"\", "
"description=\"\", "
"default=\"\", "
"options={'ANIMATABLE'}, "
- "update=None)\n"
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
"\n"
" Returns a new enumerator property definition.\n"
"\n"
@@ -1246,7 +2520,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
if (srna) {
static const char *kwlist[] = {"attr", "items", "name", "description", "default",
- "options", "update", NULL};
+ "options", "update", "get", "set", NULL};
const char *id = NULL, *name = NULL, *description = "";
PyObject *def = NULL;
int id_len;
@@ -1256,22 +2530,30 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
PropertyRNA *prop;
PyObject *pyopts = NULL;
int opts = 0;
- short is_itemf = FALSE;
+ bool is_itemf = false;
PyObject *update_cb = NULL;
+ PyObject *get_cb = NULL;
+ PyObject *set_cb = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#O|ssOO!O:EnumProperty",
+ "s#O|ssOO!OOO:EnumProperty",
(char **)kwlist, &id, &id_len,
&items, &name, &description,
&def, &PySet_Type, &pyopts,
- &update_cb))
+ &update_cb, &get_cb, &set_cb))
{
return NULL;
}
BPY_PROPDEF_CHECK(EnumProperty, property_flag_enum_items);
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
return NULL;
}
@@ -1292,7 +2574,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
return NULL;
}
- is_itemf = TRUE;
+ is_itemf = true;
eitems = DummyRNA_NULL_items;
}
else {
@@ -1314,25 +2596,17 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
if (opts & PROP_ENUM_FLAG) prop = RNA_def_enum_flag(srna, id, eitems, defvalue, name ? name : id, description);
else prop = RNA_def_enum(srna, id, eitems, defvalue, name ? name : id, description);
- if (is_itemf) {
- RNA_def_enum_funcs(prop, bpy_props_enum_itemf);
- RNA_def_enum_py_data(prop, (void *)items);
-
- /* watch out!, if a user is tricky they can probably crash blender
- * if they manage to free the callback, take care! */
- /* Py_INCREF(items); */
- }
-
if (pyopts) {
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
+ bpy_prop_callback_assign_enum(prop, get_cb, set_cb, (is_itemf ? items : NULL));
RNA_def_property_duplicate_pointers(srna, prop);
- if (is_itemf == FALSE) {
+ if (is_itemf == false) {
/* note: this must be postponed until after #RNA_def_property_duplicate_pointers
* otherwise if this is a generator it may free the strings before we copy them */
Py_DECREF(items_fast);
@@ -1424,7 +2698,7 @@ static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *k
if (!ptype)
return NULL;
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
return NULL;
}
@@ -1435,7 +2709,7 @@ static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *k
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index bc245ecda5c..94f262f57f5 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -37,6 +37,12 @@
#include "RNA_types.h"
+#include "BLI_dynstr.h"
+#include "BLI_string.h"
+#include "BLI_listbase.h"
+#include "BLI_math_rotation.h"
+#include "BLI_utildefines.h"
+
#include "BPY_extern.h"
#include "bpy_rna.h"
@@ -50,12 +56,6 @@
# include "MEM_guardedalloc.h"
#endif
-#include "BLI_dynstr.h"
-#include "BLI_string.h"
-#include "BLI_listbase.h"
-#include "BLI_math_rotation.h"
-#include "BLI_utildefines.h"
-
#ifdef USE_PYRNA_INVALIDATE_WEAKREF
# include "BLI_ghash.h"
#endif
@@ -309,9 +309,9 @@ void BPY_id_release(struct ID *id)
}
#ifdef USE_PEDANTIC_WRITE
-static short rna_disallow_writes = FALSE;
+static bool rna_disallow_writes = false;
-static int rna_id_write_error(PointerRNA *ptr, PyObject *key)
+static bool rna_id_write_error(PointerRNA *ptr, PyObject *key)
{
ID *id = ptr->id.data;
if (id) {
@@ -329,30 +329,30 @@ static int rna_id_write_error(PointerRNA *ptr, PyObject *key)
"%.200s, %.200s datablock, error setting %.200s.%.200s",
id->name + 2, idtype, RNA_struct_identifier(ptr->type), pyname);
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
#endif /* USE_PEDANTIC_WRITE */
#ifdef USE_PEDANTIC_WRITE
-int pyrna_write_check(void)
+bool pyrna_write_check(void)
{
return !rna_disallow_writes;
}
-void pyrna_write_set(int val)
+void pyrna_write_set(bool val)
{
rna_disallow_writes = !val;
}
#else /* USE_PEDANTIC_WRITE */
-int pyrna_write_check(void)
+bool pyrna_write_check(void)
{
- return TRUE;
+ return true;
}
-void pyrna_write_set(int UNUSED(val))
+void pyrna_write_set(bool UNUSED(val))
{
/* nothing */
}
@@ -644,7 +644,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix);
}
else {
- PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 4, 4, mathutils_rna_matrix_cb_index, FALSE);
+ PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 4, 4, mathutils_rna_matrix_cb_index, 0);
Py_DECREF(ret); /* the matrix owns now */
ret = mat_cb; /* return the matrix instead */
}
@@ -655,7 +655,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix);
}
else {
- PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 3, 3, mathutils_rna_matrix_cb_index, FALSE);
+ PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 3, 3, mathutils_rna_matrix_cb_index, 0);
Py_DECREF(ret); /* the matrix owns now */
ret = mat_cb; /* return the matrix instead */
}
@@ -1123,7 +1123,7 @@ static const char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop)
{
EnumPropertyItem *item;
const char *result;
- int free = FALSE;
+ int free = false;
RNA_property_enum_items(BPy_GetContext(), ptr, prop, &item, NULL, &free);
if (item) {
@@ -1187,7 +1187,7 @@ int pyrna_set_to_enum_bitfield(EnumPropertyItem *items, PyObject *value, int *r_
return -1;
}
- if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) < 0) {
+ if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) == -1) {
return -1;
}
@@ -1202,7 +1202,7 @@ static int pyrna_prop_to_enum_bitfield(PointerRNA *ptr, PropertyRNA *prop, PyObj
{
EnumPropertyItem *item;
int ret;
- int free = FALSE;
+ int free = false;
*r_value = 0;
@@ -1282,7 +1282,7 @@ static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val)
}
else {
EnumPropertyItem *enum_item;
- int free = FALSE;
+ int free = false;
/* don't throw error here, can't trust blender 100% to give the
* right values, python code should not generate error for that */
@@ -1682,13 +1682,13 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
/* type checkins is done by each function */
if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
/* set of enum items, concatenate all values with OR */
- if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) < 0) {
+ if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) == -1) {
return -1;
}
}
else {
/* simple enum string */
- if (pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) < 0) {
+ if (pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) == -1) {
return -1;
}
}
@@ -1777,7 +1777,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
}
else {
BPy_StructRNA *param = (BPy_StructRNA *)value;
- int raise_error = FALSE;
+ bool raise_error = false;
if (data) {
if (flag & PROP_RNAPTR) {
@@ -1804,7 +1804,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
*((void **)data) = param->ptr.data;
}
else {
- raise_error = TRUE;
+ raise_error = true;
}
}
else {
@@ -2195,7 +2195,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel
else {
PyObject *keylib = PyTuple_GET_ITEM(key, 1);
Library *lib;
- int found = FALSE;
+ bool found = false;
if (keylib == Py_None) {
lib = NULL;
@@ -2232,7 +2232,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel
{
ID *id = itemptr.data; /* always an ID */
if (id->lib == lib && (strncmp(keyname, id->name + 2, sizeof(id->name) - 2) == 0)) {
- found = TRUE;
+ found = true;
if (r_ptr) {
*r_ptr = itemptr;
}
@@ -2242,7 +2242,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel
RNA_PROP_END;
/* we may want to fail silently as with collection.get() */
- if ((found == FALSE) && err_not_found) {
+ if ((found == false) && err_not_found) {
/* only runs for getitem access so use fixed string */
PyErr_SetString(PyExc_KeyError,
"bpy_prop_collection[key, lib]: not found");
@@ -2255,7 +2255,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel
}
static PyObject *pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *self, PyObject *key,
- const char *err_prefix, const short err_not_found)
+ const char *err_prefix, const bool err_not_found)
{
PointerRNA ptr;
const int contains = pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key, err_prefix, err_not_found, &ptr);
@@ -2448,7 +2448,7 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject
else if (PyTuple_Check(key)) {
/* special case, for ID datablocks we */
return pyrna_prop_collection_subscript_str_lib_pair(self, key,
- "bpy_prop_collection[id, lib]", TRUE);
+ "bpy_prop_collection[id, lib]", true);
}
else {
PyErr_Format(PyExc_TypeError,
@@ -2865,7 +2865,7 @@ static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *key)
if (PyTuple_Check(key)) {
/* special case, for ID datablocks we */
return pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key,
- "(id, lib) in bpy_prop_collection", FALSE, NULL);
+ "(id, lib) in bpy_prop_collection", false, NULL);
}
else {
@@ -4205,7 +4205,7 @@ static PyObject *pyrna_prop_collection_get(BPy_PropertyRNA *self, PyObject *args
}
else if (PyTuple_Check(key_ob)) {
PyObject *ret = pyrna_prop_collection_subscript_str_lib_pair(self, key_ob,
- "bpy_prop_collection.get((id, lib))", FALSE);
+ "bpy_prop_collection.get((id, lib))", false);
if (ret) {
return ret;
}
@@ -4267,12 +4267,12 @@ static PyObject *pyrna_prop_collection_find(BPy_PropertyRNA *self, PyObject *key
static void foreach_attr_type(BPy_PropertyRNA *self, const char *attr,
/* values to assign */
- RawPropertyType *raw_type, int *attr_tot, int *attr_signed)
+ RawPropertyType *raw_type, int *attr_tot, bool *attr_signed)
{
PropertyRNA *prop;
*raw_type = PROP_RAW_UNSET;
*attr_tot = 0;
- *attr_signed = FALSE;
+ *attr_signed = false;
/* note: this is fail with zero length lists, so don't let this get caled in that case */
RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop)
@@ -4280,7 +4280,7 @@ static void foreach_attr_type(BPy_PropertyRNA *self, const char *attr,
prop = RNA_struct_find_property(&itemptr, attr);
*raw_type = RNA_property_raw_type(prop);
*attr_tot = RNA_property_array_length(&itemptr, prop);
- *attr_signed = (RNA_property_subtype(prop) == PROP_UNSIGNED) ? FALSE : TRUE;
+ *attr_signed = (RNA_property_subtype(prop) == PROP_UNSIGNED) ? false : true;
break;
}
RNA_PROP_END;
@@ -4291,7 +4291,7 @@ static int foreach_parse_args(BPy_PropertyRNA *self, PyObject *args,
/* values to assign */
const char **attr, PyObject **seq, int *tot, int *size,
- RawPropertyType *raw_type, int *attr_tot, int *attr_signed
+ RawPropertyType *raw_type, int *attr_tot, bool *attr_signed
)
{
#if 0
@@ -4299,7 +4299,8 @@ static int foreach_parse_args(BPy_PropertyRNA *self, PyObject *args,
int target_tot;
#endif
- *size = *attr_tot = *attr_signed = FALSE;
+ *size = *attr_tot = 0;
+ *attr_signed = false;
*raw_type = PROP_RAW_UNSET;
if (!PyArg_ParseTuple(args, "sO", attr, seq) || (!PySequence_Check(*seq) && PyObject_CheckBuffer(*seq))) {
@@ -4344,7 +4345,7 @@ static int foreach_parse_args(BPy_PropertyRNA *self, PyObject *args,
return 0;
}
-static int foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, const char *format)
+static bool foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, const char *format)
{
char f = format ? *format : 'B'; /* B is assumed when not set */
@@ -4372,16 +4373,18 @@ static int foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, cons
static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
{
PyObject *item = NULL;
- int i = 0, ok = 0, buffer_is_compat;
+ int i = 0, ok = 0;
+ bool buffer_is_compat;
void *array = NULL;
/* get/set both take the same args currently */
const char *attr;
PyObject *seq;
- int tot, size, attr_tot, attr_signed;
+ int tot, size, attr_tot;
+ bool attr_signed;
RawPropertyType raw_type;
- if (foreach_parse_args(self, args, &attr, &seq, &tot, &size, &raw_type, &attr_tot, &attr_signed) < 0)
+ if (foreach_parse_args(self, args, &attr, &seq, &tot, &size, &raw_type, &attr_tot, &attr_signed) == -1)
return NULL;
if (tot == 0)
@@ -4390,7 +4393,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
if (set) { /* get the array from python */
- buffer_is_compat = FALSE;
+ buffer_is_compat = false;
if (PyObject_CheckBuffer(seq)) {
Py_buffer buf;
PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT);
@@ -4441,7 +4444,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
}
}
else {
- buffer_is_compat = FALSE;
+ buffer_is_compat = false;
if (PyObject_CheckBuffer(seq)) {
Py_buffer buf;
PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT);
@@ -4945,7 +4948,8 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
ParameterIterator iter;
PropertyRNA *parm;
PyObject *ret, *item;
- int i, pyargs_len, pykw_len, parms_len, ret_len, flag, err = 0, kw_tot = 0, kw_arg;
+ int i, pyargs_len, pykw_len, parms_len, ret_len, flag, err = 0, kw_tot = 0;
+ bool kw_arg;
PropertyRNA *pret_single = NULL;
void *retdata_single = NULL;
@@ -5026,7 +5030,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
if (i < pyargs_len) {
item = PyTuple_GET_ITEM(args, i);
- kw_arg = FALSE;
+ kw_arg = false;
}
else if (kw != NULL) {
#if 0
@@ -5037,7 +5041,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
if (item)
kw_tot++; /* make sure invalid keywords are not given */
- kw_arg = TRUE;
+ kw_arg = true;
}
i++; /* current argument */
@@ -5074,7 +5078,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
char error_prefix[512];
PyErr_Clear(); /* re-raise */
- if (kw_arg == TRUE)
+ if (kw_arg == true)
BLI_snprintf(error_prefix, sizeof(error_prefix),
"%.200s.%.200s(): error with keyword argument \"%.200s\" - ",
RNA_struct_identifier(self_ptr->type),
@@ -5109,12 +5113,12 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
DynStr *good_args = BLI_dynstr_new();
const char *arg_name, *bad_args_str, *good_args_str;
- int found = FALSE, first = TRUE;
+ bool found = false, first = true;
while (PyDict_Next(kw, &pos, &key, &value)) {
arg_name = _PyUnicode_AsString(key);
- found = FALSE;
+ found = false;
if (arg_name == NULL) { /* unlikely the argname is not a string but ignore if it is*/
PyErr_Clear();
@@ -5125,22 +5129,22 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
for (; iter.valid; RNA_parameter_list_next(&iter)) {
parm = iter.parm;
if (strcmp(arg_name, RNA_property_identifier(parm)) == 0) {
- found = TRUE;
+ found = true;
break;
}
}
RNA_parameter_list_end(&iter);
- if (found == FALSE) {
+ if (found == false) {
BLI_dynstr_appendf(bad_args, first ? "%s" : ", %s", arg_name);
- first = FALSE;
+ first = false;
}
}
}
/* list good args */
- first = TRUE;
+ first = true;
RNA_parameter_list_begin(&parms, &iter);
for (; iter.valid; RNA_parameter_list_next(&iter)) {
@@ -5149,7 +5153,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
continue;
BLI_dynstr_appendf(good_args, first ? "%s" : ", %s", RNA_property_identifier(parm));
- first = FALSE;
+ first = false;
}
RNA_parameter_list_end(&iter);
@@ -5179,7 +5183,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
BKE_reports_init(&reports, RPT_STORE);
RNA_function_call(C, &reports, self_ptr, self_func, &parms);
- err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE));
+ err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, true));
/* return value */
if (err != -1) {
@@ -5242,7 +5246,7 @@ static PyObject *pyrna_func_doc_get(BPy_FunctionRNA *self, void *UNUSED(closure)
PyObject *ret;
char *args;
- args = RNA_function_as_string_keywords(NULL, self->func, NULL, TRUE, TRUE);
+ args = RNA_function_as_string_keywords(NULL, self->func, NULL, true, true);
ret = PyUnicode_FromFormat("%.200s.%.200s(%.200s)\n%s",
RNA_struct_identifier(self->ptr.type),
@@ -5974,7 +5978,7 @@ static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self)
static PyObject *pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA *self)
{
- if (self->iter.valid == FALSE) {
+ if (self->iter.valid == false) {
PyErr_SetString(PyExc_StopIteration, "pyrna_prop_collection_iter stop");
return NULL;
}
@@ -6052,7 +6056,7 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
FunctionRNA *func = (FunctionRNA *)link;
const int flag = RNA_function_flag(func);
if ((flag & FUNC_NO_SELF) && /* is staticmethod or classmethod */
- (flag & FUNC_REGISTER) == FALSE) /* is not for registration */
+ (flag & FUNC_REGISTER) == false) /* is not for registration */
{
/* we may want to set the type of this later */
PyObject *func_py = pyrna_func_to_py(&func_ptr, func);
@@ -6262,7 +6266,7 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr)
pyrna->ptr = *ptr;
#ifdef PYRNA_FREE_SUPPORT
- pyrna->freeptr = FALSE;
+ pyrna->freeptr = false;
#endif
#ifdef USE_PYRNA_STRUCT_REFERENCE
@@ -6342,15 +6346,15 @@ PyObject *pyrna_id_CreatePyObject(ID *id)
}
}
-int pyrna_id_FromPyObject(PyObject *obj, ID **id)
+bool pyrna_id_FromPyObject(PyObject *obj, ID **id)
{
if (BPy_StructRNA_Check(obj) && (RNA_struct_is_ID(((BPy_StructRNA *)obj)->ptr.type))) {
*id = ((BPy_StructRNA *)obj)->ptr.id.data;
- return TRUE;
+ return true;
}
else {
*id = NULL;
- return FALSE;
+ return false;
}
}
@@ -6561,7 +6565,7 @@ PyObject *BPY_rna_types(void)
return (PyObject *)self;
}
-StructRNA *pyrna_struct_as_srna(PyObject *self, int parent, const char *error_prefix)
+StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *error_prefix)
{
BPy_StructRNA *py_srna = NULL;
StructRNA *srna;
@@ -6635,7 +6639,7 @@ StructRNA *srna_from_self(PyObject *self, const char *error_prefix)
PyErr_Fetch(&error_type, &error_value, &error_traceback);
PyErr_Clear();
- srna = pyrna_struct_as_srna(self, 0, error_prefix);
+ srna = pyrna_struct_as_srna(self, false, error_prefix);
if (!PyErr_Occurred()) {
PyErr_Restore(error_type, error_value, error_traceback);
@@ -7051,7 +7055,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
if (py_class->tp_init) {
#ifdef USE_PEDANTIC_WRITE
const int prev_write = rna_disallow_writes;
- rna_disallow_writes = is_operator ? FALSE : TRUE; /* only operators can write on __init__ */
+ rna_disallow_writes = is_operator ? false : true; /* only operators can write on __init__ */
#endif
/* true in most cases even when the class its self doesn't define an __init__ function. */
@@ -7070,7 +7074,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
#else
const int prev_write = rna_disallow_writes;
- rna_disallow_writes = TRUE;
+ rna_disallow_writes = true;
/* 'almost' all the time calling the class isn't needed.
* We could just do... */
@@ -7146,7 +7150,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
}
#ifdef USE_PEDANTIC_WRITE
- rna_disallow_writes = is_readonly ? TRUE : FALSE;
+ rna_disallow_writes = is_readonly ? true : false;
#endif
/* *** Main Caller *** */
@@ -7155,7 +7159,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
/* *** Done Calling *** */
#ifdef USE_PEDANTIC_WRITE
- rna_disallow_writes = FALSE;
+ rna_disallow_writes = false;
#endif
RNA_parameter_list_end(&iter);
@@ -7420,7 +7424,7 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class
}
/* warning: gets parent classes srna, only for the register function */
- srna = pyrna_struct_as_srna(py_class, 1, "register_class(...):");
+ srna = pyrna_struct_as_srna(py_class, true, "register_class(...):");
if (srna == NULL)
return NULL;
@@ -7456,7 +7460,7 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class
srna_new = reg(CTX_data_main(C), &reports, py_class, identifier,
bpy_class_validate, bpy_class_call, bpy_class_free);
- if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
+ if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
return NULL;
/* python errors validating are not converted into reports so the check above will fail.
@@ -7563,7 +7567,7 @@ static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_cla
return NULL;
}
- srna = pyrna_struct_as_srna(py_class, 0, "unregister_class(...):");
+ srna = pyrna_struct_as_srna(py_class, false, "unregister_class(...):");
if (srna == NULL)
return NULL;
diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h
index edd2ada0539..424452ef6fe 100644
--- a/source/blender/python/intern/bpy_rna.h
+++ b/source/blender/python/intern/bpy_rna.h
@@ -115,7 +115,7 @@ typedef struct {
#endif /* !USE_PYRNA_STRUCT_REFERENCE */
#ifdef PYRNA_FREE_SUPPORT
- int freeptr; /* needed in some cases if ptr.data is created on the fly, free when deallocing */
+ bool freeptr; /* needed in some cases if ptr.data is created on the fly, free when deallocing */
#endif /* PYRNA_FREE_SUPPORT */
} BPy_StructRNA;
@@ -164,7 +164,7 @@ typedef struct {
#define BPy_BaseTypeRNA BPy_PropertyRNA
StructRNA *srna_from_self(PyObject *self, const char *error_prefix);
-StructRNA *pyrna_struct_as_srna(PyObject *self, int parent, const char *error_prefix);
+StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *error_prefix);
void BPY_rna_init(void);
PyObject *BPY_rna_module(void);
@@ -178,7 +178,7 @@ PyObject *pyrna_prop_CreatePyObject(PointerRNA *ptr, PropertyRNA *prop);
/* extern'd by other modules which don't deal closely with RNA */
PyObject *pyrna_id_CreatePyObject(struct ID *id);
-int pyrna_id_FromPyObject(PyObject *obj, struct ID **id);
+bool pyrna_id_FromPyObject(PyObject *obj, struct ID **id);
/* operators also need this to set args */
int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const char *error_prefix);
@@ -205,8 +205,8 @@ PyObject *pyrna_py_from_array_index(BPy_PropertyArrayRNA *self, PointerRNA *ptr,
PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop);
int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value);
-int pyrna_write_check(void);
-void pyrna_write_set(int val);
+bool pyrna_write_check(void);
+void pyrna_write_set(bool val);
void pyrna_invalidate(BPy_DummyPointerRNA *self);
int pyrna_struct_validity_check(BPy_StructRNA *pysrna);
diff --git a/source/blender/python/intern/bpy_rna_anim.c b/source/blender/python/intern/bpy_rna_anim.c
index 0acfc36bb4e..a19f8e2d8ed 100644
--- a/source/blender/python/intern/bpy_rna_anim.c
+++ b/source/blender/python/intern/bpy_rna_anim.c
@@ -160,14 +160,14 @@ static int pyrna_struct_keyframe_parse(
return -1;
}
- if (pyrna_struct_anim_args_parse(ptr, error_prefix, path, path_full, index) < 0)
+ if (pyrna_struct_anim_args_parse(ptr, error_prefix, path, path_full, index) == -1)
return -1;
if (*cfra == FLT_MAX)
*cfra = CTX_data_scene(BPy_GetContext())->r.cfra;
/* flag may be null (no option currently for remove keyframes e.g.). */
- if (pyoptions && options && (pyrna_set_to_enum_bitfield(keying_flag_items, pyoptions, options, error_prefix) < 0))
+ if (pyoptions && options && (pyrna_set_to_enum_bitfield(keying_flag_items, pyoptions, options, error_prefix) == -1))
return -1;
return 0; /* success */
@@ -222,7 +222,7 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb
result = insert_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, options);
MEM_freeN((void *)path_full);
- if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
+ if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
return NULL;
return PyBool_FromLong(result);
@@ -271,7 +271,7 @@ PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyOb
result = delete_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0);
MEM_freeN((void *)path_full);
- if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
+ if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
return NULL;
return PyBool_FromLong(result);
@@ -301,7 +301,7 @@ PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
if (!PyArg_ParseTuple(args, "s|i:driver_add", &path, &index))
return NULL;
- if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_add():", path, &path_full, &index) < 0) {
+ if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_add():", path, &path_full, &index) == -1) {
return NULL;
}
else {
@@ -313,7 +313,7 @@ PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
result = ANIM_add_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0, DRIVER_TYPE_PYTHON);
- if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
+ if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
return NULL;
if (result) {
@@ -377,7 +377,7 @@ PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
if (!PyArg_ParseTuple(args, "s|i:driver_remove", &path, &index))
return NULL;
- if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_remove():", path, &path_full, &index) < 0) {
+ if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_remove():", path, &path_full, &index) == -1) {
return NULL;
}
else {
@@ -390,7 +390,7 @@ PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
MEM_freeN((void *)path_full);
- if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
+ if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
return NULL;
WM_event_add_notifier(BPy_GetContext(), NC_ANIMATION | ND_FCURVES_ORDER, NULL);
diff --git a/source/blender/python/intern/bpy_rna_callback.c b/source/blender/python/intern/bpy_rna_callback.c
index adb4ae6a2c6..1043f68dbdb 100644
--- a/source/blender/python/intern/bpy_rna_callback.c
+++ b/source/blender/python/intern/bpy_rna_callback.c
@@ -32,12 +32,12 @@
#include "RNA_types.h"
+#include "BLI_utildefines.h"
+
#include "bpy_rna.h"
#include "bpy_rna_callback.h"
#include "bpy_util.h"
-#include "BLI_utildefines.h"
-
#include "DNA_space_types.h"
#include "DNA_screen_types.h"
@@ -101,7 +101,7 @@ PyObject *pyrna_callback_add(BPy_StructRNA *self, PyObject *args)
if (RNA_struct_is_a(self->ptr.type, &RNA_Region)) {
if (cb_event_str) {
- if (pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") < 0) {
+ if (pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") == -1) {
return NULL;
}
}
@@ -194,7 +194,7 @@ PyObject *pyrna_callback_classmethod_add(PyObject *UNUSED(self), PyObject *args)
}
cls = PyTuple_GET_ITEM(args, 0);
- if (!(srna = pyrna_struct_as_srna(cls, FALSE, "handler_add"))) {
+ if (!(srna = pyrna_struct_as_srna(cls, false, "handler_add"))) {
return NULL;
}
cb_func = PyTuple_GET_ITEM(args, 1);
@@ -212,10 +212,10 @@ PyObject *pyrna_callback_classmethod_add(PyObject *UNUSED(self), PyObject *args)
return NULL;
}
- if (pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") < 0) {
+ if (pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") == -1) {
return NULL;
}
- else if (pyrna_enum_value_from_id(region_type_items, cb_regiontype_str, &cb_regiontype, "bpy_struct.callback_add()") < 0) {
+ else if (pyrna_enum_value_from_id(region_type_items, cb_regiontype_str, &cb_regiontype, "bpy_struct.callback_add()") == -1) {
return NULL;
}
else {
@@ -257,7 +257,7 @@ PyObject *pyrna_callback_classmethod_remove(PyObject *UNUSED(self), PyObject *ar
}
cls = PyTuple_GET_ITEM(args, 0);
- if (!(srna = pyrna_struct_as_srna(cls, FALSE, "callback_remove"))) {
+ if (!(srna = pyrna_struct_as_srna(cls, false, "callback_remove"))) {
return NULL;
}
py_handle = PyTuple_GET_ITEM(args, 1);
@@ -278,7 +278,7 @@ PyObject *pyrna_callback_classmethod_remove(PyObject *UNUSED(self), PyObject *ar
customdata = ED_region_draw_cb_customdata(handle);
Py_DECREF((PyObject *)customdata);
- if (pyrna_enum_value_from_id(region_type_items, cb_regiontype_str, &cb_regiontype, "bpy_struct.callback_remove()") < 0) {
+ if (pyrna_enum_value_from_id(region_type_items, cb_regiontype_str, &cb_regiontype, "bpy_struct.callback_remove()") == -1) {
return NULL;
}
else {
diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c
index b7994eeccdc..b0b0f346944 100644
--- a/source/blender/python/intern/bpy_util.c
+++ b/source/blender/python/intern/bpy_util.c
@@ -29,9 +29,13 @@
#include <Python.h>
-#include "bpy_util.h"
+#include "BLI_utildefines.h"
#include "BLI_dynstr.h"
+
+#include "bpy_util.h"
+
#include "MEM_guardedalloc.h"
+
#include "BKE_report.h"
#include "BKE_context.h"
@@ -59,13 +63,13 @@ char *BPy_enum_as_string(EnumPropertyItem *item)
return cstring;
}
-short BPy_reports_to_error(ReportList *reports, PyObject *exception, const short clear)
+short BPy_reports_to_error(ReportList *reports, PyObject *exception, const bool clear)
{
char *report_str;
report_str = BKE_reports_string(reports, RPT_ERROR);
- if (clear) {
+ if (clear == true) {
BKE_reports_clear(reports);
}
diff --git a/source/blender/python/intern/bpy_util.h b/source/blender/python/intern/bpy_util.h
index b5f679b741f..b007e123cfc 100644
--- a/source/blender/python/intern/bpy_util.h
+++ b/source/blender/python/intern/bpy_util.h
@@ -39,7 +39,7 @@ char *BPy_enum_as_string(struct EnumPropertyItem *item);
#define BLANK_PYTHON_TYPE {PyVarObject_HEAD_INIT(NULL, 0) NULL}
/* error reporting */
-short BPy_reports_to_error(struct ReportList *reports, PyObject *exception, const short clear);
+short BPy_reports_to_error(struct ReportList *reports, PyObject *exception, const bool clear);
short BPy_errors_to_report(struct ReportList *reports);
/* TODO - find a better solution! */
diff --git a/source/blender/quicktime/apple/qtkit_export.m b/source/blender/quicktime/apple/qtkit_export.m
index 6935c908ee4..4a8a06134c8 100644
--- a/source/blender/quicktime/apple/qtkit_export.m
+++ b/source/blender/quicktime/apple/qtkit_export.m
@@ -61,8 +61,8 @@
#import <QTKit/QTKit.h>
#include <AudioToolbox/AudioToolbox.h>
-#if (MAC_OS_X_VERSION_MIN_REQUIRED <= 1040) || !__LP64__
-#error 64 bit build & OSX 10.5 minimum are needed for QTKit
+#if MAC_OS_X_VERSION_MIN_REQUIRED <= 1040
+#error OSX 10.5 minimum is needed for QTKit
#endif
#include "quicktime_import.h"
@@ -557,7 +557,7 @@ int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, R
[qtexport->movie setAttribute:[NSNumber numberWithBool:YES] forKey:QTMovieEditableAttribute];
[qtexport->movie setAttribute:@"Made with Blender" forKey:QTMovieCopyrightAttribute];
- qtexport->frameDuration = QTMakeTime(rd->frs_sec_base*1000, rd->frs_sec*1000);
+ qtexport->frameDuration = QTMakeTime(rd->frs_sec_base * 1000, rd->frs_sec * 1000);
/* specifying the codec attributes : try to retrieve them from render data first*/
if (rd->qtcodecsettings.codecType) {
diff --git a/source/blender/quicktime/quicktime_export.h b/source/blender/quicktime/quicktime_export.h
index d773cdc8f3a..55323c05278 100644
--- a/source/blender/quicktime/quicktime_export.h
+++ b/source/blender/quicktime/quicktime_export.h
@@ -65,14 +65,14 @@ void filepath_qt(char *string, struct RenderData *rd);
void quicktime_verify_image_type(struct RenderData *rd, struct ImageFormatData *imf); //used by RNA for defaults values init, if needed
/*Video codec type*/
int quicktime_get_num_videocodecs(void);
-QuicktimeCodecTypeDesc* quicktime_get_videocodecType_desc(int indexValue);
+QuicktimeCodecTypeDesc *quicktime_get_videocodecType_desc(int indexValue);
int quicktime_rnatmpvalue_from_videocodectype(int codecType);
int quicktime_videocodecType_from_rnatmpvalue(int rnatmpvalue);
#ifdef USE_QTKIT
/*Audio codec type*/
int quicktime_get_num_audiocodecs(void);
-QuicktimeCodecTypeDesc* quicktime_get_audiocodecType_desc(int indexValue);
+QuicktimeCodecTypeDesc *quicktime_get_audiocodecType_desc(int indexValue);
int quicktime_rnatmpvalue_from_audiocodectype(int codecType);
int quicktime_audiocodecType_from_rnatmpvalue(int rnatmpvalue);
#endif
diff --git a/source/blender/render/intern/raytrace/rayobject_octree.cpp b/source/blender/render/intern/raytrace/rayobject_octree.cpp
index 148e3417ea9..658ab9dc091 100644
--- a/source/blender/render/intern/raytrace/rayobject_octree.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_octree.cpp
@@ -1015,7 +1015,7 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is)
vec2[2] = oz1 - dda_lambda * doz;
calc_ocval_ray(&ocval, (float)xo, (float)yo, (float)zo, vec1, vec2);
- //is->dist = (u1+dda_lambda*(u2-u1))*o_lambda;
+ //is->dist = (u1 + dda_lambda * (u2 - u1)) * o_lambda;
if (testnode(oc, is, no, ocval) )
found = 1;
diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c
index b8784685836..091ba9589d7 100644
--- a/source/blender/render/intern/source/multires_bake.c
+++ b/source/blender/render/intern/source/multires_bake.c
@@ -952,7 +952,7 @@ static void create_ao_raytree(MultiresBakeRender *bkr, MAOBakeData *ao_data)
RayFace *face;
CCGElem **grid_data;
CCGKey key;
- int num_grids, grid_size, face_side, num_faces;
+ int num_grids, grid_size /*, face_side */, num_faces;
int i;
num_grids = hidm->getNumGrids(hidm);
@@ -960,7 +960,7 @@ static void create_ao_raytree(MultiresBakeRender *bkr, MAOBakeData *ao_data)
grid_data = hidm->getGridData(hidm);
hidm->getGridKey(hidm, &key);
- face_side = (grid_size << 1) - 1;
+ /* face_side = (grid_size << 1) - 1; */ /* UNUSED */
num_faces = num_grids * (grid_size - 1) * (grid_size - 1);
raytree = ao_data->raytree = RE_rayobject_create(bkr->raytrace_structure, num_faces, bkr->octree_resolution);
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 43bada3b383..e37b24b13a4 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -45,6 +45,16 @@
#include "MEM_guardedalloc.h"
+#include "BLI_math.h"
+#include "BLI_rect.h"
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+#include "BLI_path_util.h"
+#include "BLI_fileops.h"
+#include "BLI_threads.h"
+#include "BLI_rand.h"
+#include "BLI_callbacks.h"
+
#include "BKE_animsys.h" /* <------ should this be here?, needed for sequencer update */
#include "BKE_camera.h"
#include "BKE_global.h"
@@ -57,16 +67,6 @@
#include "BKE_sequencer.h"
#include "BKE_writeavi.h" /* <------ should be replaced once with generic movie module */
-#include "BLI_math.h"
-#include "BLI_rect.h"
-#include "BLI_listbase.h"
-#include "BLI_string.h"
-#include "BLI_path_util.h"
-#include "BLI_fileops.h"
-#include "BLI_threads.h"
-#include "BLI_rand.h"
-#include "BLI_callbacks.h"
-
#include "PIL_time.h"
#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
index 0587b097f36..62919297e73 100644
--- a/source/blender/render/intern/source/render_result.c
+++ b/source/blender/render/intern/source/render_result.c
@@ -35,11 +35,6 @@
#include "MEM_guardedalloc.h"
-#include "BKE_image.h"
-#include "BKE_global.h"
-#include "BKE_main.h"
-#include "BKE_report.h"
-
#include "BLI_fileops.h"
#include "BLI_listbase.h"
#include "BLI_path_util.h"
@@ -48,6 +43,11 @@
#include "BLI_threads.h"
#include "BLI_utildefines.h"
+#include "BKE_image.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_report.h"
+
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "IMB_colormanagement.h"
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index 2e1b23435e5..a0267cd65b7 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -4148,8 +4148,17 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
}
if (addpassflag & SCE_PASS_INDEXMA) {
ObjectRen *obr = R.objectinstance[zrow[totface-1].obi].obr;
- VlakRen *vr = obr->vlaknodes->vlak;
- Material *mat = vr->mat;
+ Material *mat = NULL;
+
+ if (zrow[totface-1].segment == -1) {
+ if (obr->vlaknodes)
+ mat = obr->vlaknodes->vlak->mat;
+ }
+ else {
+ if (obr->strandbuf)
+ mat = obr->strandbuf->ma;
+ }
+
if (mat) {
for (a= 0; a<totfullsample; a++)
add_transp_material_index(rlpp[a], od, mat);
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index eee4b5a3a57..eb1aad75a88 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -204,9 +204,9 @@ void WM_operator_stack_clear(struct wmWindowManager *wm);
struct wmOperatorType *WM_operatortype_find(const char *idnamem, int quiet);
struct GHashIterator *WM_operatortype_iter(void);
-void WM_operatortype_append (void (*opfunc)(struct wmOperatorType*));
-void WM_operatortype_append_ptr (void (*opfunc)(struct wmOperatorType*, void *), void *userdata);
-void WM_operatortype_append_macro_ptr (void (*opfunc)(struct wmOperatorType*, void *), void *userdata);
+void WM_operatortype_append(void (*opfunc)(struct wmOperatorType *));
+void WM_operatortype_append_ptr(void (*opfunc)(struct wmOperatorType *, void *), void *userdata);
+void WM_operatortype_append_macro_ptr(void (*opfunc)(struct wmOperatorType *, void *), void *userdata);
int WM_operatortype_remove(const char *idname);
struct wmOperatorType *WM_operatortype_append_macro(const char *idname, const char *name, const char *description, int flag);
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index a6b3efd30bf..48cad9e020b 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -1345,6 +1345,15 @@ static void wm_event_modalkeymap(const bContext *C, wmOperator *op, wmEvent *eve
}
}
}
+ else {
+ /* modal keymap checking returns handled events fine, but all hardcoded modal
+ handling typically swallows all events (OPERATOR_RUNNING_MODAL).
+ This bypass just disables support for double clicks in hardcoded modal handlers */
+ if (event->val == KM_DBL_CLICK) {
+ event->prevval = event->val;
+ event->val = KM_PRESS;
+ }
+ }
}
/* bad hacking event system... better restore event type for checking of KM_CLICK for example */
@@ -1357,6 +1366,8 @@ static void wm_event_modalmap_end(wmEvent *event)
event->val = event->prevval;
event->prevval = 0;
}
+ else if (event->prevval == KM_DBL_CLICK)
+ event->val = KM_DBL_CLICK;
}
@@ -2792,6 +2803,8 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
switch (pd->subtype) {
case GHOST_kTrackpadEventMagnify:
event.type = MOUSEZOOM;
+ pd->deltaX = -pd->deltaX;
+ pd->deltaY = -pd->deltaY;
break;
case GHOST_kTrackpadEventRotate:
event.type = MOUSEROTATE;
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 61699c94567..550a9f83cff 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -740,11 +740,11 @@ static ImBuf *blend_file_thumb(Scene *scene, bScreen *screen, int **thumb_pt)
if (scene->camera) {
ibuf = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera,
BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2,
- IB_rect, OB_SOLID, FALSE, FALSE, FALSE, err_out);
+ IB_rect, OB_SOLID, FALSE, FALSE, R_ADDSKY, err_out);
}
else {
ibuf = ED_view3d_draw_offscreen_imbuf(scene, v3d, ar, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2,
- IB_rect, FALSE, FALSE, err_out);
+ IB_rect, FALSE, R_ADDSKY, err_out);
}
if (ibuf) {
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index bfcd4b1e955..b2c3c935553 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -151,7 +151,7 @@ void WM_operatortype_append(void (*opfunc)(wmOperatorType *))
wmOperatorType *ot;
ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
- ot->srna = RNA_def_struct(&BLENDER_RNA, "", "OperatorProperties");
+ ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
/* Set the default i18n context now, so that opfunc can redefine it if needed! */
RNA_def_struct_translation_context(ot->srna, BLF_I18NCONTEXT_OPERATOR_DEFAULT);
opfunc(ot);
@@ -173,7 +173,7 @@ void WM_operatortype_append_ptr(void (*opfunc)(wmOperatorType *, void *), void *
wmOperatorType *ot;
ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
- ot->srna = RNA_def_struct(&BLENDER_RNA, "", "OperatorProperties");
+ ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
/* Set the default i18n context now, so that opfunc can redefine it if needed! */
RNA_def_struct_translation_context(ot->srna, BLF_I18NCONTEXT_OPERATOR_DEFAULT);
opfunc(ot, userdata);
@@ -360,7 +360,7 @@ wmOperatorType *WM_operatortype_append_macro(const char *idname, const char *nam
}
ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
- ot->srna = RNA_def_struct(&BLENDER_RNA, "", "OperatorProperties");
+ ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
ot->idname = idname;
ot->name = name;
@@ -390,7 +390,7 @@ void WM_operatortype_append_macro_ptr(void (*opfunc)(wmOperatorType *, void *),
wmOperatorType *ot;
ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
- ot->srna = RNA_def_struct(&BLENDER_RNA, "", "OperatorProperties");
+ ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
ot->flag = OPTYPE_MACRO;
ot->exec = wm_macro_exec;
@@ -1558,7 +1558,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_NO_WIN_CLIP);
/* XXX splash scales with pixelsize, should become widget-units */
- but = uiDefBut(block, BUT_IMAGE, 0, "", 0, 0.5f * U.widget_unit, U.pixelsize * 501, U.pixelsize *282, ibuf, 0.0, 0.0, 0, 0, ""); /* button owns the imbuf now */
+ but = uiDefBut(block, BUT_IMAGE, 0, "", 0, 0.5f * U.widget_unit, U.pixelsize * 501, U.pixelsize * 282, ibuf, 0.0, 0.0, 0, 0, ""); /* button owns the imbuf now */
uiButSetFunc(but, wm_block_splash_close, block, NULL);
uiBlockSetFunc(block, wm_block_splash_refreshmenu, block, NULL);
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index ec94501c8be..9e0f8613a1a 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -701,6 +701,14 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
case GHOST_kEventWindowDeactivate:
wm_event_add_ghostevent(wm, win, type, time, data);
win->active = 0; /* XXX */
+
+ /* clear modifiers for inactive windows */
+ win->eventstate->alt = 0;
+ win->eventstate->ctrl = 0;
+ win->eventstate->shift = 0;
+ win->eventstate->oskey = 0;
+ win->eventstate->keymodifier = 0;
+
break;
case GHOST_kEventWindowActivate:
{
diff --git a/source/creator/creator.c b/source/creator/creator.c
index d678df33ad0..55a24971c61 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -40,6 +40,17 @@
# include <xmmintrin.h>
#endif
+/* crash handler */
+#ifdef WIN32
+# include <process.h> /* getpid */
+#else
+# include <unistd.h> /* getpid */
+#endif
+/* for backtrace */
+#ifndef WIN32
+# include <execinfo.h>
+#endif
+
#ifdef WIN32
# include <Windows.h>
# include "utfconv.h"
@@ -48,6 +59,7 @@
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
+#include <errno.h>
/* This little block needed for linking to Blender... */
@@ -161,6 +173,8 @@ static int print_version(int argc, const char **argv, void *data);
/* Initialize callbacks for the modules that need them */
static void setCallbacks(void);
+static bool use_crash_handler = true;
+
#ifndef WITH_PYTHON_MODULE
/* set breakpoints here when running in debug mode, useful to catch floating point errors */
@@ -250,6 +264,7 @@ static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data)
printf("Misc Options:\n");
BLI_argsPrintArgDoc(ba, "--debug");
BLI_argsPrintArgDoc(ba, "--debug-fpe");
+ BLI_argsPrintArgDoc(ba, "--disable-crash-handler");
#ifdef WITH_FFMPEG
BLI_argsPrintArgDoc(ba, "--debug-ffmpeg");
@@ -354,6 +369,12 @@ static int disable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNU
return 0;
}
+static int disable_crash_handler(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
+{
+ use_crash_handler = false;
+ return 0;
+}
+
static int background_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
{
G.background = 1;
@@ -427,6 +448,102 @@ static int set_fpe(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(dat
return 0;
}
+static void blender_crash_handler_backtrace(FILE *fp)
+{
+#ifndef WIN32
+#define SIZE 100
+ void *buffer[SIZE];
+ int nptrs;
+ char **strings;
+ int i;
+
+ fputs("\n# backtrace\n", fp);
+
+ /* include a backtrace for good measure */
+ nptrs = backtrace(buffer, SIZE);
+ strings = backtrace_symbols(buffer, nptrs);
+ for (i = 0; i < nptrs; i++) {
+ fputs(strings[i], fp);
+ fputc('\n', fp);
+ }
+
+ free(strings);
+#undef SIZE
+#else /* WIN32 */
+ /* TODO */
+ (void)fp;
+#endif
+}
+static void blender_crash_handler(int signum)
+{
+
+#if 0
+ {
+ char fname[FILE_MAX];
+
+ if (!G.main->name[0]) {
+ BLI_make_file_string("/", fname, BLI_temporary_dir(), "crash.blend");
+ }
+ else {
+ BLI_strncpy(fname, G.main->name, sizeof(fname));
+ BLI_replace_extension(fname, sizeof(fname), ".crash.blend");
+ }
+
+ printf("Writing: %s\n", fname);
+ fflush(stdout);
+
+ BKE_undo_save_file(fname);
+ }
+#endif
+
+ FILE *fp;
+ char header[512];
+ wmWindowManager *wm = G.main->wm.first;
+
+ char fname[FILE_MAX];
+
+ if (!G.main->name[0]) {
+ BLI_make_file_string("/", fname, BLI_temporary_dir(), "blender.crash.txt");
+ }
+ else {
+ BLI_strncpy(fname, G.main->name, sizeof(fname));
+ BLI_replace_extension(fname, sizeof(fname), ".crash.txt");
+ }
+
+ printf("Writing: %s\n", fname);
+ fflush(stdout);
+
+ BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_STRING_FMT);
+
+ /* open the crash log */
+ errno = 0;
+ fp = BLI_fopen(fname, "wb");
+ if (fp == NULL) {
+ fprintf(stderr, "Unable to save '%s': %s\n",
+ fname, errno ? strerror(errno) : "Unknown error opening file");
+ }
+ else {
+ if (wm) {
+ BKE_report_write_file_fp(fp, &wm->reports, header);
+ }
+
+ blender_crash_handler_backtrace(fp);
+
+ fclose(fp);
+ }
+
+
+ /* really crash */
+ signal(signum, SIG_DFL);
+#ifndef WIN32
+ kill(getpid(), signum);
+#else
+ /* force crash on windows for now */
+ *((void **)NULL) = NULL;
+#endif
+}
+
+
static int set_factory_startup(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
{
G.factory_startup = 1;
@@ -1126,6 +1243,8 @@ static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
BLI_argsAdd(ba, 1, "-y", "--enable-autoexec", "\n\tEnable automatic python script execution" PY_ENABLE_AUTO, enable_python, NULL);
BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers & startup scripts)" PY_DISABLE_AUTO, disable_python, NULL);
+ BLI_argsAdd(ba, 1, NULL, "--disable-crash-handler", "\n\tDisable the crash handler", disable_crash_handler, NULL);
+
#undef PY_ENABLE_AUTO
#undef PY_DISABLE_AUTO
@@ -1310,6 +1429,10 @@ int main(int argc, const char **argv)
BLI_argsParse(ba, 1, NULL, NULL);
#endif
+ if (use_crash_handler) {
+ /* after parsing args */
+ signal(SIGSEGV, blender_crash_handler);
+ }
/* after level 1 args, this is so playanim skips RNA init */
RNA_init();
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index a4c4253754e..9267b2b9fed 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -650,11 +650,10 @@ static bool ConvertMaterial(
material->texname[i] = material->img[i]->id.name;
material->flag[i] |= ( mttmp->tex->imaflag &TEX_MIPMAP )?MIPMAP:0;
// -----------------------
- if ( mttmp->tex->imaflag &TEX_USEALPHA ) {
+ if (material->img[i] && (material->img[i]->flag & IMA_IGNORE_ALPHA) == 0)
material->flag[i] |= USEALPHA;
- }
// -----------------------
- else if ( mttmp->tex->imaflag &TEX_CALCALPHA ) {
+ if ( mttmp->tex->imaflag &TEX_CALCALPHA ) {
material->flag[i] |= CALCALPHA;
}
else if (mttmp->tex->flag &TEX_NEGALPHA) {
diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
index b7fbe958c86..dce62ad189a 100644
--- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
+++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
@@ -307,8 +307,11 @@ int SCA_Joystick::pGetAxis(int axisnum, int udlr)
int SCA_Joystick::pAxisTest(int axisnum)
{
#ifdef WITH_SDL
- short i1 = m_axis_array[(axisnum * 2)];
- short i2 = m_axis_array[(axisnum * 2) + 1];
+ /* Use ints instead of shorts here to avoid problems when we get -32768.
+ * When we take the negative of that later, we should get 32768, which is greater
+ * than what a short can hold. In other words, abs(MIN_SHORT) > MAX_SHRT. */
+ int i1 = m_axis_array[(axisnum * 2)];
+ int i2 = m_axis_array[(axisnum * 2) + 1];
/* long winded way to do:
* return max_ff(absf(i1), absf(i2))
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index c7f6954fd6c..eec45669e04 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -42,7 +42,6 @@ typedef unsigned __int64 uint_ptr;
typedef unsigned long uint_ptr;
#endif
-#define KX_INERTIA_INFINITE 10000
#include "RAS_IPolygonMaterial.h"
#include "KX_BlenderMaterial.h"
#include "KX_GameObject.h"
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index f0d5d5c6685..87683f8b57b 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -83,7 +83,7 @@
// not valid, skip rendering this frame.
//#define NZC_GUARDED_OUTPUT
#define DEFAULT_LOGIC_TIC_RATE 60.0
-#define DEFAULT_PHYSICS_TIC_RATE 60.0
+//#define DEFAULT_PHYSICS_TIC_RATE 60.0
#ifdef FREE_WINDOWS /* XXX mingw64 (gcc 4.7.0) defines a macro for DrawText that translates to DrawTextA. Not good */
#ifdef DrawText
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index 02995a53954..6b3f745b899 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -198,7 +198,7 @@ static PyObject *gp_OrigPythonSysModules= NULL;
/* Macro for building the keyboard translation */
//#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, PyLong_FromLong(SCA_IInputDevice::KX_##name))
-#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, item=PyLong_FromLong(name)); Py_DECREF(item)
+//#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, item=PyLong_FromLong(name)); Py_DECREF(item)
/* For the defines for types from logic bricks, we do stuff explicitly... */
#define KX_MACRO_addTypesToDict(dict, name, name2) PyDict_SetItemString(dict, #name, item=PyLong_FromLong(name2)); Py_DECREF(item)