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:
-rw-r--r--CMakeLists.txt18
-rw-r--r--SConstruct12
-rw-r--r--config/darwin-config.py3
-rw-r--r--config/win64-vc-config.py6
-rw-r--r--intern/ghost/GHOST_C-api.h4
-rw-r--r--intern/ghost/GHOST_ISystem.h4
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp4
-rw-r--r--intern/ghost/intern/GHOST_System.h4
-rw-r--r--intern/ghost/intern/GHOST_SystemCarbon.cpp17
-rw-r--r--intern/ghost/intern/GHOST_SystemCarbon.h4
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.h4
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.mm4
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp4
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.h4
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp14
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.h4
-rw-r--r--intern/ghost/intern/GHOST_WindowCarbon.cpp4
-rw-r--r--projectfiles_vc9/blender/BPY_python/BPY_python.vcproj4
-rw-r--r--projectfiles_vc9/blender/editors/ED_editors.vcproj16
-rw-r--r--projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj2
-rw-r--r--release/scripts/addons/add_mesh_gears.py (renamed from release/scripts/extensions/add_mesh_gears.py)293
-rw-r--r--release/scripts/addons/io_mesh_raw/__init__.py51
-rw-r--r--release/scripts/addons/io_mesh_raw/export_raw.py114
-rw-r--r--release/scripts/addons/io_mesh_raw/import_raw.py142
-rw-r--r--release/scripts/io/engine_render_pov.py10
-rw-r--r--release/scripts/io/export_fbx.py69
-rw-r--r--release/scripts/io/export_mdd.py2
-rw-r--r--release/scripts/io/export_obj.py19
-rw-r--r--release/scripts/io/export_ply.py4
-rw-r--r--release/scripts/io/export_x3d.py6
-rw-r--r--release/scripts/io/import_anim_bvh.py5
-rw-r--r--release/scripts/io/import_scene_3ds.py18
-rw-r--r--release/scripts/io/import_scene_obj.py6
-rw-r--r--release/scripts/io/import_shape_mdd.py157
-rw-r--r--release/scripts/io/netrender/__init__.py2
-rw-r--r--release/scripts/io/netrender/client.py12
-rw-r--r--release/scripts/io/netrender/master.py6
-rw-r--r--release/scripts/io/netrender/operators.py2
-rw-r--r--release/scripts/io/netrender/ui.py4
-rw-r--r--release/scripts/io/netrender/utils.py8
-rw-r--r--release/scripts/modules/bpy/ops.py1
-rw-r--r--release/scripts/modules/bpy/utils.py43
-rw-r--r--release/scripts/modules/rigify/__init__.py6
-rw-r--r--release/scripts/modules/rigify/leg_quadruped.py5
-rw-r--r--release/scripts/modules/rigify/mouth.py14
-rw-r--r--release/scripts/modules/rigify/shape_key_control.py (renamed from release/scripts/modules/rigify/shape_key_transforms.py)200
-rw-r--r--release/scripts/modules/rigify/tail_control.py34
-rw-r--r--release/scripts/modules/rna_prop_ui.py11
-rw-r--r--release/scripts/op/add_mesh_torus.py5
-rw-r--r--release/scripts/op/console_python.py6
-rw-r--r--release/scripts/op/console_shell.py2
-rw-r--r--release/scripts/op/fcurve_euler_filter.py17
-rw-r--r--release/scripts/op/image.py4
-rw-r--r--release/scripts/op/mesh.py2
-rw-r--r--release/scripts/op/object.py63
-rw-r--r--release/scripts/op/object_align.py131
-rw-r--r--release/scripts/op/object_randomize_transform.py2
-rw-r--r--release/scripts/op/presets.py22
-rw-r--r--release/scripts/op/screen_play_rendered_anim.py11
-rw-r--r--release/scripts/op/uv.py33
-rw-r--r--release/scripts/op/uvcalc_smart_project.py4
-rw-r--r--release/scripts/op/vertexpaint_dirt.py2
-rw-r--r--release/scripts/op/wm.py27
-rw-r--r--release/scripts/presets/render/HDTV_1080p.py14
-rw-r--r--release/scripts/presets/render/HDTV_720p.py14
-rw-r--r--release/scripts/presets/render/TV_NTSC.py14
-rw-r--r--release/scripts/presets/render/TV_PAL.py14
-rw-r--r--release/scripts/presets/render/TV_PAL_16_colon_9.py14
-rw-r--r--release/scripts/templates/operator_modal.py8
-rw-r--r--release/scripts/ui/properties_animviz.py50
-rw-r--r--release/scripts/ui/properties_data_armature.py9
-rw-r--r--release/scripts/ui/properties_data_armature_rigify.py5
-rw-r--r--release/scripts/ui/properties_data_bone.py3
-rw-r--r--release/scripts/ui/properties_data_camera.py2
-rw-r--r--release/scripts/ui/properties_data_curve.py2
-rw-r--r--release/scripts/ui/properties_data_empty.py3
-rw-r--r--release/scripts/ui/properties_data_lamp.py2
-rw-r--r--release/scripts/ui/properties_data_lattice.py2
-rw-r--r--release/scripts/ui/properties_data_mesh.py6
-rw-r--r--release/scripts/ui/properties_data_metaball.py2
-rw-r--r--release/scripts/ui/properties_data_modifier.py2
-rw-r--r--release/scripts/ui/properties_game.py20
-rw-r--r--release/scripts/ui/properties_material.py33
-rw-r--r--release/scripts/ui/properties_object.py7
-rw-r--r--release/scripts/ui/properties_object_constraint.py3
-rw-r--r--release/scripts/ui/properties_particle.py3
-rw-r--r--release/scripts/ui/properties_physics_cloth.py4
-rw-r--r--release/scripts/ui/properties_physics_common.py2
-rw-r--r--release/scripts/ui/properties_physics_field.py6
-rw-r--r--release/scripts/ui/properties_physics_fluid.py4
-rw-r--r--release/scripts/ui/properties_physics_smoke.py4
-rw-r--r--release/scripts/ui/properties_physics_softbody.py4
-rw-r--r--release/scripts/ui/properties_render.py47
-rw-r--r--release/scripts/ui/properties_scene.py62
-rw-r--r--release/scripts/ui/properties_texture.py2
-rw-r--r--release/scripts/ui/properties_world.py6
-rw-r--r--release/scripts/ui/space_buttons.py2
-rw-r--r--release/scripts/ui/space_console.py2
-rw-r--r--release/scripts/ui/space_dopesheet.py2
-rw-r--r--release/scripts/ui/space_filebrowser.py2
-rw-r--r--release/scripts/ui/space_graph.py5
-rw-r--r--release/scripts/ui/space_image.py6
-rw-r--r--release/scripts/ui/space_info.py9
-rw-r--r--release/scripts/ui/space_logic.py2
-rw-r--r--release/scripts/ui/space_nla.py2
-rw-r--r--release/scripts/ui/space_node.py8
-rw-r--r--release/scripts/ui/space_outliner.py2
-rw-r--r--release/scripts/ui/space_sequencer.py6
-rw-r--r--release/scripts/ui/space_text.py2
-rw-r--r--release/scripts/ui/space_time.py2
-rw-r--r--release/scripts/ui/space_userpref.py153
-rw-r--r--release/scripts/ui/space_view3d.py63
-rw-r--r--release/scripts/ui/space_view3d_toolbar.py2
-rw-r--r--source/blender/blenkernel/BKE_animsys.h6
-rw-r--r--source/blender/blenkernel/BKE_global.h2
-rw-r--r--source/blender/blenkernel/BKE_image.h3
-rw-r--r--source/blender/blenkernel/BKE_object.h5
-rw-r--r--source/blender/blenkernel/BKE_pointcache.h1
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c6
-rw-r--r--source/blender/blenkernel/intern/armature.c3
-rw-r--r--source/blender/blenkernel/intern/blender.c4
-rw-r--r--source/blender/blenkernel/intern/boids.c12
-rw-r--r--source/blender/blenkernel/intern/cloth.c2
-rw-r--r--source/blender/blenkernel/intern/collision.c18
-rw-r--r--source/blender/blenkernel/intern/constraint.c4
-rw-r--r--source/blender/blenkernel/intern/curve.c1
-rw-r--r--source/blender/blenkernel/intern/fcurve.c43
-rw-r--r--source/blender/blenkernel/intern/image.c101
-rw-r--r--source/blender/blenkernel/intern/implicit.c125
-rw-r--r--source/blender/blenkernel/intern/modifier.c23
-rw-r--r--source/blender/blenkernel/intern/object.c86
-rw-r--r--source/blender/blenkernel/intern/particle_system.c9
-rw-r--r--source/blender/blenkernel/intern/pointcache.c92
-rw-r--r--source/blender/blenkernel/intern/unit.c3
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c2
-rw-r--r--source/blender/blenlib/BLI_dynstr.h9
-rw-r--r--source/blender/blenlib/BLI_path_util.h1
-rw-r--r--source/blender/blenlib/CMakeLists.txt2
-rw-r--r--source/blender/blenlib/SConscript2
-rw-r--r--source/blender/blenlib/intern/BLI_bfile.c30
-rw-r--r--source/blender/blenlib/intern/BLI_dynstr.c17
-rw-r--r--source/blender/blenlib/intern/Makefile2
-rw-r--r--source/blender/blenlib/intern/math_rotation.c10
-rw-r--r--source/blender/blenlib/intern/path_util.c100
-rw-r--r--source/blender/blenlib/intern/string.c7
-rw-r--r--source/blender/blenloader/intern/readfile.c20
-rw-r--r--source/blender/blenloader/intern/writefile.c6
-rw-r--r--source/blender/collada/DocumentExporter.cpp4
-rw-r--r--source/blender/editors/animation/anim_markers.c3
-rw-r--r--source/blender/editors/animation/keyingsets.c32
-rw-r--r--source/blender/editors/armature/editarmature_retarget.c4
-rw-r--r--source/blender/editors/armature/poseobject.c77
-rw-r--r--source/blender/editors/include/ED_mesh.h1
-rw-r--r--source/blender/editors/include/ED_numinput.h3
-rw-r--r--source/blender/editors/include/ED_space_api.h1
-rw-r--r--source/blender/editors/interface/interface_handlers.c2
-rw-r--r--source/blender/editors/interface/interface_templates.c22
-rw-r--r--source/blender/editors/mesh/editface.c52
-rw-r--r--source/blender/editors/object/object_ops.c12
-rw-r--r--source/blender/editors/render/Makefile6
-rw-r--r--source/blender/editors/render/SConscript4
-rw-r--r--source/blender/editors/render/render_preview.c24
-rw-r--r--source/blender/editors/space_api/spacetypes.c5
-rw-r--r--source/blender/editors/space_buttons/buttons_ops.c3
-rw-r--r--source/blender/editors/space_console/console_draw.c30
-rw-r--r--source/blender/editors/space_console/console_ops.c85
-rw-r--r--source/blender/editors/space_nla/nla_edit.c38
-rw-r--r--source/blender/editors/space_outliner/outliner.c4
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c90
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c173
-rw-r--r--source/blender/editors/transform/transform.c56
-rw-r--r--source/blender/editors/transform/transform_conversions.c8
-rw-r--r--source/blender/editors/transform/transform_generics.c3
-rw-r--r--source/blender/editors/transform/transform_orientations.c5
-rw-r--r--source/blender/editors/util/numinput.c8
-rw-r--r--source/blender/imbuf/intern/divers.c2
-rw-r--r--source/blender/makesdna/DNA_cloth_types.h3
-rw-r--r--source/blender/makesdna/DNA_scene_types.h1
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h18
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h3
-rw-r--r--source/blender/makesrna/RNA_access.h6
-rw-r--r--source/blender/makesrna/RNA_enum_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_access.c38
-rw-r--r--source/blender/makesrna/intern/rna_animation.c1
-rw-r--r--source/blender/makesrna/intern/rna_animation_api.c8
-rw-r--r--source/blender/makesrna/intern/rna_cloth.c6
-rw-r--r--source/blender/makesrna/intern/rna_curve.c14
-rw-r--r--source/blender/makesrna/intern/rna_image_api.c72
-rw-r--r--source/blender/makesrna/intern/rna_lamp.c5
-rw-r--r--source/blender/makesrna/intern/rna_main_api.c53
-rw-r--r--source/blender/makesrna/intern/rna_object.c7
-rw-r--r--source/blender/makesrna/intern/rna_pose.c2
-rw-r--r--source/blender/makesrna/intern/rna_scene.c121
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c65
-rw-r--r--source/blender/python/generic/BGL.c65
-rw-r--r--source/blender/python/generic/BGL.h37
-rw-r--r--source/blender/python/generic/matrix.c93
-rw-r--r--source/blender/python/intern/bpy_driver.c39
-rw-r--r--source/blender/python/intern/bpy_interface.c40
-rw-r--r--source/blender/python/intern/bpy_rna.c391
-rw-r--r--source/blender/python/intern/bpy_rna.h2
-rw-r--r--source/blender/python/intern/bpy_rna_callback.c111
-rw-r--r--source/blender/python/intern/bpy_rna_callback.h29
-rw-r--r--source/blender/render/intern/source/convertblender.c2
-rw-r--r--source/blender/render/intern/source/shadbuf.c3
-rw-r--r--source/blender/render/intern/source/volumetric.c2
-rw-r--r--source/blender/windowmanager/intern/wm.c7
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c28
-rw-r--r--source/blender/windowmanager/intern/wm_files.c4
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c25
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c4
-rw-r--r--source/creator/creator.c19
-rw-r--r--source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp249
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.cpp90
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.h4
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Application.cpp6
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_ghost.cpp96
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp14
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.h4
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp1
-rw-r--r--source/gameengine/Rasterizer/RAS_CameraData.h4
-rw-r--r--source/gameengine/VideoTexture/CMakeLists.txt1
-rw-r--r--source/gameengine/VideoTexture/Exception.cpp2
-rw-r--r--source/gameengine/VideoTexture/Exception.h2
-rw-r--r--source/gameengine/VideoTexture/ImageBase.cpp170
-rw-r--r--source/gameengine/VideoTexture/ImageBase.h15
-rw-r--r--source/gameengine/VideoTexture/ImageBuff.cpp167
-rw-r--r--source/gameengine/VideoTexture/ImageBuff.h2
-rw-r--r--source/gameengine/VideoTexture/ImageMix.cpp3
-rw-r--r--source/gameengine/VideoTexture/ImageRender.cpp9
-rw-r--r--source/gameengine/VideoTexture/ImageViewport.cpp26
-rw-r--r--source/gameengine/VideoTexture/Makefile1
-rw-r--r--source/gameengine/VideoTexture/SConscript2
-rw-r--r--source/gameengine/VideoTexture/Texture.cpp2
-rw-r--r--source/gameengine/VideoTexture/VideoFFmpeg.cpp66
-rw-r--r--source/gameengine/VideoTexture/VideoFFmpeg.h3
-rw-r--r--source/gameengine/VideoTexture/blendVideoTex.cpp16
-rw-r--r--source/nan_definitions.mk2
239 files changed, 3899 insertions, 2255 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c7bfce682f0..35730af3f4f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -276,15 +276,10 @@ IF(WIN32)
SET(PYTHON_LIB python31)
SET(PYTHON_LIBPATH ${PYTHON}/lib)
- IF(CMAKE_CL_64)
- SET(WITH_OPENAL OFF)
- ELSE(CMAKE_CL_64)
- #SET(WITH_OPENAL ON)
- SET(OPENAL ${LIBDIR}/openal)
- SET(OPENAL_INCLUDE_DIR ${OPENAL}/include)
- SET(OPENAL_LIBRARY wrap_oal)
- SET(OPENAL_LIBPATH ${OPENAL}/lib)
- ENDIF(CMAKE_CL_64)
+ SET(OPENAL ${LIBDIR}/openal)
+ SET(OPENAL_INCLUDE_DIR ${OPENAL}/include)
+ SET(OPENAL_LIBRARY wrap_oal)
+ SET(OPENAL_LIBPATH ${OPENAL}/lib)
IF(WITH_JACK)
SET(JACK ${LIBDIR}/jack)
@@ -508,7 +503,7 @@ IF(APPLE)
SET(ZLIB /usr)
SET(ZLIB_INC "${ZLIB}/include")
- SET(ZLIB_LIBRARIES z)
+ SET(ZLIB_LIBRARIES z bz2)
SET(FREETYPE ${LIBDIR}/freetype)
SET(FREETYPE_INCLUDE_DIRS ${FREETYPE}/include ${FREETYPE}/include/freetype2)
@@ -522,7 +517,7 @@ IF(APPLE)
SET(FFMPEG ${LIBDIR}/ffmpeg)
SET(FFMPEG_INC ${FFMPEG}/include)
- SET(FFMPEG_LIB avcodec avdevice avformat avutil mp3lame swscale x264 xvidcore)
+ SET(FFMPEG_LIB avcodec avdevice avformat avutil mp3lame swscale x264 xvidcore theora theoradec theoraenc vorbis vorbisenc vorbisfile ogg)
SET(FFMPEG_LIBPATH ${FFMPEG}/lib)
SET(LIBSAMPLERATE ${LIBDIR}/samplerate)
@@ -689,4 +684,3 @@ ADD_SUBDIRECTORY(source/creator)
IF(WITH_PLAYER)
ADD_SUBDIRECTORY(source/blenderplayer)
ENDIF(WITH_PLAYER)
-
diff --git a/SConstruct b/SConstruct
index 6c404784ab0..7e432bf7dfa 100644
--- a/SConstruct
+++ b/SConstruct
@@ -611,18 +611,6 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'):
'${BF_FFMPEG_LIBPATH}/avutil-50.dll',
'${BF_FFMPEG_LIBPATH}/swscale-0.dll']
- if env['OURPLATFORM'] != 'linuxcross':
- #
- # TODO: Does it mean we haven't got support of this codecs if
- # we're using cross-compilation?
- # Or in case of native compilation this libraries are
- # unneccessary to?
- #
- dllsources += ['${LCGDIR}/ffmpeg/lib/libfaac-0.dll',
- '${LCGDIR}/ffmpeg/lib/libfaad-2.dll',
- '${LCGDIR}/ffmpeg/lib/libmp3lame-0.dll',
- '${LCGDIR}/ffmpeg/lib/libx264-67.dll']
-
if env['WITH_BF_JACK']:
dllsources += ['${LCGDIR}/jack/lib/libjack.dll']
windlls = env.Install(dir=env['BF_INSTALLDIR'], source = dllsources)
diff --git a/config/darwin-config.py b/config/darwin-config.py
index cd4d7ee88e9..b0e6948001b 100644
--- a/config/darwin-config.py
+++ b/config/darwin-config.py
@@ -82,7 +82,8 @@ WITH_BF_FFMPEG = True # -DWITH_FFMPEG
BF_FFMPEG = LIBDIR + '/ffmpeg'
BF_FFMPEG_INC = "${BF_FFMPEG}/include"
BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
-BF_FFMPEG_LIB = 'avcodec avdevice avformat avutil mp3lame swscale x264 xvidcore'
+BF_FFMPEG_LIB = 'avcodec avdevice avformat avutil mp3lame swscale x264 xvidcore theora theoradec theoraenc vorbis vorbisenc vorbisfile ogg bz2'
+#bz2 is a standard osx dynlib
# python 3.1 uses precompiled libraries in bf svn /lib by default
BF_PYTHON_VERSION = '3.1'
diff --git a/config/win64-vc-config.py b/config/win64-vc-config.py
index 457640507da..41772dea14b 100644
--- a/config/win64-vc-config.py
+++ b/config/win64-vc-config.py
@@ -2,11 +2,11 @@ LCGDIR = '#../lib/win64'
LIBDIR = '${LCGDIR}'
# enable ffmpeg support
-WITH_BF_FFMPEG = False # -DWITH_FFMPEG
+WITH_BF_FFMPEG = True # -DWITH_FFMPEG
BF_FFMPEG = LIBDIR +'/ffmpeg'
-BF_FFMPEG_INC = '${BF_FFMPEG}/include'
+BF_FFMPEG_INC = '${BF_FFMPEG}/include ${BF_FFMPEG}/include/msvc '
BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
-BF_FFMPEG_LIB = 'avformat-52.lib avcodec-51.lib avdevice-52.lib avutil-49.lib swscale-0.lib'
+BF_FFMPEG_LIB = 'avformat-52.lib avcodec-52.lib avdevice-52.lib avutil-50.lib swscale-0.lib'
BF_PYTHON = LIBDIR + '/python'
BF_PYTHON_VERSION = '3.1'
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index 75a055075bc..346fa292520 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -824,14 +824,14 @@ extern void GHOST_putClipboard(GHOST_TInt8 *buffer, int selection);
* "unpack and run" path, then look for properly installed path, not including versioning.
* @return Unsigned char string pointing to system dir (eg /usr/share/blender/).
*/
-extern GHOST_TUns8* GHOST_getSystemDir();
+extern const GHOST_TUns8* GHOST_getSystemDir();
/**
* Determine the base dir in which user configuration is stored, not including versioning.
* If needed, it will create the base directory.
* @return Unsigned char string pointing to user dir (eg ~/.blender/).
*/
-extern GHOST_TUns8* GHOST_getUserDir();
+extern const GHOST_TUns8* GHOST_getUserDir();
#ifdef __cplusplus
diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h
index 5e0c7f41ab8..fd8641f2055 100644
--- a/intern/ghost/GHOST_ISystem.h
+++ b/intern/ghost/GHOST_ISystem.h
@@ -380,14 +380,14 @@ public:
* "unpack and run" path, then look for properly installed path, not including versioning.
* @return Unsigned char string pointing to system dir (eg /usr/share/blender/).
*/
- virtual GHOST_TUns8* getSystemDir() const = 0;
+ virtual const GHOST_TUns8* getSystemDir() const = 0;
/**
* Determine the base dir in which user configuration is stored, not including versioning.
* If needed, it will create the base directory.
* @return Unsigned char string pointing to user dir (eg ~/.blender/).
*/
- virtual GHOST_TUns8* getUserDir() const = 0;
+ virtual const GHOST_TUns8* getUserDir() const = 0;
protected:
/**
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index fd06d7620ab..51305e82064 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -855,13 +855,13 @@ void GHOST_putClipboard(GHOST_TInt8 *buffer, int selection)
system->putClipboard(buffer, selection);
}
-GHOST_TUns8* GHOST_getSystemDir()
+const GHOST_TUns8* GHOST_getSystemDir()
{
GHOST_ISystem* system = GHOST_ISystem::getSystem();
return system->getSystemDir();
}
-GHOST_TUns8* GHOST_getUserDir()
+const GHOST_TUns8* GHOST_getUserDir()
{
GHOST_ISystem* system = GHOST_ISystem::getSystem();
return system->getUserDir();
diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h
index 59f933ea865..d6c6a356323 100644
--- a/intern/ghost/intern/GHOST_System.h
+++ b/intern/ghost/intern/GHOST_System.h
@@ -302,14 +302,14 @@ public:
* "unpack and run" path, then look for properly installed path, not including versioning.
* @return Unsigned char string pointing to system dir (eg /usr/share/blender/).
*/
- virtual GHOST_TUns8* getSystemDir() const = 0;
+ virtual const GHOST_TUns8* getSystemDir() const = 0;
/**
* Determine the base dir in which user configuration is stored, not including versioning.
* If needed, it will create the base directory.
* @return Unsigned char string pointing to user dir (eg ~/.blender/).
*/
- virtual GHOST_TUns8* getUserDir() const = 0;
+ virtual const GHOST_TUns8* getUserDir() const = 0;
protected:
/**
diff --git a/intern/ghost/intern/GHOST_SystemCarbon.cpp b/intern/ghost/intern/GHOST_SystemCarbon.cpp
index 52b797f56b5..36ea1c7fe85 100644
--- a/intern/ghost/intern/GHOST_SystemCarbon.cpp
+++ b/intern/ghost/intern/GHOST_SystemCarbon.cpp
@@ -809,7 +809,7 @@ OSStatus GHOST_SystemCarbon::handleTabletEvent(EventRef event)
}
err = noErr;
}
-
+ return err;
}
OSStatus GHOST_SystemCarbon::handleMouseEvent(EventRef event)
@@ -1215,22 +1215,19 @@ void GHOST_SystemCarbon::putClipboard(GHOST_TInt8 *buffer, bool selection) const
}
}
-GHOST_TUns8* GHOST_SystemCarbon::getSystemDir() const
+const GHOST_TUns8* GHOST_SystemCarbon::getSystemDir() const
{
- static GHOST_TUns8 sysPath[64];
-
- strcpy((char*)sysPath,"/Library/Application Support/Blender");
-
- return sysPath;
+ return (GHOST_TUns8*)"/Library/Application Support/Blender";
}
-GHOST_TUns8* GHOST_SystemCarbon::getUserDir() const
+const GHOST_TUns8* GHOST_SystemCarbon::getUserDir() const
{
- static char usrPath[512] = "";
+ static char usrPath[256] = "";
char* env = getenv("HOME");
if (env) {
- strcpy(usrPath, env);
+ strncpy(usrPath, env, 245);
+ usrPath[245]=0;
strcat(usrPath, "/Library/Application Support/Blender");
return (GHOST_TUns8*) usrPath;
}
diff --git a/intern/ghost/intern/GHOST_SystemCarbon.h b/intern/ghost/intern/GHOST_SystemCarbon.h
index b27d7917377..7f0870674b4 100644
--- a/intern/ghost/intern/GHOST_SystemCarbon.h
+++ b/intern/ghost/intern/GHOST_SystemCarbon.h
@@ -195,14 +195,14 @@ public:
* "unpack and run" path, then look for properly installed path, not including versioning.
* @return Unsigned char string pointing to system dir (eg /usr/share/blender/).
*/
- virtual GHOST_TUns8* getSystemDir() const;
+ virtual const GHOST_TUns8* getSystemDir() const;
/**
* Determine the base dir in which user configuration is stored, not including versioning.
* If needed, it will create the base directory.
* @return Unsigned char string pointing to user dir (eg ~/.blender/).
*/
- virtual GHOST_TUns8* getUserDir() const;
+ virtual const GHOST_TUns8* getUserDir() const;
protected:
/**
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h
index 2f1a94fc8eb..b25f8890cf1 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.h
+++ b/intern/ghost/intern/GHOST_SystemCocoa.h
@@ -218,14 +218,14 @@ public:
* "unpack and run" path, then look for properly installed path, not including versioning.
* @return Unsigned char string pointing to system dir (eg /usr/share/blender/).
*/
- virtual GHOST_TUns8* getSystemDir() const;
+ virtual const GHOST_TUns8* getSystemDir() const;
/**
* Determine the base dir in which user configuration is stored, not including versioning.
* If needed, it will create the base directory.
* @return Unsigned char string pointing to user dir (eg ~/.blender/).
*/
- virtual GHOST_TUns8* getUserDir() const;
+ virtual const GHOST_TUns8* getUserDir() const;
/**
* Handles a window event. Called by GHOST_WindowCocoa window delegate
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm
index 15ea3730c6e..5289920cccb 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.mm
+++ b/intern/ghost/intern/GHOST_SystemCocoa.mm
@@ -1714,7 +1714,7 @@ void GHOST_SystemCocoa::putClipboard(GHOST_TInt8 *buffer, bool selection) const
#pragma mark Base directories retrieval
-GHOST_TUns8* GHOST_SystemCocoa::getSystemDir() const
+const GHOST_TUns8* GHOST_SystemCocoa::getSystemDir() const
{
static GHOST_TUns8 tempPath[512] = "";
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@@ -1742,7 +1742,7 @@ GHOST_TUns8* GHOST_SystemCocoa::getSystemDir() const
return tempPath;
}
-GHOST_TUns8* GHOST_SystemCocoa::getUserDir() const
+const GHOST_TUns8* GHOST_SystemCocoa::getUserDir() const
{
static GHOST_TUns8 tempPath[512] = "";
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 0cbd3e99c73..b1c5ee6e6f2 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -1095,12 +1095,12 @@ void GHOST_SystemWin32::putClipboard(GHOST_TInt8 *buffer, bool selection) const
}
}
-GHOST_TUns8* GHOST_SystemWin32::getSystemDir() const
+const GHOST_TUns8* GHOST_SystemWin32::getSystemDir() const
{
return NULL;
}
-GHOST_TUns8* GHOST_SystemWin32::getUserDir() const
+const GHOST_TUns8* GHOST_SystemWin32::getUserDir() const
{
return NULL;
}
diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h
index 1b7b2aad766..75bb858fb49 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.h
+++ b/intern/ghost/intern/GHOST_SystemWin32.h
@@ -193,14 +193,14 @@ public:
* "unpack and run" path, then look for properly installed path, not including versioning.
* @return Unsigned char string pointing to system dir (eg /usr/share/blender/).
*/
- GHOST_TUns8* getSystemDir() const;
+ virtual const GHOST_TUns8* getSystemDir() const;
/**
* Determine the base dir in which user configuration is stored, not including versioning.
* If needed, it will create the base directory.
* @return Unsigned char string pointing to user dir (eg ~/.blender/).
*/
- GHOST_TUns8* getUserDir() const;
+ virtual const GHOST_TUns8* getUserDir() const;
/**
* Creates a drag'n'drop event and pushes it immediately onto the event queue.
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index 5eab71eebf5..cbf775045fd 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -1458,19 +1458,19 @@ void GHOST_SystemX11::putClipboard(GHOST_TInt8 *buffer, bool selection) const
}
}
-GHOST_TUns8* GHOST_SystemX11::getSystemDir() const
+const GHOST_TUns8* GHOST_SystemX11::getSystemDir() const
{
-
+ return (GHOST_TUns8*)"/usr/share/blender";
}
-GHOST_TUns8* GHOST_SystemX11::getUserDir() const
+const GHOST_TUns8* GHOST_SystemX11::getUserDir() const
{
- char* path;
+ static char path[256];
char* env = getenv("HOME");
if(env) {
- path = (char*) malloc(strlen(env) + 10); // "/.blender/"
- strcat(path, env);
- strcat(path, "/,blender/");
+ strncpy(path, env, 245);
+ path[245]=0;
+ strcat(path, "/.blender/");
return (GHOST_TUns8*) path;
} else {
return NULL;
diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h
index b839b5a057a..1d9959cc931 100644
--- a/intern/ghost/intern/GHOST_SystemX11.h
+++ b/intern/ghost/intern/GHOST_SystemX11.h
@@ -231,14 +231,14 @@ public:
* "unpack and run" path, then look for properly installed path, not including versioning.
* @return Unsigned char string pointing to system dir (eg /usr/share/blender/).
*/
- GHOST_TUns8* getSystemDir() const;
+ const GHOST_TUns8* getSystemDir() const;
/**
* Determine the base dir in which user configuration is stored, not including versioning.
* If needed, it will create the base directory.
* @return Unsigned char string pointing to user dir (eg ~/.blender/).
*/
- GHOST_TUns8* getUserDir() const;
+ const GHOST_TUns8* getUserDir() const;
/**
* Atom used for ICCCM, WM-spec and Motif.
diff --git a/intern/ghost/intern/GHOST_WindowCarbon.cpp b/intern/ghost/intern/GHOST_WindowCarbon.cpp
index ab06df8a746..65584e4cc1f 100644
--- a/intern/ghost/intern/GHOST_WindowCarbon.cpp
+++ b/intern/ghost/intern/GHOST_WindowCarbon.cpp
@@ -136,14 +136,14 @@ GHOST_WindowCarbon::GHOST_WindowCarbon(
&m_windowRef);
if ( err != noErr) {
- fprintf(stderr," error creating window %i \n",err);
+ fprintf(stderr," error creating window %i \n",(int)err);
} else {
::SetWRefCon(m_windowRef,(SInt32)this);
setTitle(title);
err = InstallWindowEventHandler (m_windowRef, myWEventHandlerProc, GetEventTypeCount(kWEvents), kWEvents,NULL,NULL);
if ( err != noErr) {
- fprintf(stderr," error creating handler %i \n",err);
+ fprintf(stderr," error creating handler %i \n",(int)err);
} else {
// ::TransitionWindow (m_windowRef,kWindowZoomTransitionEffect,kWindowShowTransitionAction,NULL);
::ShowWindow(m_windowRef);
diff --git a/projectfiles_vc9/blender/BPY_python/BPY_python.vcproj b/projectfiles_vc9/blender/BPY_python/BPY_python.vcproj
index d6703509e52..c96e6e86364 100644
--- a/projectfiles_vc9/blender/BPY_python/BPY_python.vcproj
+++ b/projectfiles_vc9/blender/BPY_python/BPY_python.vcproj
@@ -426,6 +426,10 @@
Filter="h;hpp;hxx;hm;inl"
>
<File
+ RelativePath="..\..\..\source\blender\python\generic\BGL.h"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\python\BPY_extern.h"
>
</File>
diff --git a/projectfiles_vc9/blender/editors/ED_editors.vcproj b/projectfiles_vc9/blender/editors/ED_editors.vcproj
index fcb49f0dc81..ade42b37933 100644
--- a/projectfiles_vc9/blender/editors/ED_editors.vcproj
+++ b/projectfiles_vc9/blender/editors/ED_editors.vcproj
@@ -251,6 +251,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\editors\include\ED_numinput.h"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\editors\include\ED_object.h"
>
</File>
@@ -600,6 +604,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\editors\util\numinput.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\editors\util\undo.c"
>
</File>
@@ -1164,10 +1172,6 @@
>
</File>
<File
- RelativePath="..\..\..\source\blender\editors\transform\transform_numinput.c"
- >
- </File>
- <File
RelativePath="..\..\..\source\blender\editors\transform\transform_ops.c"
>
</File>
@@ -1288,6 +1292,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\editors\armature\poseUtils.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\editors\armature\reeb.c"
>
</File>
diff --git a/projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj b/projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj
index 4eb37259785..ccbc6c15004 100644
--- a/projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj
+++ b/projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj
@@ -42,7 +42,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\lib\windows\pthreads\include;..\..\..\source\gameengine\Ketsji;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\GameLogic;..\..\..\source\gameengine\SceneGraph;..\..\..\source\gameengine\Rasterizer;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\BlenderRoutines;..\..\..\source\blender\editors\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\gpu;..\..\..\source\kernel\gen_system;..\..\..\intern\string;..\..\..\intern\moto\include;..\..\..\intern\guardedalloc;..\..\..\intern\SoundSystem;..\..\..\extern\glew\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\lib\windows\pthreads\include;..\..\..\source\gameengine\Ketsji;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\GameLogic;..\..\..\source\gameengine\SceneGraph;..\..\..\source\gameengine\Rasterizer;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\BlenderRoutines;..\..\..\source\blender\editors\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\python\generic;..\..\..\source\blender\gpu;..\..\..\source\kernel\gen_system;..\..\..\intern\string;..\..\..\intern\moto\include;..\..\..\intern\guardedalloc;..\..\..\intern\SoundSystem;..\..\..\extern\glew\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;WITH_FFMPEG;__STDC_CONSTANT_MACROS"
StringPooling="false"
BasicRuntimeChecks="3"
diff --git a/release/scripts/extensions/add_mesh_gears.py b/release/scripts/addons/add_mesh_gears.py
index a7e08f7a3bc..45d5f9317e3 100644
--- a/release/scripts/extensions/add_mesh_gears.py
+++ b/release/scripts/addons/add_mesh_gears.py
@@ -50,7 +50,7 @@ for i in vertexgroup_vertex_indices:
Now for some reason the name does not 'stick' and we have to set it this way:
vertexgroup.name = 'NAME_OF_VERTEXGROUP'
-
+
Conversion to 2.50 also meant we could simply do away with our crude user interface.
Just definining the appropriate properties in the AddGear() operator will display the
properties in the Blender GUI with the added benefit of making it interactive: changing
@@ -65,7 +65,7 @@ we could no longer use deepcopy(zip(...)) but had to convert the zip object to a
first.
The code to actually implement the AddGear() function is mostly copied from add_mesh_torus()
-(distributed with Blender).
+(distributed with Blender).
Unresolved issues:
@@ -108,148 +108,148 @@ tv = [13,14,15,29,30,31] #vertices on a tooth
spokefaces=((0,1,2,5),(2,3,4,7),(5,2,7,6),(5,6,9,8),(6,7,10,9),(11,8,13,12),(8,9,10,13),(13,10,15,14))
def add_tooth(a,t,d,r,Ad,De,b,p,rack=0,crown=0.0):
- """
- private function: calculate the vertex coords for a single side
- section of a gear tooth. returns them as a list of lists.
- """
-
- A=[a,a+t/4,a+t/2,a+3*t/4,a+t]
- C=[cos(i) for i in A]
- S=[sin(i) for i in A]
-
- Ra=r+Ad
- Rd=r-De
- Rb=Rd-b
-
- #Pressure angle calc
- O =Ad*tan(p)
- p =atan(O/Ra)
- if r<0 : p = -p
-
- if rack :
- S =[sin(t/4)*I for I in range(-2,3)]
- Sp=[0,sin(-t/4+p),0,sin(t/4-p)]
-
- v=[(Rb,r*S[I],d) for I in range(5)]
- v.extend([(Rd,r*S[I],d) for I in range(5)])
- v.extend([(r,r*S[I],d) for I in range(1,4)])
- v.extend([(Ra,r*Sp[I],d) for I in range(1,4)])
-
- else :
- Cp=[0,cos(a+t/4+p),cos(a+t/2),cos(a+3*t/4-p)]
- Sp=[0,sin(a+t/4+p),sin(a+t/2),sin(a+3*t/4-p)]
-
- v=[(Rb*C[I],Rb*S[I],d) for I in range(5)]
- v.extend([(Rd*C[I],Rd*S[I],d) for I in range(5)])
- v.extend([(r*C[I],r*S[I],d+crown/3) for I in range(1,4)])
- v.extend([(Ra*Cp[I],Ra*Sp[I],d+crown) for I in range(1,4)])
-
- return v
+ """
+ private function: calculate the vertex coords for a single side
+ section of a gear tooth. returns them as a list of lists.
+ """
+
+ A=[a,a+t/4,a+t/2,a+3*t/4,a+t]
+ C=[cos(i) for i in A]
+ S=[sin(i) for i in A]
+
+ Ra=r+Ad
+ Rd=r-De
+ Rb=Rd-b
+
+ #Pressure angle calc
+ O =Ad*tan(p)
+ p =atan(O/Ra)
+ if r<0 : p = -p
+
+ if rack :
+ S =[sin(t/4)*I for I in range(-2,3)]
+ Sp=[0,sin(-t/4+p),0,sin(t/4-p)]
+
+ v=[(Rb,r*S[I],d) for I in range(5)]
+ v.extend([(Rd,r*S[I],d) for I in range(5)])
+ v.extend([(r,r*S[I],d) for I in range(1,4)])
+ v.extend([(Ra,r*Sp[I],d) for I in range(1,4)])
+
+ else :
+ Cp=[0,cos(a+t/4+p),cos(a+t/2),cos(a+3*t/4-p)]
+ Sp=[0,sin(a+t/4+p),sin(a+t/2),sin(a+3*t/4-p)]
+
+ v=[(Rb*C[I],Rb*S[I],d) for I in range(5)]
+ v.extend([(Rd*C[I],Rd*S[I],d) for I in range(5)])
+ v.extend([(r*C[I],r*S[I],d+crown/3) for I in range(1,4)])
+ v.extend([(Ra*Cp[I],Ra*Sp[I],d+crown) for I in range(1,4)])
+
+ return v
def add_spoke2(a,t,d,r,De,b,s,w,l,gap=0,width=19):
- """
- EXPERIMENTAL private function: calculate the vertex coords for a single side
- section of a gearspoke. returns them as a list of lists.
- """
-
- Rd=r-De
- Rb=Rd-b
- Rl=Rb
-
- v =[]
- ef =[]
- ef2=[]
- sf =[]
- if not gap :
- for N in range(width,1,-2) :
- ef.append(len(v))
- ts = t/4
- tm = a + 2*ts
- te = asin(w/Rb)
- td = te - ts
- t4 = ts+td*(width-N)/(width-3.0)
- A=[tm+(i-int(N/2))*t4 for i in range(N)]
- C=[cos(i) for i in A]
- S=[sin(i) for i in A]
- v.extend([ (Rb*I,Rb*J,d) for (I,J) in zip(C,S)])
- ef2.append(len(v)-1)
- Rb= Rb-s
- n=0
- for N in range(width,3,-2) :
- sf.extend([(i+n,i+1+n,i+2+n,i+N+n) for i in range(0,N-1,2)])
- sf.extend([(i+2+n,i+N+n,i+N+1+n,i+N+2+n) for i in range(0,N-3,2)])
- n = n + N
-
- return v,ef,ef2,sf
+ """
+ EXPERIMENTAL private function: calculate the vertex coords for a single side
+ section of a gearspoke. returns them as a list of lists.
+ """
+
+ Rd=r-De
+ Rb=Rd-b
+ Rl=Rb
+
+ v =[]
+ ef =[]
+ ef2=[]
+ sf =[]
+ if not gap :
+ for N in range(width,1,-2) :
+ ef.append(len(v))
+ ts = t/4
+ tm = a + 2*ts
+ te = asin(w/Rb)
+ td = te - ts
+ t4 = ts+td*(width-N)/(width-3.0)
+ A=[tm+(i-int(N/2))*t4 for i in range(N)]
+ C=[cos(i) for i in A]
+ S=[sin(i) for i in A]
+ v.extend([ (Rb*I,Rb*J,d) for (I,J) in zip(C,S)])
+ ef2.append(len(v)-1)
+ Rb= Rb-s
+ n=0
+ for N in range(width,3,-2) :
+ sf.extend([(i+n,i+1+n,i+2+n,i+N+n) for i in range(0,N-1,2)])
+ sf.extend([(i+2+n,i+N+n,i+N+1+n,i+N+2+n) for i in range(0,N-3,2)])
+ n = n + N
+
+ return v,ef,ef2,sf
def add_gear(N,r,Ad,De,b,p,D=1,skew=0,conangle=0,rack=0,crown=0.0, spoke=0,spbevel=0.1,spwidth=0.2,splength=1.0,spresol=9):
- """
- """
- worm =0
- if N<5 : (worm,N)=(N,24)
- t =2*pi/N
- if rack: N=1
- p =rad(p)
- conangle=rad(conangle)
- skew =rad(skew)
- scale = (r - 2*D*tan(conangle) )/r
-
- f =[]
- v =[]
- tg=[] #vertexgroup of top vertices.
- vg=[] #vertexgroup of valley vertices
-
-
- M=[0]
- if worm : (M,skew,D)=(range(32),rad(11.25),D/2)
-
- for W in M:
- fl=W*N*L*2
- l=0 #number of vertices
- for I in range(int(N)):
- a=I*t
- for(s,d,c,first) in ((W*skew,W*2*D-D,1,1),((W+1)*skew,W*2*D+D,scale,0)):
- if worm and I%(int(N)/worm)!=0:
- v.extend(add_tooth(a+s,t,d,r-De,0.0,0.0,b,p))
- else:
- v.extend(add_tooth(a+s,t,d,r*c,Ad*c,De*c,b*c,p,rack,crown))
- if not worm or (W==0 and first) or (W==(len(M)-1) and not first) :
- f.extend([ [j+l+fl for j in i]for i in dc(faces)])
- l += L
-
- #print (len(f))
- #print (dc(efc))
- f.extend([ [j+I*L*2+fl for j in i] for i in dc(efc)])
- #print (len(f))
- tg.extend([i+I*L*2 for i in tv])
- vg.extend([i+I*L*2 for i in vv])
- # EXPERIMENTAL: add spokes
- if not worm and spoke>0 :
- fl=len(v)
- for I in range(int(N)):
- a=I*t
- s=0 # for test
- if I%spoke==0 :
- for d in (-D,D) :
- (sv,ef,ef2,sf) = add_spoke2(a+s,t,d,r*c,De*c,b*c,spbevel,spwidth,splength,0,spresol)
- v.extend(sv)
- f.extend([ [j+fl for j in i]for i in sf])
- fl += len(sv)
- d1 = fl-len(sv)
- d2 = fl-2*len(sv)
- f.extend([(i+d2,j+d2,j+d1,i+d1) for (i,j) in zip(ef[:-1],ef[1:])])
- f.extend([(i+d2,j+d2,j+d1,i+d1) for (i,j) in zip(ef2[:-1],ef2[1:])])
- else :
- for d in (-D,D) :
- (sv,ef,ef2,sf) = add_spoke2(a+s,t,d,r*c,De*c,b*c,spbevel,spwidth,splength,1,spresol)
- v.extend(sv)
- fl += len(sv)
- d1 = fl-len(sv)
- d2 = fl-2*len(sv)
- #f.extend([(i+d2,i+1+d2,i+1+d1,i+d1) for (i) in (0,1,2,3)])
- #f.extend([(i+d2,i+1+d2,i+1+d1,i+d1) for (i) in (5,6,7,8)])
-
- return flatten(v), flatten(f), tg, vg
+ """
+ """
+ worm =0
+ if N<5 : (worm,N)=(N,24)
+ t =2*pi/N
+ if rack: N=1
+ p =rad(p)
+ conangle=rad(conangle)
+ skew =rad(skew)
+ scale = (r - 2*D*tan(conangle) )/r
+
+ f =[]
+ v =[]
+ tg=[] #vertexgroup of top vertices.
+ vg=[] #vertexgroup of valley vertices
+
+
+ M=[0]
+ if worm : (M,skew,D)=(range(32),rad(11.25),D/2)
+
+ for W in M:
+ fl=W*N*L*2
+ l=0 #number of vertices
+ for I in range(int(N)):
+ a=I*t
+ for(s,d,c,first) in ((W*skew,W*2*D-D,1,1),((W+1)*skew,W*2*D+D,scale,0)):
+ if worm and I%(int(N)/worm)!=0:
+ v.extend(add_tooth(a+s,t,d,r-De,0.0,0.0,b,p))
+ else:
+ v.extend(add_tooth(a+s,t,d,r*c,Ad*c,De*c,b*c,p,rack,crown))
+ if not worm or (W==0 and first) or (W==(len(M)-1) and not first) :
+ f.extend([ [j+l+fl for j in i]for i in dc(faces)])
+ l += L
+
+ #print (len(f))
+ #print (dc(efc))
+ f.extend([ [j+I*L*2+fl for j in i] for i in dc(efc)])
+ #print (len(f))
+ tg.extend([i+I*L*2 for i in tv])
+ vg.extend([i+I*L*2 for i in vv])
+ # EXPERIMENTAL: add spokes
+ if not worm and spoke>0 :
+ fl=len(v)
+ for I in range(int(N)):
+ a=I*t
+ s=0 # for test
+ if I%spoke==0 :
+ for d in (-D,D) :
+ (sv,ef,ef2,sf) = add_spoke2(a+s,t,d,r*c,De*c,b*c,spbevel,spwidth,splength,0,spresol)
+ v.extend(sv)
+ f.extend([ [j+fl for j in i]for i in sf])
+ fl += len(sv)
+ d1 = fl-len(sv)
+ d2 = fl-2*len(sv)
+ f.extend([(i+d2,j+d2,j+d1,i+d1) for (i,j) in zip(ef[:-1],ef[1:])])
+ f.extend([(i+d2,j+d2,j+d1,i+d1) for (i,j) in zip(ef2[:-1],ef2[1:])])
+ else :
+ for d in (-D,D) :
+ (sv,ef,ef2,sf) = add_spoke2(a+s,t,d,r*c,De*c,b*c,spbevel,spwidth,splength,1,spresol)
+ v.extend(sv)
+ fl += len(sv)
+ d1 = fl-len(sv)
+ d2 = fl-2*len(sv)
+ #f.extend([(i+d2,i+1+d2,i+1+d1,i+d1) for (i) in (0,1,2,3)])
+ #f.extend([(i+d2,i+1+d2,i+1+d1,i+d1) for (i) in (5,6,7,8)])
+
+ return flatten(v), flatten(f), tg, vg
from bpy.props import *
@@ -307,7 +307,7 @@ class AddGear(bpy.types.Operator):
crown=self.properties.crown)
#print(len(verts_loc)/3,faces)
-
+
mesh = bpy.data.meshes.new("Gear")
mesh.add_geometry(int(len(verts_loc) / 3), 0, int(len(faces) / 4))
@@ -321,22 +321,21 @@ class AddGear(bpy.types.Operator):
ob.selected = False
mesh.update()
-
- ob_new = bpy.data.objects.new('Gear','MESH')
- ob_new.data = mesh
+
+ ob_new = bpy.data.objects.new('Gear', mesh)
tipgroup = ob_new.add_vertex_group('Tips')
# for some reason the name does not 'stick' and we have to set it this way:
tipgroup.name = 'Tips'
for i in tip_vertices:
ob_new.add_vertex_to_group(i, tipgroup, 1.0, 'ADD')
-
+
valleygroup = ob_new.add_vertex_group('Valleys')
# for some reason the name does not 'stick' and we have to set it this way:
valleygroup.name = 'Valleys'
for i in valley_vertices:
ob_new.add_vertex_to_group(i, valleygroup, 1.0, 'ADD')
-
+
scene.objects.link(ob_new)
scene.objects.active = ob_new
ob_new.selected = True
@@ -349,7 +348,7 @@ class AddGear(bpy.types.Operator):
# unfortunately the next line wont get us back to object mode but bombs
#bpy.ops.object.mode_set('OBJECT')
#print(4,bpy.context.mode)
-
+
ob_new.location = tuple(context.scene.cursor_location)
return {'FINISHED'}
diff --git a/release/scripts/addons/io_mesh_raw/__init__.py b/release/scripts/addons/io_mesh_raw/__init__.py
new file mode 100644
index 00000000000..a7f38ad6a5f
--- /dev/null
+++ b/release/scripts/addons/io_mesh_raw/__init__.py
@@ -0,0 +1,51 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# blender 1 line description
+"Raw Mesh IO (File > Import/Export > Raw Faces (.raw))"
+
+import bpy
+
+
+def menu_import(self, context):
+ from io_mesh_raw import import_raw
+ self.layout.operator(import_raw.RawImporter.bl_idname, text="Raw Faces (.raw)").path = "*.raw"
+
+
+def menu_export(self, context):
+ from io_mesh_raw import export_raw
+ default_path = bpy.data.filename.replace(".blend", ".raw")
+ self.layout.operator(export_raw.RawExporter.bl_idname, text="Raw Faces (.raw)").path = default_path
+
+
+def register():
+ from io_mesh_raw import import_raw, export_raw
+ bpy.types.register(import_raw.RawImporter)
+ bpy.types.register(export_raw.RawExporter)
+ bpy.types.INFO_MT_file_import.append(menu_import)
+ bpy.types.INFO_MT_file_export.append(menu_export)
+
+def unregister():
+ from io_mesh_raw import import_raw, export_raw
+ bpy.types.unregister(import_raw.RawImporter)
+ bpy.types.unregister(export_raw.RawExporter)
+ bpy.types.INFO_MT_file_import.remove(menu_import)
+ bpy.types.INFO_MT_file_export.remove(menu_export)
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons/io_mesh_raw/export_raw.py b/release/scripts/addons/io_mesh_raw/export_raw.py
new file mode 100644
index 00000000000..e94e26bb604
--- /dev/null
+++ b/release/scripts/addons/io_mesh_raw/export_raw.py
@@ -0,0 +1,114 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+__author__ = ["Aurel Wildfellner"]
+__version__ = '0.2'
+__bpydoc__ = """\
+This script exports a Mesh to a RAW triangle format file.
+
+The raw triangle format is very simple; it has no verts or faces lists.
+It's just a simple ascii text file with the vertices of each triangle
+listed on each line. In addition, also quads can be exported as a line
+of 12 values (this was the default before blender 2.5). Now default
+settings will triangulate the mesh.
+
+Usage:<br>
+ Execute this script from the "File->Export" menu. You can select
+whether modifiers should be applied and if the mesh is triangulated.
+
+"""
+
+import bpy
+
+
+def faceToTriangles(face):
+ triangles = []
+ if (len(face) == 4): #quad
+ triangles.append( [ face[0], face[1], face[2] ] )
+ triangles.append( [ face[2], face[3], face[0] ] )
+ else:
+ triangles.append(face)
+
+ return triangles
+
+
+def faceValues(face, mesh, matrix):
+ fv = []
+ for verti in face.verts_raw:
+ fv.append(matrix * mesh.verts[verti].co)
+ return fv
+
+
+def faceToLine(face):
+ line = ""
+ for v in face:
+ line += str(v[0]) + " " + str(v[1]) + " " + str(v[2]) + " "
+ return line[:-1] + "\n"
+
+
+def export_raw(path, applyMods, triangulate):
+ faces = []
+ for obj in bpy.context.selected_objects:
+ if obj.type == 'MESH':
+ matrix = obj.matrix
+
+ if (applyMods):
+ me = obj.create_mesh(True, "PREVIEW")
+ else:
+ me = obj.data
+
+ for face in me.faces:
+ fv = faceValues(face, me, matrix)
+ if triangulate:
+ faces.extend(faceToTriangles(fv))
+ else:
+ faces.append(fv)
+
+ # write the faces to a file
+ file = open(path, "w")
+ for face in faces:
+ file.write(faceToLine(face))
+ file.close()
+
+
+from bpy.props import *
+
+
+class RawExporter(bpy.types.Operator):
+ '''Save Raw triangle mesh data'''
+ bl_idname = "export_mesh.raw"
+ bl_label = "Export RAW"
+
+ path = StringProperty(name="File Path", description="File path used for exporting the RAW file", maxlen= 1024, default= "")
+ filename = StringProperty(name="File Name", description="Name of the file.")
+ directory = StringProperty(name="Directory", description="Directory of the file.")
+ check_existing = BoolProperty(name="Check Existing", description="Check and warn on overwriting existing files", default=True, options={'HIDDEN'})
+
+ apply_modifiers = BoolProperty(name="Apply Modifiers", description="Use transformed mesh data from each object", default=True)
+ triangulate = BoolProperty(name="Triangulate", description="Triangulate quads.", default=True)
+
+ def execute(self, context):
+ export_raw(self.properties.path, self.properties.apply_modifiers, self.properties.triangulate)
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ wm = context.manager
+ wm.add_fileselect(self)
+ return {'RUNNING_MODAL'}
+
+# package manages registering
diff --git a/release/scripts/addons/io_mesh_raw/import_raw.py b/release/scripts/addons/io_mesh_raw/import_raw.py
new file mode 100644
index 00000000000..fc1bddc79fd
--- /dev/null
+++ b/release/scripts/addons/io_mesh_raw/import_raw.py
@@ -0,0 +1,142 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+__author__ = ["Anthony D'Agostino (Scorpius)", "Aurel Wildfellner"]
+__version__ = '0.2'
+__bpydoc__ = """\
+This script imports Raw Triangle File format files to Blender.
+
+The raw triangle format is very simple; it has no verts or faces lists.
+It's just a simple ascii text file with the vertices of each triangle
+listed on each line. In addition, a line with 12 values will be
+imported as a quad. This may be in conflict with some other
+applications, which use a raw format, but this is how it was
+implemented back in blender 2.42.
+
+Usage:<br>
+ Execute this script from the "File->Import" menu and choose a Raw file to
+open.
+
+Notes:<br>
+ Generates the standard verts and faces lists, but without duplicate
+verts. Only *exact* duplicates are removed, there is no way to specify a
+tolerance.
+"""
+
+
+
+import bpy
+
+# move those to a utility modul
+from import_scene_obj import unpack_face_list, unpack_list # TODO, make generic
+
+
+def readMesh(filename, objName):
+ file = open(filename, "rb")
+
+ def line_to_face(line):
+ # Each triplet is an xyz float
+ line_split = []
+ try:
+ line_split = list(map(float, line.split()))
+ except:
+ return None
+
+ if len(line_split) == 9: # Tri
+ f1, f2, f3, f4, f5, f6, f7, f8, f9 = line_split
+ return [(f1, f2, f3), (f4, f5, f6), (f7, f8, f9)]
+ elif len(line_split) == 12: # Quad
+ f1, f2, f3, f4, f5, f6, f7, f8, f9, A, B, C = line_split
+ return [(f1, f2, f3), (f4, f5, f6), (f7, f8, f9), (A, B, C)]
+ else:
+ return None
+
+
+ faces = []
+ for line in file.readlines():
+ face = line_to_face(line)
+ if face:
+ faces.append(face)
+
+ file.close()
+
+ # Generate verts and faces lists, without duplicates
+ verts = []
+ coords = {}
+ index = 0
+
+ for f in faces:
+ for i, v in enumerate(f):
+ try:
+ f[i] = coords[v]
+ except:
+ f[i] = coords[v] = index
+ index += 1
+ verts.append(v)
+
+ mesh = bpy.data.meshes.new(objName)
+ mesh.add_geometry(int(len(verts)), 0, int(len(faces)))
+ mesh.verts.foreach_set("co", unpack_list(verts))
+ mesh.faces.foreach_set("verts_raw", unpack_face_list(faces))
+ mesh.faces.foreach_set("smooth", [False] * len(mesh.faces))
+
+ return mesh
+
+
+def addMeshObj(mesh, objName):
+ scn = bpy.context.scene
+
+ for o in scn.objects:
+ o.selected = False
+
+ mesh.update()
+ nobj = bpy.data.objects.new(objName, mesh)
+ scn.objects.link(nobj)
+ nobj.selected = True
+
+ if scn.objects.active == None or scn.objects.active.mode == 'OBJECT':
+ scn.objects.active = nobj
+
+
+from bpy.props import *
+
+class RawImporter(bpy.types.Operator):
+ '''Load Raw triangle mesh data'''
+ bl_idname = "import_mesh.raw"
+ bl_label = "Import RAW"
+
+ path = StringProperty(name="File Path", description="File path used for importing the RAW file", maxlen=1024, default="")
+ filename = StringProperty(name="File Name", description="Name of the file.")
+ directory = StringProperty(name="Directory", description="Directory of the file.")
+
+ def execute(self, context):
+
+ #convert the filename to an object name
+ objName = bpy.utils.display_name(self.properties.filename)
+
+ mesh = readMesh(self.properties.path, objName)
+ addMeshObj(mesh, objName)
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ wm = context.manager
+ wm.add_fileselect(self)
+ return {'RUNNING_MODAL'}
+
+# package manages registering
diff --git a/release/scripts/io/engine_render_pov.py b/release/scripts/io/engine_render_pov.py
index 1be08fc82d4..338676968cd 100644
--- a/release/scripts/io/engine_render_pov.py
+++ b/release/scripts/io/engine_render_pov.py
@@ -41,7 +41,7 @@ def write_pov(filename, scene=None, info_callback=None):
if not scene:
scene = bpy.data.scenes[0]
- render = scene.render_data
+ render = scene.render
world = scene.world
def uniqueName(name, nameSeq):
@@ -602,7 +602,7 @@ def write_pov(filename, scene=None, info_callback=None):
def write_pov_ini(filename_ini, filename_pov, filename_image):
scene = bpy.data.scenes[0]
- render = scene.render_data
+ render = scene.render
x = int(render.resolution_x * render.resolution_percentage * 0.01)
y = int(render.resolution_y * render.resolution_percentage * 0.01)
@@ -785,7 +785,7 @@ class PovrayRender(bpy.types.RenderEngine):
self.update_stats("", "POVRAY: Parsing File")
self._render()
- r = scene.render_data
+ r = scene.render
# compute resolution
x = int(r.resolution_x * r.resolution_percentage * 0.01)
@@ -889,7 +889,7 @@ class RenderButtonsPanel(bpy.types.Panel):
# COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
def poll(self, context):
- rd = context.scene.render_data
+ rd = context.scene.render
return (rd.use_game_engine == False) and (rd.engine in self.COMPAT_ENGINES)
@@ -906,7 +906,7 @@ class RENDER_PT_povray_radiosity(RenderButtonsPanel):
layout = self.layout
scene = context.scene
- rd = scene.render_data
+ rd = scene.render
layout.active = scene.pov_radio_enable
diff --git a/release/scripts/io/export_fbx.py b/release/scripts/io/export_fbx.py
index 558c5896397..e1c7f68c557 100644
--- a/release/scripts/io/export_fbx.py
+++ b/release/scripts/io/export_fbx.py
@@ -412,13 +412,13 @@ def write(filename, batch_objects = None, \
# XXX don't know what to do with this, probably do the same? (Arystan)
if BATCH_GROUP: #group
# group, so objects update properly, add a dummy scene.
- sce = bpy.data.scenes.new()
- sce.Layers = (1<<20) -1
- bpy.data.scenes.active = sce
+ scene = bpy.data.scenes.new()
+ scene.Layers = (1<<20) -1
+ bpy.data.scenes.active = scene
for ob_base in data.objects:
- sce.objects.link(ob_base)
+ scene.objects.link(ob_base)
- sce.update(1)
+ scene.update(1)
# TODO - BUMMER! Armatures not in the group wont animate the mesh
@@ -450,8 +450,8 @@ def write(filename, batch_objects = None, \
if BATCH_GROUP:
# remove temp group scene
- bpy.data.remove_scene(sce)
-# bpy.data.scenes.unlink(sce)
+ bpy.data.remove_scene(scene)
+# bpy.data.scenes.unlink(scene)
bpy.data.scenes.active = orig_sce
@@ -618,9 +618,9 @@ def write(filename, batch_objects = None, \
except:
return False
- sce = context.scene
-# sce = bpy.data.scenes.active
- world = sce.world
+ scene = context.scene
+# scene = bpy.data.scenes.active
+ world = scene.world
# ---------------------------- Write the header first
@@ -983,10 +983,10 @@ def write(filename, batch_objects = None, \
'''
Write a blender camera
'''
- render = sce.render_data
+ render = scene.render
width = render.resolution_x
height = render.resolution_y
-# render = sce.render
+# render = scene.render
# width = render.sizeX
# height = render.sizeY
aspect = float(width)/height
@@ -1293,16 +1293,18 @@ def write(filename, batch_objects = None, \
file.write('\n\t}')
def copy_image(image):
-
- rel = image.get_export_path(basepath, True)
- base = os.path.basename(rel)
+ fn = bpy.utils.expandpath(image.filename)
+ fn_strip = os.path.basename(fn)
if EXP_IMAGE_COPY:
- absp = image.get_export_path(basepath, False)
- if not os.path.exists(absp):
- shutil.copy(image.get_abs_filename(), absp)
+ rel = fn_strip
+ fn_abs_dest = os.path.join(basepath, fn_strip)
+ if not os.path.exists(fn_abs_dest):
+ shutil.copy(fn, fn_abs_dest)
+ else:
+ rel = os.path.relpath(fn, basepath)
- return (rel, base)
+ return (rel, fn_strip)
# tex is an Image (Arystan)
def write_video(texname, tex):
@@ -2016,8 +2018,8 @@ def write(filename, batch_objects = None, \
# if EXP_OBS_SELECTED is false, use sceens objects
if not batch_objects:
if EXP_OBS_SELECTED: tmp_objects = context.selected_objects
-# if EXP_OBS_SELECTED: tmp_objects = sce.objects.context
- else: tmp_objects = sce.objects
+# if EXP_OBS_SELECTED: tmp_objects = scene.objects.context
+ else: tmp_objects = scene.objects
else:
tmp_objects = batch_objects
@@ -2039,7 +2041,7 @@ def write(filename, batch_objects = None, \
# ob_base.makeDisplayList()
# This causes the makeDisplayList command to effect the mesh
- sce.set_frame(sce.current_frame)
+ scene.set_frame(scene.current_frame)
# Blender.Set('curframe', Blender.Get('curframe'))
@@ -2214,7 +2216,7 @@ def write(filename, batch_objects = None, \
ob_base.make_display_list()
# ob_base.makeDisplayList()
# This causes the makeDisplayList command to effect the mesh
- sce.set_frame(sce.current_frame)
+ scene.set_frame(scene.current_frame)
# Blender.Set('curframe', Blender.Get('curframe'))
del tmp_ob_type, tmp_objects
@@ -2689,8 +2691,8 @@ Connections: {''')
# Needed for scene footer as well as animation
- render = sce.render_data
-# render = sce.render
+ render = scene.render
+# render = scene.render
# from the FBX sdk
#define KTIME_ONE_SECOND KTime (K_LONGLONG(46186158000))
@@ -2699,9 +2701,9 @@ Connections: {''')
return int(0.5 + ((t/fps) * 46186158000))
fps = float(render.fps)
- start = sce.start_frame
+ start = scene.start_frame
# start = render.sFrame
- end = sce.end_frame
+ end = scene.end_frame
# end = render.eFrame
if end < start: start, end = end, start
if start==end: ANIM_ENABLE = False
@@ -2711,7 +2713,7 @@ Connections: {''')
if ANIM_ENABLE and [tmp for tmp in ob_anim_lists if tmp]:
- frame_orig = sce.current_frame
+ frame_orig = scene.current_frame
# frame_orig = Blender.Get('curframe')
if ANIM_OPTIMIZE:
@@ -2812,7 +2814,7 @@ Takes: {''')
if blenAction in my_bone.blenActionList:
ob.action = blenAction
# print '\t\tSetting Action!', blenAction
- # sce.update(1)
+ # scene.update(1)
file.write('\n\t\tFileName: "Default_Take.tak"') # ??? - not sure why this is needed
file.write('\n\t\tLocalTime: %i,%i' % (fbx_time(act_start-1), fbx_time(act_end-1))) # ??? - not sure why this is needed
@@ -2832,7 +2834,7 @@ Takes: {''')
'''
i = act_start
while i <= act_end:
- sce.set_frame(i)
+ scene.set_frame(i)
# Blender.Set('curframe', i)
for ob_generic in ob_anim_lists:
for my_ob in ob_generic:
@@ -2971,7 +2973,7 @@ Takes: {''')
file.write('\n}')
- sce.set_frame(frame_orig)
+ scene.set_frame(frame_orig)
# Blender.Set('curframe', frame_orig)
else:
@@ -3463,6 +3465,7 @@ class ExportFBX(bpy.types.Operator):
# SMALL or COSMETICAL
# - find a way to get blender version, and put it in bpy.util?, old was Blender.Get('version')
+
def menu_func(self, context):
default_path = bpy.data.filename.replace(".blend", ".fbx")
self.layout.operator(ExportFBX.bl_idname, text="Autodesk FBX (.fbx)").path = default_path
@@ -3471,11 +3474,11 @@ def menu_func(self, context):
def register():
bpy.types.register(ExportFBX)
bpy.types.INFO_MT_file_export.append(menu_func)
-
+
+
def unregister():
bpy.types.unregister(ExportFBX)
bpy.types.INFO_MT_file_export.remove(menu_func)
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/io/export_mdd.py b/release/scripts/io/export_mdd.py
index 6ac6ea0bee3..a4dca4db204 100644
--- a/release/scripts/io/export_mdd.py
+++ b/release/scripts/io/export_mdd.py
@@ -190,7 +190,7 @@ def menu_func(self, context):
def register():
bpy.types.register(ExportMDD)
bpy.types.INFO_MT_file_export.append(menu_func)
-
+
def unregister():
bpy.types.unregister(ExportMDD)
bpy.types.INFO_MT_file_export.remove(menu_func)
diff --git a/release/scripts/io/export_obj.py b/release/scripts/io/export_obj.py
index aa9968d71ad..2d039bfd45c 100644
--- a/release/scripts/io/export_obj.py
+++ b/release/scripts/io/export_obj.py
@@ -44,6 +44,7 @@ will be exported as mesh data.
# import math
import os
import time
+import shutil
import bpy
import Mathutils
@@ -76,12 +77,15 @@ def write_mtl(scene, filename, copy_images):
dest_dir = os.path.dirname(filename)
def copy_image(image):
- rel = image.get_export_path(dest_dir, True)
-
+ fn = bpy.utils.expandpath(image.filename)
+ fn_strip = os.path.basename(fn)
if copy_images:
- abspath = image.get_export_path(dest_dir, False)
- if not os.path.exists(abs_path):
- shutil.copy(image.get_abs_filename(), abs_path)
+ rel = fn_strip
+ fn_abs_dest = os.path.join(dest_dir, fn_strip)
+ if not os.path.exists(fn_abs_dest):
+ shutil.copy(fn, fn_abs_dest)
+ else:
+ rel = fn
return rel
@@ -447,8 +451,7 @@ def write(filename, objects, scene,
break
if has_quads:
- newob = bpy.data.objects.new('temp_object', 'MESH')
- newob.data = me
+ newob = bpy.data.objects.new('temp_object', me)
# if we forget to set Object.data - crash
scene.objects.link(newob)
newob.convert_to_triface(scene)
@@ -967,7 +970,7 @@ def menu_func(self, context):
def register():
bpy.types.register(ExportOBJ)
bpy.types.INFO_MT_file_export.append(menu_func)
-
+
def unregister():
bpy.types.unregister(ExportOBJ)
bpy.types.INFO_MT_file_export.remove(menu_func)
diff --git a/release/scripts/io/export_ply.py b/release/scripts/io/export_ply.py
index 2ee8caba279..92d4f2ff914 100644
--- a/release/scripts/io/export_ply.py
+++ b/release/scripts/io/export_ply.py
@@ -321,11 +321,11 @@ def menu_func(self, context):
def register():
bpy.types.register(ExportPLY)
bpy.types.INFO_MT_file_export.append(menu_func)
-
+
+
def unregister():
bpy.types.unregister(ExportPLY)
bpy.types.INFO_MT_file_export.remove(menu_func)
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/io/export_x3d.py b/release/scripts/io/export_x3d.py
index cd944b07ca0..f1ab8cd3de7 100644
--- a/release/scripts/io/export_x3d.py
+++ b/release/scripts/io/export_x3d.py
@@ -228,7 +228,7 @@ class x3d_class:
'''
def writeViewpoint(self, ob, mat, scene):
- context = scene.render_data
+ context = scene.render
# context = scene.render
ratio = float(context.resolution_x)/float(context.resolution_y)
# ratio = float(context.imageSizeY())/float(context.imageSizeX())
@@ -794,7 +794,7 @@ class x3d_class:
pic = tex.image
# using .expandpath just in case, os.path may not expect //
- basename = os.path.basename(pic.get_abs_filename())
+ basename = os.path.basename(bpy.utils.expandpath(pic.filename))
pic = alltextures[i].image
# pic = alltextures[i].getImage()
@@ -1251,7 +1251,7 @@ def menu_func(self, context):
def register():
bpy.types.register(ExportX3D)
bpy.types.INFO_MT_file_export.append(menu_func)
-
+
def unregister():
bpy.types.unregister(ExportX3D)
bpy.types.INFO_MT_file_export.remove(menu_func)
diff --git a/release/scripts/io/import_anim_bvh.py b/release/scripts/io/import_anim_bvh.py
index 97dfbcba5b6..364bd6e96ee 100644
--- a/release/scripts/io/import_anim_bvh.py
+++ b/release/scripts/io/import_anim_bvh.py
@@ -295,7 +295,7 @@ def bvh_node_dict2objects(context, bvh_nodes, IMPORT_START_FRAME=1, IMPORT_LOOP=
objects = []
def add_ob(name):
- ob = scn.objects.new('Empty')
+ ob = scn.objects.new('Empty', None)
objects.append(ob)
return ob
@@ -352,8 +352,7 @@ def bvh_node_dict2armature(context, bvh_nodes, ROT_MODE='XYZ', IMPORT_START_FRAM
scn.set_frame(IMPORT_START_FRAME)
arm_data = bpy.data.armatures.new("MyBVH")
- arm_ob = bpy.data.objects.new("MyBVH", 'ARMATURE')
- arm_ob.data = arm_data
+ arm_ob = bpy.data.objects.new("MyBVH", arm_data)
scn.objects.link(arm_ob)
diff --git a/release/scripts/io/import_scene_3ds.py b/release/scripts/io/import_scene_3ds.py
index aea07d47dd9..d1dbdc62563 100644
--- a/release/scripts/io/import_scene_3ds.py
+++ b/release/scripts/io/import_scene_3ds.py
@@ -293,12 +293,12 @@ def skip_to_end(file, skip_chunk):
def add_texture_to_material(image, texture, material, mapto):
#print('assigning %s to %s' % (texture, material))
-
+
if mapto not in ("COLOR", "SPECULARITY", "ALPHA", "NORMAL"):
print('/tError: Cannot map to "%s"\n\tassuming diffuse color. modify material "%s" later.' % (mapto, material.name))
mapto = "COLOR"
- if image:
+ if image:
texture.image = image
# if image: texture.setImage(image) # double check its an image.
@@ -413,13 +413,12 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
# targetFace.uv = [contextMeshUV[vindex] for vindex in myContextMesh_facels[i]]
if img:
uf.image = img
-
+
# to get this image to show up in 'Textured' shading mode
- uf.tex = True
+ uf.tex = True
# bmesh.transform(contextMatrix)
- ob = bpy.data.objects.new(tempName, 'MESH')
- ob.data = bmesh
+ ob = bpy.data.objects.new(tempName, bmesh)
SCN.objects.link(ob)
# ob = SCN_OBJECTS.new(bmesh, tempName)
'''
@@ -638,8 +637,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
x,y,z = struct.unpack('<3f', temp_data)
new_chunk.bytes_read += STRUCT_SIZE_3FLOAT
- ob = bpy.data.objects.new("Lamp", 'LAMP')
- ob.data = bpy.data.lamps.new("Lamp")
+ ob = bpy.data.objects.new("Lamp", bpy.data.lamps.new("Lamp"))
SCN.objects.link(ob)
contextLamp[1]= ob.data
@@ -1017,7 +1015,7 @@ class IMPORT_OT_autodesk_3ds(bpy.types.Operator):
path = StringProperty(name="File Path", description="File path used for importing the 3DS file", maxlen= 1024, default= "")
filename = StringProperty(name="File Name", description="Name of the file.")
directory = StringProperty(name="Directory", description="Directory of the file.")
-
+
# size_constraint = FloatProperty(name="Size Constraint", description="Scale the model by 10 until it reacehs the size constraint. Zero Disables.", min=0.0, max=1000.0, soft_min=0.0, soft_max=1000.0, default=10.0),
# search_images = BoolProperty(name="Image Search", description="Search subdirectories for any assosiated images (Warning, may be slow)", default=True),
# apply_matrix = BoolProperty(name="Transform Fix", description="Workaround for object transformations importing incorrectly", default=False),
@@ -1038,7 +1036,7 @@ menu_func = lambda self, context: self.layout.operator(IMPORT_OT_autodesk_3ds.bl
def register():
bpy.types.register(IMPORT_OT_autodesk_3ds)
bpy.types.INFO_MT_file_import.append(menu_func)
-
+
def unregister():
bpy.types.unregister(IMPORT_OT_autodesk_3ds)
bpy.types.INFO_MT_file_import.remove(menu_func)
diff --git a/release/scripts/io/import_scene_obj.py b/release/scripts/io/import_scene_obj.py
index 86dd1b4920d..c5bd8339a15 100644
--- a/release/scripts/io/import_scene_obj.py
+++ b/release/scripts/io/import_scene_obj.py
@@ -863,10 +863,8 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
me.update()
# me.calcNormals()
- ob= bpy.data.objects.new("Mesh", 'MESH')
- ob.data= me
+ ob= bpy.data.objects.new("Mesh", me)
scn.objects.link(ob)
-# ob= scn.objects.new(me)
new_objects.append(ob)
# Create the vertex groups. No need to have the flag passed here since we test for the
@@ -1629,7 +1627,7 @@ menu_func = lambda self, context: self.layout.operator(IMPORT_OT_obj.bl_idname,
def register():
bpy.types.register(IMPORT_OT_obj)
bpy.types.INFO_MT_file_import.append(menu_func)
-
+
def unregister():
bpy.types.unregister(IMPORT_OT_obj)
bpy.types.INFO_MT_file_import.remove(menu_func)
diff --git a/release/scripts/io/import_shape_mdd.py b/release/scripts/io/import_shape_mdd.py
new file mode 100644
index 00000000000..c64fbd15a5c
--- /dev/null
+++ b/release/scripts/io/import_shape_mdd.py
@@ -0,0 +1,157 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# ***** END GPL LICENCE BLOCK *****
+
+# <pep8 compliant>
+
+# mdd importer by Bill L.Nieuwendorp
+# conversion to blender 2.5: Ivo Grigull (loolarge)
+#
+# Warning if the vertex order or vertex count differs from the
+# origonal model the mdd was Baked out from their will be Strange
+# behavior
+#
+# vertex animation to ShapeKeys with ipo and gives the frame a value of 1.0
+# A modifier to read mdd files would be Ideal but thats for another day :)
+#
+# Please send any fixes,updates,bugs to Slow67_at_Gmail.com
+# Bill Niewuendorp
+
+import bpy
+from struct import unpack
+
+
+def mdd_import(filepath, ob, scene, PREF_START_FRAME=0, PREF_JUMP=1):
+
+ print('\n\nimporting mdd "%s"' % filepath)
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ file = open(filepath, 'rb')
+ frames, points = unpack(">2i", file.read(8))
+ time = unpack((">%df" % frames), file.read(frames * 4))
+
+ print('\tpoints:%d frames:%d' % (points,frames))
+
+ # If target object doesn't have Basis shape key, create it.
+ try:
+ num_keys = len( ob.data.shape_keys.keys )
+ except:
+ basis = ob.add_shape_key()
+ basis.name = "Basis"
+ ob.data.update()
+
+ scene.current_frame = PREF_START_FRAME
+
+ def UpdateMesh(ob, fr):
+
+ # Insert new shape key
+ new_shapekey = ob.add_shape_key()
+ new_shapekey.name = ("frame_%.4d" % fr)
+ new_shapekey_name = new_shapekey.name
+
+ ob.active_shape_key_index = len(ob.data.shape_keys.keys)-1
+ index = len(ob.data.shape_keys.keys)-1
+ ob.shape_key_lock = True
+
+ verts = ob.data.shape_keys.keys[ len(ob.data.shape_keys.keys)-1 ].data
+
+
+ for v in verts:
+ # 12 is the size of 3 floats
+ x,y,z= unpack('>3f', file.read(12))
+ v.co[:] = x,z,y
+ #me.update()
+ ob.shape_key_lock = False
+
+
+ # insert keyframes
+ shape_keys = ob.data.shape_keys
+
+ scene.current_frame -= 1
+ ob.data.shape_keys.keys[index].value = 0.0
+ shape_keys.keys[len(ob.data.shape_keys.keys)-1].keyframe_insert("value")
+
+ scene.current_frame += 1
+ ob.data.shape_keys.keys[index].value = 1.0
+ shape_keys.keys[len(ob.data.shape_keys.keys)-1].keyframe_insert("value")
+
+ scene.current_frame += 1
+ ob.data.shape_keys.keys[index].value = 0.0
+ shape_keys.keys[len(ob.data.shape_keys.keys)-1].keyframe_insert("value")
+
+ ob.data.update()
+
+
+ for i in range(frames):
+ UpdateMesh(ob, i)
+
+
+from bpy.props import *
+
+
+class importMDD(bpy.types.Operator):
+ '''Import MDD vertex keyframe file to shape keys'''
+ bl_idname = "import.mdd"
+ bl_label = "Import MDD"
+
+ # get first scene to get min and max properties for frames, fps
+
+ minframe = 1
+ maxframe = 300000
+ minfps = 1
+ maxfps = 120
+
+ # List of operator properties, the attributes will be assigned
+ # to the class instance from the operator settings before calling.
+ path = StringProperty(name="File Path", description="File path used for importing the MDD file", maxlen=1024)
+ #fps = IntProperty(name="Frames Per Second", description="Number of frames/second", min=minfps, max=maxfps, default=25)
+ start_frame = IntProperty(name="Start Frame", description="Start frame for inserting animation", min=minframe, max=maxframe, default=0)
+
+
+ def poll(self, context):
+ ob = context.active_object
+ return (ob and ob.type == 'MESH')
+
+ def execute(self, context):
+ if not self.properties.path:
+ raise Exception("filename not set")
+
+ mdd_import( self.properties.path, bpy.context.active_object, context.scene, self.properties.start_frame, 1)
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ wm = context.manager
+ wm.add_fileselect(self)
+ return {'RUNNING_MODAL'}
+
+
+def menu_func(self, context):
+ self.layout.operator(importMDD.bl_idname, text="Lightwave Point Cache (.mdd)")
+
+
+def register():
+ bpy.types.register(importMDD)
+ bpy.types.INFO_MT_file_import.append(menu_func)
+
+def unregister():
+ bpy.types.unregister(importMDD)
+ bpy.types.INFO_MT_file_import.remove(menu_func)
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/io/netrender/__init__.py b/release/scripts/io/netrender/__init__.py
index a57115762be..e06d061f173 100644
--- a/release/scripts/io/netrender/__init__.py
+++ b/release/scripts/io/netrender/__init__.py
@@ -44,4 +44,4 @@ def unregister():
bpy.types.unregister(ui.NetRenderJob)
bpy.types.unregister(ui.NetRenderSettings)
bpy.types.unregister(ui.NetRenderSlave)
-
+
diff --git a/release/scripts/io/netrender/client.py b/release/scripts/io/netrender/client.py
index 26f6b6809a2..aea9c37ff47 100644
--- a/release/scripts/io/netrender/client.py
+++ b/release/scripts/io/netrender/client.py
@@ -113,14 +113,18 @@ def clientSendJob(conn, scene, anim = False):
# LIBRARIES
###########################
for lib in bpy.data.libraries:
- job.addFile(bpy.utils.expandpath(lib.filename))
+ file_path = bpy.utils.expandpath(lib.filename)
+ if os.path.exists(file_path):
+ job.addFile(file_path)
###########################
# IMAGES
###########################
for image in bpy.data.images:
if image.source == "FILE" and not image.packed_file:
- job.addFile(bpy.utils.expandpath(image.filename))
+ file_path = bpy.utils.expandpath(image.filename)
+ if os.path.exists(file_path):
+ job.addFile(file_path)
###########################
# FLUID + POINT CACHE
@@ -201,7 +205,7 @@ class NetworkRenderEngine(bpy.types.RenderEngine):
def render_slave(self, scene):
- slave.render_slave(self, scene.network_render, scene.render_data.threads)
+ slave.render_slave(self, scene.network_render, scene.render.threads)
def render_client(self, scene):
netsettings = scene.network_render
@@ -250,7 +254,7 @@ class NetworkRenderEngine(bpy.types.RenderEngine):
conn.close()
return
- r = scene.render_data
+ r = scene.render
x= int(r.resolution_x*r.resolution_percentage*0.01)
y= int(r.resolution_y*r.resolution_percentage*0.01)
diff --git a/release/scripts/io/netrender/master.py b/release/scripts/io/netrender/master.py
index 4c9116982b5..019f33047d8 100644
--- a/release/scripts/io/netrender/master.py
+++ b/release/scripts/io/netrender/master.py
@@ -17,7 +17,7 @@
# ##### END GPL LICENSE BLOCK #####
import sys, os
-import http, http.client, http.server, urllib, socket
+import http, http.client, http.server, urllib, socket, socketserver, threading
import subprocess, shutil, time, hashlib
import select # for select.error
@@ -80,7 +80,7 @@ class MRenderJob(netrender.model.RenderJob):
def initInfo(self):
if not self.resolution:
- self.resolution = tuple(getFileInfo(self.files[0].filepath, ["bpy.context.scene.render_data.resolution_x", "bpy.context.scene.render_data.resolution_y", "bpy.context.scene.render_data.resolution_percentage"]))
+ self.resolution = tuple(getFileInfo(self.files[0].filepath, ["bpy.context.scene.render.resolution_x", "bpy.context.scene.render.resolution_y", "bpy.context.scene.render.resolution_percentage"]))
def save(self):
if self.save_path:
@@ -860,7 +860,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
else: # invalid url
self.send_head(http.client.NO_CONTENT)
-class RenderMasterServer(http.server.HTTPServer):
+class RenderMasterServer(socketserver.ThreadingMixIn, http.server.HTTPServer):
def __init__(self, address, handler_class, path):
super().__init__(address, handler_class)
self.jobs = []
diff --git a/release/scripts/io/netrender/operators.py b/release/scripts/io/netrender/operators.py
index f5e665f9947..f667be68c84 100644
--- a/release/scripts/io/netrender/operators.py
+++ b/release/scripts/io/netrender/operators.py
@@ -372,7 +372,7 @@ class netclientdownload(bpy.types.Operator):
def execute(self, context):
netsettings = context.scene.network_render
- rd = context.scene.render_data
+ rd = context.scene.render
conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
diff --git a/release/scripts/io/netrender/ui.py b/release/scripts/io/netrender/ui.py
index 53f4e6413d3..ba14d7e4f42 100644
--- a/release/scripts/io/netrender/ui.py
+++ b/release/scripts/io/netrender/ui.py
@@ -83,7 +83,7 @@ class RenderButtonsPanel(bpy.types.Panel):
# COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
def poll(self, context):
- rd = context.scene.render_data
+ rd = context.scene.render
return (rd.use_game_engine==False) and (rd.engine in self.COMPAT_ENGINES)
# Setting panel, use in the scene for now.
@@ -136,7 +136,7 @@ class RENDER_PT_network_slave_settings(RenderButtonsPanel):
layout = self.layout
scene = context.scene
- rd = scene.render_data
+ rd = scene.render
netsettings = scene.network_render
layout.prop(netsettings, "slave_clear")
diff --git a/release/scripts/io/netrender/utils.py b/release/scripts/io/netrender/utils.py
index ac4a9307f81..1d35ea00c99 100644
--- a/release/scripts/io/netrender/utils.py
+++ b/release/scripts/io/netrender/utils.py
@@ -197,12 +197,12 @@ def thumbnail(filename):
return thumbname
if bpy:
- sce = bpy.data.scenes[0]
- sce.render_data.file_format = "JPEG"
- sce.render_data.quality = 90
+ scene = bpy.data.scenes[0] # FIXME, this is dodgy!
+ scene.render.file_format = "JPEG"
+ scene.render.quality = 90
bpy.ops.image.open(path = filename)
img = bpy.data.images[imagename]
- img.save(thumbname, scene = sce)
+ img.save_render(thumbname, scene=scene)
try:
process = subprocess.Popen(["convert", thumbname, "-resize", "300x300", thumbname])
diff --git a/release/scripts/modules/bpy/ops.py b/release/scripts/modules/bpy/ops.py
index 045401b54f7..f8f01730a49 100644
--- a/release/scripts/modules/bpy/ops.py
+++ b/release/scripts/modules/bpy/ops.py
@@ -27,6 +27,7 @@ op_call = ops_module.call
op_as_string = ops_module.as_string
op_get_rna = ops_module.get_rna
+
class bpy_ops(object):
'''
Fake module like class.
diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py
index 5ddf2def5f2..7787d9ee5fe 100644
--- a/release/scripts/modules/bpy/utils.py
+++ b/release/scripts/modules/bpy/utils.py
@@ -48,10 +48,11 @@ def _test_import(module_name, loaded_modules):
if _bpy.app.debug:
print("time %s %.4f" % (module_name, time.time() - t))
-
+
loaded_modules.add(mod.__name__) # should match mod.__name__ too
return mod
+
def modules_from_path(path, loaded_modules):
"""
Load all modules in a path and return them as a list.
@@ -65,9 +66,9 @@ def modules_from_path(path, loaded_modules):
"""
import traceback
import time
-
+
modules = []
-
+
for f in sorted(_os.listdir(path)):
if f.endswith(".py"):
# python module
@@ -77,10 +78,10 @@ def modules_from_path(path, loaded_modules):
mod = _test_import(f, loaded_modules)
else:
mod = None
-
+
if mod:
modules.append(mod)
-
+
return modules
_loaded = [] # store loaded modules for reloading.
@@ -90,7 +91,7 @@ _bpy_types = __import__("bpy_types") # keep for comparisons, never ever reload t
def load_scripts(reload_scripts=False, refresh_scripts=False):
"""
Load scripts and run each modules register function.
-
+
:arg reload_scripts: Causes all scripts to have their unregister method called before loading.
:type reload_scripts: bool
:arg refresh_scripts: only load scripts which are not already loaded as modules.
@@ -102,7 +103,7 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
t_main = time.time()
loaded_modules = set()
-
+
if refresh_scripts:
original_modules = _sys.modules.values()
@@ -121,7 +122,7 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
return reload(mod)
except:
traceback.print_exc()
-
+
def test_register(mod):
if refresh_scripts and mod in original_modules:
@@ -141,7 +142,7 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
else:
print("\nWarning! '%s' has no register function, this is now a requirement for registerable scripts." % mod.__file__)
_loaded.append(mod)
-
+
if reload_scripts:
# reload modules that may not be directly included
for type_class_name in dir(_bpy.types):
@@ -155,7 +156,7 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
for module_name in sorted(loaded_modules):
print("Reloading:", module_name)
test_reload(_sys.modules[module_name])
-
+
# loop over and unload all scripts
_loaded.reverse()
for mod in _loaded:
@@ -167,7 +168,7 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
traceback.print_exc()
_loaded[:] = []
- for base_path in script_paths(user = False):
+ for base_path in script_paths(user=False):
for path_subdir in ("ui", "op", "io", "cfg"):
path = _os.path.join(base_path, path_subdir)
if _os.path.isdir(path):
@@ -182,20 +183,20 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
path = _os.path.join(user_path, path_subdir)
if _os.path.isdir(path):
sys_path_ensure(path)
-
+
for mod in modules_from_path(path, loaded_modules):
test_register(mod)
- # load extensions
- used_ext = {ext.module for ext in _bpy.context.user_preferences.extensions}
- paths = script_paths("extensions")
+ # load addons
+ used_ext = {ext.module for ext in _bpy.context.user_preferences.addons}
+ paths = script_paths("addons")
for path in paths:
sys_path_ensure(path)
-
+
for module_name in sorted(used_ext):
mod = _test_import(module_name, loaded_modules)
test_register(mod)
-
+
if reload_scripts:
import gc
print("gc.collect() -> %d" % gc.collect())
@@ -262,16 +263,18 @@ def display_name(name):
_scripts = _os.path.join(_os.path.dirname(__file__), _os.path.pardir, _os.path.pardir)
_scripts = (_os.path.normpath(_scripts), )
+
def user_script_path():
path = _bpy.context.user_preferences.filepaths.python_scripts_directory
-
+
if path:
path = _os.path.normpath(path)
return path
else:
return None
-def script_paths(subdir = None, user = True):
+
+def script_paths(subdir=None, user=True):
"""
Returns a list of valid script paths from the home directory and user preferences.
@@ -284,7 +287,7 @@ def script_paths(subdir = None, user = True):
user_script_path = _bpy.context.user_preferences.filepaths.python_scripts_directory
else:
user_script_path = None
-
+
for path in home_paths("scripts") + (user_script_path, ):
if path:
path = _os.path.normpath(path)
diff --git a/release/scripts/modules/rigify/__init__.py b/release/scripts/modules/rigify/__init__.py
index 8cb7a926c06..895afd20d59 100644
--- a/release/scripts/modules/rigify/__init__.py
+++ b/release/scripts/modules/rigify/__init__.py
@@ -182,8 +182,7 @@ def generate_rig(context, obj_orig, prefix="ORG-", META_DEF=True):
try:
obj = scene.objects[name]
except KeyError:
- obj = bpy.data.objects.new(name, type='ARMATURE')
- obj.data = bpy.data.armatures.new(name)
+ obj = bpy.data.objects.new(name, bpy.data.armatures.new(name))
scene.objects.link(obj)
obj.data.pose_position = 'POSE'
@@ -487,9 +486,8 @@ def generate_test(context, metarig_type="", GENERATE_FINAL=True):
scene = context.scene
def create_empty_armature(name):
- obj_new = bpy.data.objects.new(name, 'ARMATURE')
armature = bpy.data.armatures.new(name)
- obj_new.data = armature
+ obj_new = bpy.data.objects.new(name, armature)
scene.objects.link(obj_new)
scene.objects.active = obj_new
for obj in scene.objects:
diff --git a/release/scripts/modules/rigify/leg_quadruped.py b/release/scripts/modules/rigify/leg_quadruped.py
index da27081930b..c21680740bd 100644
--- a/release/scripts/modules/rigify/leg_quadruped.py
+++ b/release/scripts/modules/rigify/leg_quadruped.py
@@ -130,6 +130,9 @@ def ik(obj, bone_definition, base_names, options):
# keep the foot_ik as the parent
ik_chain.toe_e.connected = False
+ # Foot uses pose space, not local space, for translation
+ ik_chain.foot_e.local_location = False
+
# must be after disconnecting the toe
ik_chain.foot_e.align_orientation(mt_chain.toe_e)
@@ -259,6 +262,8 @@ def ik(obj, bone_definition, base_names, options):
con = ik.foot_roll_01_p.constraints.new('COPY_ROTATION')
con.target = obj
con.subtarget = ik.foot_roll
+ con.target_space = 'LOCAL'
+ con.owner_space = 'LOCAL'
# IK
diff --git a/release/scripts/modules/rigify/mouth.py b/release/scripts/modules/rigify/mouth.py
index a30a8757d70..31d7c5a1ce9 100644
--- a/release/scripts/modules/rigify/mouth.py
+++ b/release/scripts/modules/rigify/mouth.py
@@ -197,23 +197,23 @@ def deform(obj, definitions, base_names, options):
con = pb[lip4].constraints.new('COPY_TRANSFORMS')
con.target = obj
con.subtarget = definitions[5]
-
+
con = pb[lip5].constraints.new('COPY_TRANSFORMS')
con.target = obj
con.subtarget = definitions[6]
-
+
con = pb[lip6].constraints.new('COPY_TRANSFORMS')
con.target = obj
con.subtarget = definitions[7]
-
+
con = pb[lip7].constraints.new('COPY_TRANSFORMS')
con.target = obj
con.subtarget = definitions[8]
-
+
con = pb[lip8].constraints.new('COPY_TRANSFORMS')
con.target = obj
con.subtarget = definitions[9]
-
+
# Constraint mouth corner spread bones
con = pb[spread_l_1].constraints.new('DAMPED_TRACK')
con.target = obj
@@ -234,12 +234,12 @@ def deform(obj, definitions, base_names, options):
con = pb[spread_r_2].constraints.new('COPY_TRANSFORMS')
con.target = obj
con.subtarget = spread_r_1
-
+
con = pb[spread_r_2].constraints.new('DAMPED_TRACK')
con.target = obj
con.subtarget = lip8
-
+
# Corrective shape keys for the corners of the mouth.
bpy.ops.object.mode_set(mode='EDIT')
diff --git a/release/scripts/modules/rigify/shape_key_transforms.py b/release/scripts/modules/rigify/shape_key_control.py
index 5b818d925cf..fd0e900a7b5 100644
--- a/release/scripts/modules/rigify/shape_key_transforms.py
+++ b/release/scripts/modules/rigify/shape_key_control.py
@@ -24,7 +24,7 @@ from rigify_utils import copy_bone_simple
from rna_prop_ui import rna_idprop_ui_prop_get
#METARIG_NAMES = ("cpy",)
-RIG_TYPE = "shape_key_transforms"
+RIG_TYPE = "shape_key_control"
def addget_shape_key(obj, name="Key"):
@@ -88,8 +88,11 @@ def metarig_definition(obj, orig_bone_name):
def main(obj, definitions, base_names, options):
- """ A rig that drives shape keys with the local transforms of a single bone.
-
+ """ A rig that drives shape keys with the local transforms and/or custom
+ properties of a single bone.
+ A different shape can be driven by the negative value of a transform as
+ well by giving a comma-separated list of two shapes.
+
Required options:
mesh: name of mesh object(s) to add/get shapekeys to/from
(if multiple objects, make a comma-separated list)
@@ -100,14 +103,17 @@ def main(obj, definitions, base_names, options):
rot_<x/y/z>_fac: default multiplier of the bone influence on the shape key
scale_<x/y/z>: name of the shape key to tie to scale of the bone
scale_<x/y/z>_fac: default multiplier of the bone influence on the shape key
+ shape_key_sliders: comma-separated list of custom properties to create sliders out of for driving shape keys
+ <custom_prop>: for each property listed in shape_key_sliders, specify a shape key for it to drive
+
"""
-
+
bpy.ops.object.mode_set(mode='EDIT')
eb = obj.data.edit_bones
pb = obj.pose.bones
org_bone = definitions[0]
-
+
# Options
req_options = ["mesh"]
for option in req_options:
@@ -115,11 +121,11 @@ def main(obj, definitions, base_names, options):
raise RigifyError("'%s' rig type requires a '%s' option (bone: %s)" % (RIG_TYPE, option, base_names[definitions[0]]))
meshes = options["mesh"].replace(" ", "").split(",")
-
+
bone = copy_bone_simple(obj.data, org_bone, base_names[org_bone], parent=True).name
-
+
bpy.ops.object.mode_set(mode='OBJECT')
-
+
# Set rotation mode and axis locks
pb[bone].rotation_mode = pb[org_bone].rotation_mode
pb[bone].lock_location = tuple(pb[org_bone].lock_location)
@@ -127,10 +133,10 @@ def main(obj, definitions, base_names, options):
pb[bone].lock_rotation_w = pb[org_bone].lock_rotation_w
pb[bone].lock_rotations_4d = pb[org_bone].lock_rotations_4d
pb[bone].lock_scale = tuple(pb[org_bone].lock_scale)
-
+
# List of rig options for specifying shape keys
- # Append '_fac' to the end for the name of the correspond 'factor default'
- # option for that shape
+ # Append '_fac' to the end for the name of the corresponding 'factor
+ # default' option for that shape
shape_key_options = ["loc_x",
"loc_y",
"loc_z",
@@ -140,7 +146,7 @@ def main(obj, definitions, base_names, options):
"scale_x",
"scale_y",
"scale_z"]
-
+
driver_paths = {"loc_x":".location[0]",
"loc_y":".location[1]",
"loc_z":".location[2]",
@@ -153,76 +159,146 @@ def main(obj, definitions, base_names, options):
"scale_x":".scale[0]",
"scale_y":".scale[1]",
"scale_z":".scale[2]"}
-
- # Create the shape keys and drivers
+
+ # Create the shape keys and drivers for transforms
shape_info = []
for option in shape_key_options:
if option in options:
- shape_name = options[option]
-
- var_name = bone + "_" + option
- # Different paths for euler vs quat
- if option in shape_key_options[3:6] and pb[bone].rotation_mode == 'QUATERNION':
+ shape_names = options[option].replace(" ", "").split(",")
+
+ var_name = bone.replace(".","").replace("-","_") + "_" + option
+ # Different RNA paths for euler vs quat
+ if option in (shape_key_options[3:6]+shape_key_options[12:15]) \
+ and pb[bone].rotation_mode == 'QUATERNION':
var_path = driver_paths['q' + option]
else:
var_path = driver_paths[option]
-
- fac_name = option + "_factor"
+
if (option+"_fac") in options:
- fac_default = options[option+"_fac"]
+ fac = options[option+"_fac"]
else:
- fac_default = 1.0
-
- # Different expressions for loc/rot/scale
- if option in shape_key_options[:3]:
- expression = var_name + " * " + fac_name
- elif option in shape_key_options[:6]:
- # Different expressions for euler vs quats
- if pb[bone].rotation_mode == 'QUATERNION':
- expression = "2 * asin(" + var_name + ") * " + fac_name
- else:
- expression = var_name + " * " + fac_name
- else:
- expression = "(1.0 - " + var_name + ") * " + fac_name + " * -2"
-
- create_shape_and_driver(obj, bone, meshes, shape_name, var_name, var_path, fac_name, fac_default, expression)
-
+ fac = 1.0
+
+ # Positive
+ if shape_names[0] != "":
+ # Different expressions for loc/rot/scale and positive/negative
+ if option in shape_key_options[:3]:
+ # Location
+ expression = var_name + " * " + str(fac)
+ elif option in shape_key_options[3:6]:
+ # Rotation
+ # Different expressions for euler vs quats
+ if pb[bone].rotation_mode == 'QUATERNION':
+ expression = "2 * asin(" + var_name + ") * " + str(fac)
+ else:
+ expression = var_name + " * " + str(fac)
+ elif option in shape_key_options[6:9]:
+ # Scale
+ expression = "(1.0 - " + var_name + ") * " + str(fac) + " * -2"
+ shape_name = shape_names[0]
+ create_shape_and_driver(obj, bone, meshes, shape_name, var_name, var_path, expression)
+
+ # Negative
+ if shape_names[0] != "" and len(shape_names) > 1:
+ # Different expressions for loc/rot/scale and positive/negative
+ if option in shape_key_options[:3]:
+ # Location
+ expression = var_name + " * " + str(fac) + " * -1"
+ elif option in shape_key_options[3:6]:
+ # Rotation
+ # Different expressions for euler vs quats
+ if pb[bone].rotation_mode == 'QUATERNION':
+ expression = "-2 * asin(" + var_name + ") * " + str(fac)
+ else:
+ expression = var_name + " * " + str(fac) + " * -1"
+ elif option in shape_key_options[6:9]:
+ # Scale
+ expression = "(1.0 - " + var_name + ") * " + str(fac) + " * 2"
+ shape_name = shape_names[1]
+ create_shape_and_driver(obj, bone, meshes, shape_name, var_name, var_path, expression)
+
+ # Create the shape keys and drivers for custom-property sliders
+ if "shape_key_sliders" in options:
+ # Get the slider names
+ slider_names = options["shape_key_sliders"].replace(" ", "").split(",")
+ if slider_names[0] != "":
+ # Loop through the slider names and check if they have
+ # shape keys specified for them, and if so, set them up.
+ for slider_name in slider_names:
+ if slider_name in options:
+ shape_names = options[slider_name].replace(" ", "").split(",")
+
+ # Set up the custom property on the bone
+ prop = rna_idprop_ui_prop_get(pb[bone], slider_name, create=True)
+ pb[bone][slider_name] = 0.0
+ prop["min"] = 0.0
+ prop["max"] = 1.0
+ prop["soft_min"] = 0.0
+ prop["soft_max"] = 1.0
+ if len(shape_names) > 1:
+ prop["min"] = -1.0
+ prop["soft_min"] = -1.0
+
+ # Add the shape drivers
+ # Positive
+ if shape_names[0] != "":
+ # Set up the variables for creating the shape key driver
+ shape_name = shape_names[0]
+ var_name = slider_name.replace(".", "_").replace("-", "_")
+ var_path = '["' + slider_name + '"]'
+ if slider_name + "_fac" in options:
+ fac = options[slider_name + "_fac"]
+ else:
+ fac = 1.0
+ expression = var_name + " * " + str(fac)
+ # Create the shape key driver
+ create_shape_and_driver(obj, bone, meshes, shape_name, var_name, var_path, expression)
+ # Negative
+ if shape_names[0] != "" and len(shape_names) > 1:
+ # Set up the variables for creating the shape key driver
+ shape_name = shape_names[1]
+ var_name = slider_name.replace(".", "_").replace("-", "_")
+ var_path = '["' + slider_name + '"]'
+ if slider_name + "_fac" in options:
+ fac = options[slider_name + "_fac"]
+ else:
+ fac = 1.0
+ expression = var_name + " * " + str(fac) + " * -1"
+ # Create the shape key driver
+ create_shape_and_driver(obj, bone, meshes, shape_name, var_name, var_path, expression)
+
+
+ # Org bone copy transforms of control bone
+ con = pb[org_bone].constraints.new('COPY_TRANSFORMS')
+ con.target = obj
+ con.subtarget = bone
+
return (None,)
-def create_shape_and_driver(obj, bone, meshes, shape_name, var_name, var_path, fac_name, fac_default, expression):
+def create_shape_and_driver(obj, bone, meshes, shape_name, var_name, var_path, expression):
""" Creates/gets a shape key and sets up a driver for it.
-
+
obj = armature object
bone = driving bone name
meshes = list of meshes to create the shapekey/driver on
shape_name = name of the shape key
var_name = name of the driving variable
var_path = path to the property on the bone to drive with
- fac_name = name of the "factor" custom property on the bone
- fac_default = default starting value of the factor property
expression = python expression for the driver
"""
pb = obj.pose.bones
bpy.ops.object.mode_set(mode='OBJECT')
-
- # Set up the "factor" custom property on the bone
- prop = rna_idprop_ui_prop_get(pb[bone], fac_name, create=True)
- pb[bone][fac_name] = fac_default
- prop["min"] = -1000.0
- prop["max"] = 1000.0
- prop["soft_min"] = -1000.0
- prop["soft_max"] = 1000.0
-
+
for mesh_name in meshes:
mesh_obj = bpy.data.objects[mesh_name]
-
+
# Add/get the shape key
shape = addget_shape_key(mesh_obj, name=shape_name)
-
+
# Add/get the shape key driver
fcurve, a = addget_shape_key_driver(mesh_obj, name=shape_name)
-
+
# Set up the driver
driver = fcurve.driver
driver.type = 'SCRIPTED'
@@ -234,23 +310,11 @@ def create_shape_and_driver(obj, bone, meshes, shape_name, var_name, var_path, f
else:
var = driver.variables.new()
var.name = var_name
-
- # Get the fac variable, or create it if it doesn't already exist
- if fac_name in driver.variables:
- var_fac = driver.variables[fac_name]
- else:
- var_fac = driver.variables.new()
- var_fac.name = fac_name
# Set up the variable
var.type = "SINGLE_PROP"
var.targets[0].id_type = 'OBJECT'
var.targets[0].id = obj
var.targets[0].data_path = 'pose.bones["' + bone + '"]' + var_path
-
- # Set up the fac variable
- var_fac.type = "SINGLE_PROP"
- var_fac.targets[0].id_type = 'OBJECT'
- var_fac.targets[0].id = obj
- var_fac.targets[0].data_path = 'pose.bones["' + bone + '"]["' + fac_name + '"]'
-
+
+
diff --git a/release/scripts/modules/rigify/tail_control.py b/release/scripts/modules/rigify/tail_control.py
index f33b51e9690..56305b5e07e 100644
--- a/release/scripts/modules/rigify/tail_control.py
+++ b/release/scripts/modules/rigify/tail_control.py
@@ -41,7 +41,7 @@ def metarig_template():
#bone.tail[:] = 0.0000, -0.0306, -0.0159
#bone.roll = 0.0000
#bone.connected = False
-
+
#bpy.ops.object.mode_set(mode='OBJECT')
#pbone = obj.pose.bones['tail.01']
#pbone['type'] = 'tail_spline_ik'
@@ -72,13 +72,13 @@ def main(obj, bone_definitions, base_names, options):
bb = obj.data.bones
eb = obj.data.edit_bones
pb = obj.pose.bones
-
+
# Create bones for hinge/free
# hinge 1 sticks with the parent
# hinge 2 is the parent of the tail controls
hinge1 = copy_bone_simple(arm, bone_definitions[0], "MCH-%s.hinge1" % base_names[bone_definitions[0]], parent=True).name
hinge2 = copy_bone_simple(arm, bone_definitions[0], "MCH-%s.hinge2" % base_names[bone_definitions[0]], parent=False).name
-
+
# Create tail control bones
bones = []
i = 0
@@ -90,10 +90,10 @@ def main(obj, bone_definitions, base_names, options):
eb[bone].local_location = False
i = 1
bones += [bone]
-
-
+
+
bpy.ops.object.mode_set(mode='OBJECT')
-
+
# Rotation mode and axis locks
for bone, org_bone in zip(bones, bone_definitions):
pb[bone].rotation_mode = pb[org_bone].rotation_mode
@@ -102,7 +102,7 @@ def main(obj, bone_definitions, base_names, options):
pb[bone].lock_rotation = tuple(pb[org_bone].lock_rotation)
pb[bone].lock_rotation_w = pb[org_bone].lock_rotation_w
pb[bone].lock_scale = tuple(pb[org_bone].lock_scale)
-
+
# Add custom properties
pb[bones[0]]["hinge"] = 0.0
prop = rna_idprop_ui_prop_get(pb[bones[0]], "hinge", create=True)
@@ -110,31 +110,31 @@ def main(obj, bone_definitions, base_names, options):
prop["max"] = 1.0
prop["soft_min"] = 0.0
prop["soft_max"] = 1.0
-
+
pb[bones[0]]["free"] = 0.0
prop = rna_idprop_ui_prop_get(pb[bones[0]], "free", create=True)
prop["min"] = 0.0
prop["max"] = 1.0
prop["soft_min"] = 0.0
prop["soft_max"] = 1.0
-
+
# Add constraints
for bone, org_bone in zip(bones, bone_definitions):
con = pb[org_bone].constraints.new('COPY_TRANSFORMS')
con.target = obj
con.subtarget = bone
-
+
con_f = pb[hinge2].constraints.new('COPY_LOCATION')
con_f.target = obj
con_f.subtarget = hinge1
-
+
con_h = pb[hinge2].constraints.new('COPY_TRANSFORMS')
con_h.target = obj
con_h.subtarget = hinge1
-
+
# Add drivers
bone_path = pb[bones[0]].path_to_id()
-
+
driver_fcurve = con_f.driver_add("influence", 0)
driver = driver_fcurve.driver
driver.type = 'AVERAGE'
@@ -147,7 +147,7 @@ def main(obj, bone_definitions, base_names, options):
mod.poly_order = 1
mod.coefficients[0] = 1.0
mod.coefficients[1] = -1.0
-
+
driver_fcurve = con_h.driver_add("influence", 0)
driver = driver_fcurve.driver
driver.type = 'AVERAGE'
@@ -160,7 +160,7 @@ def main(obj, bone_definitions, base_names, options):
mod.poly_order = 1
mod.coefficients[0] = 1.0
mod.coefficients[1] = -1.0
-
-
+
+
return None
-
+
diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py
index a25cf5ddd76..246fa4bdb7d 100644
--- a/release/scripts/modules/rna_prop_ui.py
+++ b/release/scripts/modules/rna_prop_ui.py
@@ -164,10 +164,6 @@ class WM_OT_properties_edit(bpy.types.Operator):
max = rna_max
description = StringProperty(name="Tip", default="")
- # the class instance is not persistant, need to store in the class
- # not ideal but changes as the op runs.
- _last_prop = ['']
-
def execute(self, context):
path = self.properties.path
value = self.properties.value
@@ -179,9 +175,6 @@ class WM_OT_properties_edit(bpy.types.Operator):
except:
value_eval = value
- if type(value_eval) == str:
- value_eval = '"' + value_eval + '"'
-
# First remove
item = eval("context.%s" % path)
@@ -192,7 +185,7 @@ class WM_OT_properties_edit(bpy.types.Operator):
# Reassign
- exec_str = "item['%s'] = %s" % (prop, value_eval)
+ exec_str = "item['%s'] = %s" % (prop, repr(value_eval))
# print(exec_str)
exec(exec_str)
self._last_prop[:] = [prop]
@@ -212,7 +205,7 @@ class WM_OT_properties_edit(bpy.types.Operator):
def invoke(self, context, event):
- self._last_prop[:] = [self.properties.property]
+ self._last_prop = [self.properties.property]
item = eval("context.%s" % self.properties.path)
diff --git a/release/scripts/op/add_mesh_torus.py b/release/scripts/op/add_mesh_torus.py
index 860ac93954a..4dae80cd9d6 100644
--- a/release/scripts/op/add_mesh_torus.py
+++ b/release/scripts/op/add_mesh_torus.py
@@ -130,8 +130,7 @@ class AddTorus(bpy.types.Operator):
ob.selected = False
mesh.update()
- ob_new = bpy.data.objects.new("Torus", 'MESH')
- ob_new.data = mesh
+ ob_new = bpy.data.objects.new("Torus", mesh)
scene.objects.link(ob_new)
ob_new.selected = True
@@ -166,10 +165,10 @@ def register():
bpy.types.register(AddTorus)
bpy.types.INFO_MT_mesh_add.append(menu_func)
+
def unregister():
bpy.types.unregister(AddTorus)
bpy.types.INFO_MT_mesh_add.remove(menu_func)
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/op/console_python.py b/release/scripts/op/console_python.py
index 5382781e882..587e9f619bc 100644
--- a/release/scripts/op/console_python.py
+++ b/release/scripts/op/console_python.py
@@ -166,7 +166,7 @@ def autocomplete(context):
# Separate automplete output by command prompts
if scrollback != '':
- bpy.ops.console.scrollback_append(text=sc.prompt + current_line.line, type='INPUT')
+ bpy.ops.console.scrollback_append(text=sc.prompt + current_line.line, type='INPUT')
# Now we need to copy back the line from blender back into the
# text editor. This will change when we dont use the text editor
@@ -201,12 +201,14 @@ def banner(context):
return {'FINISHED'}
+
def register():
pass
+
def unregister():
pass
+
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/op/console_shell.py b/release/scripts/op/console_shell.py
index 22067ce749e..e269cc0bb2f 100644
--- a/release/scripts/op/console_shell.py
+++ b/release/scripts/op/console_shell.py
@@ -81,9 +81,9 @@ def banner(context):
def register():
pass
+
def unregister():
pass
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/op/fcurve_euler_filter.py b/release/scripts/op/fcurve_euler_filter.py
index 225d2479950..1c9e9a73312 100644
--- a/release/scripts/op/fcurve_euler_filter.py
+++ b/release/scripts/op/fcurve_euler_filter.py
@@ -5,19 +5,19 @@ from Mathutils import *
def main(context):
def cleanupEulCurve(fcv):
keys = []
-
+
for k in fcv.keyframe_points:
- keys.append([k.handle1.copy(), k.co.copy(), k.handle2.copy()])
+ keys.append([k.handle1.copy(), k.co.copy(), k.handle2.copy()])
print(keys)
-
+
for i in range(len(keys)):
cur = keys[i]
prev = keys[i-1] if i > 0 else None
next = keys[i+1] if i < len(keys)-1 else None
-
+
if prev == None:
continue
-
+
th = pi
if abs(prev[1][1] - cur[1][1]) >= th: # more than 180 degree jump
fac = pi*2
@@ -31,13 +31,13 @@ def main(context):
cur[0][1] -= fac
cur[1][1] -= fac
cur[2][1] -= fac
-
+
for i in range(len(keys)):
for x in range(2):
fcv.keyframe_points[i].handle1[x] = keys[i][0][x]
fcv.keyframe_points[i].co[x] = keys[i][1][x]
fcv.keyframe_points[i].handle2[x] = keys[i][2][x]
-
+
flist = bpy.context.active_object.animation_data.action.fcurves
for f in flist:
if f.selected and f.data_path.endswith("rotation_euler"):
@@ -45,7 +45,7 @@ def main(context):
class DiscontFilterOp(bpy.types.Operator):
"""Fixes the most common causes of gimbal lock in the fcurves of the active bone"""
- bl_idname = "graph.discont_filter"
+ bl_idname = "graph.euler_filter"
bl_label = "Filter out discontinuities in the active fcurves"
def poll(self, context):
@@ -63,4 +63,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/op/image.py b/release/scripts/op/image.py
index 0db0590312a..9cf335be714 100644
--- a/release/scripts/op/image.py
+++ b/release/scripts/op/image.py
@@ -38,16 +38,16 @@ class SaveDirty(bpy.types.Operator):
self.report({'WARNING'}, "Path used by more then one image: " + path)
else:
unique_paths.add(path)
- image.save(path=path)
+ image.save()
return {'FINISHED'}
def register():
bpy.types.register(SaveDirty)
+
def unregister():
bpy.types.unregister(SaveDirty)
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/op/mesh.py b/release/scripts/op/mesh.py
index bda87261c3e..5eda8187f00 100644
--- a/release/scripts/op/mesh.py
+++ b/release/scripts/op/mesh.py
@@ -185,6 +185,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -192,4 +193,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/op/object.py b/release/scripts/op/object.py
index cb243e66e29..b9bd3cb6459 100644
--- a/release/scripts/op/object.py
+++ b/release/scripts/op/object.py
@@ -96,6 +96,48 @@ class SelectCamera(bpy.types.Operator):
return {'FINISHED'}
+class SelectHierarchy(bpy.types.Operator):
+ '''Select object relative to the active objects position in the hierarchy'''
+ bl_idname = "object.select_hierarchy"
+ bl_label = "Select Hierarchy"
+ bl_register = True
+ bl_undo = True
+
+ direction = EnumProperty(items=(
+ ('PARENT', "Parent", ""),
+ ('CHILD', "Child", "")),
+ name="Direction",
+ description="Direction to select in the hierarchy",
+ default='PARENT')
+
+ extend = BoolProperty(name="Extend", description="Extend the existing selection", default=False)
+
+ def poll(self, context):
+ return context.object
+
+ def execute(self, context):
+ obj = context.object
+ if self.properties.direction == 'PARENT':
+ parent = obj.parent
+ if not parent:
+ return {'CANCELLED'}
+ obj_act = parent
+ else:
+ children = obj.children
+ if len(children) != 1:
+ return {'CANCELLED'}
+ obj_act = children[0]
+
+ if not self.properties.extend:
+ # obj.selected = False
+ bpy.ops.object.select_all(action='DESELECT')
+
+ obj_act.selected = True
+ context.scene.objects.active = obj_act
+
+ return {'FINISHED'}
+
+
class SubdivisionSet(bpy.types.Operator):
'''Sets a Subdivision Surface Level (1-5)'''
@@ -336,7 +378,7 @@ class ShapeTransfer(bpy.types.Operator):
self.report({'ERROR'}, "Expected one other selected mesh object to copy from")
return {'CANCELLED'}
ob_act, objects = objects[0], [ob_act]
-
+
if ob_act.type != 'MESH':
self.report({'ERROR'}, "Other object is not a mesh.")
return {'CANCELLED'}
@@ -344,7 +386,7 @@ class ShapeTransfer(bpy.types.Operator):
if ob_act.active_shape_key is None:
self.report({'ERROR'}, "Other object has no shape key")
return {'CANCELLED'}
- return self._main(ob_act, objects, self.properties.mode, self.properties.use_clamp)
+ return self._main(ob_act, objects, self.properties.mode, self.properties.use_clamp)
class JoinUVs(bpy.types.Operator):
'''Copy UV Layout to objects with matching geometry'''
@@ -424,7 +466,7 @@ class MakeDupliFace(bpy.types.Operator):
# scale = matrix.median_scale
trans = matrix.translation_part()
rot = matrix.rotation_part() # also contains scale
-
+
return [(rot * b) + trans for b in base_tri]
scene = bpy.context.scene
linked = {}
@@ -444,22 +486,20 @@ class MakeDupliFace(bpy.types.Operator):
mesh.faces.foreach_set("verts_raw", faces)
mesh.update() # generates edge data
- # pick an object to use
+ # pick an object to use
obj = objects[0]
- ob_new = bpy.data.objects.new(mesh.name, 'MESH')
- ob_new.data = mesh
+ ob_new = bpy.data.objects.new(mesh.name, mesh)
base = scene.objects.link(ob_new)
base.layers[:] = obj.layers
-
- ob_inst = bpy.data.objects.new(data.name, obj.type)
- ob_inst.data = data
+
+ ob_inst = bpy.data.objects.new(data.name, data)
base = scene.objects.link(ob_inst)
base.layers[:] = obj.layers
-
+
for obj in objects:
scene.objects.unlink(obj)
-
+
ob_new.dupli_type = 'FACES'
ob_inst.parent = ob_new
ob_new.use_dupli_faces_scale = True
@@ -473,6 +513,7 @@ class MakeDupliFace(bpy.types.Operator):
classes = [
SelectPattern,
SelectCamera,
+ SelectHierarchy,
SubdivisionSet,
ShapeTransfer,
JoinUVs,
diff --git a/release/scripts/op/object_align.py b/release/scripts/op/object_align.py
index e7c2f219471..5abef11b980 100644
--- a/release/scripts/op/object_align.py
+++ b/release/scripts/op/object_align.py
@@ -28,42 +28,42 @@ def align_objects(align_x, align_y, align_z, align_mode, relative_to):
Left_Up_Front_SEL = [[],[],[]]
Right_Down_Back_SEL = [[],[],[]]
-
+
flag_first = True
-
+
for obj in bpy.context.selected_objects:
if obj.type == 'MESH':
-
+
bb_world = [obj.matrix * Vector(v[:]) for v in obj.bound_box]
-
+
Left_Up_Front = bb_world[1]
Right_Down_Back = bb_world[7]
-
+
# Active Center
-
+
if obj == bpy.context.active_object:
-
+
center_active_x = ( Left_Up_Front[0] + Right_Down_Back[0] ) / 2
center_active_y = ( Left_Up_Front[1] + Right_Down_Back[1] ) / 2
center_active_z = ( Left_Up_Front[2] + Right_Down_Back[2] ) / 2
-
+
size_active_x = ( Right_Down_Back[0] - Left_Up_Front[0] ) / 2
size_active_y = ( Right_Down_Back[1] - Left_Up_Front[1] ) / 2
size_active_z = ( Left_Up_Front[2] - Right_Down_Back[2] ) / 2
-
+
# Selection Center
-
+
if flag_first:
flag_first = False
-
+
Left_Up_Front_SEL[0] = Left_Up_Front[0]
Left_Up_Front_SEL[1] = Left_Up_Front[1]
Left_Up_Front_SEL[2] = Left_Up_Front[2]
-
+
Right_Down_Back_SEL[0] = Right_Down_Back[0]
Right_Down_Back_SEL[1] = Right_Down_Back[1]
Right_Down_Back_SEL[2] = Right_Down_Back[2]
-
+
else:
# X axis
if Left_Up_Front[0] < Left_Up_Front_SEL[0]:
@@ -74,7 +74,7 @@ def align_objects(align_x, align_y, align_z, align_mode, relative_to):
# Z axis
if Left_Up_Front[2] > Left_Up_Front_SEL[2]:
Left_Up_Front_SEL[2] = Left_Up_Front[2]
-
+
# X axis
if Right_Down_Back[0] > Right_Down_Back_SEL[0]:
Right_Down_Back_SEL[0] = Right_Down_Back[0]
@@ -84,7 +84,7 @@ def align_objects(align_x, align_y, align_z, align_mode, relative_to):
# Z axis
if Right_Down_Back[2] < Right_Down_Back_SEL[2]:
Right_Down_Back_SEL[2] = Right_Down_Back[2]
-
+
center_sel_x = ( Left_Up_Front_SEL[0] + Right_Down_Back_SEL[0] ) / 2
center_sel_y = ( Left_Up_Front_SEL[1] + Right_Down_Back_SEL[1] ) / 2
center_sel_z = ( Left_Up_Front_SEL[2] + Right_Down_Back_SEL[2] ) / 2
@@ -93,143 +93,144 @@ def align_objects(align_x, align_y, align_z, align_mode, relative_to):
for obj in bpy.context.selected_objects:
if obj.type == 'MESH':
-
+
loc_world = obj.location
bb_world = [obj.matrix * Vector(v[:]) for v in obj.bound_box]
-
+
Left_Up_Front = bb_world[1]
Right_Down_Back = bb_world[7]
-
+
center_x = ( Left_Up_Front[0] + Right_Down_Back[0] ) / 2
center_y = ( Left_Up_Front[1] + Right_Down_Back[1] ) / 2
center_z = ( Left_Up_Front[2] + Right_Down_Back[2] ) / 2
-
+
positive_x = Right_Down_Back[0]
positive_y = Right_Down_Back[1]
positive_z = Left_Up_Front[2]
-
+
negative_x = Left_Up_Front[0]
negative_y = Left_Up_Front[1]
negative_z = Right_Down_Back[2]
-
+
obj_loc = obj.location
-
+
if align_x:
-
+
# Align Mode
-
+
if relative_to == 'OPT_4': # Active relative
if align_mode == 'OPT_1':
obj_x = obj_loc[0] - negative_x - size_active_x
-
+
elif align_mode == 'OPT_3':
obj_x = obj_loc[0] - positive_x + size_active_x
-
+
else: # Everything else relative
if align_mode == 'OPT_1':
obj_x = obj_loc[0] - negative_x
-
+
elif align_mode == 'OPT_3':
obj_x = obj_loc[0] - positive_x
-
+
if align_mode == 'OPT_2': # All relative
obj_x = obj_loc[0] - center_x
-
+
# Relative To
-
+
if relative_to == 'OPT_1':
loc_x = obj_x
-
+
elif relative_to == 'OPT_2':
loc_x = obj_x + cursor[0]
-
+
elif relative_to == 'OPT_3':
loc_x = obj_x + center_sel_x
-
+
elif relative_to == 'OPT_4':
loc_x = obj_x + center_active_x
-
+
obj.location[0] = loc_x
-
-
+
+
if align_y:
-
+
# Align Mode
-
+
if relative_to == 'OPT_4': # Active relative
if align_mode == 'OPT_1':
obj_y = obj_loc[1] - negative_y - size_active_y
-
+
elif align_mode == 'OPT_3':
obj_y = obj_loc[1] - positive_y + size_active_y
-
+
else: # Everything else relative
if align_mode == 'OPT_1':
obj_y = obj_loc[1] - negative_y
-
+
elif align_mode == 'OPT_3':
obj_y = obj_loc[1] - positive_y
-
+
if align_mode == 'OPT_2': # All relative
obj_y = obj_loc[1] - center_y
-
+
# Relative To
-
+
if relative_to == 'OPT_1':
loc_y = obj_y
-
+
elif relative_to == 'OPT_2':
loc_y = obj_y + cursor[1]
-
+
elif relative_to == 'OPT_3':
loc_y = obj_y + center_sel_y
-
+
elif relative_to == 'OPT_4':
loc_y = obj_y + center_active_y
-
+
obj.location[1] = loc_y
-
-
+
+
if align_z:
-
+
# Align Mode
-
+
if relative_to == 'OPT_4': # Active relative
if align_mode == 'OPT_1':
obj_z = obj_loc[2] - negative_z - size_active_z
-
+
elif align_mode == 'OPT_3':
obj_z = obj_loc[2] - positive_z + size_active_z
-
+
else: # Everything else relative
if align_mode == 'OPT_1':
obj_z = obj_loc[2] - negative_z
-
+
elif align_mode == 'OPT_3':
obj_z = obj_loc[2] - positive_z
-
+
if align_mode == 'OPT_2': # All relative
obj_z = obj_loc[2] - center_z
-
+
# Relative To
-
+
if relative_to == 'OPT_1':
loc_z = obj_z
-
+
elif relative_to == 'OPT_2':
loc_z = obj_z + cursor[2]
-
+
elif relative_to == 'OPT_3':
loc_z = obj_z + center_sel_z
-
+
elif relative_to == 'OPT_4':
loc_z = obj_z + center_active_z
-
+
obj.location[2] = loc_z
from bpy.props import *
+
class AlignObjects(bpy.types.Operator):
'''Align Objects'''
bl_idname = "object.align"
@@ -265,8 +266,11 @@ class AlignObjects(bpy.types.Operator):
align_z = BoolProperty(name="Align Z",
description="Align in the Z axis", default=False)
+ def poll(self, context):
+ return context.mode == 'OBJECT'
+
def execute(self, context):
-
+
align_mode = self.properties.align_mode
relative_to = self.properties.relative_to
align_x = self.properties.align_x
@@ -288,6 +292,7 @@ def register():
bpy.types.register(AlignObjects)
bpy.types.VIEW3D_MT_transform.append(menu_func)
+
def unregister():
bpy.types.unregister(AlignObjects)
bpy.types.VIEW3D_MT_transform.remove(menu_func)
diff --git a/release/scripts/op/object_randomize_transform.py b/release/scripts/op/object_randomize_transform.py
index a79941fc26c..71961404a69 100644
--- a/release/scripts/op/object_randomize_transform.py
+++ b/release/scripts/op/object_randomize_transform.py
@@ -144,10 +144,10 @@ def register():
bpy.types.register(RandomizeLocRotSize)
bpy.types.VIEW3D_MT_transform.append(menu_func)
+
def unregister():
bpy.types.unregister(RandomizeLocRotSize)
bpy.types.VIEW3D_MT_transform.remove(menu_func)
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/op/presets.py b/release/scripts/op/presets.py
index d201f553ec2..1a8e57f7c32 100644
--- a/release/scripts/op/presets.py
+++ b/release/scripts/op/presets.py
@@ -75,16 +75,16 @@ class AddPresetRender(AddPresetBase):
name = AddPresetBase.name
preset_values = [
- "bpy.context.scene.render_data.resolution_x",
- "bpy.context.scene.render_data.resolution_y",
- "bpy.context.scene.render_data.pixel_aspect_x",
- "bpy.context.scene.render_data.pixel_aspect_y",
- "bpy.context.scene.render_data.fps",
- "bpy.context.scene.render_data.fps_base",
- "bpy.context.scene.render_data.resolution_percentage",
- "bpy.context.scene.render_data.fields",
- "bpy.context.scene.render_data.field_order",
- "bpy.context.scene.render_data.fields_still",
+ "bpy.context.scene.render.resolution_x",
+ "bpy.context.scene.render.resolution_y",
+ "bpy.context.scene.render.pixel_aspect_x",
+ "bpy.context.scene.render.pixel_aspect_y",
+ "bpy.context.scene.render.fps",
+ "bpy.context.scene.render.fps_base",
+ "bpy.context.scene.render.resolution_percentage",
+ "bpy.context.scene.render.fields",
+ "bpy.context.scene.render.field_order",
+ "bpy.context.scene.render.fields_still",
]
preset_subdir = "render"
@@ -170,6 +170,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -177,4 +178,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/op/screen_play_rendered_anim.py b/release/scripts/op/screen_play_rendered_anim.py
index 1f9b84bd8cf..53742ed41b1 100644
--- a/release/scripts/op/screen_play_rendered_anim.py
+++ b/release/scripts/op/screen_play_rendered_anim.py
@@ -68,8 +68,8 @@ class PlayRenderedAnim(bpy.types.Operator):
bl_undo = False
def execute(self, context):
- sce = context.scene
- rd = sce.render_data
+ scene = context.scene
+ rd = scene.render
prefs = context.user_preferences
preset = prefs.filepaths.animation_player_preset
@@ -86,7 +86,7 @@ class PlayRenderedAnim(bpy.types.Operator):
file = ''.join([(c if file_b[i] == c else "#") for i, c in enumerate(file_a)])
else:
# works for movies and images
- file = rd.frame_path(frame=sce.start_frame)
+ file = rd.frame_path(frame=scene.start_frame)
cmd = [player_path]
# extra options, fps controls etc.
@@ -97,7 +97,7 @@ class PlayRenderedAnim(bpy.types.Operator):
opts = [file, "-playback_speed", str(rd.fps)]
cmd.extend(opts)
elif preset == 'FRAMECYCLER':
- opts = [file, "%d-%d" % (sce.start_frame, sce.end_frame)]
+ opts = [file, "%d-%d" % (scene.start_frame, scene.end_frame)]
cmd.extend(opts)
elif preset == 'RV':
opts = ["-fps", str(rd.fps), "-play", "[ %s ]" % file]
@@ -112,12 +112,13 @@ class PlayRenderedAnim(bpy.types.Operator):
pass
#raise OSError("Couldn't find an external animation player.")
- return('FINISHED',)
+ return {'FINISHED'}
def register():
bpy.types.register(PlayRenderedAnim)
+
def unregister():
bpy.types.unregister(PlayRenderedAnim)
diff --git a/release/scripts/op/uv.py b/release/scripts/op/uv.py
index f2a7495bbaa..35a20a002a8 100644
--- a/release/scripts/op/uv.py
+++ b/release/scripts/op/uv.py
@@ -39,7 +39,7 @@ class ExportUVLayout(bpy.types.Operator):
name="Format",
description="File format to export the UV layout to",
default='SVG')
-
+
def poll(self, context):
obj = context.active_object
return (obj and obj.type == 'MESH')
@@ -71,18 +71,18 @@ class ExportUVLayout(bpy.types.Operator):
mesh = obj.data
uv_layer = mesh.active_uv_texture.data
uv_layer_len = len(uv_layer)
-
+
if not self.properties.export_all:
-
+
local_image = Ellipsis
if context.tool_settings.uv_local_view:
space_data = self._space_image(context)
if space_data:
local_image = space_data.image
-
+
faces = mesh.faces
-
+
for i in range(uv_layer_len):
uv_elem = uv_layer[i]
# context checks
@@ -90,16 +90,13 @@ class ExportUVLayout(bpy.types.Operator):
#~ uv = uv_elem.uv
#~ if False not in uv_elem.uv_selected[:len(uv)]:
#~ yield (i, uv)
-
+
# just write what we see.
yield (i, uv_layer[i].uv)
else:
# all, simple
for i in range(uv_layer_len):
yield (i, uv_layer[i].uv)
-
-
-
def execute(self, context):
# for making an XML compatible string
@@ -116,7 +113,7 @@ class ExportUVLayout(bpy.types.Operator):
faces = mesh.faces
mode = self.properties.mode
-
+
file = open(self.properties.path, "w")
fw = file.write
@@ -129,13 +126,13 @@ class ExportUVLayout(bpy.types.Operator):
fw(' xmlns="http://www.w3.org/2000/svg" version="1.1">\n')
desc = "%s, %s, %s (Blender %s)" % (basename(bpy.data.filename), obj.name, mesh.name, bpy.app.version_string)
fw('<desc>%s</desc>\n' % escape(desc))
-
+
# svg colors
fill_settings = []
fill_default = 'fill="grey"'
for mat in mesh.materials if mesh.materials else [None]:
if mat:
- fill_settings.append('fill="rgb(%d, %d, %d)"' % tuple(int(c*255) for c in mat.diffuse_color))
+ fill_settings.append('fill="rgb(%d, %d, %d)"' % tuple(int(c * 255) for c in mat.diffuse_color))
else:
fill_settings.append(fill_default)
@@ -144,10 +141,10 @@ class ExportUVLayout(bpy.types.Operator):
fill = fill_settings[faces[i].material_index]
except IndexError:
fill = fill_default
-
+
fw('<polygon %s fill-opacity="0.5" stroke="black" stroke-width="1px" \n' % fill)
fw(' points="')
-
+
for j, uv in enumerate(uvs):
x, y = uv[0], 1.0 - uv[1]
fw('%.3f,%.3f ' % (x * image_width, y * image_height))
@@ -172,15 +169,15 @@ class ExportUVLayout(bpy.types.Operator):
fw('1 setlinejoin\n')
fw('1 setlinecap\n')
fw('newpath\n')
-
+
for i, uvs in self._face_uv_iter(context):
for j, uv in enumerate(uvs):
x, y = uv[0], uv[1]
- if j==0:
+ if j == 0:
fw('%.5f %.5f moveto\n' % (x * image_width, y * image_height))
else:
fw('%.5f %.5f lineto\n' % (x * image_width, y * image_height))
-
+
fw('closepath\n')
fw('stroke\n')
fw('showpage\n')
@@ -206,10 +203,10 @@ def register():
bpy.types.register(ExportUVLayout)
bpy.types.IMAGE_MT_uvs.append(menu_func)
+
def unreguster():
bpy.types.unregister(ExportUVLayout)
bpy.types.IMAGE_MT_uvs.remove(menu_func)
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/op/uvcalc_smart_project.py b/release/scripts/op/uvcalc_smart_project.py
index be9042e7e32..7fe0d1e5d60 100644
--- a/release/scripts/op/uvcalc_smart_project.py
+++ b/release/scripts/op/uvcalc_smart_project.py
@@ -1143,11 +1143,11 @@ menu_func = (lambda self, context: self.layout.operator(SmartProject.bl_idname,
def register():
bpy.types.register(SmartProject)
bpy.types.VIEW3D_MT_uv_map.append(menu_func)
-
+
+
def unregister():
bpy.types.unregister(SmartProject)
bpy.types.VIEW3D_MT_uv_map.remove(menu_func)
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/op/vertexpaint_dirt.py b/release/scripts/op/vertexpaint_dirt.py
index fa84da73faf..42987dbc4be 100644
--- a/release/scripts/op/vertexpaint_dirt.py
+++ b/release/scripts/op/vertexpaint_dirt.py
@@ -178,9 +178,9 @@ class VertexPaintDirt(bpy.types.Operator):
def register():
bpy.types.register(VertexPaintDirt)
+
def unregister():
bpy.types.unregister(VertexPaintDirt)
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/op/wm.py b/release/scripts/op/wm.py
index 33e691f7674..c70e80cdfe8 100644
--- a/release/scripts/op/wm.py
+++ b/release/scripts/op/wm.py
@@ -297,33 +297,29 @@ doc_new = StringProperty(name="Edit Description",
description="", maxlen=1024, default="")
-
class WM_OT_context_modal_mouse(bpy.types.Operator):
'''Adjust arbitrary values with mouse input'''
bl_idname = "wm.context_modal_mouse"
bl_label = "Context Modal Mouse"
-
+
path_iter = StringProperty(description="The path relative to the context, must point to an iterable.")
path_item = StringProperty(description="The path from each iterable to the value (int or float)")
input_scale = FloatProperty(default=0.01, description="Scale the mouse movement by this value before applying the delta")
invert = BoolProperty(default=False, description="Invert the mouse input")
initial_x = IntProperty(options={'HIDDEN'})
- _values = {}
-
def _values_store(self, context):
path_iter = self.properties.path_iter
path_item = self.properties.path_item
- self._values.clear()
- values = self._values
+ self._values = values = {}
for item in getattr(context, path_iter):
try:
value_orig = eval("item." + path_item)
except:
continue
-
+
# check this can be set, maybe this is library data.
try:
exec("item.%s = %s" % (path_item, value_orig))
@@ -332,15 +328,17 @@ class WM_OT_context_modal_mouse(bpy.types.Operator):
values[item] = value_orig
-
def _values_delta(self, delta):
delta *= self.properties.input_scale
if self.properties.invert:
- delta = -delta
+ delta = - delta
path_item = self.properties.path_item
for item, value_orig in self._values.items():
- exec("item.%s = %s" % (path_item, value_orig + delta))
+ if type(value_orig) == int:
+ exec("item.%s = int(%d)" % (path_item, round(value_orig + delta)))
+ else:
+ exec("item.%s = %f" % (path_item, value_orig + delta))
def _values_restore(self):
path_item = self.properties.path_item
@@ -348,7 +346,7 @@ class WM_OT_context_modal_mouse(bpy.types.Operator):
exec("item.%s = %s" % (path_item, value_orig))
self._values.clear()
-
+
def _values_clear(self):
self._values.clear()
@@ -363,10 +361,10 @@ class WM_OT_context_modal_mouse(bpy.types.Operator):
self._values_clear()
return {'FINISHED'}
- elif event_type in ('RIGHTMOUSE', 'ESCAPE'):
+ elif event_type in ('RIGHTMOUSE', 'ESC'):
self._values_restore()
return {'FINISHED'}
-
+
return {'RUNNING_MODAL'}
def invoke(self, context, event):
@@ -530,11 +528,13 @@ classes = [
rna_prop_ui.WM_OT_properties_add,
rna_prop_ui.WM_OT_properties_remove]
+
def register():
register = bpy.types.register
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -542,4 +542,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/presets/render/HDTV_1080p.py b/release/scripts/presets/render/HDTV_1080p.py
index 75a5faeb27d..7693dae9347 100644
--- a/release/scripts/presets/render/HDTV_1080p.py
+++ b/release/scripts/presets/render/HDTV_1080p.py
@@ -1,7 +1,7 @@
-bpy.context.scene.render_data.resolution_x = 1920
-bpy.context.scene.render_data.resolution_y = 1080
-bpy.context.scene.render_data.resolution_percentage = 100
-bpy.context.scene.render_data.pixel_aspect_x = 1
-bpy.context.scene.render_data.pixel_aspect_y = 1
-bpy.context.scene.render_data.fps = 24
-bpy.context.scene.render_data.fps_base = 1
+bpy.context.scene.render.resolution_x = 1920
+bpy.context.scene.render.resolution_y = 1080
+bpy.context.scene.render.resolution_percentage = 100
+bpy.context.scene.render.pixel_aspect_x = 1
+bpy.context.scene.render.pixel_aspect_y = 1
+bpy.context.scene.render.fps = 24
+bpy.context.scene.render.fps_base = 1
diff --git a/release/scripts/presets/render/HDTV_720p.py b/release/scripts/presets/render/HDTV_720p.py
index 4f46f4045e0..ee16c1e8b33 100644
--- a/release/scripts/presets/render/HDTV_720p.py
+++ b/release/scripts/presets/render/HDTV_720p.py
@@ -1,7 +1,7 @@
-bpy.context.scene.render_data.resolution_x = 1280
-bpy.context.scene.render_data.resolution_y = 720
-bpy.context.scene.render_data.resolution_percentage = 100
-bpy.context.scene.render_data.pixel_aspect_x = 1
-bpy.context.scene.render_data.pixel_aspect_y = 1
-bpy.context.scene.render_data.fps = 24
-bpy.context.scene.render_data.fps_base = 1
+bpy.context.scene.render.resolution_x = 1280
+bpy.context.scene.render.resolution_y = 720
+bpy.context.scene.render.resolution_percentage = 100
+bpy.context.scene.render.pixel_aspect_x = 1
+bpy.context.scene.render.pixel_aspect_y = 1
+bpy.context.scene.render.fps = 24
+bpy.context.scene.render.fps_base = 1
diff --git a/release/scripts/presets/render/TV_NTSC.py b/release/scripts/presets/render/TV_NTSC.py
index c6bc7518fac..cd6322fd21a 100644
--- a/release/scripts/presets/render/TV_NTSC.py
+++ b/release/scripts/presets/render/TV_NTSC.py
@@ -1,7 +1,7 @@
-bpy.context.scene.render_data.resolution_x = 720
-bpy.context.scene.render_data.resolution_y = 480
-bpy.context.scene.render_data.resolution_percentage = 100
-bpy.context.scene.render_data.pixel_aspect_x = 10
-bpy.context.scene.render_data.pixel_aspect_y = 11
-bpy.context.scene.render_data.fps = 30
-bpy.context.scene.render_data.fps_base = 1.001
+bpy.context.scene.render.resolution_x = 720
+bpy.context.scene.render.resolution_y = 480
+bpy.context.scene.render.resolution_percentage = 100
+bpy.context.scene.render.pixel_aspect_x = 10
+bpy.context.scene.render.pixel_aspect_y = 11
+bpy.context.scene.render.fps = 30
+bpy.context.scene.render.fps_base = 1.001
diff --git a/release/scripts/presets/render/TV_PAL.py b/release/scripts/presets/render/TV_PAL.py
index 0992b9b8de8..4a71ad021fe 100644
--- a/release/scripts/presets/render/TV_PAL.py
+++ b/release/scripts/presets/render/TV_PAL.py
@@ -1,7 +1,7 @@
-bpy.context.scene.render_data.resolution_x = 720
-bpy.context.scene.render_data.resolution_y = 576
-bpy.context.scene.render_data.resolution_percentage = 100
-bpy.context.scene.render_data.pixel_aspect_x = 54
-bpy.context.scene.render_data.pixel_aspect_y = 51
-bpy.context.scene.render_data.fps = 25
-bpy.context.scene.render_data.fps_base = 1
+bpy.context.scene.render.resolution_x = 720
+bpy.context.scene.render.resolution_y = 576
+bpy.context.scene.render.resolution_percentage = 100
+bpy.context.scene.render.pixel_aspect_x = 54
+bpy.context.scene.render.pixel_aspect_y = 51
+bpy.context.scene.render.fps = 25
+bpy.context.scene.render.fps_base = 1
diff --git a/release/scripts/presets/render/TV_PAL_16_colon_9.py b/release/scripts/presets/render/TV_PAL_16_colon_9.py
index 9b85805352d..516209a877d 100644
--- a/release/scripts/presets/render/TV_PAL_16_colon_9.py
+++ b/release/scripts/presets/render/TV_PAL_16_colon_9.py
@@ -1,7 +1,7 @@
-bpy.context.scene.render_data.resolution_x = 720
-bpy.context.scene.render_data.resolution_y = 576
-bpy.context.scene.render_data.resolution_percentage = 100
-bpy.context.scene.render_data.pixel_aspect_x = 64
-bpy.context.scene.render_data.pixel_aspect_y = 45
-bpy.context.scene.render_data.fps = 25
-bpy.context.scene.render_data.fps_base = 1
+bpy.context.scene.render.resolution_x = 720
+bpy.context.scene.render.resolution_y = 576
+bpy.context.scene.render.resolution_percentage = 100
+bpy.context.scene.render.pixel_aspect_x = 64
+bpy.context.scene.render.pixel_aspect_y = 45
+bpy.context.scene.render.fps = 25
+bpy.context.scene.render.fps_base = 1
diff --git a/release/scripts/templates/operator_modal.py b/release/scripts/templates/operator_modal.py
index ff3863ff59a..b2839efabe4 100644
--- a/release/scripts/templates/operator_modal.py
+++ b/release/scripts/templates/operator_modal.py
@@ -4,7 +4,7 @@ class ModalOperator(bpy.types.Operator):
'''Move an object with the mouse, example.'''
bl_idname = "object.modal_operator"
bl_label = "Simple Modal Operator"
-
+
first_mouse_x = IntProperty()
first_value = FloatProperty()
@@ -16,10 +16,10 @@ class ModalOperator(bpy.types.Operator):
elif event.type == 'LEFTMOUSE':
return {'FINISHED'}
- elif event.type in ('RIGHTMOUSE', 'ESCAPE'):
+ elif event.type in ('RIGHTMOUSE', 'ESC'):
context.object.location.x = self.properties.first_value
return {'CANCELLED'}
-
+
return {'RUNNING_MODAL'}
def invoke(self, context, event):
@@ -36,4 +36,4 @@ class ModalOperator(bpy.types.Operator):
bpy.types.register(ModalOperator)
if __name__ == "__main__":
- bpy.ops.object.modal_operator() \ No newline at end of file
+ bpy.ops.object.modal_operator()
diff --git a/release/scripts/ui/properties_animviz.py b/release/scripts/ui/properties_animviz.py
index 547e13a6a80..71b49cea2f2 100644
--- a/release/scripts/ui/properties_animviz.py
+++ b/release/scripts/ui/properties_animviz.py
@@ -29,6 +29,7 @@ class MotionPathButtonsPanel(bpy.types.Panel):
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_label = "Motion Paths"
+ bl_default_closed = True
def draw_settings(self, context, avs, wide_ui, bones=False):
layout = self.layout
@@ -68,6 +69,7 @@ class OnionSkinButtonsPanel(bpy.types.Panel):
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_label = "Onion Skinning"
+ bl_default_closed = True
def draw(self, context):
layout = self.layout
@@ -101,7 +103,6 @@ class OnionSkinButtonsPanel(bpy.types.Panel):
################################################
# Specific Panels for DataTypes
-
class OBJECT_PT_motion_paths(MotionPathButtonsPanel):
#bl_label = "Object Motion Paths"
bl_context = "object"
@@ -128,9 +129,23 @@ class OBJECT_PT_motion_paths(MotionPathButtonsPanel):
col = split.column()
col.operator("object.paths_clear", text="Clear Paths")
+class OBJECT_PT_onion_skinning(OnionSkinButtonsPanel):
+ #bl_label = "Object Onion Skinning"
+ bl_context = "object"
+
+ def poll(self, context):
+ return (context.object)
+
+ def draw(self, context):
+ layout = self.layout
+
+ ob = context.object
+ wide_ui = context.region.width > narrowui
+
+ self.draw_settings(context, ob.animation_visualisation, wide_ui)
class DATA_PT_motion_paths(MotionPathButtonsPanel):
- #bl_label = "Bone Motion Paths"
+ #bl_label = "Bones Motion Paths"
bl_context = "data"
def poll(self, context):
@@ -156,19 +171,39 @@ class DATA_PT_motion_paths(MotionPathButtonsPanel):
col = split.column()
col.operator("pose.paths_clear", text="Clear Paths")
+class DATA_PT_onion_skinning(OnionSkinButtonsPanel):
+ #bl_label = "Bones Onion Skinning"
+ bl_context = "data"
-classes = [
- OBJECT_PT_motion_paths,
- DATA_PT_motion_paths]
+ def poll(self, context):
+ # XXX: include posemode check?
+ return (context.object) and (context.armature)
-# OBJECT_PT_onion_skinning
-# DATA_PT_onion_skinning
+ def draw(self, context):
+ layout = self.layout
+
+ ob = context.object
+ wide_ui = context.region.width > narrowui
+
+ self.draw_settings(context, ob.pose.animation_visualisation, wide_ui, bones=True)
+
+# NOTE:
+# The specialised panel types defined here (i.e. OBJECT_PT_*, etc.)
+# aren't registered here, but are rather imported to (and registered)
+# in the files defining the contexts where they reside. Otherwise,
+# these panels appear at the top of the lists by default.
+#
+# However, we keep these empty register funcs here just in case
+# something will need them again one day, and also to make
+# it easier to maintain these scripts.
+classes = []
def register():
register = bpy.types.register
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -176,4 +211,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_data_armature.py b/release/scripts/ui/properties_data_armature.py
index e92f2cb9f71..b7864618de6 100644
--- a/release/scripts/ui/properties_data_armature.py
+++ b/release/scripts/ui/properties_data_armature.py
@@ -253,6 +253,9 @@ class DATA_PT_iksolver_itasc(DataButtonsPanel):
row.prop(itasc, "dampmax", text="Damp", slider=True)
row.prop(itasc, "dampeps", text="Eps", slider=True)
+# import generic panels from other files
+from properties_animviz import DATA_PT_motion_paths, DATA_PT_onion_skinning
+
classes = [
DATA_PT_context_arm,
DATA_PT_skeleton,
@@ -261,13 +264,18 @@ classes = [
DATA_PT_ghost,
DATA_PT_iksolver_itasc,
+ DATA_PT_motion_paths,
+ #DATA_PT_onion_skinning,
+
DATA_PT_custom_props_arm]
+
def register():
register = bpy.types.register
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -275,4 +283,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_data_armature_rigify.py b/release/scripts/ui/properties_data_armature_rigify.py
index 30b4ec5ca30..c6a5d846b4c 100644
--- a/release/scripts/ui/properties_data_armature_rigify.py
+++ b/release/scripts/ui/properties_data_armature_rigify.py
@@ -351,6 +351,7 @@ classes = [
menu_func = (lambda self, context: self.layout.menu("INFO_MT_armature_metarig_add", icon='OUTLINER_OB_ARMATURE'))
import space_info # ensure the menu is loaded first
+
def register():
register = bpy.types.register
for cls in classes:
@@ -358,13 +359,13 @@ def register():
space_info.INFO_MT_armature_add.append(menu_func)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
unregister(cls)
-
+
bpy.types.INFO_MT_armature_add.remove(menu_func)
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_data_bone.py b/release/scripts/ui/properties_data_bone.py
index d8d5bf3bea0..a6bac3e6aaa 100644
--- a/release/scripts/ui/properties_data_bone.py
+++ b/release/scripts/ui/properties_data_bone.py
@@ -398,11 +398,13 @@ classes = [
BONE_PT_custom_props]
+
def register():
register = bpy.types.register
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -410,4 +412,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_data_camera.py b/release/scripts/ui/properties_data_camera.py
index 3befc565adb..be0a4f84145 100644
--- a/release/scripts/ui/properties_data_camera.py
+++ b/release/scripts/ui/properties_data_camera.py
@@ -163,6 +163,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -170,4 +171,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_data_curve.py b/release/scripts/ui/properties_data_curve.py
index 8877e9ab121..9848e423665 100644
--- a/release/scripts/ui/properties_data_curve.py
+++ b/release/scripts/ui/properties_data_curve.py
@@ -401,6 +401,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -408,4 +409,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_data_empty.py b/release/scripts/ui/properties_data_empty.py
index 30d9a278d35..a0999fb9d4a 100644
--- a/release/scripts/ui/properties_data_empty.py
+++ b/release/scripts/ui/properties_data_empty.py
@@ -51,11 +51,13 @@ class DATA_PT_empty(DataButtonsPanel):
classes = [
DATA_PT_empty]
+
def register():
register = bpy.types.register
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -63,4 +65,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_data_lamp.py b/release/scripts/ui/properties_data_lamp.py
index 1f08aca638e..9a99959a610 100644
--- a/release/scripts/ui/properties_data_lamp.py
+++ b/release/scripts/ui/properties_data_lamp.py
@@ -411,6 +411,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -418,4 +419,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_data_lattice.py b/release/scripts/ui/properties_data_lattice.py
index c8676b654b0..0c1f9d8001c 100644
--- a/release/scripts/ui/properties_data_lattice.py
+++ b/release/scripts/ui/properties_data_lattice.py
@@ -108,6 +108,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -115,4 +116,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_data_mesh.py b/release/scripts/ui/properties_data_mesh.py
index c3fbc369c1d..d48d2ec8046 100644
--- a/release/scripts/ui/properties_data_mesh.py
+++ b/release/scripts/ui/properties_data_mesh.py
@@ -28,7 +28,7 @@ class MESH_MT_vertex_group_specials(bpy.types.Menu):
def draw(self, context):
layout = self.layout
-
+
layout.operator("object.vertex_group_sort", icon='SORTALPHA')
layout.operator("object.vertex_group_copy", icon='COPY_ID')
layout.operator("object.vertex_group_copy_to_linked", icon='LINK_AREA')
@@ -227,7 +227,7 @@ class DATA_PT_shape_keys(DataButtonsPanel):
subsub.prop(ob, "shape_key_lock", text="")
subsub.prop(kb, "mute", text="")
sub.prop(ob, "shape_key_edit_mode", text="")
-
+
sub = row.row()
sub.operator("object.shape_key_clear", icon='X', text="")
@@ -325,6 +325,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -332,4 +333,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_data_metaball.py b/release/scripts/ui/properties_data_metaball.py
index 984ab89c062..b751a9f9059 100644
--- a/release/scripts/ui/properties_data_metaball.py
+++ b/release/scripts/ui/properties_data_metaball.py
@@ -149,6 +149,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -156,4 +157,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_data_modifier.py b/release/scripts/ui/properties_data_modifier.py
index fb8489d7df5..8364d070d1a 100644
--- a/release/scripts/ui/properties_data_modifier.py
+++ b/release/scripts/ui/properties_data_modifier.py
@@ -739,6 +739,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -746,4 +747,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_game.py b/release/scripts/ui/properties_game.py
index 52821bb6a0f..41af955d9ec 100644
--- a/release/scripts/ui/properties_game.py
+++ b/release/scripts/ui/properties_game.py
@@ -29,7 +29,7 @@ class PhysicsButtonsPanel(bpy.types.Panel):
def poll(self, context):
ob = context.active_object
- rd = context.scene.render_data
+ rd = context.scene.render
return ob and ob.game and (rd.engine == 'BLENDER_GAME')
@@ -166,7 +166,7 @@ class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel):
def poll(self, context):
game = context.object.game
- rd = context.scene.render_data
+ rd = context.scene.render
return (game.physics_type in ('DYNAMIC', 'RIGID_BODY', 'SENSOR', 'SOFT_BODY', 'STATIC')) and (rd.engine == 'BLENDER_GAME')
def draw_header(self, context):
@@ -202,7 +202,7 @@ class RenderButtonsPanel(bpy.types.Panel):
bl_context = "render"
def poll(self, context):
- rd = context.scene.render_data
+ rd = context.scene.render
return (rd.engine == 'BLENDER_GAME')
@@ -357,13 +357,13 @@ class RENDER_PT_game_performance(RenderButtonsPanel):
col.prop(gs, "show_debug_properties", text="Debug Properties")
col.prop(gs, "show_framerate_profile", text="Framerate and Profile")
col.prop(gs, "show_physics_visualization", text="Physics Visualization")
- col.prop(gs, "deprecation_warnings")
+ col.prop(gs, "use_deprecation_warnings")
if wide_ui:
col = split.column()
col.label(text="Render:")
- col.prop(gs, "all_frames")
- col.prop(gs, "display_lists")
+ col.prop(gs, "use_frame_rate")
+ col.prop(gs, "use_display_lists")
class RENDER_PT_game_sound(RenderButtonsPanel):
@@ -389,8 +389,8 @@ class WorldButtonsPanel(bpy.types.Panel):
bl_context = "world"
def poll(self, context):
- rd = context.scene.render_data
- return (rd.engine == 'BLENDER_GAME')
+ scene = context.scene
+ return (scene.render.engine == 'BLENDER_GAME') and (scene.world is not None)
class WORLD_PT_game_context_world(WorldButtonsPanel):
@@ -398,7 +398,7 @@ class WORLD_PT_game_context_world(WorldButtonsPanel):
bl_show_header = False
def poll(self, context):
- rd = context.scene.render_data
+ rd = context.scene.render
return (context.scene) and (rd.use_game_engine)
def draw(self, context):
@@ -533,6 +533,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -540,4 +541,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_material.py b/release/scripts/ui/properties_material.py
index f105e0b0718..13bfd7a7f5d 100644
--- a/release/scripts/ui/properties_material.py
+++ b/release/scripts/ui/properties_material.py
@@ -62,7 +62,7 @@ class MaterialButtonsPanel(bpy.types.Panel):
def poll(self, context):
mat = context.material
- engine = context.scene.render_data.engine
+ engine = context.scene.render.engine
return mat and (engine in self.COMPAT_ENGINES)
@@ -83,7 +83,7 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel):
# An exception, dont call the parent poll func because
# this manages materials for all engine types
- engine = context.scene.render_data.engine
+ engine = context.scene.render.engine
return (context.material or context.object) and (engine in self.COMPAT_ENGINES)
def draw(self, context):
@@ -149,7 +149,7 @@ class MATERIAL_PT_shading(MaterialButtonsPanel):
def poll(self, context):
mat = active_node_mat(context.material)
- engine = context.scene.render_data.engine
+ engine = context.scene.render.engine
return mat and (mat.type in ('SURFACE', 'WIRE', 'HALO')) and (engine in self.COMPAT_ENGINES)
def draw(self, context):
@@ -188,7 +188,7 @@ class MATERIAL_PT_strand(MaterialButtonsPanel):
def poll(self, context):
mat = context.material
- engine = context.scene.render_data.engine
+ engine = context.scene.render.engine
return mat and (mat.type in ('SURFACE', 'WIRE', 'HALO')) and (engine in self.COMPAT_ENGINES)
def draw(self, context):
@@ -260,7 +260,7 @@ class MATERIAL_PT_options(MaterialButtonsPanel):
def poll(self, context):
mat = active_node_mat(context.material)
- engine = context.scene.render_data.engine
+ engine = context.scene.render.engine
return mat and (mat.type in ('SURFACE', 'WIRE', 'HALO')) and (engine in self.COMPAT_ENGINES)
def draw(self, context):
@@ -306,7 +306,7 @@ class MATERIAL_PT_shadow(MaterialButtonsPanel):
def poll(self, context):
mat = active_node_mat(context.material)
- engine = context.scene.render_data.engine
+ engine = context.scene.render.engine
return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES)
def draw(self, context):
@@ -336,13 +336,14 @@ class MATERIAL_PT_shadow(MaterialButtonsPanel):
sub.prop(mat, "shadow_ray_bias", text="Ray Bias")
col.prop(mat, "cast_approximate")
+
class MATERIAL_PT_diffuse(MaterialButtonsPanel):
bl_label = "Diffuse"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
def poll(self, context):
mat = active_node_mat(context.material)
- engine = context.scene.render_data.engine
+ engine = context.scene.render.engine
return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES)
def draw(self, context):
@@ -413,7 +414,7 @@ class MATERIAL_PT_specular(MaterialButtonsPanel):
def poll(self, context):
mat = active_node_mat(context.material)
- engine = context.scene.render_data.engine
+ engine = context.scene.render.engine
return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES)
def draw(self, context):
@@ -483,7 +484,7 @@ class MATERIAL_PT_sss(MaterialButtonsPanel):
def poll(self, context):
mat = active_node_mat(context.material)
- engine = context.scene.render_data.engine
+ engine = context.scene.render.engine
return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES)
def draw_header(self, context):
@@ -535,7 +536,7 @@ class MATERIAL_PT_mirror(MaterialButtonsPanel):
def poll(self, context):
mat = active_node_mat(context.material)
- engine = context.scene.render_data.engine
+ engine = context.scene.render.engine
return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES)
def draw_header(self, context):
@@ -594,7 +595,7 @@ class MATERIAL_PT_transp(MaterialButtonsPanel):
def poll(self, context):
mat = active_node_mat(context.material)
- engine = context.scene.render_data.engine
+ engine = context.scene.render.engine
return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES)
def draw_header(self, context):
@@ -661,7 +662,7 @@ class MATERIAL_PT_transp_game(MaterialButtonsPanel):
def poll(self, context):
mat = active_node_mat(context.material)
- engine = context.scene.render_data.engine
+ engine = context.scene.render.engine
return mat and (engine in self.COMPAT_ENGINES)
def draw_header(self, context):
@@ -695,7 +696,7 @@ class MATERIAL_PT_halo(MaterialButtonsPanel):
def poll(self, context):
mat = context.material
- engine = context.scene.render_data.engine
+ engine = context.scene.render.engine
return mat and (mat.type == 'HALO') and (engine in self.COMPAT_ENGINES)
def draw(self, context):
@@ -745,7 +746,7 @@ class MATERIAL_PT_flare(MaterialButtonsPanel):
def poll(self, context):
mat = context.material
- engine = context.scene.render_data.engine
+ engine = context.scene.render.engine
return mat and (mat.type == 'HALO') and (engine in self.COMPAT_ENGINES)
def draw_header(self, context):
@@ -781,7 +782,7 @@ class VolumeButtonsPanel(bpy.types.Panel):
def poll(self, context):
mat = context.material
- engine = context.scene.render_data.engine
+ engine = context.scene.render.engine
return mat and (mat.type == 'VOLUME') and (engine in self.COMPAT_ENGINES)
@@ -947,6 +948,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -954,4 +956,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_object.py b/release/scripts/ui/properties_object.py
index 4bf691106a0..b11180411f4 100644
--- a/release/scripts/ui/properties_object.py
+++ b/release/scripts/ui/properties_object.py
@@ -304,6 +304,8 @@ class OBJECT_PT_animation(ObjectButtonsPanel):
row.prop(ob, "track_override_parent", text="Override Parent")
row.active = (ob.parent is not None)
+# import generic panels from other files
+from properties_animviz import OBJECT_PT_motion_paths, OBJECT_PT_onion_skinning
classes = [
OBJECT_PT_context_object,
@@ -314,6 +316,9 @@ classes = [
OBJECT_PT_display,
OBJECT_PT_duplication,
OBJECT_PT_animation,
+
+ OBJECT_PT_motion_paths,
+ #OBJECT_PT_onion_skinning,
OBJECT_PT_custom_props]
@@ -323,6 +328,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -330,4 +336,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_object_constraint.py b/release/scripts/ui/properties_object_constraint.py
index d6ab13a3860..6f6fcfc1641 100644
--- a/release/scripts/ui/properties_object_constraint.py
+++ b/release/scripts/ui/properties_object_constraint.py
@@ -466,7 +466,6 @@ class ConstraintButtonsPanel(bpy.types.Panel):
self.space_template(layout, con, wide_ui)
-
#def SCRIPT(self, context, layout, con):
def ACTION(self, context, layout, con, wide_ui):
@@ -765,6 +764,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -772,4 +772,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_particle.py b/release/scripts/ui/properties_particle.py
index 88bda7c6dd8..dbd2b90fea2 100644
--- a/release/scripts/ui/properties_particle.py
+++ b/release/scripts/ui/properties_particle.py
@@ -231,6 +231,7 @@ class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel):
sub.prop(cloth, "mass")
sub.prop(cloth, "bending_stiffness", text="Bending")
sub.prop(cloth, "internal_friction", slider=True)
+ sub.prop(cloth, "collider_friction", slider=True)
col = split.column()
@@ -1023,6 +1024,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -1030,4 +1032,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_physics_cloth.py b/release/scripts/ui/properties_physics_cloth.py
index b7743fbdce5..7a65420e172 100644
--- a/release/scripts/ui/properties_physics_cloth.py
+++ b/release/scripts/ui/properties_physics_cloth.py
@@ -47,7 +47,7 @@ class PhysicButtonsPanel(bpy.types.Panel):
def poll(self, context):
ob = context.object
- rd = context.scene.render_data
+ rd = context.scene.render
return (ob and ob.type == 'MESH') and (not rd.use_game_engine)
@@ -244,6 +244,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -251,4 +252,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_physics_common.py b/release/scripts/ui/properties_physics_common.py
index 7964861c46e..b81fa25b1a1 100644
--- a/release/scripts/ui/properties_physics_common.py
+++ b/release/scripts/ui/properties_physics_common.py
@@ -215,9 +215,9 @@ def basic_force_field_falloff_ui(self, context, field):
def register():
pass
+
def unregister():
pass
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_physics_field.py b/release/scripts/ui/properties_physics_field.py
index 964c73bff15..e0be01d4c1c 100644
--- a/release/scripts/ui/properties_physics_field.py
+++ b/release/scripts/ui/properties_physics_field.py
@@ -32,7 +32,7 @@ class PhysicButtonsPanel(bpy.types.Panel):
bl_context = "physics"
def poll(self, context):
- rd = context.scene.render_data
+ rd = context.scene.render
return (context.object) and (not rd.use_game_engine)
@@ -174,7 +174,7 @@ class PHYSICS_PT_collision(PhysicButtonsPanel):
def poll(self, context):
ob = context.object
- rd = context.scene.render_data
+ rd = context.scene.render
return (ob and ob.type == 'MESH') and (not rd.use_game_engine)
def draw(self, context):
@@ -253,6 +253,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -260,4 +261,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_physics_fluid.py b/release/scripts/ui/properties_physics_fluid.py
index 856a14ee071..9b36b98bc24 100644
--- a/release/scripts/ui/properties_physics_fluid.py
+++ b/release/scripts/ui/properties_physics_fluid.py
@@ -29,7 +29,7 @@ class PhysicButtonsPanel(bpy.types.Panel):
def poll(self, context):
ob = context.object
- rd = context.scene.render_data
+ rd = context.scene.render
return (ob and ob.type == 'MESH') and (not rd.use_game_engine)
@@ -304,6 +304,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -311,4 +312,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_physics_smoke.py b/release/scripts/ui/properties_physics_smoke.py
index 7f9a03fe6a6..1f91b761e1a 100644
--- a/release/scripts/ui/properties_physics_smoke.py
+++ b/release/scripts/ui/properties_physics_smoke.py
@@ -33,7 +33,7 @@ class PhysicButtonsPanel(bpy.types.Panel):
def poll(self, context):
ob = context.object
- rd = context.scene.render_data
+ rd = context.scene.render
return (ob and ob.type == 'MESH') and (not rd.use_game_engine)
@@ -253,6 +253,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -260,4 +261,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_physics_softbody.py b/release/scripts/ui/properties_physics_softbody.py
index 4d774bf5e25..8a59e087dc3 100644
--- a/release/scripts/ui/properties_physics_softbody.py
+++ b/release/scripts/ui/properties_physics_softbody.py
@@ -37,7 +37,7 @@ class PhysicButtonsPanel(bpy.types.Panel):
def poll(self, context):
ob = context.object
- rd = context.scene.render_data
+ rd = context.scene.render
return (ob and ob.type == 'MESH') and (not rd.use_game_engine)
@@ -296,6 +296,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -303,4 +304,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_render.py b/release/scripts/ui/properties_render.py
index 766c85fdbcb..e88a40315b1 100644
--- a/release/scripts/ui/properties_render.py
+++ b/release/scripts/ui/properties_render.py
@@ -36,7 +36,7 @@ class RenderButtonsPanel(bpy.types.Panel):
# COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
def poll(self, context):
- rd = context.scene.render_data
+ rd = context.scene.render
return (context.scene and rd.use_game_engine is False) and (rd.engine in self.COMPAT_ENGINES)
@@ -47,7 +47,7 @@ class RENDER_PT_render(RenderButtonsPanel):
def draw(self, context):
layout = self.layout
- rd = context.scene.render_data
+ rd = context.scene.render
wide_ui = context.region.width > narrowui
split = layout.split()
@@ -71,7 +71,7 @@ class RENDER_PT_layers(RenderButtonsPanel):
layout = self.layout
scene = context.scene
- rd = scene.render_data
+ rd = scene.render
wide_ui = context.region.width > narrowui
row = layout.row()
@@ -204,7 +204,7 @@ class RENDER_PT_shading(RenderButtonsPanel):
def draw(self, context):
layout = self.layout
- rd = context.scene.render_data
+ rd = context.scene.render
wide_ui = context.region.width > narrowui
split = layout.split()
@@ -230,7 +230,7 @@ class RENDER_PT_performance(RenderButtonsPanel):
def draw(self, context):
layout = self.layout
- rd = context.scene.render_data
+ rd = context.scene.render
wide_ui = context.region.width > narrowui
split = layout.split()
@@ -250,7 +250,7 @@ class RENDER_PT_performance(RenderButtonsPanel):
col = split.column()
col.label(text="Memory:")
sub = col.column()
- sub.enabled = not (rd.use_border or rd.full_sample)
+ sub.enabled = not (rd.use_border or rd.full_sample)
sub.prop(rd, "save_buffers")
sub = col.column()
sub.active = rd.use_compositing
@@ -274,7 +274,7 @@ class RENDER_PT_post_processing(RenderButtonsPanel):
def draw(self, context):
layout = self.layout
- rd = context.scene.render_data
+ rd = context.scene.render
wide_ui = context.region.width > narrowui
split = layout.split()
@@ -323,7 +323,7 @@ class RENDER_PT_output(RenderButtonsPanel):
def draw(self, context):
layout = self.layout
- rd = context.scene.render_data
+ rd = context.scene.render
wide_ui = context.region.width > narrowui
layout.prop(rd, "output_path", text="")
@@ -389,7 +389,7 @@ class RENDER_PT_output(RenderButtonsPanel):
elif rd.file_format == 'QUICKTIME_CARBON':
split = layout.split()
- split.operator("scene.render_data_set_quicktime_codec")
+ split.operator("scene.render_set_quicktime_codec")
elif rd.file_format == 'QUICKTIME_QTKIT':
split = layout.split()
@@ -404,13 +404,13 @@ class RENDER_PT_encoding(RenderButtonsPanel):
COMPAT_ENGINES = {'BLENDER_RENDER'}
def poll(self, context):
- rd = context.scene.render_data
+ rd = context.scene.render
return rd.file_format in ('FFMPEG', 'XVID', 'H264', 'THEORA')
def draw(self, context):
layout = self.layout
- rd = context.scene.render_data
+ rd = context.scene.render
wide_ui = context.region.width > narrowui
split = layout.split()
@@ -453,7 +453,7 @@ class RENDER_PT_encoding(RenderButtonsPanel):
sub = layout.column()
if rd.ffmpeg_format not in ('MP3'):
- sub.prop(rd, "ffmpeg_audio_codec", text="Audio Codec")
+ sub.prop(rd, "ffmpeg_audio_codec", text="Audio Codec")
sub.separator()
@@ -473,14 +473,14 @@ class RENDER_PT_antialiasing(RenderButtonsPanel):
COMPAT_ENGINES = {'BLENDER_RENDER'}
def draw_header(self, context):
- rd = context.scene.render_data
+ rd = context.scene.render
self.layout.prop(rd, "antialiasing", text="")
def draw(self, context):
layout = self.layout
- rd = context.scene.render_data
+ rd = context.scene.render
wide_ui = context.region.width > narrowui
layout.active = rd.antialiasing
@@ -488,7 +488,7 @@ class RENDER_PT_antialiasing(RenderButtonsPanel):
col = split.column()
col.row().prop(rd, "antialiasing_samples", expand=True)
- sub = col.row()
+ sub = col.row()
sub.enabled = not rd.use_border
sub.prop(rd, "full_sample")
@@ -496,7 +496,7 @@ class RENDER_PT_antialiasing(RenderButtonsPanel):
col = split.column()
col.prop(rd, "pixel_filter", text="")
col.prop(rd, "filter_size", text="Size")
-
+
class RENDER_PT_motion_blur(RenderButtonsPanel):
bl_label = "Full Sample Motion Blur"
@@ -504,19 +504,20 @@ class RENDER_PT_motion_blur(RenderButtonsPanel):
COMPAT_ENGINES = {'BLENDER_RENDER'}
def draw_header(self, context):
- rd = context.scene.render_data
+ rd = context.scene.render
self.layout.prop(rd, "motion_blur", text="")
def draw(self, context):
layout = self.layout
- rd = context.scene.render_data
+ rd = context.scene.render
layout.active = rd.motion_blur
row = layout.row()
row.prop(rd, "motion_blur_samples")
+
class RENDER_PT_dimensions(RenderButtonsPanel):
bl_label = "Dimensions"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -525,7 +526,7 @@ class RENDER_PT_dimensions(RenderButtonsPanel):
layout = self.layout
scene = context.scene
- rd = scene.render_data
+ rd = scene.render
wide_ui = context.region.width > narrowui
row = layout.row().split()
@@ -571,14 +572,14 @@ class RENDER_PT_stamp(RenderButtonsPanel):
COMPAT_ENGINES = {'BLENDER_RENDER'}
def draw_header(self, context):
- rd = context.scene.render_data
+ rd = context.scene.render
self.layout.prop(rd, "render_stamp", text="")
def draw(self, context):
layout = self.layout
- rd = context.scene.render_data
+ rd = context.scene.render
wide_ui = context.region.width > narrowui
layout.active = rd.render_stamp
@@ -619,7 +620,7 @@ class RENDER_PT_bake(RenderButtonsPanel):
def draw(self, context):
layout = self.layout
- rd = context.scene.render_data
+ rd = context.scene.render
wide_ui = context.region.width > narrowui
layout.operator("object.bake_image", icon='RENDER_STILL')
@@ -679,6 +680,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -686,4 +688,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_scene.py b/release/scripts/ui/properties_scene.py
index 511130222eb..0209140ef4e 100644
--- a/release/scripts/ui/properties_scene.py
+++ b/release/scripts/ui/properties_scene.py
@@ -102,7 +102,7 @@ class SCENE_PT_keying_sets(SceneButtonsPanel):
col = row.column()
col.prop(ks, "name")
col.prop(ks, "absolute")
-
+
subcol = col.column()
subcol.operator_context = 'INVOKE_DEFAULT'
op = subcol.operator("anim.keying_set_export", text="Export to File")
@@ -192,13 +192,13 @@ class SCENE_PT_simplify(SceneButtonsPanel):
def draw_header(self, context):
scene = context.scene
- rd = scene.render_data
+ rd = scene.render
self.layout.prop(rd, "use_simplify", text="")
def draw(self, context):
layout = self.layout
scene = context.scene
- rd = scene.render_data
+ rd = scene.render
wide_ui = context.region.width > narrowui
layout.active = rd.use_simplify
@@ -208,7 +208,7 @@ class SCENE_PT_simplify(SceneButtonsPanel):
col = split.column()
col.prop(rd, "simplify_subdivision", text="Subdivision")
col.prop(rd, "simplify_child_particles", text="Child Particles")
-
+
col.prop(rd, "simplify_triangulate")
if wide_ui:
@@ -242,83 +242,83 @@ class ANIM_OT_keying_set_export(bpy.types.Operator):
scene = context.scene
ks = scene.active_keying_set
-
-
+
+
f.write("# Keying Set: %s\n" % ks.name)
-
+
f.write("import bpy\n\n")
f.write("scene= bpy.data.scenes[0]\n\n")
- # Add KeyingSet and set general settings
+ # Add KeyingSet and set general settings
f.write("# Keying Set Level declarations\n")
f.write("ks= scene.add_keying_set(name=\"%s\")\n" % ks.name)
-
+
if ks.absolute is False:
f.write("ks.absolute = False\n")
f.write("\n")
-
+
f.write("ks.insertkey_needed = %s\n" % ks.insertkey_needed)
f.write("ks.insertkey_visual = %s\n" % ks.insertkey_visual)
f.write("ks.insertkey_xyz_to_rgb = %s\n" % ks.insertkey_xyz_to_rgb)
f.write("\n")
-
-
+
+
# generate and write set of lookups for id's used in paths
id_to_paths_cache = {} # cache for syncing ID-blocks to bpy paths + shorthands
-
+
for ksp in ks.paths:
if ksp.id is None:
- continue;
+ continue
if ksp.id in id_to_paths_cache:
- continue;
-
+ continue
+
# - idtype_list is used to get the list of id-datablocks from bpy.data.*
# since this info isn't available elsewhere
- # - id.bl_rna.name gives a name suitable for UI,
+ # - id.bl_rna.name gives a name suitable for UI,
# with a capitalised first letter, but we need
# the plural form that's all lower case
idtype_list = ksp.id.bl_rna.name.lower() + "s"
id_bpy_path = "bpy.data.%s[\"%s\"]" % (idtype_list, ksp.id.name)
-
+
# shorthand ID for the ID-block (as used in the script)
short_id = "id_%d" % len(id_to_paths_cache)
-
+
# store this in the cache now
id_to_paths_cache[ksp.id] = [short_id, id_bpy_path]
-
+
f.write("# ID's that are commonly used\n")
for id_pair in id_to_paths_cache.values():
f.write("%s = %s\n" % (id_pair[0], id_pair[1]))
f.write("\n")
-
-
+
+
# write paths
- f.write("# Path Definitions\n")
+ f.write("# Path Definitions\n")
for ksp in ks.paths:
f.write("ksp = ks.add_destination(")
-
+
# id-block + RNA-path
if ksp.id:
# find the relevant shorthand from the cache
id_bpy_path = id_to_paths_cache[ksp.id][0]
else:
- id_bpy_path = "None" # XXX...
+ id_bpy_path = "None" # XXX...
f.write("%s, '%s'" % (id_bpy_path, ksp.data_path))
-
+
# array index settings (if applicable)
if ksp.entire_array is False:
f.write(", entire_array=False, array_index=%d" % ksp.array_index)
-
+
# grouping settings (if applicable)
# NOTE: the current default is KEYINGSET, but if this changes, change this code too
if ksp.grouping == 'NAMED':
f.write(", grouping_method='%s', group_name=\"%s\"" % (ksp.grouping, ksp.group))
elif ksp.grouping != 'KEYINGSET':
f.write(", grouping_method='%s'" % ksp.grouping)
-
+
# finish off
f.write(")\n")
-
+
f.write("\n")
f.close()
@@ -337,7 +337,7 @@ classes = [
SCENE_PT_keying_set_paths,
SCENE_PT_physics,
SCENE_PT_simplify,
-
+
SCENE_PT_custom_props,
ANIM_OT_keying_set_export]
@@ -348,6 +348,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -355,4 +356,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_texture.py b/release/scripts/ui/properties_texture.py
index 0ad56b3aa82..8794b19bd4d 100644
--- a/release/scripts/ui/properties_texture.py
+++ b/release/scripts/ui/properties_texture.py
@@ -991,6 +991,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -998,4 +999,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/properties_world.py b/release/scripts/ui/properties_world.py
index 8c28678259c..1ee47e942a0 100644
--- a/release/scripts/ui/properties_world.py
+++ b/release/scripts/ui/properties_world.py
@@ -30,7 +30,7 @@ class WorldButtonsPanel(bpy.types.Panel):
# COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
def poll(self, context):
- rd = context.scene.render_data
+ rd = context.scene.render
return (context.world) and (not rd.use_game_engine) and (rd.engine in self.COMPAT_ENGINES)
@@ -48,7 +48,7 @@ class WORLD_PT_context_world(WorldButtonsPanel):
COMPAT_ENGINES = {'BLENDER_RENDER'}
def poll(self, context):
- rd = context.scene.render_data
+ rd = context.scene.render
return (not rd.use_game_engine) and (rd.engine in self.COMPAT_ENGINES)
def draw(self, context):
@@ -287,6 +287,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -294,4 +295,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/space_buttons.py b/release/scripts/ui/space_buttons.py
index bada9f20649..019f751449f 100644
--- a/release/scripts/ui/space_buttons.py
+++ b/release/scripts/ui/space_buttons.py
@@ -62,6 +62,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -69,4 +70,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/space_console.py b/release/scripts/ui/space_console.py
index 2115177be18..37de6bacad2 100644
--- a/release/scripts/ui/space_console.py
+++ b/release/scripts/ui/space_console.py
@@ -218,6 +218,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -225,4 +226,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/space_dopesheet.py b/release/scripts/ui/space_dopesheet.py
index 2409ec1a162..1dc8ffd1af9 100644
--- a/release/scripts/ui/space_dopesheet.py
+++ b/release/scripts/ui/space_dopesheet.py
@@ -205,6 +205,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -212,4 +213,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/space_filebrowser.py b/release/scripts/ui/space_filebrowser.py
index 893bbb92421..39bae6ca59b 100644
--- a/release/scripts/ui/space_filebrowser.py
+++ b/release/scripts/ui/space_filebrowser.py
@@ -74,6 +74,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -81,4 +82,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/space_graph.py b/release/scripts/ui/space_graph.py
index c9c79a7f16b..64f6337177e 100644
--- a/release/scripts/ui/space_graph.py
+++ b/release/scripts/ui/space_graph.py
@@ -148,7 +148,7 @@ class GRAPH_MT_channel(bpy.types.Menu):
layout.operator("anim.channels_collapse")
layout.separator()
- layout.operator("graph.discont_filter", text="Discontinuity (Euler) Filter")
+ layout.operator("graph.euler_filter", text="Discontinuity (Euler) Filter")
class GRAPH_MT_key(bpy.types.Menu):
@@ -185,6 +185,7 @@ class GRAPH_MT_key(bpy.types.Menu):
layout.operator("graph.copy")
layout.operator("graph.paste")
+
class GRAPH_MT_key_transform(bpy.types.Menu):
bl_label = "Transform"
@@ -212,6 +213,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -219,4 +221,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/space_image.py b/release/scripts/ui/space_image.py
index bb5cc01354f..3fd7025a4f7 100644
--- a/release/scripts/ui/space_image.py
+++ b/release/scripts/ui/space_image.py
@@ -349,7 +349,7 @@ class IMAGE_PT_game_properties(bpy.types.Panel):
bl_label = "Game Properties"
def poll(self, context):
- rd = context.scene.render_data
+ rd = context.scene.render
sima = context.space_data
return (sima and sima.image) and (rd.engine == 'BLENDER_GAME')
@@ -520,6 +520,7 @@ class IMAGE_PT_paint(bpy.types.Panel):
col.prop(brush, "clone_image", text="Image")
col.prop(brush, "clone_alpha", text="Alpha")
+
class IMAGE_PT_paint_stroke(bpy.types.Panel):
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'UI'
@@ -550,6 +551,7 @@ class IMAGE_PT_paint_stroke(bpy.types.Panel):
layout.prop(brush, "use_wrap")
+
class IMAGE_PT_paint_curve(bpy.types.Panel):
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'UI'
@@ -596,6 +598,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -603,4 +606,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/space_info.py b/release/scripts/ui/space_info.py
index c50893a2483..ff0646ba788 100644
--- a/release/scripts/ui/space_info.py
+++ b/release/scripts/ui/space_info.py
@@ -28,7 +28,7 @@ class INFO_HT_header(bpy.types.Header):
window = context.window
scene = context.scene
- rd = scene.render_data
+ rd = scene.render
row = layout.row(align=True)
row.template_header()
@@ -253,7 +253,8 @@ class INFO_MT_game(bpy.types.Menu):
layout.prop(gs, "show_debug_properties")
layout.prop(gs, "show_framerate_profile")
layout.prop(gs, "show_physics_visualization")
- layout.prop(gs, "deprecation_warnings")
+ layout.prop(gs, "use_deprecation_warnings")
+ layout.prop(gs, "use_animation_record")
class INFO_MT_render(bpy.types.Menu):
@@ -262,7 +263,7 @@ class INFO_MT_render(bpy.types.Menu):
def draw(self, context):
layout = self.layout
- # rd = context.scene.render_data
+ # rd = context.scene.render
layout.operator("screen.render", text="Render Image", icon='RENDER_STILL')
layout.operator("screen.render", text="Render Animation", icon='RENDER_ANIMATION').animation = True
@@ -422,6 +423,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -429,4 +431,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/space_logic.py b/release/scripts/ui/space_logic.py
index a5187c151db..07b26fdc862 100644
--- a/release/scripts/ui/space_logic.py
+++ b/release/scripts/ui/space_logic.py
@@ -56,6 +56,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -63,4 +64,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/space_nla.py b/release/scripts/ui/space_nla.py
index 35712236055..12ed8aa7740 100644
--- a/release/scripts/ui/space_nla.py
+++ b/release/scripts/ui/space_nla.py
@@ -173,6 +173,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -180,4 +181,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/space_node.py b/release/scripts/ui/space_node.py
index e6b89b06fd5..f510235a39d 100644
--- a/release/scripts/ui/space_node.py
+++ b/release/scripts/ui/space_node.py
@@ -60,10 +60,10 @@ class NODE_HT_header(bpy.types.Header):
layout.prop(snode_id, "use_nodes")
elif snode.tree_type == 'COMPOSITING':
- snode_id = snode.id
+ scene = snode.id
- layout.prop(snode_id, "use_nodes")
- layout.prop(snode_id.render_data, "free_unused_nodes", text="Free Unused")
+ layout.prop(scene, "use_nodes")
+ layout.prop(scene.render, "free_unused_nodes", text="Free Unused")
layout.prop(snode, "backdrop")
@@ -152,6 +152,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -159,4 +160,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/space_outliner.py b/release/scripts/ui/space_outliner.py
index bf2576b8586..d5bb35baa6c 100644
--- a/release/scripts/ui/space_outliner.py
+++ b/release/scripts/ui/space_outliner.py
@@ -111,6 +111,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -118,4 +119,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/space_sequencer.py b/release/scripts/ui/space_sequencer.py
index 25682a02b57..4cbabc71235 100644
--- a/release/scripts/ui/space_sequencer.py
+++ b/release/scripts/ui/space_sequencer.py
@@ -312,7 +312,7 @@ class SEQUENCER_PT_edit(SequencerButtonsPanel):
def draw(self, context):
layout = self.layout
- render_data = context.scene.render_data
+ render = context.scene.render
strip = act_strip(context)
split = layout.split(percentage=0.3)
@@ -348,7 +348,7 @@ class SEQUENCER_PT_edit(SequencerButtonsPanel):
col.prop(strip, "start_frame")
subrow = col.split(percentage=0.66)
subrow.prop(strip, "length")
- subrow.label(text="%.2f sec" % (strip.length / (render_data.fps / render_data.fps_base)))
+ subrow.label(text="%.2f sec" % (strip.length / (render.fps / render.fps_base)))
col = layout.column(align=True)
col.label(text="Offset:")
@@ -692,6 +692,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -699,4 +700,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/space_text.py b/release/scripts/ui/space_text.py
index 68f0b3c4b49..3a789566a61 100644
--- a/release/scripts/ui/space_text.py
+++ b/release/scripts/ui/space_text.py
@@ -293,6 +293,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -300,4 +301,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/space_time.py b/release/scripts/ui/space_time.py
index 9ec4a4446d5..2f2fad59e9f 100644
--- a/release/scripts/ui/space_time.py
+++ b/release/scripts/ui/space_time.py
@@ -181,6 +181,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -188,4 +189,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/space_userpref.py b/release/scripts/ui/space_userpref.py
index 84d0b973c60..f674696a740 100644
--- a/release/scripts/ui/space_userpref.py
+++ b/release/scripts/ui/space_userpref.py
@@ -171,9 +171,9 @@ class USERPREF_HT_header(bpy.types.Header):
op.path = "keymap.py"
op = layout.operator("wm.keyconfig_import", "Import Key Configuration...")
op.path = "keymap.py"
- elif userpref.active_section == 'EXTENSIONS':
+ elif userpref.active_section == 'ADDONS':
layout.operator_context = 'INVOKE_DEFAULT'
- op = layout.operator("wm.extension_install", "Install Extension...")
+ op = layout.operator("wm.addon_install", "Install Add-On...")
op.path = "*.py"
@@ -429,7 +429,7 @@ class USERPREF_PT_system(bpy.types.Panel):
col.prop(system, "dpi")
col.prop(system, "frame_server_port")
col.prop(system, "scrollback", text="Console Scrollback")
- col.prop(system, "auto_run_python_scripts")
+ col.prop(system, "auto_execute_scripts")
col.separator()
col.separator()
@@ -1366,21 +1366,21 @@ class USERPREF_PT_input(bpy.types.Panel):
#print("runtime", time.time() - start)
-class USERPREF_PT_extensions(bpy.types.Panel):
+class USERPREF_PT_addons(bpy.types.Panel):
bl_space_type = 'USER_PREFERENCES'
- bl_label = "Extensions"
+ bl_label = "Addons"
bl_region_type = 'WINDOW'
bl_show_header = False
def poll(self, context):
userpref = context.user_preferences
- return (userpref.active_section == 'EXTENSIONS')
+ return (userpref.active_section == 'ADDONS')
- def _extension_list(self):
+ def _addon_list(self):
import sys
modules = []
loaded_modules = set()
- paths = bpy.utils.script_paths("extensions")
+ paths = bpy.utils.script_paths("addons")
# sys.path.insert(0, None)
for path in paths:
# sys.path[0] = path
@@ -1393,11 +1393,11 @@ class USERPREF_PT_extensions(bpy.types.Panel):
layout = self.layout
userpref = context.user_preferences
- used_ext = {ext.module for ext in userpref.extensions}
+ used_ext = {ext.module for ext in userpref.addons}
col = layout.column()
- for mod in self._extension_list():
+ for mod in self._addon_list():
box = col.box()
row = box.row()
text = mod.__doc__
@@ -1405,24 +1405,25 @@ class USERPREF_PT_extensions(bpy.types.Panel):
text = mod.__name__
row.label(text=text)
module_name = mod.__name__
- row.operator("wm.extension_disable" if module_name in used_ext else "wm.extension_enable").module = module_name
+ row.operator("wm.addon_disable" if module_name in used_ext else "wm.addon_enable").module = module_name
from bpy.props import *
-class WM_OT_extension_enable(bpy.types.Operator):
- "Enable an extension"
- bl_idname = "wm.extension_enable"
- bl_label = "Enable Extension"
- module = StringProperty(name="Module", description="Module name of the extension to enable")
+class WM_OT_addon_enable(bpy.types.Operator):
+ "Enable an addon"
+ bl_idname = "wm.addon_enable"
+ bl_label = "Enable Add-On"
+
+ module = StringProperty(name="Module", description="Module name of the addon to enable")
def execute(self, context):
import traceback
- ext = context.user_preferences.extensions.new()
+ ext = context.user_preferences.addons.new()
module_name = self.properties.module
ext.module = module_name
-
+
try:
mod = __import__(module_name)
mod.register()
@@ -1432,12 +1433,12 @@ class WM_OT_extension_enable(bpy.types.Operator):
return {'FINISHED'}
-class WM_OT_extension_disable(bpy.types.Operator):
- "Disable an extension"
- bl_idname = "wm.extension_disable"
- bl_label = "Disable Extension"
+class WM_OT_addon_disable(bpy.types.Operator):
+ "Disable an addon"
+ bl_idname = "wm.addon_disable"
+ bl_label = "Disable Add-On"
- module = StringProperty(name="Module", description="Module name of the extension to disable")
+ module = StringProperty(name="Module", description="Module name of the addon to disable")
def execute(self, context):
import traceback
@@ -1448,27 +1449,27 @@ class WM_OT_extension_disable(bpy.types.Operator):
mod.unregister()
except:
traceback.print_exc()
-
- extensions = context.user_preferences.extensions
+
+ addons = context.user_preferences.addons
ok = True
while ok: # incase its in more then once.
ok = False
- for ext in extensions:
+ for ext in addons:
if ext.module == module_name:
- extensions.remove(ext)
+ addons.remove(ext)
ok = True
break
return {'FINISHED'}
-class WM_OT_extension_install(bpy.types.Operator):
- "Install an extension"
- bl_idname = "wm.extension_install"
- bl_label = "Install Extension"
+class WM_OT_addon_install(bpy.types.Operator):
+ "Install an addon"
+ bl_idname = "wm.addon_install"
+ bl_label = "Install Add-On"
+
+ module = StringProperty(name="Module", description="Module name of the addon to disable")
- module = StringProperty(name="Module", description="Module name of the extension to disable")
-
path = StringProperty(name="File Path", description="File path to write file to")
filename = StringProperty(name="File Name", description="Name of the file")
directory = StringProperty(name="Directory", description="Directory of the file")
@@ -1477,35 +1478,48 @@ class WM_OT_extension_install(bpy.types.Operator):
def execute(self, context):
import traceback
+ import zipfile
pyfile = self.properties.path
- paths = bpy.utils.script_paths("extensions")
- path_dest = os.path.join(paths[-1], os.path.basename(pyfile))
+ path_addons = bpy.utils.script_paths("addons")[-1]
- if os.path.exists(path_dest):
- self.report({'WARNING'}, "File already installed to '%s'\n" % path_dest)
- return {'CANCELLED'}
-
- if os.path.exists(path_dest):
- self.report({'WARNING'}, "File already installed to '%s'\n" % path_dest)
- return {'CANCELLED'}
+ #check to see if the file is in compressed format (.zip)
+ if zipfile.is_zipfile(pyfile):
+ try:
+ file_to_extract = zipfile.ZipFile(pyfile, 'r')
- try:
- shutil.copyfile(pyfile, path_dest)
- except:
- traceback.print_exc()
- return {'CANCELLED'}
+ #extract the file to "addons"
+ file_to_extract.extractall(path_addons)
+
+ except:
+ traceback.print_exc()
+ return {'CANCELLED'}
+
+ else:
+ path_dest = os.path.join(path_addons, os.path.basename(pyfile))
+
+ if os.path.exists(path_dest):
+ self.report({'WARNING'}, "File already installed to '%s'\n" % path_dest)
+ return {'CANCELLED'}
+
+ #if not compressed file just copy into the addon path
+ try:
+ shutil.copyfile(pyfile, path_dest)
+
+ except:
+ traceback.print_exc()
+ return {'CANCELLED'}
# TODO, should not be a warning.
# self.report({'WARNING'}, "File installed to '%s'\n" % path_dest)
return {'FINISHED'}
def invoke(self, context, event):
- paths = bpy.utils.script_paths("extensions")
+ paths = bpy.utils.script_paths("addons")
if not paths:
- self.report({'ERROR'}, "No 'extensions' path could be found in " + str(bpy.utils.script_paths()))
+ self.report({'ERROR'}, "No 'addons' path could be found in " + str(bpy.utils.script_paths()))
return {'CANCELLED'}
-
+
wm = context.manager
wm.add_fileselect(self)
return {'RUNNING_MODAL'}
@@ -1620,27 +1634,10 @@ class WM_OT_keyconfig_test(bpy.types.Operator):
def _string_value(value):
- result = ""
- if isinstance(value, str):
- if value != "":
- result = "\'%s\'" % value
- elif isinstance(value, bool):
- if value:
- result = "True"
- else:
- result = "False"
- elif isinstance(value, float):
- result = "%.10f" % value
- elif isinstance(value, int):
- result = "%d" % value
+ if isinstance(value, str) or isinstance(value, bool) or isinstance(value, float) or isinstance(value, int):
+ result = repr(value)
elif getattr(value, '__len__', False):
- if len(value):
- result = "["
- for i in range(0, len(value)):
- result += _string_value(value[i])
- if i != len(value)-1:
- result += ", "
- result += "]"
+ repr(list(value))
else:
print("Export key configuration: can't write ", value)
@@ -1695,7 +1692,7 @@ class WM_OT_keyconfig_import(bpy.types.Operator):
__import__(config_name)
- wm = bpy.data.window_managers[0]
+ wm = bpy.context.manager
wm.active_keyconfig = wm.keyconfigs[config_name]
return {'FINISHED'}
@@ -1737,7 +1734,7 @@ class WM_OT_keyconfig_export(bpy.types.Operator):
f.write("# Configuration %s\n" % name)
f.write("import bpy\n\n")
- f.write("wm = bpy.data.window_managers[0]\n")
+ f.write("wm = bpy.context.manager\n")
f.write("kc = wm.add_keyconfig('%s')\n\n" % name)
for km in kc.keymaps:
@@ -1916,11 +1913,11 @@ classes = [
USERPREF_PT_system,
USERPREF_PT_file,
USERPREF_PT_input,
- USERPREF_PT_extensions,
-
- WM_OT_extension_enable,
- WM_OT_extension_disable,
- WM_OT_extension_install,
+ USERPREF_PT_addons,
+
+ WM_OT_addon_enable,
+ WM_OT_addon_disable,
+ WM_OT_addon_install,
WM_OT_keyconfig_export,
WM_OT_keyconfig_import,
@@ -1938,6 +1935,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -1945,4 +1943,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/space_view3d.py b/release/scripts/ui/space_view3d.py
index 3a1bca75baa..865e132745b 100644
--- a/release/scripts/ui/space_view3d.py
+++ b/release/scripts/ui/space_view3d.py
@@ -80,7 +80,7 @@ class VIEW3D_HT_header(bpy.types.Header):
row.prop(toolsettings, "proportional_editing", text="", icon_only=True)
if toolsettings.proportional_editing != 'DISABLED':
row.prop(toolsettings, "proportional_editing_falloff", text="", icon_only=True)
-
+
# paint save
if mode_string == 'PAINT_TEXTURE':
row.operator("image.save_dirty", text="Save Edited")
@@ -719,17 +719,17 @@ class VIEW3D_MT_object_specials(bpy.types.Menu):
props.path_iter = "selected_editable_objects"
props.path_item = "data.spot_size"
props.input_scale = 0.01
-
+
props = layout.operator("wm.context_modal_mouse", text="Distance")
props.path_iter = "selected_editable_objects"
props.path_item = "data.distance"
props.input_scale = 0.1
-
+
props = layout.operator("wm.context_modal_mouse", text="Clip Start")
props.path_iter = "selected_editable_objects"
props.path_item = "data.shadow_buffer_clip_start"
props.input_scale = 0.05
-
+
props = layout.operator("wm.context_modal_mouse", text="Clip End")
props.path_iter = "selected_editable_objects"
props.path_item = "data.shadow_buffer_clip_end"
@@ -849,7 +849,6 @@ class VIEW3D_MT_paint_vertex(bpy.types.Menu):
layout = self.layout
layout.operator("paint.vertex_color_set")
- layout.operator("paint.vertex_color_set", text="Set Selected Vertex Colors").selected = True
class VIEW3D_MT_hook(bpy.types.Menu):
@@ -1026,6 +1025,10 @@ class VIEW3D_MT_pose(bpy.types.Menu):
layout.separator()
+ layout.operator("pose.relax")
+
+ layout.separator()
+
layout.menu("VIEW3D_MT_pose_apply")
layout.separator()
@@ -1262,7 +1265,7 @@ class VIEW3D_MT_edit_mesh_extrude(bpy.types.Menu):
totface = mesh.total_face_sel
totedge = mesh.total_edge_sel
totvert = mesh.total_vert_sel
-
+
# the following is dependent on selection modes
# we don't really want that
# if selection_mode[0]: # vert
@@ -1300,38 +1303,38 @@ class VIEW3D_MT_edit_mesh_extrude(bpy.types.Menu):
if totvert == 0:
return ()
elif totedge == 0:
- return (0,3)
+ return (0, 3)
elif totface == 0:
- return (0,2,3)
+ return (0, 2, 3)
else:
- return (0,1,2,3)
-
-
+ return (0, 1, 2, 3)
+
# should never get here
return ()
def draw(self, context):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
-
- def region_menu():
+
+ def region_menu():
layout.operator("view3d.edit_mesh_extrude_move_normal", text="Region")
-
+
def face_menu():
layout.operator("mesh.extrude_faces_move", text="Individual Faces")
-
+
def edge_menu():
layout.operator("mesh.extrude_edges_move", text="Edges Only")
-
+
def vert_menu():
layout.operator("mesh.extrude_vertices_move", text="Vertices Only")
-
+
menu_funcs = region_menu, face_menu, edge_menu, vert_menu
-
+
for i in self.extrude_options(context):
func = menu_funcs[i]
func()
+
class VIEW3D_OT_edit_mesh_extrude_individual_move(bpy.types.Operator):
"Extrude individual elements and move"
bl_label = "Extrude Individual and Move"
@@ -1344,19 +1347,20 @@ class VIEW3D_OT_edit_mesh_extrude_individual_move(bpy.types.Operator):
totface = mesh.total_face_sel
totedge = mesh.total_edge_sel
totvert = mesh.total_vert_sel
-
+
if selection_mode[2] and totface == 1:
- return bpy.ops.mesh.extrude_region_move('INVOKE_REGION_WIN', TRANSFORM_OT_translate = {"constraint_orientation":"NORMAL", "constraint_axis":[False, False, True]})
+ return bpy.ops.mesh.extrude_region_move('INVOKE_REGION_WIN', TRANSFORM_OT_translate={"constraint_orientation": "NORMAL", "constraint_axis": [False, False, True]})
elif selection_mode[2] and totface > 1:
return bpy.ops.mesh.extrude_faces_move('INVOKE_REGION_WIN')
- elif selection_mode[1] and totedge >= 1:
+ elif selection_mode[1] and totedge >= 1:
return bpy.ops.mesh.extrude_edges_move('INVOKE_REGION_WIN')
- else:
+ else:
return bpy.ops.mesh.extrude_vertices_move('INVOKE_REGION_WIN')
-
+
def invoke(self, context, event):
return self.execute(context)
+
class VIEW3D_OT_edit_mesh_extrude_move(bpy.types.Operator):
"Extrude and move along normals"
bl_label = "Extrude and Move on Normals"
@@ -1368,17 +1372,18 @@ class VIEW3D_OT_edit_mesh_extrude_move(bpy.types.Operator):
totface = mesh.total_face_sel
totedge = mesh.total_edge_sel
totvert = mesh.total_vert_sel
-
+
if totface >= 1 or totvert == 1:
- return bpy.ops.mesh.extrude_region_move('INVOKE_REGION_WIN', TRANSFORM_OT_translate = {"constraint_orientation":"NORMAL", "constraint_axis":[False, False, True]})
- elif totedge == 1:
- return bpy.ops.mesh.extrude_region_move('INVOKE_REGION_WIN', TRANSFORM_OT_translate = {"constraint_orientation":"NORMAL", "constraint_axis":[True, True, False]})
+ return bpy.ops.mesh.extrude_region_move('INVOKE_REGION_WIN', TRANSFORM_OT_translate={"constraint_orientation": "NORMAL", "constraint_axis": [False, False, True]})
+ elif totedge == 1:
+ return bpy.ops.mesh.extrude_region_move('INVOKE_REGION_WIN', TRANSFORM_OT_translate={"constraint_orientation": "NORMAL", "constraint_axis": [True, True, False]})
else:
return bpy.ops.mesh.extrude_region_move('INVOKE_REGION_WIN')
-
+
def invoke(self, context, event):
return self.execute(context)
+
class VIEW3D_MT_edit_mesh_vertices(bpy.types.Menu):
bl_label = "Vertices"
@@ -2258,6 +2263,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -2265,4 +2271,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/ui/space_view3d_toolbar.py b/release/scripts/ui/space_view3d_toolbar.py
index e45d79f622e..6de4ba6ce34 100644
--- a/release/scripts/ui/space_view3d_toolbar.py
+++ b/release/scripts/ui/space_view3d_toolbar.py
@@ -1029,6 +1029,7 @@ def register():
for cls in classes:
register(cls)
+
def unregister():
unregister = bpy.types.unregister
for cls in classes:
@@ -1036,4 +1037,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index 2f2fcfcc531..f6950ba07b8 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -70,11 +70,11 @@ void BKE_animdata_make_local(struct AnimData *adt);
/* Used to create a new 'custom' KeyingSet for the user, that will be automatically added to the stack */
struct KeyingSet *BKE_keyingset_add(struct ListBase *list, const char name[], short flag, short keyingflag);
-/* Add a destination to a KeyingSet */
-void BKE_keyingset_add_destination(struct KeyingSet *ks, struct ID *id, const char group_name[], const char rna_path[], int array_index, short flag, short groupmode);
+/* Add a path to a KeyingSet */
+void BKE_keyingset_add_path(struct KeyingSet *ks, struct ID *id, const char group_name[], const char rna_path[], int array_index, short flag, short groupmode);
/* Find the destination matching the criteria given */
-struct KS_Path *BKE_keyingset_find_destination(struct KeyingSet *ks, struct ID *id, const char group_name[], const char rna_path[], int array_index, int group_mode);
+struct KS_Path *BKE_keyingset_find_path(struct KeyingSet *ks, struct ID *id, const char group_name[], const char rna_path[], int array_index, int group_mode);
/* Copy all KeyingSets in the given list */
void BKE_keyingsets_copy(struct ListBase *newlist, struct ListBase *list);
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index 3aad5a8c1e4..6084b0cfb73 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -113,7 +113,7 @@ typedef struct Global {
/* #define G_FACESELECT (1 << 8) use (mesh->editflag & ME_EDIT_PAINT_MASK) */
#define G_DEBUG (1 << 12)
-#define G_DOSCRIPTLINKS (1 << 13)
+#define G_SCRIPT_AUTOEXEC (1 << 13)
/* #define G_NOFROZEN (1 << 17) also removed */
#define G_GREASEPENCIL (1 << 17)
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 153cf3f300e..6b22b10cf24 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -130,9 +130,6 @@ void BKE_image_assign_ibuf(struct Image *ima, struct ImBuf *ibuf);
/* called on frame change or before render */
void BKE_image_user_calc_frame(struct ImageUser *iuser, int cfra, int fieldnr);
-/* produce image export path */
-int BKE_get_image_export_path(struct Image *im, const char *dest_dir, char *abs, int abs_size, char *rel, int rel_size);
-
/* fix things in ImageUser when new image gets assigned */
void BKE_image_user_new_image(struct Image *ima, struct ImageUser *iuser);
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 703ed118a58..a6a641a3219 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -112,10 +112,13 @@ void boundbox_set_from_min_max(struct BoundBox *bb, float min[3], float max[3]);
struct BoundBox *object_get_boundbox(struct Object *ob);
void object_boundbox_flag(struct Object *ob, int flag, int set);
void minmax_object(struct Object *ob, float *min, float *max);
-void minmax_object_duplis(struct Scene *scene, struct Object *ob, float *min, float *max);
+int minmax_object_duplis(struct Scene *scene, struct Object *ob, float *min, float *max);
void solve_tracking (struct Object *ob, float targetmat[][4]);
int ray_hit_boundbox(struct BoundBox *bb, float ray_start[3], float ray_normal[3]);
+void *object_tfm_backup(struct Object *ob);
+void object_tfm_restore(struct Object *ob, void *obtfm_pt);
+
void object_handle_update(struct Scene *scene, struct Object *ob);
float give_timeoffset(struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h
index b291d9126ee..10550ccdc05 100644
--- a/source/blender/blenkernel/BKE_pointcache.h
+++ b/source/blender/blenkernel/BKE_pointcache.h
@@ -55,6 +55,7 @@
/* File open options, for BKE_ptcache_file_open */
#define PTCACHE_FILE_READ 0
#define PTCACHE_FILE_WRITE 1
+#define PTCACHE_FILE_UPDATE 2
/* PTCacheID types */
#define PTCACHE_TYPE_SOFTBODY 0
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 7b2eea141f2..a880417a111 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -547,7 +547,7 @@ void BKE_all_animdata_fix_paths_rename (char *prefix, char *oldName, char *newNa
/* Find the first path that matches the given criteria */
// TODO: do we want some method to perform partial matches too?
-KS_Path *BKE_keyingset_find_destination (KeyingSet *ks, ID *id, const char group_name[], const char rna_path[], int array_index, int group_mode)
+KS_Path *BKE_keyingset_find_path (KeyingSet *ks, ID *id, const char group_name[], const char rna_path[], int array_index, int group_mode)
{
KS_Path *ksp;
@@ -624,7 +624,7 @@ KeyingSet *BKE_keyingset_add (ListBase *list, const char name[], short flag, sho
/* Add a destination to a KeyingSet. Nothing is returned for now...
* Checks are performed to ensure that destination is appropriate for the KeyingSet in question
*/
-void BKE_keyingset_add_destination (KeyingSet *ks, ID *id, const char group_name[], const char rna_path[], int array_index, short flag, short groupmode)
+void BKE_keyingset_add_path (KeyingSet *ks, ID *id, const char group_name[], const char rna_path[], int array_index, short flag, short groupmode)
{
KS_Path *ksp;
@@ -643,7 +643,7 @@ void BKE_keyingset_add_destination (KeyingSet *ks, ID *id, const char group_name
}
/* don't add if there is already a matching KS_Path in the KeyingSet */
- if (BKE_keyingset_find_destination(ks, id, group_name, rna_path, array_index, groupmode)) {
+ if (BKE_keyingset_find_path(ks, id, group_name, rna_path, array_index, groupmode)) {
if (G.f & G_DEBUG)
printf("ERROR: destination already exists in Keying Set \n");
return;
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 9c1e15b0f77..4903ea84b3d 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -1502,7 +1502,8 @@ void where_is_armature (bArmature *arm)
}
}
-/* if bone layer is protected, copy the data from from->pose */
+/* if bone layer is protected, copy the data from from->pose
+ * when used with linked libraries this copies from the linked pose into the local pose */
static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected)
{
bPose *pose= ob->pose, *frompose= from->pose;
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 1567ed0f986..171b48af974 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -291,8 +291,6 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename)
if (G.f & G_SWAP_EXCHANGE) bfd->globalf |= G_SWAP_EXCHANGE;
else bfd->globalf &= ~G_SWAP_EXCHANGE;
- if ((U.flag & USER_DONT_DOSCRIPTLINKS)) bfd->globalf &= ~G_DOSCRIPTLINKS;
-
G.f= bfd->globalf;
if (!G.background) {
@@ -358,7 +356,7 @@ void BKE_userdef_free(void)
BLI_freelistN(&U.uifonts);
BLI_freelistN(&U.themes);
BLI_freelistN(&U.keymaps);
- BLI_freelistN(&U.extensions);
+ BLI_freelistN(&U.addons);
}
/* returns:
diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c
index 89c3da9b3e9..b521ec41cba 100644
--- a/source/blender/blenkernel/intern/boids.c
+++ b/source/blender/blenkernel/intern/boids.c
@@ -162,8 +162,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
else if(rule->type == eBoidRuleType_Avoid && bpa->data.mode == eBoidMode_Climbing &&
priority > 2.0f * gabr->fear_factor) {
/* detach from surface and try to fly away from danger */
- VECCOPY(efd.vec_to_point, bpa->gravity);
- mul_v3_fl(efd.vec_to_point, -1.0f);
+ negate_v3_v3(efd.vec_to_point, bpa->gravity);
}
VECCOPY(bbd->wanted_co, efd.vec_to_point);
@@ -689,7 +688,7 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti
if(bpa->data.health/bbd->part->boids->health * bbd->part->boids->aggression < e_strength / f_strength) {
/* decide to flee */
if(closest_dist < fbr->flee_distance * fbr->distance) {
- mul_v3_fl(bbd->wanted_co, -1.0f);
+ negate_v3(bbd->wanted_co);
bbd->wanted_speed = val->max_speed;
}
else { /* wait for better odds */
@@ -1342,9 +1341,8 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
float grav[3];
/* Don't take gravity's strength in to account, */
/* otherwise amount of banking is hard to control. */
- VECCOPY(grav, ground_nor);
- mul_v3_fl(grav, -1.0f);
-
+ negate_v3_v3(grav, ground_nor);
+
project_v3_v3v3(dvec, bpa->data.acc, pa->state.vel);
sub_v3_v3v3(dvec, bpa->data.acc, dvec);
@@ -1387,7 +1385,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
VECCOPY(mat[2], bpa->gravity);
}
- mul_v3_fl(mat[2], -1.0f);
+ negate_v3(mat[2]);
cross_v3_v3v3(mat[1], mat[2], mat[0]);
/* apply rotation */
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 86591fe784d..855de95572a 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -545,7 +545,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
implicit_set_positions(clmd);
cache->flag |= PTCACHE_SIMULATION_VALID;
}
- else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) {
+ else if( /*ob->id.lib ||*/ (cache->flag & PTCACHE_BAKED)) { /* 2.4x disabled lib, but this can be used in some cases, testing further - campbell */
/* if baked and nothing in cache, do nothing */
cache->flag &= ~PTCACHE_SIMULATION_VALID;
cache->simframe= 0;
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index b726437a874..b024ba5f4e1 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -1550,8 +1550,8 @@ static int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, Collision
// cloth - object collisions
int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, float dt )
{
- Cloth *cloth=NULL;
- BVHTree *cloth_bvh=NULL;
+ Cloth *cloth= clmd->clothObject;
+ BVHTree *cloth_bvh= cloth->bvhtree;
int i=0, numfaces = 0, numverts = 0, k, l, j;
int rounds = 0; // result counts applied collisions; ic is for debug output;
ClothVertex *verts = NULL;
@@ -1559,16 +1559,12 @@ int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, fl
Object **collobjs = NULL;
int numcollobj = 0;
- if ( ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) || ! ( ( ( Cloth * ) clmd->clothObject )->bvhtree ) )
- {
+ if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || cloth_bvh==NULL)
return 0;
- }
- cloth = clmd->clothObject;
verts = cloth->verts;
- cloth_bvh = ( BVHTree * ) cloth->bvhtree;
- numfaces = clmd->clothObject->numfaces;
- numverts = clmd->clothObject->numverts;
+ numfaces = cloth->numfaces;
+ numverts = cloth->numverts;
////////////////////////////////////////////////////////////
// static collisions
@@ -1672,8 +1668,8 @@ int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, fl
// collisions = 1;
verts = cloth->verts; // needed for openMP
- numfaces = clmd->clothObject->numfaces;
- numverts = clmd->clothObject->numverts;
+ numfaces = cloth->numfaces;
+ numverts = cloth->numverts;
verts = cloth->verts;
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index c22510a2527..53a07193aa6 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -1947,7 +1947,7 @@ static void pycon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintT
/* only execute target calculation if allowed */
#ifndef DISABLE_PYTHON
- if (G.f & G_DOSCRIPTLINKS)
+ if (G.f & G_SCRIPT_AUTOEXEC)
BPY_pyconstraint_target(data, ct);
#endif
}
@@ -1963,7 +1963,7 @@ static void pycon_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targ
bPythonConstraint *data= con->data;
/* only evaluate in python if we're allowed to do so */
- if ((G.f & G_DOSCRIPTLINKS)==0) return;
+ if ((G.f & G_SCRIPT_AUTOEXEC)==0) return;
/* currently removed, until I this can be re-implemented for multiple targets */
#if 0
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 9d33bc5ae11..fb27327c3be 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -191,6 +191,7 @@ Curve *copy_curve(Curve *cu)
cun->path= 0;
cun->editnurb= NULL;
+ cun->editfont= NULL;
#if 0 // XXX old animation system
/* single user ipo too */
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 552c7d0767d..bd29bd55428 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -326,7 +326,7 @@ FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction
}
/* threshold for binary-searching keyframes - threshold here should be good enough for now, but should become userpref */
-#define BEZT_BINARYSEARCH_THRESH 0.00001f
+#define BEZT_BINARYSEARCH_THRESH 0.01f /* was 0.00001, but giving errors */
/* Binary search algorithm for finding where to insert BezTriple. (for use by insert_bezt_fcurve)
* Returns the index to insert at (data already at that index will be offset if replace is 0)
@@ -801,13 +801,19 @@ typedef struct DriverVarTypeInfo {
/* ......... */
+static ID *dtar_id_ensure_proxy_from(ID *id)
+{
+ if (id && GS(id->name)==ID_OB && ((Object *)id)->proxy_from)
+ return (ID *)(((Object *)id)->proxy_from);
+ return id;
+}
+
/* Helper function to obtain a value using RNA from the specified source (for evaluating drivers) */
static float dtar_get_prop_val (ChannelDriver *driver, DriverTarget *dtar)
{
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
ID *id;
- char *path;
int index;
float value= 0.0f;
@@ -815,22 +821,22 @@ static float dtar_get_prop_val (ChannelDriver *driver, DriverTarget *dtar)
if ELEM(NULL, driver, dtar)
return 0.0f;
- /* get RNA-pointer for the ID-block given in target */
- RNA_id_pointer_create(dtar->id, &id_ptr);
- id= dtar->id;
- path= dtar->rna_path;
+ id= dtar_id_ensure_proxy_from(dtar->id);
/* error check for missing pointer... */
// TODO: tag the specific target too as having issues
if (id == NULL) {
printf("Error: driver has an invalid target to use \n");
- if (G.f & G_DEBUG) printf("\tpath = %s\n", path);
+ if (G.f & G_DEBUG) printf("\tpath = %s\n", dtar->rna_path);
driver->flag |= DRIVER_FLAG_INVALID;
return 0.0f;
}
+ /* get RNA-pointer for the ID-block given in target */
+ RNA_id_pointer_create(id, &id_ptr);
+
/* get property to read from, and get value as appropriate */
- if (RNA_path_resolve_full(&id_ptr, path, &ptr, &prop, &index)) {
+ if (RNA_path_resolve_full(&id_ptr, dtar->rna_path, &ptr, &prop, &index)) {
switch (RNA_property_type(prop)) {
case PROP_BOOLEAN:
if (RNA_property_array_length(&ptr, prop))
@@ -859,7 +865,7 @@ static float dtar_get_prop_val (ChannelDriver *driver, DriverTarget *dtar)
}
else {
if (G.f & G_DEBUG)
- printf("Driver Evaluation Error: cannot resolve target for %s -> %s \n", id->name, path);
+ printf("Driver Evaluation Error: cannot resolve target for %s -> %s \n", id->name, dtar->rna_path);
driver->flag |= DRIVER_FLAG_INVALID;
return 0.0f;
@@ -871,13 +877,16 @@ static float dtar_get_prop_val (ChannelDriver *driver, DriverTarget *dtar)
/* Helper function to obtain a pointer to a Pose Channel (for evaluating drivers) */
static bPoseChannel *dtar_get_pchan_ptr (ChannelDriver *driver, DriverTarget *dtar)
{
+ ID *id;
/* sanity check */
if ELEM(NULL, driver, dtar)
return NULL;
-
+
+ id= dtar_id_ensure_proxy_from(dtar->id);
+
/* check if the ID here is a valid object */
- if ((dtar->id) && GS(dtar->id->name)) {
- Object *ob= (Object *)dtar->id;
+ if (id && GS(id->name)) {
+ Object *ob= (Object *)id;
/* get pose, and subsequently, posechannel */
return get_pose_channel(ob->pose, dtar->pchan_name);
@@ -947,12 +956,12 @@ static float dvar_eval_locDiff (ChannelDriver *driver, DriverVar *dvar)
DRIVER_TARGETS_USED_LOOPER(dvar)
{
/* get pointer to loc values to store in */
- Object *ob= (Object *)dtar->id;
+ Object *ob= (Object *)dtar_id_ensure_proxy_from(dtar->id);
bPoseChannel *pchan;
float tmp_loc[3];
/* check if this target has valid data */
- if ((ob == NULL) || (GS(dtar->id->name) != ID_OB)) {
+ if ((ob == NULL) || (GS(ob->id.name) != ID_OB)) {
/* invalid target, so will not have enough targets */
driver->flag |= DRIVER_FLAG_INVALID;
return 0.0f;
@@ -1007,14 +1016,14 @@ static float dvar_eval_locDiff (ChannelDriver *driver, DriverVar *dvar)
static float dvar_eval_transChan (ChannelDriver *driver, DriverVar *dvar)
{
DriverTarget *dtar= &dvar->targets[0];
- Object *ob= (Object *)dtar->id;
+ Object *ob= (Object *)dtar_id_ensure_proxy_from(dtar->id);
bPoseChannel *pchan;
float mat[4][4];
float eul[3] = {0.0f,0.0f,0.0f};
short useEulers=0, rotOrder=ROT_MODE_EUL;
/* check if this target has valid data */
- if ((ob == NULL) || (GS(dtar->id->name) != ID_OB)) {
+ if ((ob == NULL) || (GS(ob->id.name) != ID_OB)) {
/* invalid target, so will not have enough targets */
driver->flag |= DRIVER_FLAG_INVALID;
return 0.0f;
@@ -1281,7 +1290,7 @@ ChannelDriver *fcurve_copy_driver (ChannelDriver *driver)
float driver_get_variable_value (ChannelDriver *driver, DriverVar *dvar)
{
DriverVarTypeInfo *dvti;
-
+
/* sanity check */
if (ELEM(NULL, driver, dvar))
return 0.0f;
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index d6edb068fa0..accadb3d434 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -2260,104 +2260,3 @@ void BKE_image_user_calc_frame(ImageUser *iuser, int cfra, int fieldnr)
if(iuser->ok==0) iuser->ok= 1;
}
}
-
-/*
- Produce image export path.
-
- Fails returning 0 if image filename is empty or if destination path
- matches image path (i.e. both are the same file).
-
- Trailing slash in dest_dir is optional.
-
- Logic:
-
- - if an image is "below" current .blend file directory, rebuild the
- same dir structure in dest_dir
-
- For example //textures/foo/bar.png becomes
- [dest_dir]/textures/foo/bar.png.
-
- - if an image is not "below" current .blend file directory,
- disregard it's path and copy it in the same directory where 3D file
- goes.
-
- For example //../foo/bar.png becomes [dest_dir]/bar.png.
-
- This logic will help ensure that all image paths are relative and
- that a user gets his images in one place. It'll also provide
- consistent behaviour across exporters.
- */
-int BKE_get_image_export_path(struct Image *im, const char *dest_dir, char *abs, int abs_size, char *rel, int rel_size)
-{
- char path[FILE_MAX];
- char dir[FILE_MAX];
- char base[FILE_MAX];
- char blend_dir[FILE_MAX]; /* directory, where current .blend file resides */
- char dest_path[FILE_MAX];
- char rel_dir[FILE_MAX];
- int len;
-
- if (abs)
- abs[0]= 0;
-
- if (rel)
- rel[0]= 0;
-
- BLI_split_dirfile_basic(G.sce, blend_dir, NULL);
-
- if (!strlen(im->name)) {
- if (G.f & G_DEBUG) printf("Invalid image type.\n");
- return 0;
- }
-
- BLI_strncpy(path, im->name, sizeof(path));
-
- /* expand "//" in filename and get absolute path */
- BLI_convertstringcode(path, G.sce);
-
- /* get the directory part */
- BLI_split_dirfile_basic(path, dir, base);
-
- len= strlen(blend_dir);
-
- rel_dir[0] = 0;
-
- /* if image is "below" current .blend file directory */
- if (!strncmp(path, blend_dir, len)) {
-
- /* if image is _in_ current .blend file directory */
- if (!strcmp(dir, blend_dir)) {
- BLI_join_dirfile(dest_path, dest_dir, base);
- }
- /* "below" */
- else {
- /* rel = image_path_dir - blend_dir */
- BLI_strncpy(rel_dir, dir + len, sizeof(rel_dir));
-
- BLI_join_dirfile(dest_path, dest_dir, rel_dir);
- BLI_join_dirfile(dest_path, dest_path, base);
- }
-
- }
- /* image is out of current directory */
- else {
- BLI_join_dirfile(dest_path, dest_dir, base);
- }
-
- if (abs)
- BLI_strncpy(abs, dest_path, abs_size);
-
- if (rel) {
- strncat(rel, rel_dir, rel_size);
- strncat(rel, base, rel_size);
- }
-
- /* return 2 if src=dest */
- if (!strcmp(path, dest_path)) {
- if (G.f & G_DEBUG) printf("%s and %s are the same file\n", path, dest_path);
- return 2;
- }
-
- return 1;
-}
-
diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c
index ed3e7348d7e..6912a65886a 100644
--- a/source/blender/blenkernel/intern/implicit.c
+++ b/source/blender/blenkernel/intern/implicit.c
@@ -1408,19 +1408,29 @@ typedef struct HairGridVert {
float velocity[3];
float density;
} HairGridVert;
+#define HAIR_GRID_INDEX(vec, min, max, axis) (int)( (vec[axis] - min[axis]) / (max[axis] - min[axis]) * 9.99f );
/* Smoothing of hair velocities:
* adapted from
Volumetric Methods for Simulation and Rendering of Hair
by Lena Petrovic, Mark Henne and John Anderson
* Pixar Technical Memo #06-08, Pixar Animation Studios
*/
-static void hair_velocity_smoothing(float smoothfac, lfVector *lF, lfVector *lX, lfVector *lV, int numverts)
+static void hair_velocity_smoothing(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVector *lV, int numverts)
{
- /* TODO: this is an initial implementation and should be made much better in due time */
+ /* TODO: This is an initial implementation and should be made much better in due time.
+ * What should at least be implemented is a grid size parameter and a smoothing kernel
+ * for bigger grids.
+ */
/* 10x10x10 grid gives nice initial results */
HairGridVert grid[10][10][10];
+ HairGridVert colg[10][10][10];
+ ListBase *colliders = get_collider_cache(clmd->scene, NULL);
+ ColliderCache *col = NULL;
float gmin[3], gmax[3], density;
+ /* 2.0f is an experimental value that seems to give good results */
+ float smoothfac = 2.0f * clmd->sim_parms->velocity_smooth;
+ float collfac = 2.0f * clmd->sim_parms->collider_friction;
int v = 0;
int i = 0;
int j = 0;
@@ -1439,15 +1449,20 @@ static void hair_velocity_smoothing(float smoothfac, lfVector *lF, lfVector *lX,
grid[i][j][k].velocity[1] = 0.0f;
grid[i][j][k].velocity[2] = 0.0f;
grid[i][j][k].density = 0.0f;
+
+ colg[i][j][k].velocity[0] = 0.0f;
+ colg[i][j][k].velocity[1] = 0.0f;
+ colg[i][j][k].velocity[2] = 0.0f;
+ colg[i][j][k].density = 0.0f;
}
}
}
/* gather velocities & density */
- for(v = 0; v < numverts; v++) {
- i = (int)( (lX[v][0] - gmin[0]) / (gmax[0] - gmin[0]) * 9.99f );
- j = (int)( (lX[v][1] - gmin[1]) / (gmax[1] - gmin[1]) * 9.99f );
- k = (int)( (lX[v][2] - gmin[2]) / (gmax[2] - gmin[2]) * 9.99f );
+ if(smoothfac > 0.0f) for(v = 0; v < numverts; v++) {
+ i = HAIR_GRID_INDEX(lX[v], gmin, gmax, 0);
+ j = HAIR_GRID_INDEX(lX[v], gmin, gmax, 1);
+ k = HAIR_GRID_INDEX(lX[v], gmin, gmax, 2);
grid[i][j][k].velocity[0] += lV[v][0];
grid[i][j][k].velocity[1] += lV[v][1];
@@ -1455,6 +1470,36 @@ static void hair_velocity_smoothing(float smoothfac, lfVector *lF, lfVector *lX,
grid[i][j][k].density += 1.0f;
}
+ /* gather colliders */
+ if(colliders && collfac > 0.0f) for(col = colliders->first; col; col = col->next)
+ {
+ MVert *loc0 = col->collmd->x;
+ MVert *loc1 = col->collmd->xnew;
+ float vel[3];
+
+ for(v=0; v<col->collmd->numverts; v++, loc0++, loc1++) {
+ i = HAIR_GRID_INDEX(loc1->co, gmin, gmax, 0);
+
+ if(i>=0 && i<10) {
+ j = HAIR_GRID_INDEX(loc1->co, gmin, gmax, 1);
+
+ if(j>=0 && j<10) {
+ k = HAIR_GRID_INDEX(loc1->co, gmin, gmax, 2);
+
+ if(k>=0 && k<10) {
+ VECSUB(vel, loc1->co, loc0->co);
+
+ colg[i][j][k].velocity[0] += vel[0];
+ colg[i][j][k].velocity[1] += vel[1];
+ colg[i][j][k].velocity[2] += vel[2];
+ colg[i][j][k].density += 1.0;
+ }
+ }
+ }
+ }
+ }
+
+
/* divide velocity with density */
for(i = 0; i < 10; i++) {
for(j = 0; j < 10; j++) {
@@ -1465,21 +1510,35 @@ static void hair_velocity_smoothing(float smoothfac, lfVector *lF, lfVector *lX,
grid[i][j][k].velocity[1] /= density;
grid[i][j][k].velocity[2] /= density;
}
+
+ density = colg[i][j][k].density;
+ if(density > 0.0f) {
+ colg[i][j][k].velocity[0] /= density;
+ colg[i][j][k].velocity[1] /= density;
+ colg[i][j][k].velocity[2] /= density;
+ }
}
}
}
/* calculate forces */
for(v = 0; v < numverts; v++) {
- i = (int)( (lX[v][0] - gmin[0]) / (gmax[0] - gmin[0]) * 9.99f );
- j = (int)( (lX[v][1] - gmin[1]) / (gmax[1] - gmin[1]) * 9.99f );
- k = (int)( (lX[v][2] - gmin[2]) / (gmax[2] - gmin[2]) * 9.99f );
-
- /* 2.0f is an experimental value that seems to give good results */
- lF[v][0] += 2.0f * smoothfac * (grid[i][j][k].velocity[0] - lV[v][0]);
- lF[v][1] += 2.0f * smoothfac * (grid[i][j][k].velocity[1] - lV[v][1]);
- lF[v][2] += 2.0f * smoothfac * (grid[i][j][k].velocity[2] - lV[v][2]);
+ i = HAIR_GRID_INDEX(lX[v], gmin, gmax, 0);
+ j = HAIR_GRID_INDEX(lX[v], gmin, gmax, 1);
+ k = HAIR_GRID_INDEX(lX[v], gmin, gmax, 2);
+
+ lF[v][0] += smoothfac * (grid[i][j][k].velocity[0] - lV[v][0]);
+ lF[v][1] += smoothfac * (grid[i][j][k].velocity[1] - lV[v][1]);
+ lF[v][2] += smoothfac * (grid[i][j][k].velocity[2] - lV[v][2]);
+
+ if(colg[i][j][k].density > 0.0f) {
+ lF[v][0] += collfac * (colg[i][j][k].velocity[0] - lV[v][0]);
+ lF[v][1] += collfac * (colg[i][j][k].velocity[1] - lV[v][1]);
+ lF[v][2] += collfac * (colg[i][j][k].velocity[2] - lV[v][2]);
+ }
}
+
+ free_collider_cache(&colliders);
}
static void cloth_calc_force(ClothModifierData *clmd, float frame, lfVector *lF, lfVector *lX, lfVector *lV, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors, float time, fmatrix3x3 *M)
{
@@ -1508,8 +1567,8 @@ static void cloth_calc_force(ClothModifierData *clmd, float frame, lfVector *lF,
init_lfvector(lF, gravity, numverts);
- if(clmd->sim_parms->velocity_smooth > 0.0f)
- hair_velocity_smoothing(clmd->sim_parms->velocity_smooth, lF, lX, lV, numverts);
+ if(clmd->sim_parms->velocity_smooth > 0.0f || clmd->sim_parms->collider_friction > 0.0f)
+ hair_velocity_smoothing(clmd, lF, lX, lV, numverts);
/* multiply lF with mass matrix
// force = mass * acceleration (in this case: gravity)
@@ -1579,6 +1638,36 @@ static void cloth_calc_force(ClothModifierData *clmd, float frame, lfVector *lF,
VECADDS(lF[mfaces[i].v4], lF[mfaces[i].v4], tmp, factor);
}
}
+
+ /* Hair has only edges */
+ if(cloth->numfaces == 0) {
+ ClothSpring *spring;
+ float edgevec[3]={0,0,0}; //edge vector
+ float edgeunnormal[3]={0,0,0}; // not-normalized-edge normal
+ float tmp[3]={0,0,0};
+ float factor = 0.01;
+
+ search = cloth->springs;
+ while(search) {
+ spring = search->link;
+
+ if(spring->type == CLOTH_SPRING_TYPE_STRUCTURAL) {
+ VECSUB(edgevec, (float*)lX[spring->ij], (float*)lX[spring->kl]);
+
+ project_v3_v3v3(tmp, winvec[spring->ij], edgevec);
+ VECSUB(edgeunnormal, winvec[spring->ij], tmp);
+ /* hair doesn't stretch too much so we can use restlen pretty safely */
+ VECADDS(lF[spring->ij], lF[spring->ij], edgeunnormal, spring->restlen * factor);
+
+ project_v3_v3v3(tmp, winvec[spring->kl], edgevec);
+ VECSUB(edgeunnormal, winvec[spring->kl], tmp);
+ VECADDS(lF[spring->kl], lF[spring->kl], edgeunnormal, spring->restlen * factor);
+ }
+
+ search = search->next;
+ }
+ }
+
del_lfvector(winvec);
}
@@ -1689,8 +1778,8 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
VECCOPY(verts[i].txold, id->X[i]);
}
-
- if(clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED)
+
+ if(clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED && clmd->clothObject->bvhtree)
{
float temp = clmd->sim_parms->stepsPerFrame;
/* not too nice hack, but collisions need this correction -jahka */
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index ff00dc9dc3c..146701f2976 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -353,15 +353,14 @@ static void latticeModifier_updateDepgraph(ModifierData *md, DagForest *forest,
static void modifier_vgroup_cache(ModifierData *md, float (*vertexCos)[3])
{
- md= md->next;
- if(md) {
- if(md->type==eModifierType_Armature) {
- ArmatureModifierData *amd = (ArmatureModifierData*) md;
- if(amd->multi)
- amd->prevCos= MEM_dupallocN(vertexCos);
- }
- /* lattice/mesh modifier too */
+ while((md=md->next) && md->type==eModifierType_Armature) {
+ ArmatureModifierData *amd = (ArmatureModifierData*) md;
+ if(amd->multi && amd->prevCos==NULL)
+ amd->prevCos= MEM_dupallocN(vertexCos);
+ else
+ break;
}
+ /* lattice/mesh modifier too */
}
@@ -4826,9 +4825,15 @@ static void castModifier_deformVerts(
ModifierData *md, Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
{
- DerivedMesh *dm = get_dm(md->scene, ob, NULL, derivedData, NULL, 0);
+ DerivedMesh *dm = NULL;
CastModifierData *cmd = (CastModifierData *)md;
+ if (ob->type == OB_MESH) {
+ /* DerivedMesh is used only in case object is MESH */
+ /* so we could optimize modifier applying by skipping DM creation */
+ dm = get_dm(md->scene, ob, NULL, derivedData, NULL, 0);
+ }
+
if (cmd->type == MOD_CAST_TYPE_CUBOID) {
castModifier_cuboid_do(cmd, ob, dm, vertexCos, numVerts);
} else { /* MOD_CAST_TYPE_SPHERE or MOD_CAST_TYPE_CYLINDER */
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 88aaf054aec..46c26524f47 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -2373,27 +2373,97 @@ void minmax_object(Object *ob, float *min, float *max)
}
}
-/* TODO - use dupli objects bounding boxes */
-void minmax_object_duplis(Scene *scene, Object *ob, float *min, float *max)
+int minmax_object_duplis(Scene *scene, Object *ob, float *min, float *max)
{
+ int ok= 0;
if ((ob->transflag & OB_DUPLI)==0) {
- return;
+ return ok;
} else {
ListBase *lb;
DupliObject *dob;
lb= object_duplilist(scene, ob);
for(dob= lb->first; dob; dob= dob->next) {
- if(dob->no_draw);
- else {
- /* should really use bound box of dup object */
- DO_MINMAX(dob->mat[3], min, max);
+ if(dob->no_draw == 0) {
+ BoundBox *bb= object_get_boundbox(dob->ob);
+
+ if(bb) {
+ int i;
+ for(i=0; i<8; i++) {
+ float vec[3];
+ mul_v3_m4v3(vec, dob->mat, bb->vec[i]);
+ DO_MINMAX(vec, min, max);
+ }
+
+ ok= 1;
+ }
}
}
free_object_duplilist(lb); /* does restore */
}
-}
+ return ok;
+}
+
+/* copied from DNA_object_types.h */
+typedef struct ObTfmBack {
+ float loc[3], dloc[3], orig[3];
+ float size[3], dsize[3]; /* scale and delta scale */
+ float rot[3], drot[3]; /* euler rotation */
+ float quat[4], dquat[4]; /* quaternion rotation */
+ float rotAxis[3], drotAxis[3]; /* axis angle rotation - axis part */
+ float rotAngle, drotAngle; /* axis angle rotation - angle part */
+ float obmat[4][4]; /* final worldspace matrix with constraints & animsys applied */
+ float parentinv[4][4]; /* inverse result of parent, so that object doesn't 'stick' to parent */
+ float constinv[4][4]; /* inverse result of constraints. doesn't include effect of parent or object local transform */
+ float imat[4][4]; /* inverse matrix of 'obmat' for during render, old game engine, temporally: ipokeys of transform */
+} ObTfmBack;
+
+void *object_tfm_backup(Object *ob)
+{
+ ObTfmBack *obtfm= MEM_mallocN(sizeof(ObTfmBack), "ObTfmBack");
+ copy_v3_v3(obtfm->loc, ob->loc);
+ copy_v3_v3(obtfm->dloc, ob->dloc);
+ copy_v3_v3(obtfm->orig, ob->orig);
+ copy_v3_v3(obtfm->size, ob->size);
+ copy_v3_v3(obtfm->dsize, ob->dsize);
+ copy_v3_v3(obtfm->rot, ob->rot);
+ copy_v3_v3(obtfm->drot, ob->drot);
+ copy_qt_qt(obtfm->quat, ob->quat);
+ copy_qt_qt(obtfm->dquat, ob->dquat);
+ copy_v3_v3(obtfm->rotAxis, ob->rotAxis);
+ copy_v3_v3(obtfm->drotAxis, ob->drotAxis);
+ obtfm->rotAngle= ob->rotAngle;
+ obtfm->drotAngle= ob->drotAngle;
+ copy_m4_m4(obtfm->obmat, ob->obmat);
+ copy_m4_m4(obtfm->parentinv, ob->parentinv);
+ copy_m4_m4(obtfm->constinv, ob->constinv);
+ copy_m4_m4(obtfm->imat, ob->imat);
+
+ return (void *)obtfm;
+}
+
+void object_tfm_restore(Object *ob, void *obtfm_pt)
+{
+ ObTfmBack *obtfm= (ObTfmBack *)obtfm_pt;
+ copy_v3_v3(ob->loc, obtfm->loc);
+ copy_v3_v3(ob->dloc, obtfm->dloc);
+ copy_v3_v3(ob->orig, obtfm->orig);
+ copy_v3_v3(ob->size, obtfm->size);
+ copy_v3_v3(ob->dsize, obtfm->dsize);
+ copy_v3_v3(ob->rot, obtfm->rot);
+ copy_v3_v3(ob->drot, obtfm->drot);
+ copy_qt_qt(ob->quat, obtfm->quat);
+ copy_qt_qt(ob->dquat, obtfm->dquat);
+ copy_v3_v3(ob->rotAxis, obtfm->rotAxis);
+ copy_v3_v3(ob->drotAxis, obtfm->drotAxis);
+ ob->rotAngle= obtfm->rotAngle;
+ ob->drotAngle= obtfm->drotAngle;
+ copy_m4_m4(ob->obmat, obtfm->obmat);
+ copy_m4_m4(ob->parentinv, obtfm->parentinv);
+ copy_m4_m4(ob->constinv, obtfm->constinv);
+ copy_m4_m4(ob->imat, obtfm->imat);
+}
/* proxy rule: lib_object->proxy_from == the one we borrow from, only set temporal and cleared here */
/* local_object->proxy == pointer to library object, saved in files and read */
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index a4784fc606d..9b1d48ac8c3 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -1056,6 +1056,8 @@ static int psys_threads_init_distribution(ParticleThread *threads, Scene *scene,
cpa->num=-1;
}
}
+ /* dmcache must be updated for parent particles if children from faces is used */
+ psys_calc_dmcache(ob, finaldm, psys);
return 0;
}
@@ -1820,8 +1822,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
project_v3_v3v3(dvec, r_vel, pa->state.ave);
sub_v3_v3v3(mat[0], pa->state.ave, dvec);
normalize_v3(mat[0]);
- VECCOPY(mat[2], r_vel);
- mul_v3_fl(mat[2], -1.0f);
+ negate_v3_v3(mat[2], r_vel);
normalize_v3(mat[2]);
cross_v3_v3v3(mat[1], mat[2], mat[0]);
@@ -3313,6 +3314,8 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
if(pa->alive==PARS_UNBORN
&& (part->flag & PART_UNBORN || cfra + psys->pointcache->step > pa->time))
reset_particle(sim, pa, dtime, cfra);
+ else if(part->phystype == PART_PHYS_NO)
+ reset_particle(sim, pa, dtime, cfra);
if(dfra>0.0 && ELEM(pa->alive,PARS_ALIVE,PARS_DYING)){
switch(part->phystype){
@@ -3805,7 +3808,7 @@ static void system_step(ParticleSimulationData *sim, float cfra)
pa->alive = PARS_ALIVE;
}
}
- else if(cfra != startframe && (sim->ob->id.lib || (cache->flag & PTCACHE_BAKED))) {
+ else if(cfra != startframe && ( /*sim->ob->id.lib ||*/ (cache->flag & PTCACHE_BAKED))) { /* 2.4x disabled lib, but this can be used in some cases, testing further - campbell */
psys_reset(psys, PSYS_RESET_CACHE_MISS);
psys->cfra=cfra;
psys->recalc = 0;
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 6859aba57c9..b1319a81f5d 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -203,9 +203,9 @@ static int ptcache_write_particle(int index, void *psys_v, void **data)
ParticleData *pa = psys->particles + index;
BoidParticle *boid = (psys->part->phystype == PART_PHYS_BOIDS) ? pa->boid : NULL;
float times[3] = {pa->time, pa->dietime, pa->lifetime};
+ int step = psys->pointcache->step;
if(data[BPHYS_DATA_INDEX]) {
- int step = psys->pointcache->step;
/* No need to store unborn or died particles */
if(pa->time - step > pa->state.time || pa->dietime + step < pa->state.time)
return 0;
@@ -222,7 +222,8 @@ static int ptcache_write_particle(int index, void *psys_v, void **data)
if(boid)
PTCACHE_DATA_FROM(data, BPHYS_DATA_BOIDS, &boid->data);
- return 1;
+ /* return flag 1+1=2 for newly born particles to copy exact birth location to previously cached frame */
+ return 1 + (pa->state.time >= pa->time && pa->prev_state.time <= pa->time);
}
void BKE_ptcache_make_particle_key(ParticleKey *key, int index, void **data, float time)
{
@@ -249,6 +250,10 @@ static void ptcache_read_particle(int index, void *psys_v, void **data, float fr
BKE_ptcache_make_particle_key(&pa->state, 0, data, cfra);
+ /* set frames cached before birth to birth time */
+ if(cfra < pa->time)
+ pa->state.time = pa->time;
+
if(data[BPHYS_DATA_SIZE])
PTCACHE_DATA_TO(data, BPHYS_DATA_SIZE, 0, &pa->size);
@@ -1148,6 +1153,9 @@ static PTCacheFile *ptcache_file_open(PTCacheID *pid, int mode, int cfra)
} else if (mode==PTCACHE_FILE_WRITE) {
BLI_make_existing_file(filename); /* will create the dir if needs be, same as //textures is created */
fp = fopen(filename, "wb");
+ } else if (mode==PTCACHE_FILE_UPDATE) {
+ BLI_make_existing_file(filename);
+ fp = fopen(filename, "rb+");
}
if (!fp)
@@ -1253,6 +1261,18 @@ static void ptcache_file_init_pointers(PTCacheFile *pf)
pf->cur[BPHYS_DATA_BOIDS] = data_types & (1<<BPHYS_DATA_BOIDS) ? &pf->data.boids : NULL;
}
+static void ptcache_file_seek_pointers(int index, PTCacheFile *pf)
+{
+ int i, size=0;
+ int data_types = pf->data_types;
+
+ for(i=0; i<BPHYS_TOT_DATA; i++)
+ size += pf->data_types & (1<<i) ? ptcache_data_size[i] : 0;
+
+ ptcache_file_init_pointers(pf);
+ /* size of default header + data up to index */
+ fseek(pf->fp, 8 + 3*sizeof(int) + index * size, SEEK_SET);
+}
void BKE_ptcache_mem_init_pointers(PTCacheMem *pm)
{
int data_types = pm->data_types;
@@ -1271,6 +1291,14 @@ void BKE_ptcache_mem_incr_pointers(PTCacheMem *pm)
pm->cur[i] = (char*)pm->cur[i] + ptcache_data_size[i];
}
}
+void BKE_ptcache_mem_seek_pointers(int index, PTCacheMem *pm)
+{
+ int data_types = pm->data_types;
+ int i;
+
+ for(i=0; i<BPHYS_TOT_DATA; i++)
+ pm->cur[i] = data_types & (1<<i) ? (char*)pm->data[i] + index * ptcache_data_size[i] : NULL;
+}
static void ptcache_alloc_data(PTCacheMem *pm)
{
int data_types = pm->data_types;
@@ -1453,7 +1481,7 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
else if(pid->read_header(pf2)) {
ptcache_file_init_pointers(pf2);
totpoint2 = pf2->totpoint;
- index2 = pf->data_types & BPHYS_DATA_INDEX ? &pf2->data.index : &i;
+ index2 = pf2->data_types & BPHYS_DATA_INDEX ? &pf2->data.index : &i;
}
}
else {
@@ -1615,7 +1643,7 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
{
PointCache *cache = pid->cache;
- PTCacheFile *pf= NULL;
+ PTCacheFile *pf= NULL, *pf2= NULL;
int i;
int totpoint = pid->totpoint(pid->calldata);
int add = 0, overwrite = 0;
@@ -1625,7 +1653,7 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
return 0;
if(cache->flag & PTCACHE_DISK_CACHE) {
- int efra = cache->endframe;
+ int ofra, efra = cache->endframe;
if(cfra==0)
add = 1;
@@ -1636,7 +1664,6 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
add = 1;
}
else {
- int ofra;
/* find last cached frame */
while(efra > cache->startframe && !BKE_ptcache_id_exist(pid, efra))
efra--;
@@ -1679,11 +1706,36 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
}
else
for(i=0; i<totpoint; i++) {
- if(pid->write_elem && pid->write_elem(i, pid->calldata, pf->cur))
- if(!ptcache_file_write_data(pf)) {
- ptcache_file_close(pf);
- return 0;
+ if(pid->write_elem) {
+ int write = pid->write_elem(i, pid->calldata, pf->cur);
+ if(write) {
+ if(!ptcache_file_write_data(pf)) {
+ ptcache_file_close(pf);
+ if(pf2) ptcache_file_close(pf2);
+ return 0;
+ }
+ /* newly born particles have to be copied to previous cached frame */
+ else if(overwrite && write == 2) {
+ if(!pf2) {
+ pf2 = ptcache_file_open(pid, PTCACHE_FILE_UPDATE, ofra);
+ if(!pf2) {
+ ptcache_file_close(pf);
+ return 0;
+ }
+ pf2->type = pid->type;
+ pf2->totpoint = totpoint;
+ pf2->data_types = pid->data_types;
+ }
+ ptcache_file_seek_pointers(i, pf2);
+ pid->write_elem(i, pid->calldata, pf2->cur);
+ if(!ptcache_file_write_data(pf2)) {
+ ptcache_file_close(pf);
+ ptcache_file_close(pf2);
+ return 0;
+ }
+ }
}
+ }
}
}
}
@@ -1728,8 +1780,19 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
BKE_ptcache_mem_init_pointers(pm);
for(i=0; i<totpoint; i++) {
- if(pid->write_elem && pid->write_elem(i, pid->calldata, pm->cur))
- BKE_ptcache_mem_incr_pointers(pm);
+ if(pid->write_elem) {
+ int write = pid->write_elem(i, pid->calldata, pm->cur);
+ if(write) {
+ BKE_ptcache_mem_incr_pointers(pm);
+
+ /* newly born particles have to be copied to previous cached frame */
+ if(overwrite && write == 2) {
+ pm2 = cache->mem_cache.last;
+ BKE_ptcache_mem_seek_pointers(i, pm2);
+ pid->write_elem(i, pid->calldata, pm2->cur);
+ }
+ }
+ }
}
//ptcache_make_index_array(pm, pid->totpoint(pid->calldata));
@@ -1748,8 +1811,9 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
cache->flag |= PTCACHE_FRAMES_SKIPPED;
}
- if(pf)
- ptcache_file_close(pf);
+ if(pf) ptcache_file_close(pf);
+
+ if(pf2) ptcache_file_close(pf2);
BKE_ptcache_update_info(pid);
diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c
index 22dc5a15650..a16c1956cc4 100644
--- a/source/blender/blenkernel/intern/unit.c
+++ b/source/blender/blenkernel/intern/unit.c
@@ -170,7 +170,8 @@ static void unit_dual_convert(double value, bUnitCollection *usys,
{
bUnitDef *unit= unit_best_fit(value, usys, NULL, 1);
- *value_a= floor(value/unit->scalar) * unit->scalar;
+ if(value < 0.0) *value_a= -floor(-value/unit->scalar) * unit->scalar;
+ else *value_a= floor( value/unit->scalar) * unit->scalar;
*value_b= value - (*value_a);
*unit_a= unit;
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 917ecd044ea..6e94602c0c9 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -880,7 +880,7 @@ int append_ffmpeg(RenderData *rd, int frame, int *pixels, int rectx, int recty,
}
}
- write_audio_frames(frame / (((double)rd->frs_sec) / rd->frs_sec_base));
+ write_audio_frames((frame - rd->sfra) / (((double)rd->frs_sec) / rd->frs_sec_base));
return success;
}
diff --git a/source/blender/blenlib/BLI_dynstr.h b/source/blender/blenlib/BLI_dynstr.h
index 8544b451b65..c5158264e72 100644
--- a/source/blender/blenlib/BLI_dynstr.h
+++ b/source/blender/blenlib/BLI_dynstr.h
@@ -60,6 +60,15 @@ DynStr* BLI_dynstr_new (void);
*/
void BLI_dynstr_append (DynStr *ds, const char *cstr);
+/**
+ * Append a length clamped c-string to a DynStr.
+ *
+ * @param ds The DynStr to append to.
+ * @param cstr The c-string to append.
+ * @param len The maximum length of the c-string to copy.
+ */
+void BLI_dynstr_nappend (DynStr *ds, const char *cstr, int len);
+
/**
* Append a c-string to a DynStr, but with formatting like printf.
*
diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h
index 9e494de5379..9b4084aa172 100644
--- a/source/blender/blenlib/BLI_path_util.h
+++ b/source/blender/blenlib/BLI_path_util.h
@@ -59,6 +59,7 @@ void BLI_make_existing_file(char *name);
void BLI_split_dirfile(char *string, char *dir, char *file);
void BLI_split_dirfile_basic(const char *string, char *dir, char *file);
void BLI_join_dirfile(char *string, const char *dir, const char *file);
+int BKE_rebase_path(char *abs, int abs_size, char *rel, int rel_size, const char *base_dir, const char *src_dir, const char *dest_dir);
void BLI_getlastdir(const char* dir, char *last, int maxlen);
int BLI_testextensie(const char *str, const char *ext);
void BLI_uniquename(struct ListBase *list, void *vlink, const char defname[], char delim, short name_offs, short len);
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index b534087f32c..fec5f1803eb 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -28,7 +28,7 @@ FILE(GLOB SRC intern/*.c)
SET(INC
. ../makesdna ../blenkernel ../../../intern/guardedalloc ../include
- ../gpu
+ ../gpu ../../../intern/ghost
${FREETYPE_INCLUDE_DIRS}
${ZLIB_INC}
)
diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript
index df1a096cb99..090094a834d 100644
--- a/source/blender/blenlib/SConscript
+++ b/source/blender/blenlib/SConscript
@@ -4,7 +4,7 @@ Import ('env')
sources = env.Glob('intern/*.c')
cflags=''
-incs = '. ../makesdna ../blenkernel #/intern/guardedalloc ../editors/include ../gpu'
+incs = '. ../makesdna ../blenkernel #/intern/guardedalloc #/intern/ghost ../editors/include ../gpu'
incs += ' ' + env['BF_FREETYPE_INC']
incs += ' ' + env['BF_ZLIB_INC']
defs = ''
diff --git a/source/blender/blenlib/intern/BLI_bfile.c b/source/blender/blenlib/intern/BLI_bfile.c
index 9540b16d2f4..3306283ad3f 100644
--- a/source/blender/blenlib/intern/BLI_bfile.c
+++ b/source/blender/blenlib/intern/BLI_bfile.c
@@ -46,6 +46,8 @@
#include "BLI_storage.h"
#include "BLI_bfile.h"
+#include "GHOST_C-api.h"
+
/* Internal bfile classification flags */
#define BCF_OPEN (0)
#define BCF_FOPEN (1<<0)
@@ -54,6 +56,11 @@
#define BCF_AT_END (1<<3)
#define BCF_DISCARD (1<<4)
+/* Standard files names */
+#define LAST_SESSION_FILE "last-session"
+#define ENVIRONMENT_FILE "environment"
+
+
/* Declaration of internal functions */
void chomp(char* line);
void expand_envvars(char* src, char* dst);
@@ -221,19 +228,6 @@ void BLI_bfile_set_error(BFILE *bfile, int error) {
}
-#if defined(WIN32)
- #define LAST_SESSION_FILE "%HOME%\\Blender\\last-session FIXME FIXME FIXME"
- #define ENVIRONMENT_FILE "FIXME"
- #define SHARED_DIRECTORY "FIXME TOO"
-#elif defined(OSX)
- #define LAST_SESSION_FILE "${HOME}/Library/Application Support/Blender/last-session"
- #define ENVIRONMENT_FILE "${HOME}/Library/Application Support/Blender/${BLENDER_VERSION}/environment"
- #define SHARED_DIRECTORY "/Library/Application Support/Blender"
-#else
- #define LAST_SESSION_FILE "${HOME}/.blender/last-session"
- #define ENVIRONMENT_FILE "${HOME}/.blender/${BLENDER_VERSION}/environment"
- #define SHARED_DIRECTORY "/usr/share/blender"
-#endif
void BLI_bfile_init_vars() {
char file[MAXPATHLEN];
char temp[MAXPATHLEN];
@@ -249,10 +243,12 @@ void BLI_bfile_init_vars() {
if(BLI_exist(temp)) {
BLI_setenv_if_new("BLENDER_SHARE", dirname(bprogname));
} else {
- BLI_setenv_if_new("BLENDER_SHARE", SHARED_DIRECTORY);
+ BLI_setenv_if_new("BLENDER_SHARE", (const char*)GHOST_getSystemDir());
}
- expand_envvars(LAST_SESSION_FILE, file);
+ strcpy(file, (const char*)GHOST_getUserDir());
+ BLI_add_slash(file);
+ strcat(file, LAST_SESSION_FILE);
fp = fopen(file, "r");
/* 1st line, read previous version */
if (fp && (fscanf(fp, "%3c\n", temp) == 1)) {
@@ -283,7 +279,9 @@ void BLI_bfile_init_vars() {
}
/* Load vars from user and system files */
- expand_envvars(ENVIRONMENT_FILE, file);
+ strcpy(file, (const char *)GHOST_getUserDir());
+ BLI_add_slash(file);
+ strcat(file, ENVIRONMENT_FILE);
init_vars_from_file(file);
sprintf(temp, "/%d/environment", BLENDER_VERSION);
BLI_make_file_string("/", file, getenv("BLENDER_SHARE"), temp);
diff --git a/source/blender/blenlib/intern/BLI_dynstr.c b/source/blender/blenlib/intern/BLI_dynstr.c
index 02c7ff2e9e5..4b7b61e64d9 100644
--- a/source/blender/blenlib/intern/BLI_dynstr.c
+++ b/source/blender/blenlib/intern/BLI_dynstr.c
@@ -83,6 +83,23 @@ void BLI_dynstr_append(DynStr *ds, const char *cstr) {
ds->curlen+= cstrlen;
}
+void BLI_dynstr_nappend(DynStr *ds, const char *cstr, int len) {
+ DynStrElem *dse= malloc(sizeof(*dse));
+ int cstrlen= BLI_strnlen(cstr, len);
+
+ dse->str= malloc(cstrlen+1);
+ memcpy(dse->str, cstr, cstrlen);
+ dse->str[cstrlen] = '\0';
+ dse->next= NULL;
+
+ if (!ds->last)
+ ds->last= ds->elems= dse;
+ else
+ ds->last= ds->last->next= dse;
+
+ ds->curlen+= cstrlen;
+}
+
void BLI_dynstr_vappendf(DynStr *ds, const char *format, va_list args)
{
char *message, fixedmessage[256];
diff --git a/source/blender/blenlib/intern/Makefile b/source/blender/blenlib/intern/Makefile
index d8aed3ac0ed..7ef44aff881 100644
--- a/source/blender/blenlib/intern/Makefile
+++ b/source/blender/blenlib/intern/Makefile
@@ -52,6 +52,8 @@ CPPFLAGS += -I$(NAN_ZLIB)/include
CPPFLAGS += -I../../gpu
+CPPFLAGS += -I$(NAN_GHOST)/include
+
ifdef NAN_PTHREADS
CPPFLAGS += -I$(NAN_PTHREADS)/include
endif
diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c
index 8d5684a3ac8..a92f80e35c7 100644
--- a/source/blender/blenlib/intern/math_rotation.c
+++ b/source/blender/blenlib/intern/math_rotation.c
@@ -1333,8 +1333,14 @@ void mat4_to_dquat(DualQuat *dq,float basemat[][4], float mat[][4])
if((determinant_m4(mat) < 0.0f) || len_v3(dscale) > 1e-4) {
/* extract R and S */
- mat4_to_quat(basequat,baseRS);
- quat_to_mat4(baseR,basequat);
+ float tmp[4][4];
+
+ /* extra orthogonalize, to avoid flipping with stretched bones */
+ copy_m4_m4(tmp, baseRS);
+ orthogonalize_m4(tmp, 1);
+ mat4_to_quat(basequat, tmp);
+
+ quat_to_mat4(baseR, basequat);
copy_v3_v3(baseR[3], baseRS[3]);
invert_m4_m4(baseinv, basemat);
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index 1bf321ec1bc..fe43960b770 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -1320,6 +1320,106 @@ void BLI_join_dirfile(char *string, const char *dir, const char *file)
}
}
+
+/*
+ Produce image export path.
+
+ Fails returning 0 if image filename is empty or if destination path
+ matches image path (i.e. both are the same file).
+
+ Trailing slash in dest_dir is optional.
+
+ Logic:
+
+ - if an image is "below" current .blend file directory, rebuild the
+ same dir structure in dest_dir
+
+ For example //textures/foo/bar.png becomes
+ [dest_dir]/textures/foo/bar.png.
+
+ - if an image is not "below" current .blend file directory,
+ disregard it's path and copy it in the same directory where 3D file
+ goes.
+
+ For example //../foo/bar.png becomes [dest_dir]/bar.png.
+
+ This logic will help ensure that all image paths are relative and
+ that a user gets his images in one place. It'll also provide
+ consistent behaviour across exporters.
+ */
+int BKE_rebase_path(char *abs, int abs_size, char *rel, int rel_size, const char *base_dir, const char *src_dir, const char *dest_dir)
+{
+ char path[FILE_MAX];
+ char dir[FILE_MAX];
+ char base[FILE_MAX];
+ char blend_dir[FILE_MAX]; /* directory, where current .blend file resides */
+ char dest_path[FILE_MAX];
+ char rel_dir[FILE_MAX];
+ int len;
+
+ if (abs)
+ abs[0]= 0;
+
+ if (rel)
+ rel[0]= 0;
+
+ BLI_split_dirfile_basic(base_dir, blend_dir, NULL);
+
+ if (src_dir[0]=='\0')
+ return 0;
+
+ BLI_strncpy(path, src_dir, sizeof(path));
+
+ /* expand "//" in filename and get absolute path */
+ BLI_convertstringcode(path, base_dir);
+
+ /* get the directory part */
+ BLI_split_dirfile_basic(path, dir, base);
+
+ len= strlen(blend_dir);
+
+ rel_dir[0] = 0;
+
+ /* if image is "below" current .blend file directory */
+ if (!strncmp(path, blend_dir, len)) {
+
+ /* if image is _in_ current .blend file directory */
+ if (!strcmp(dir, blend_dir)) {
+ BLI_join_dirfile(dest_path, dest_dir, base);
+ }
+ /* "below" */
+ else {
+ /* rel = image_path_dir - blend_dir */
+ BLI_strncpy(rel_dir, dir + len, sizeof(rel_dir));
+
+ BLI_join_dirfile(dest_path, dest_dir, rel_dir);
+ BLI_join_dirfile(dest_path, dest_path, base);
+ }
+
+ }
+ /* image is out of current directory */
+ else {
+ BLI_join_dirfile(dest_path, dest_dir, base);
+ }
+
+ if (abs)
+ BLI_strncpy(abs, dest_path, abs_size);
+
+ if (rel) {
+ strncat(rel, rel_dir, rel_size);
+ strncat(rel, base, rel_size);
+ }
+
+ /* return 2 if src=dest */
+ if (!strcmp(path, dest_path)) {
+ // if (G.f & G_DEBUG) printf("%s and %s are the same file\n", path, dest_path);
+ return 2;
+ }
+
+ return 1;
+}
+
+
static int add_win32_extension(char *name)
{
int retval = 0;
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index bf2e1d28b3a..dd1d0a3bd4f 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -342,3 +342,10 @@ void BLI_timestr(double _time, char *str)
str[11]=0;
}
+
+/* determine the length of a fixed-size string */
+size_t BLI_strnlen(const char *str, size_t maxlen)
+{
+ const char *end = memchr(str, '\0', maxlen);
+ return end ? (size_t) (end - str) : maxlen;
+}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index a34507d85f2..2c8a8869ddd 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -32,6 +32,7 @@
#include <limits.h>
#include <stdio.h> // for printf fopen fwrite fclose sprintf FILE
#include <stdlib.h> // for getenv atoi
+#include <stddef.h> // for offsetof
#include <fcntl.h> // for open
#include <string.h> // for strrchr strncmp strstr
#include <math.h> // for fabs
@@ -10694,7 +10695,7 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
link_list(fd, &user->themes);
link_list(fd, &user->keymaps);
- link_list(fd, &user->extensions);
+ link_list(fd, &user->addons);
for(keymap=user->keymaps.first; keymap; keymap=keymap->next) {
keymap->modal_items= NULL;
@@ -10887,20 +10888,9 @@ char *bhead_id_name(FileData *fd, BHead *bhead)
static ID *is_yet_read(FileData *fd, Main *mainvar, BHead *bhead)
{
- ListBase *lb;
- char *idname= bhead_id_name(fd, bhead);
-
- lb= wich_libbase(mainvar, GS(idname));
-
- if(lb) {
- ID *id= lb->first;
- while(id) {
- if( strcmp(id->name, idname)==0 )
- return id;
- id= id->next;
- }
- }
- return NULL;
+ const char *idname= bhead_id_name(fd, bhead);
+ /* wich_libbase can be NULL, intentionally not using idname+2 */
+ return BLI_findstring(wich_libbase(mainvar, GS(idname)), idname, offsetof(ID, name));
}
static void expand_doit(FileData *fd, Main *mainvar, void *old)
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 1cd68ec6f04..66815f5316f 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -542,7 +542,7 @@ static void write_userdef(WriteData *wd)
bTheme *btheme;
wmKeyMap *keymap;
wmKeyMapItem *kmi;
- bExtension *bext;
+ bAddon *bext;
writestruct(wd, USER, "UserDef", 1, &U);
@@ -560,8 +560,8 @@ static void write_userdef(WriteData *wd)
}
}
- for(bext= U.extensions.first; bext; bext=bext->next)
- writestruct(wd, DATA, "bExtension", 1, bext);
+ for(bext= U.addons.first; bext; bext=bext->next)
+ writestruct(wd, DATA, "bAddon", 1, bext);
}
static void write_boid_state(WriteData *wd, BoidState *state)
diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp
index 4b35499fb62..3e1898a64d9 100644
--- a/source/blender/collada/DocumentExporter.cpp
+++ b/source/blender/collada/DocumentExporter.cpp
@@ -1435,9 +1435,9 @@ public:
BLI_split_dirfile_basic(mfilename, dir, NULL);
- BKE_get_image_export_path(image, dir, abs, sizeof(abs), rel, sizeof(rel));
+ BKE_rebase_path(abs, sizeof(abs), rel, sizeof(rel), G.sce, image->name, dir);
- if (strlen(abs)) {
+ if (abs[0] != '\0') {
// make absolute source path
BLI_strncpy(src, image->name, sizeof(src));
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index e6280a2556c..efdb9008014 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -436,6 +436,7 @@ static int ed_marker_move_init(bContext *C, wmOperator *op)
initNumInput(&mm->num);
mm->num.idx_max = 0; /* one axis */
mm->num.flag |= NUM_NO_FRACTION;
+ mm->num.increment = 1.0f;
for (a=0, marker= markers->first; marker; marker= marker->next) {
if (marker->flag & SELECT) {
@@ -617,7 +618,7 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt)
float vec[3];
char str_tx[256];
- if (handleNumInput(&mm->num, evt, 1.0))
+ if (handleNumInput(&mm->num, evt))
{
applyNumInput(&mm->num, vec);
outputNumInput(&mm->num, str_tx);
diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c
index f1d84fb1066..63323a8519d 100644
--- a/source/blender/editors/animation/keyingsets.c
+++ b/source/blender/editors/animation/keyingsets.c
@@ -355,7 +355,7 @@ static int add_keyingset_button_exec (bContext *C, wmOperator *op)
}
/* add path to this setting */
- BKE_keyingset_add_destination(ks, ptr.id.data, NULL, path, index, pflag, KSP_GROUP_KSNAME);
+ BKE_keyingset_add_path(ks, ptr.id.data, NULL, path, index, pflag, KSP_GROUP_KSNAME);
ks->active_path= BLI_countlist(&ks->paths);
success= 1;
@@ -426,7 +426,7 @@ static int remove_keyingset_button_exec (bContext *C, wmOperator *op)
KS_Path *ksp;
/* try to find a path matching this description */
- ksp= BKE_keyingset_find_destination(ks, ptr.id.data, ks->name, path, index, KSP_GROUP_KSNAME);
+ ksp= BKE_keyingset_find_path(ks, ptr.id.data, ks->name, path, index, KSP_GROUP_KSNAME);
if (ksp) {
/* just free it... */
@@ -1162,31 +1162,13 @@ static int keyingset_relative_get_templates (KeyingSet *ks)
return templates;
}
-/* Check if context data is suitable for the given absolute Keying Set */
+/* Check if context data is suitable for the given Keying Set */
short keyingset_context_ok_poll (bContext *C, KeyingSet *ks)
{
- ScrArea *sa= CTX_wm_area(C);
-
- /* data retrieved from context depends on active editor */
- if (sa == NULL) return 0;
-
- switch (sa->spacetype) {
- case SPACE_VIEW3D:
- {
- Object *obact= CTX_data_active_object(C);
-
- /* if in posemode, check if 'pose-channels' requested for in KeyingSet */
- if ((obact && obact->pose) && (obact->mode & OB_MODE_POSE)) {
- /* check for posechannels */
-
- }
- else {
- /* check for selected object */
-
- }
- }
- break;
- }
+ // TODO:
+ // For 'relative' keyingsets (i.e. py-keyingsets), add a call here
+ // which basically gets a listing of all the paths to be used for this
+ // set.
return 1;
diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c
index a9be4b346f0..b3960c3cfd5 100644
--- a/source/blender/editors/armature/editarmature_retarget.c
+++ b/source/blender/editors/armature/editarmature_retarget.c
@@ -186,12 +186,12 @@ float rollBoneByQuatAligned(EditBone *bone, float old_up_axis[3], float qrot[4],
if (dot_v3v3(new_up_axis, x_axis) < 0)
{
- mul_v3_fl(x_axis, -1);
+ negate_v3(x_axis);
}
if (dot_v3v3(new_up_axis, z_axis) < 0)
{
- mul_v3_fl(z_axis, -1);
+ negate_v3(z_axis);
}
if (angle_normalized_v3v3(x_axis, new_up_axis) < angle_normalized_v3v3(z_axis, new_up_axis))
diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c
index c49ad2a768a..0170241c6c2 100644
--- a/source/blender/editors/armature/poseobject.c
+++ b/source/blender/editors/armature/poseobject.c
@@ -52,6 +52,7 @@
#include "DNA_userdef_types.h"
#include "BKE_anim.h"
+#include "BKE_idprop.h"
#include "BKE_animsys.h"
#include "BKE_action.h"
#include "BKE_armature.h"
@@ -840,6 +841,15 @@ static bPose *g_posebuf = NULL;
void free_posebuf(void)
{
if (g_posebuf) {
+ bPoseChannel *pchan;
+
+ for (pchan= g_posebuf->chanbase.first; pchan; pchan= pchan->next) {
+ if(pchan->prop) {
+ IDP_FreeProperty(pchan->prop);
+ MEM_freeN(pchan->prop);
+ }
+ }
+
/* was copied without constraints */
BLI_freelistN(&g_posebuf->chanbase);
MEM_freeN(g_posebuf);
@@ -891,7 +901,8 @@ void POSE_OT_copy (wmOperatorType *ot)
/* Pointers to the builtin KeyingSets that we want to use */
static KeyingSet *posePaste_ks_locrotscale = NULL; /* the only keyingset we'll need */
-/* ---- */
+/* transform.h */
+extern void autokeyframe_pose_cb_func(struct bContext *C, struct Scene *scene, struct View3D *v3d, struct Object *ob, int tmode, short targetless_ik);
static int pose_paste_exec (bContext *C, wmOperator *op)
{
@@ -1002,33 +1013,55 @@ static int pose_paste_exec (bContext *C, wmOperator *op)
}
}
- if (autokeyframe_cfra_can_key(scene, &ob->id)) {
- /* Set keys on pose
- * - KeyingSet to use depends on rotation mode
- * (but that's handled by the templates code)
- */
- // TODO: for getting the KeyingSet used, we should really check which channels were affected
- if (posePaste_ks_locrotscale == NULL)
- posePaste_ks_locrotscale= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale");
-
- /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
- cks.pchan= pchan;
-
- modify_keyframes(scene, &dsources, NULL, posePaste_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)CFRA);
-
- /* clear any unkeyed tags */
- if (chan->bone)
- chan->bone->flag &= ~BONE_UNKEYED;
+ /* ID property */
+ if(pchan->prop) {
+ IDP_FreeProperty(pchan->prop);
+ MEM_freeN(pchan->prop);
+ pchan->prop= NULL;
}
- else {
- /* add unkeyed tags */
- if (chan->bone)
- chan->bone->flag |= BONE_UNKEYED;
+
+ if(chan->prop) {
+ pchan->prop= IDP_CopyProperty(chan->prop);
+ }
+
+ /* auto key, TODO, fix up this INSERTAVAIL vs all other cases */
+ if (IS_AUTOKEY_FLAG(INSERTAVAIL) == 0) { /* deal with this case later */
+ if (autokeyframe_cfra_can_key(scene, &ob->id)) {
+
+ /* Set keys on pose
+ * - KeyingSet to use depends on rotation mode
+ * (but that's handled by the templates code)
+ */
+ // TODO: for getting the KeyingSet used, we should really check which channels were affected
+ if (posePaste_ks_locrotscale == NULL)
+ posePaste_ks_locrotscale= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale");
+
+ /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
+ cks.pchan= pchan;
+
+ modify_keyframes(scene, &dsources, NULL, posePaste_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)CFRA);
+
+ /* clear any unkeyed tags */
+ if (chan->bone)
+ chan->bone->flag &= ~BONE_UNKEYED;
+ }
+ else {
+ /* add unkeyed tags */
+ if (chan->bone)
+ chan->bone->flag |= BONE_UNKEYED;
+ }
}
}
}
}
+ if (IS_AUTOKEY_FLAG(INSERTAVAIL)) {
+ View3D *v3d= CTX_wm_view3d(C);
+ autokeyframe_pose_cb_func(C, scene, v3d, ob, TFM_TRANSLATION, 0);
+ autokeyframe_pose_cb_func(C, scene, v3d, ob, TFM_ROTATION, 0);
+ autokeyframe_pose_cb_func(C, scene, v3d, ob, TFM_TIME_SCALE, 0);
+ }
+
/* Update event for pose and deformation children */
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 886da0820a2..cc875e5156f 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -178,6 +178,7 @@ int face_select(struct bContext *C, struct Object *ob, short mval[2], int extend
void face_borderselect(struct bContext *C, struct Object *ob, struct rcti *rect, int select, int extend);
void selectall_tface(struct Object *ob, int action);
void select_linked_tfaces(struct bContext *C, struct Object *ob, short mval[2], int mode);
+int minmax_tface(struct Object *ob, float *min, float *max);
/* object_vgroup.c */
diff --git a/source/blender/editors/include/ED_numinput.h b/source/blender/editors/include/ED_numinput.h
index 381131c8b2d..ca5dc4797de 100644
--- a/source/blender/editors/include/ED_numinput.h
+++ b/source/blender/editors/include/ED_numinput.h
@@ -33,6 +33,7 @@ typedef struct NumInput {
char inv[3]; /* If the value is inverted or not */
float val[3]; /* Direct value of the input */
int ctrl[3]; /* Control to indicate what to do with the numbers that are typed */
+ float increment;
} NumInput ;
/* NUMINPUT FLAGS */
@@ -48,7 +49,7 @@ void initNumInput(NumInput *n);
void outputNumInput(NumInput *n, char *str);
short hasNumInput(NumInput *n);
void applyNumInput(NumInput *n, float *vec);
-char handleNumInput(NumInput *n, struct wmEvent *event, float increment);
+char handleNumInput(NumInput *n, struct wmEvent *event);
#define NUM_MODAL_INCREMENT_UP 18
#define NUM_MODAL_INCREMENT_DOWN 19
diff --git a/source/blender/editors/include/ED_space_api.h b/source/blender/editors/include/ED_space_api.h
index 7f2effdd975..3529eddd6d9 100644
--- a/source/blender/editors/include/ED_space_api.h
+++ b/source/blender/editors/include/ED_space_api.h
@@ -69,6 +69,7 @@ void *ED_region_draw_cb_activate(struct ARegionType *,
void *custumdata, int type);
void ED_region_draw_cb_draw(const struct bContext *, struct ARegion *, int);
void ED_region_draw_cb_exit(struct ARegionType *, void *);
+void *ED_region_draw_cb_customdata(void *handle);
#endif /* ED_SPACE_API_H */
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 9624adf4879..0dd8e3d412d 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -4015,7 +4015,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
if(event->alt)
ui_but_anim_remove_keyingset(C);
else
- ui_but_anim_remove_keyingset(C);
+ ui_but_anim_add_keyingset(C);
ED_region_tag_redraw(CTX_wm_region(C));
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 4c818f9d0ac..e2804efe040 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -157,16 +157,19 @@ static void id_search_cb(const bContext *C, void *arg_template, char *str, uiSea
{
TemplateID *template= (TemplateID*)arg_template;
ListBase *lb= template->idlb;
- ID *id;
+ ID *id, *id_from= template->ptr.id.data;
int iconid;
+ int flag= RNA_property_flag(template->prop);
/* ID listbase */
for(id= lb->first; id; id= id->next) {
- if(BLI_strcasestr(id->name+2, str)) {
- iconid= ui_id_icon_get((bContext*)C, id, 0);
+ if(!((flag & PROP_ID_SELF_CHECK) && id == id_from)) {
+ if(BLI_strcasestr(id->name+2, str)) {
+ iconid= ui_id_icon_get((bContext*)C, id, 0);
- if(!uiSearchItemAdd(items, id->name+2, id, iconid))
- break;
+ if(!uiSearchItemAdd(items, id->name+2, id, iconid))
+ break;
+ }
}
}
}
@@ -281,6 +284,10 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
memset(&idptr, 0, sizeof(idptr));
RNA_property_pointer_set(&template->ptr, template->prop, idptr);
RNA_property_update(C, &template->ptr, template->prop);
+
+ if(id && CTX_wm_window(C)->eventstate->shift) /* useful hidden functionality, */
+ id->us= 0;
+
break;
case UI_ID_FAKE_USER:
if(id) {
@@ -447,8 +454,11 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
but= uiDefIconButO(block, BUT, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
}
else {
- but= uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
+ but= uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "Unlink datablock, Shift + Click to force removal on save");
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_DELETE));
+
+ if(RNA_property_flag(template->prop) & PROP_NEVER_NULL)
+ uiButSetFlag(but, UI_BUT_DISABLED);
}
if((idfrom && idfrom->lib))
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index 19eb782884d..e83be1f4f1d 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -450,52 +450,28 @@ void selectswap_tface(Scene *scene)
// XXX notifier! object_tface_flags_changed(OBACT, 0);
}
-int minmax_tface(Scene *scene, float *min, float *max)
+int minmax_tface(Object *ob, float *min, float *max)
{
- Object *ob;
- Mesh *me;
+ Mesh *me= get_mesh(ob);
MFace *mf;
- MTFace *tf;
MVert *mv;
int a, ok=0;
- float vec[3], bmat[3][3];
-
- ob = OBACT;
- if (ob==0) return ok;
- me= get_mesh(ob);
- if(me==0 || me->mtface==0) return ok;
-
- copy_m3_m4(bmat, ob->obmat);
+ float vec[3];
+
+ if(me==NULL)
+ return ok;
mv= me->mvert;
mf= me->mface;
- tf= me->mtface;
- for (a=me->totface; a>0; a--, mf++, tf++) {
- if (mf->flag & ME_HIDE || !(mf->flag & ME_FACE_SEL))
- continue;
-
- VECCOPY(vec, (mv+mf->v1)->co);
- mul_m3_v3(bmat, vec);
- add_v3_v3v3(vec, vec, ob->obmat[3]);
- DO_MINMAX(vec, min, max);
-
- VECCOPY(vec, (mv+mf->v2)->co);
- mul_m3_v3(bmat, vec);
- add_v3_v3v3(vec, vec, ob->obmat[3]);
- DO_MINMAX(vec, min, max);
-
- VECCOPY(vec, (mv+mf->v3)->co);
- mul_m3_v3(bmat, vec);
- add_v3_v3v3(vec, vec, ob->obmat[3]);
- DO_MINMAX(vec, min, max);
-
- if (mf->v4) {
- VECCOPY(vec, (mv+mf->v4)->co);
- mul_m3_v3(bmat, vec);
- add_v3_v3v3(vec, vec, ob->obmat[3]);
- DO_MINMAX(vec, min, max);
+ for (a=me->totface; a>0; a--, mf++) {
+ if ((mf->flag & ME_HIDE || !(mf->flag & ME_FACE_SEL)) == 0) {
+ int i= mf->v4 ? 3:2;
+ do {
+ mul_v3_m4v3(vec, ob->obmat, (mv + (*(&mf->v1 + i)))->co);
+ DO_MINMAX(vec, min, max);
+ } while (i--);
+ ok= 1;
}
- ok= 1;
}
return ok;
}
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index d7ffa1d983b..ab50bd4c37c 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -289,6 +289,18 @@ void ED_keymap_object(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "OBJECT_OT_select_grouped", GKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_select_mirror", MKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
+ kmi= WM_keymap_add_item(keymap, "OBJECT_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, 0, 0);
+ RNA_enum_set_identifier(kmi->ptr, "direction", "PARENT");
+ kmi= WM_keymap_add_item(keymap, "OBJECT_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_enum_set_identifier(kmi->ptr, "direction", "PARENT");
+ RNA_boolean_set(kmi->ptr, "extend", 1);
+
+ kmi= WM_keymap_add_item(keymap, "OBJECT_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, 0, 0);
+ RNA_enum_set_identifier(kmi->ptr, "direction", "CHILD");
+ kmi= WM_keymap_add_item(keymap, "OBJECT_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_enum_set_identifier(kmi->ptr, "direction", "CHILD");
+ RNA_boolean_set(kmi->ptr, "extend", 1);
+
WM_keymap_verify_item(keymap, "OBJECT_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_verify_item(keymap, "OBJECT_OT_parent_no_inverse_set", PKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
WM_keymap_verify_item(keymap, "OBJECT_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0);
diff --git a/source/blender/editors/render/Makefile b/source/blender/editors/render/Makefile
index ed25f0be02a..85b70172e0a 100644
--- a/source/blender/editors/render/Makefile
+++ b/source/blender/editors/render/Makefile
@@ -54,3 +54,9 @@ CPPFLAGS += -I../../render/extern/include
# own include
CPPFLAGS += -I../include
+
+ifeq ($(OS), darwin)
+ ifeq ($(WITH_BF_OPENMP), true)
+ CPPFLAGS += -DPARALLEL=1
+ endif
+endif
diff --git a/source/blender/editors/render/SConscript b/source/blender/editors/render/SConscript
index cb901be2494..5526194eab4 100644
--- a/source/blender/editors/render/SConscript
+++ b/source/blender/editors/render/SConscript
@@ -24,4 +24,8 @@ if env['WITH_BF_QUICKTIME']:
if env['USE_QTKIT']:
env.Append(CFLAGS=['-DUSE_QTKIT'])
+if env['OURPLATFORM'] == 'darwin':
+ if env['WITH_BF_OPENMP']:
+ env.Append(CFLAGS=['-DPARALLEL=1'])
+
env.BlenderLib ( 'bf_editors_render', sources, Split(incs), [], libtype=['core'], priority=[45])
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 1563c5a8e1d..aca13fbd66d 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -100,6 +100,13 @@
#define PR_XMAX 200
#define PR_YMAX 195
+#if defined(__APPLE__) && (PARALLEL == 1) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2)
+/* ************** libgomp (Apple gcc 4.2.1) TLS bug workaround *************** */
+#include <pthread.h>
+extern pthread_key_t gomp_tls_key;
+static void *thread_tls_data;
+#endif
+
/* XXX */
static int qtest() {return 0;}
/* XXX */
@@ -1098,6 +1105,11 @@ static void common_preview_startjob(void *customdata, short *stop, short *do_upd
{
ShaderPreview *sp= customdata;
+#if defined(__APPLE__) && (PARALLEL == 1) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2)
+ // Workaround for Apple gcc 4.2.1 omp vs background thread bug
+ pthread_setspecific (gomp_tls_key, thread_tls_data);
+#endif
+
if(sp->pr_method == PR_ICON_RENDER)
icon_preview_startjob(customdata, stop, do_update);
else
@@ -1127,7 +1139,12 @@ void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *r
WM_jobs_customdata(steve, sp, shader_preview_free);
WM_jobs_timer(steve, 0.1, NC_MATERIAL, NC_MATERIAL);
WM_jobs_callbacks(steve, common_preview_startjob, NULL, NULL);
-
+
+#if defined(__APPLE__) && (PARALLEL == 1) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2)
+ // Workaround for Apple gcc 4.2.1 omp vs background thread bug
+ thread_tls_data = pthread_getspecific(gomp_tls_key);
+#endif
+
WM_jobs_start(CTX_wm_manager(C), steve);
}
@@ -1154,6 +1171,11 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M
WM_jobs_timer(steve, 0.1, NC_MATERIAL, NC_MATERIAL);
WM_jobs_callbacks(steve, common_preview_startjob, NULL, shader_preview_updatejob);
+#if defined(__APPLE__) && (PARALLEL == 1) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2)
+ // Workaround for Apple gcc 4.2.1 omp vs background thread bug
+ thread_tls_data = pthread_getspecific(gomp_tls_key);
+#endif
+
WM_jobs_start(CTX_wm_manager(C), steve);
}
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index 9bfe3213587..a3fe29536a3 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -204,6 +204,11 @@ void ED_region_draw_cb_exit(ARegionType *art, void *handle)
}
}
+void *ED_region_draw_cb_customdata(void *handle)
+{
+ return ((RegionDrawCB *)handle)->customdata;
+}
+
void ED_region_draw_cb_draw(const bContext *C, ARegion *ar, int type)
{
RegionDrawCB *rdc;
diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c
index 3ebb4c61f7b..7b59f6aafa9 100644
--- a/source/blender/editors/space_buttons/buttons_ops.c
+++ b/source/blender/editors/space_buttons/buttons_ops.c
@@ -38,6 +38,8 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "ED_screen.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
@@ -75,6 +77,7 @@ void BUTTONS_OT_toolbox(wmOperatorType *ot)
/* api callbacks */
ot->invoke= toolbox_invoke;
+ ot->poll= ED_operator_buttons_active;
}
/********************** filebrowse operator *********************/
diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c
index 16f5f47075e..708089f8f4c 100644
--- a/source/blender/editors/space_console/console_draw.c
+++ b/source/blender/editors/space_console/console_draw.c
@@ -140,9 +140,23 @@ typedef struct ConsoleDrawContext {
static void console_draw_sel(int sel[2], int xy[2], int str_len, int cwidth, int console_width, int lheight)
{
- if(sel[0] < str_len && sel[1] > 0) {
+ if(sel[0] <= str_len && sel[1] >= 0) {
int sta = MAX2(sel[0], 0);
int end = MIN2(sel[1], str_len);
+
+ /* highly confusing but draws correctly */
+ if(sel[0] < 0 || sel[1] > str_len) {
+ if(sel[0] > 0) {
+ end= sta;
+ sta= 0;
+ }
+ if (sel[1] <= str_len) {
+ sta= end;
+ end= str_len;
+ }
+ }
+ /* end confusement */
+
{
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(stipple_halftone);
@@ -157,8 +171,8 @@ static void console_draw_sel(int sel[2], int xy[2], int str_len, int cwidth, int
}
}
- sel[0] -= str_len;
- sel[1] -= str_len;
+ sel[0] -= str_len + 1;
+ sel[1] -= str_len + 1;
}
@@ -179,7 +193,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, char *str, int str_len,
int ofs = (int)floor(((float)cdc->mval[0] / (float)cdc->cwidth));
*cdc->pos_pick += MIN2(ofs, str_len);
} else
- *cdc->pos_pick += str_len;
+ *cdc->pos_pick += str_len + 1;
}
}
@@ -190,6 +204,13 @@ static int console_draw_string(ConsoleDrawContext *cdc, char *str, int str_len,
else if (y_next-cdc->lheight < cdc->ymin) {
/* have not reached the drawable area so don't break */
cdc->xy[1]= y_next;
+
+ /* adjust selection even if not drawing */
+ if(cdc->sel[0] != cdc->sel[1]) {
+ cdc->sel[0] -= str_len + 1;
+ cdc->sel[1] -= str_len + 1;
+ }
+
return 1;
}
@@ -314,6 +335,7 @@ static int console_text_main__internal(struct SpaceConsole *sc, struct ARegion *
if(sc->sel_start != sc->sel_end) {
sel[0]= sc->sel_start;
sel[1]= sc->sel_end;
+ // printf("%d %d\n", sel[0], sel[1]);
}
/* text */
diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c
index 44c0b2159d7..763436dd05f 100644
--- a/source/blender/editors/space_console/console_ops.c
+++ b/source/blender/editors/space_console/console_ops.c
@@ -681,23 +681,71 @@ static int copy_exec(bContext *C, wmOperator *op)
char *buf_str;
ConsoleLine *cl;
-
+ int sel[2];
+ int offset= 0;
+
+#if 0
+ /* copy whole file */
for(cl= sc->scrollback.first; cl; cl= cl->next) {
BLI_dynstr_append(buf_dyn, cl->line);
BLI_dynstr_append(buf_dyn, "\n");
}
+#endif
+
+ if(sc->sel_start == sc->sel_end)
+ return OPERATOR_CANCELLED;
+
+
+ for(cl= sc->scrollback.first; cl; cl= cl->next) {
+ offset += cl->len + 1;
+ }
+
+ if(offset==0)
+ return OPERATOR_CANCELLED;
+
+
+ offset -= 1;
+ sel[0]= offset - sc->sel_end;
+ sel[1]= offset - sc->sel_start;
+
+ for(cl= sc->scrollback.first; cl; cl= cl->next) {
+
+ int sta= MAX2(0, sel[0]);
+ int end= MIN2(cl->len, sel[1]);
+
+ if(sel[0] <= cl->len && sel[1] >= 0) {
+ int str_len= cl->len;
+
+ /* highly confusing but draws correctly */
+ if(sel[0] < 0 || sel[1] > str_len) {
+ if(sel[0] > 0) {
+ end= sta;
+ sta= 0;
+ }
+ if (sel[1] <= str_len) {
+ sta= end;
+ end= str_len;
+ }
+ }
+ /* end confusement */
+
+ SWAP(int, sta, end);
+ end= cl->len - end;
+ sta= cl->len - sta;
+
+ if(BLI_dynstr_get_len(buf_dyn))
+ BLI_dynstr_append(buf_dyn, "\n");
+
+ BLI_dynstr_nappend(buf_dyn, cl->line + sta, end - sta);
+ }
+
+ sel[0] -= cl->len + 1;
+ sel[1] -= cl->len + 1;
+ }
buf_str= BLI_dynstr_get_cstring(buf_dyn);
buf_len= BLI_dynstr_get_len(buf_dyn);
BLI_dynstr_free(buf_dyn);
-
- /* hack for selection */
-#if 0
- if(sc->sel_start != sc->sel_end) {
- buf_str[buf_len - sc->sel_start]= '\0';
- WM_clipboard_text_set(buf_str+(buf_len - sc->sel_end), 0);
- }
-#endif
WM_clipboard_text_set(buf_str, 0);
MEM_freeN(buf_str);
@@ -723,11 +771,28 @@ static int paste_exec(bContext *C, wmOperator *op)
ConsoleLine *ci= console_history_verify(C);
char *buf_str= WM_clipboard_text_get(0);
+ char *buf_step, *buf_next;
if(buf_str==NULL)
return OPERATOR_CANCELLED;
- console_line_insert(ci, buf_str); /* TODO - Multiline copy?? */
+ buf_next= buf_str;
+ buf_step= buf_str;
+
+ while((buf_next=buf_step) && buf_next[0] != '\0') {
+ buf_step= strchr(buf_next, '\n');
+ if(buf_step) {
+ *buf_step= '\0';
+ buf_step++;
+ }
+
+ if(buf_next != buf_str) {
+ WM_operator_name_call(C, "CONSOLE_OT_execute", WM_OP_EXEC_DEFAULT, NULL);
+ ci= console_history_verify(C);
+ }
+
+ console_line_insert(ci, buf_next);
+ }
MEM_freeN(buf_str);
diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c
index 1cc8fc37e77..543fa1dfed7 100644
--- a/source/blender/editors/space_nla/nla_edit.c
+++ b/source/blender/editors/space_nla/nla_edit.c
@@ -246,27 +246,6 @@ void NLA_OT_tweakmode_exit (wmOperatorType *ot)
/* ******************** Add Action-Clip Operator ***************************** */
/* Add a new Action-Clip strip to the active track (or the active block if no space in the track) */
-/* pop up menu allowing user to choose the action to use */
-// TODO: at some point, we may have to migrate to a search menu to manage the case where there are many actions
-static int nlaedit_add_actionclip_invoke (bContext *C, wmOperator *op, wmEvent *evt)
-{
- Main *m= CTX_data_main(C);
- bAction *act;
- uiPopupMenu *pup;
- uiLayout *layout;
-
- pup= uiPupMenuBegin(C, "Add Action Clip", 0);
- layout= uiPupMenuLayout(pup);
-
- /* loop through Actions in Main database, adding as items in the menu */
- for (act= m->action.first; act; act= act->id.next)
- uiItemStringO(layout, act->id.name+2, 0, "NLA_OT_actionclip_add", "action", act->id.name+2);
- uiItemS(layout);
-
- uiPupMenuEnd(C, pup);
-
- return OPERATOR_CANCELLED;
-}
/* add the specified action as new strip */
static int nlaedit_add_actionclip_exec (bContext *C, wmOperator *op)
@@ -277,9 +256,9 @@ static int nlaedit_add_actionclip_exec (bContext *C, wmOperator *op)
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter, items;
-
- bAction *act = NULL;
- char actname[20];
+
+ bAction *act;
+
float cfra;
/* get editor data */
@@ -290,8 +269,7 @@ static int nlaedit_add_actionclip_exec (bContext *C, wmOperator *op)
cfra= (float)CFRA;
/* get action to use */
- RNA_string_get(op->ptr, "action", actname);
- act= (bAction *)find_id("AC", actname);
+ act= BLI_findlink(&CTX_data_main(C)->action, RNA_enum_get(op->ptr, "type"));
if (act == NULL) {
BKE_report(op->reports, RPT_ERROR, "No valid Action to add.");
@@ -350,13 +328,15 @@ static int nlaedit_add_actionclip_exec (bContext *C, wmOperator *op)
void NLA_OT_actionclip_add (wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name= "Add Action Strip";
ot->idname= "NLA_OT_actionclip_add";
ot->description= "Add an Action-Clip strip (i.e. an NLA Strip referencing an Action) to the active track";
/* api callbacks */
- ot->invoke= nlaedit_add_actionclip_invoke;
+ ot->invoke= WM_enum_search_invoke;
ot->exec= nlaedit_add_actionclip_exec;
ot->poll= nlaop_poll_tweakmode_off;
@@ -365,7 +345,9 @@ void NLA_OT_actionclip_add (wmOperatorType *ot)
/* props */
// TODO: this would be nicer as an ID-pointer...
- ot->prop = RNA_def_string(ot->srna, "action", "", 19, "Action", "Name of Action to add as a new Action-Clip Strip.");
+ prop= RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, 0, "Type", "");
+ RNA_def_enum_funcs(prop, RNA_action_itemf);
+ ot->prop= prop;
}
/* ******************** Add Transition Operator ***************************** */
diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c
index 09b5e3a80e2..4618f7a8873 100644
--- a/source/blender/editors/space_outliner/outliner.c
+++ b/source/blender/editors/space_outliner/outliner.c
@@ -3977,14 +3977,14 @@ static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBa
{
/* add a new path with the information obtained (only if valid) */
// TODO: what do we do with group name? for now, we don't supply one, and just let this use the KeyingSet name
- BKE_keyingset_add_destination(ks, id, NULL, path, array_index, flag, groupmode);
+ BKE_keyingset_add_path(ks, id, NULL, path, array_index, flag, groupmode);
ks->active_path= BLI_countlist(&ks->paths);
}
break;
case KEYINGSET_EDITMODE_REMOVE:
{
/* find the relevant path, then remove it from the KeyingSet */
- KS_Path *ksp= BKE_keyingset_find_destination(ks, id, NULL, path, array_index, groupmode);
+ KS_Path *ksp= BKE_keyingset_find_path(ks, id, NULL, path, array_index, groupmode);
if (ksp) {
/* free path's data */
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 1c04667e501..fc67881367f 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -751,6 +751,10 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
if(wmn->action == NA_RENAME)
ED_region_tag_redraw(ar);
break;
+ case NC_SCREEN:
+ if(wmn->data == ND_GPENCIL)
+ ED_region_tag_redraw(ar);
+ break;
}
}
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 81a508de139..51e8f9e43b2 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -76,6 +76,7 @@
#include "ED_screen.h"
#include "ED_transform.h"
#include "ED_types.h"
+#include "ED_mesh.h"
#include "UI_interface.h"
#include "UI_resources.h"
@@ -109,9 +110,7 @@ static void view3d_boxview_clip(ScrArea *sa)
if(ar->winx>ar->winy) y1= ar->winy*rv3d->dist/ar->winx;
else y1= rv3d->dist;
-
- ofs[0]= rv3d->ofs[0];
- ofs[1]= rv3d->ofs[1];
+ copy_v2_v2(ofs, rv3d->ofs);
}
else if(ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK)) {
ofs[2]= rv3d->ofs[2];
@@ -335,8 +334,7 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event)
VECCOPY(vod->ofs, rv3d->ofs);
/* If there's no selection, lastofs is unmodified and last value since static */
calculateTransformCenter(C, V3D_CENTROID, lastofs);
- VECCOPY(vod->dyn_ofs, lastofs);
- mul_v3_fl(vod->dyn_ofs, -1.0f);
+ negate_v3_v3(vod->dyn_ofs, lastofs);
}
else if (U.uiflag & USER_ORBIT_ZBUF) {
@@ -371,8 +369,7 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event)
closest_to_line_v3(dvec, vod->dyn_ofs, my_pivot, my_origin);
vod->dist0 = rv3d->dist = len_v3v3(my_pivot, dvec);
- negate_v3(dvec);
- VECCOPY(rv3d->ofs, dvec);
+ negate_v3_v3(rv3d->ofs, dvec);
}
negate_v3(vod->dyn_ofs);
VECCOPY(vod->ofs, rv3d->ofs);
@@ -547,11 +544,8 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y)
* dragged. */
phi = si * M_PI / 2.0;
- si= sin(phi);
q1[0]= cos(phi);
- q1[1]*= si;
- q1[2]*= si;
- q1[3]*= si;
+ mul_v3_fl(q1+1, sin(phi));
mul_qt_qtqt(rv3d->viewquat, q1, vod->oldquat);
if (vod->use_dyn_ofs) {
@@ -569,7 +563,7 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y)
}
else {
/* New turntable view code by John Aughey */
- float si, phi, q1[4];
+ float phi, q1[4];
float m[3][3];
float m_inv[3][3];
float xvec[3] = {1,0,0};
@@ -589,11 +583,8 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y)
/* Perform the up/down rotation */
phi = sensitivity * -(y - vod->oldy);
- si = sin(phi);
q1[0] = cos(phi);
- q1[1] = si * xvec[0];
- q1[2] = si * xvec[1];
- q1[3] = si * xvec[2];
+ mul_v3_v3fl(q1+1, xvec, sin(phi));
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
if (vod->use_dyn_ofs) {
@@ -634,12 +625,10 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y)
if ((dot_v3v3(snapmat[0], viewmat[0]) > thres) &&
(dot_v3v3(snapmat[1], viewmat[1]) > thres) &&
- (dot_v3v3(snapmat[2], viewmat[2]) > thres)){
-
- QUATCOPY(rv3d->viewquat, snapquats[i]);
-
- rv3d->view = view;
-
+ (dot_v3v3(snapmat[2], viewmat[2]) > thres)
+ ) {
+ copy_qt_qt(rv3d->viewquat, snapquats[i]);
+ rv3d->view= view;
break;
}
}
@@ -968,18 +957,15 @@ static void view_zoom_mouseloc(ARegion *ar, float dfac, int mx, int my)
vb[0] = ar->winx;
vb[1] = ar->winy;
- tpos[0] = -rv3d->ofs[0];
- tpos[1] = -rv3d->ofs[1];
- tpos[2] = -rv3d->ofs[2];
+ negate_v3_v3(tpos, rv3d->ofs);
/* Project cursor position into 3D space */
initgrabz(rv3d, tpos[0], tpos[1], tpos[2]);
window_to_3d_delta(ar, dvec, mouseloc[0]-vb[0]/2, mouseloc[1]-vb[1]/2);
/* Calculate view target position for dolly */
- tvec[0] = -(tpos[0] + dvec[0]);
- tvec[1] = -(tpos[1] + dvec[1]);
- tvec[2] = -(tpos[2] + dvec[2]);
+ add_v3_v3v3(tvec, tpos, dvec);
+ negate_v3(tvec);
/* Offset to target position and dolly */
new_dist = rv3d->dist * dfac;
@@ -988,11 +974,7 @@ static void view_zoom_mouseloc(ARegion *ar, float dfac, int mx, int my)
rv3d->dist = new_dist;
/* Calculate final offset */
- dvec[0] = tvec[0] + dvec[0] * dfac;
- dvec[1] = tvec[1] + dvec[1] * dfac;
- dvec[2] = tvec[2] + dvec[2] * dfac;
-
- VECCOPY(rv3d->ofs, dvec);
+ madd_v3_v3v3fl(rv3d->ofs, tvec, dvec, dfac);
} else {
rv3d->dist *= dfac;
}
@@ -1384,7 +1366,7 @@ static int viewselected_exec(bContext *C, wmOperator *op) /* like a localview wi
}
}
else if (paint_facesel_test(ob)) {
-// XXX ok= minmax_tface(min, max);
+ ok= minmax_tface(ob, min, max);
}
else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) {
ok= PE_minmax(scene, min, max);
@@ -1393,9 +1375,10 @@ static int viewselected_exec(bContext *C, wmOperator *op) /* like a localview wi
Base *base= FIRSTBASE;
while(base) {
if(TESTBASE(v3d, base)) {
- minmax_object(base->object, min, max);
+
/* account for duplis */
- minmax_object_duplis(scene, base->object, min, max);
+ if (minmax_object_duplis(scene, base->object, min, max)==0)
+ minmax_object(base->object, min, max); /* use if duplis not found */
ok= 1;
}
@@ -1405,9 +1388,7 @@ static int viewselected_exec(bContext *C, wmOperator *op) /* like a localview wi
if(ok==0) return OPERATOR_FINISHED;
- afm[0]= (max[0]-min[0]);
- afm[1]= (max[1]-min[1]);
- afm[2]= (max[2]-min[2]);
+ sub_v3_v3v3(afm, max, min);
size= MAX3(afm[0], afm[1], afm[2]);
if(rv3d->persp==RV3D_ORTHO) {
@@ -1425,9 +1406,8 @@ static int viewselected_exec(bContext *C, wmOperator *op) /* like a localview wi
}
}
- new_ofs[0]= -(min[0]+max[0])/2.0f;
- new_ofs[1]= -(min[1]+max[1])/2.0f;
- new_ofs[2]= -(min[2]+max[2])/2.0f;
+ add_v3_v3v3(new_ofs, min, max);
+ mul_v3_fl(new_ofs, -0.5f);
new_dist = size;
@@ -1482,13 +1462,8 @@ static int viewcenter_cursor_exec(bContext *C, wmOperator *op)
}
else {
/* non camera center */
- float *curs= give_cursor(scene, v3d);
float new_ofs[3];
-
- new_ofs[0]= -curs[0];
- new_ofs[1]= -curs[1];
- new_ofs[2]= -curs[2];
-
+ negate_v3_v3(new_ofs, give_cursor(scene, v3d));
smooth_view(C, NULL, NULL, new_ofs, NULL, NULL, NULL);
}
@@ -1706,9 +1681,7 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
new_ofs[2] = -p[2];
} else {
/* We cant use the depth, fallback to the old way that dosnt set the center depth */
- new_ofs[0] = rv3d->ofs[0];
- new_ofs[1] = rv3d->ofs[1];
- new_ofs[2] = rv3d->ofs[2];
+ copy_v3_v3(new_ofs, rv3d->ofs);
initgrabz(rv3d, -new_ofs[0], -new_ofs[1], -new_ofs[2]);
@@ -1982,7 +1955,7 @@ static EnumPropertyItem prop_view_orbit_items[] = {
static int vieworbit_exec(bContext *C, wmOperator *op)
{
RegionView3D *rv3d= CTX_wm_region_view3d(C);
- float phi, si, q1[4], new_quat[4];
+ float phi, q1[4], new_quat[4];
int orbitdir;
orbitdir = RNA_enum_get(op->ptr, "type");
@@ -1991,6 +1964,7 @@ static int vieworbit_exec(bContext *C, wmOperator *op)
if(rv3d->persp != RV3D_CAMOB) {
if(orbitdir == V3D_VIEW_STEPLEFT || orbitdir == V3D_VIEW_STEPRIGHT) {
+ float si;
/* z-axis */
phi= (float)(M_PI/360.0)*U.pad_rot_angle;
if(orbitdir == V3D_VIEW_STEPRIGHT) phi= -phi;
@@ -2008,11 +1982,8 @@ static int vieworbit_exec(bContext *C, wmOperator *op)
normalize_v3(q1+1);
phi= (float)(M_PI/360.0)*U.pad_rot_angle;
if(orbitdir == V3D_VIEW_STEPDOWN) phi= -phi;
- si= (float)sin(phi);
q1[0]= (float)cos(phi);
- q1[1]*= si;
- q1[2]*= si;
- q1[3]*= si;
+ mul_v3_fl(q1+1, sin(phi));
mul_qt_qtqt(new_quat, rv3d->viewquat, q1);
rv3d->view= 0;
}
@@ -2815,7 +2786,7 @@ void viewmoveNDOF(Scene *scene, ARegion *ar, View3D *v3d, int mode)
float xvec[3] = {1,0,0};
float yvec[3] = {0,-1,0};
float zvec[3] = {0,0,1};
- float phi, si;
+ float phi;
float q1[4];
float obofs[3];
float reverse;
@@ -2964,11 +2935,8 @@ void viewmoveNDOF(Scene *scene, ARegion *ar, View3D *v3d, int mode)
/* Perform the up/down rotation */
phi = sbadjust * rsens * /*0.5f * */ fval[3]; /* spin vertically half as fast as horizontally */
- si = sin(phi);
q1[0] = cos(phi);
- q1[1] = si * xvec[0];
- q1[2] = si * xvec[1];
- q1[3] = si * xvec[2];
+ mul_v3_v3fl(q1+1, xvec, sin(phi));
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
if (use_sel) {
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 59051c7a894..1674c135008 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -161,11 +161,9 @@ static void view_settings_from_ob(Object *ob, float *ofs, float *quat, float *di
if (!ob) return;
/* Offset */
- if (ofs) {
- VECCOPY(ofs, ob->obmat[3]);
- mul_v3_fl(ofs, -1.0f); /*flip the vector*/
- }
-
+ if (ofs)
+ negate_v3_v3(ofs, ob->obmat[3]);
+
/* Quat */
if (quat) {
copy_m4_m4(bmat, ob->obmat);
@@ -404,13 +402,9 @@ static void setcameratoview3d(View3D *v3d, RegionView3D *rv3d, Object *ob)
{
float dvec[3];
float mat3[3][3];
-
- dvec[0]= rv3d->dist*rv3d->viewinv[2][0];
- dvec[1]= rv3d->dist*rv3d->viewinv[2][1];
- dvec[2]= rv3d->dist*rv3d->viewinv[2][2];
-
- VECCOPY(ob->loc, dvec);
- sub_v3_v3v3(ob->loc, ob->loc, rv3d->ofs);
+
+ mul_v3_v3fl(dvec, rv3d->viewinv[2], rv3d->dist);
+ sub_v3_v3v3(ob->loc, dvec, rv3d->ofs);
rv3d->viewquat[0]= -rv3d->viewquat[0];
// quat_to_eul( ob->rot,rv3d->viewquat); // in 2.4x for xyz eulers only
@@ -602,9 +596,7 @@ void viewvector(RegionView3D *rv3d, float coord[3], float vec[3])
p2[3] = 1.0f;
mul_m4_v4(rv3d->viewmat, p2);
- p2[0] = 2.0f * p2[0];
- p2[1] = 2.0f * p2[1];
- p2[2] = 2.0f * p2[2];
+ mul_v3_fl(p2, 2.0f);
mul_m4_v4(rv3d->viewinv, p2);
@@ -1154,6 +1146,25 @@ static void view3d_viewlock(RegionView3D *rv3d)
}
}
+/* give a 4x4 matrix from a perspective view, only needs viewquat, ofs and dist
+ * basically the same as...
+ * rv3d->persp= RV3D_PERSP
+ * setviewmatrixview3d(scene, v3d, rv3d);
+ * setcameratoview3d(v3d, rv3d, v3d->camera);
+ * ...but less of a hassle
+ * */
+static void view3d_persp_mat4(RegionView3D *rv3d, float mat[][4])
+{
+ float qt[4], dvec[3];
+ copy_qt_qt(qt, rv3d->viewquat);
+ qt[0]= -qt[0];
+ quat_to_mat4(mat, qt);
+ mat[3][2] -= rv3d->dist;
+ translate_m4(mat, rv3d->ofs[0], rv3d->ofs[1], rv3d->ofs[2]);
+ mul_v3_v3fl(dvec, mat[2], -rv3d->dist);
+ sub_v3_v3v3(mat[3], dvec, rv3d->ofs);
+}
+
/* dont set windows active in in here, is used by renderwin too */
void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d)
{
@@ -1690,8 +1701,8 @@ void game_set_commmandline_options(GameData *gm)
test= (gm->flag & GAME_ENABLE_ALL_FRAMES);
SYS_WriteCommandLineInt(syshandle, "fixedtime", test);
-// a= (G.fileflags & G_FILE_GAME_TO_IPO);
-// SYS_WriteCommandLineInt(syshandle, "game2ipo", a);
+ test= (gm->flag & GAME_ENABLE_ANIMATION_RECORD);
+ SYS_WriteCommandLineInt(syshandle, "animation_record", test);
test= (gm->flag & GAME_IGNORE_DEPRECATION_WARNINGS);
SYS_WriteCommandLineInt(syshandle, "ignore_deprecation_warnings", test);
@@ -1940,12 +1951,17 @@ typedef struct FlyInfo {
float xlock_momentum, zlock_momentum; /* nicer dynamics */
float grid; /* world scale 1.0 default */
+ /* root most parent */
+ Object *root_parent;
+
/* backup values */
float dist_backup; /* backup the views distance since we use a zero dist for fly mode */
float ofs_backup[3]; /* backup the views offset incase the user cancels flying in non camera mode */
float rot_backup[4]; /* backup the views quat incase the user cancels flying in non camera mode. (quat for view, eul for camera) */
short persp_backup; /* remember if were ortho or not, only used for restoring the view if it was a ortho view */
+ void *obtfm; /* backup the objects transform */
+
/* compare between last state */
double time_lastwheel; /* used to accelerate when using the mousewheel a lot */
double time_lastdraw; /* time between draws */
@@ -2019,13 +2035,23 @@ static int initFlyInfo (bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *even
fly->persp_backup= fly->rv3d->persp;
fly->dist_backup= fly->rv3d->dist;
if (fly->rv3d->persp==RV3D_CAMOB) {
- /* store the origoinal camera loc and rot */
- VECCOPY(fly->ofs_backup, fly->v3d->camera->loc);
- VECCOPY(fly->rot_backup, fly->v3d->camera->rot);
+ Object *ob_back;
+ if((fly->root_parent=fly->v3d->camera->parent)) {
+ while(fly->root_parent->parent)
+ fly->root_parent= fly->root_parent->parent;
+ ob_back= fly->root_parent;
+ }
+ else {
+ ob_back= fly->v3d->camera;
+ }
+
+ /* store the original camera loc and rot */
+ /* TODO. axis angle etc */
+
+ fly->obtfm= object_tfm_backup(ob_back);
where_is_object(fly->scene, fly->v3d->camera);
- VECCOPY(fly->rv3d->ofs, fly->v3d->camera->obmat[3]);
- mul_v3_fl(fly->rv3d->ofs, -1.0f); /*flip the vector*/
+ negate_v3_v3(fly->rv3d->ofs, fly->v3d->camera->obmat[3]);
fly->rv3d->dist=0.0;
} else {
@@ -2066,10 +2092,14 @@ static int flyEnd(bContext *C, FlyInfo *fly)
if (fly->state == FLY_CANCEL) {
/* Revert to original view? */
if (fly->persp_backup==RV3D_CAMOB) { /* a camera view */
+ Object *ob_back;
+ if(fly->root_parent)ob_back= fly->root_parent;
+ else ob_back= fly->v3d->camera;
- VECCOPY(v3d->camera->loc, fly->ofs_backup);
- VECCOPY(v3d->camera->rot, fly->rot_backup);
- DAG_id_flush_update(&v3d->camera->id, OB_RECALC_OB);
+ /* store the original camera loc and rot */
+ object_tfm_restore(ob_back, fly->obtfm);
+
+ DAG_id_flush_update(&ob_back->id, OB_RECALC_OB);
} else {
/* Non Camera we need to reset the view back to the original location bacause the user canceled*/
QUATCOPY(rv3d->viewquat, fly->rot_backup);
@@ -2079,10 +2109,15 @@ static int flyEnd(bContext *C, FlyInfo *fly)
}
else if (fly->persp_backup==RV3D_CAMOB) { /* camera */
float mat3[3][3];
- copy_m3_m4(mat3, v3d->camera->obmat);
- object_mat3_to_rot(v3d->camera, mat3, TRUE);
+ if(fly->root_parent) {
+ DAG_id_flush_update(&fly->root_parent->id, OB_RECALC_OB);
+ }
+ else {
+ copy_m3_m4(mat3, v3d->camera->obmat);
+ object_mat3_to_rot(v3d->camera, mat3, TRUE);
+ DAG_id_flush_update(&v3d->camera->id, OB_RECALC_OB);
+ }
- DAG_id_flush_update(&v3d->camera->id, OB_RECALC_OB);
#if 0 //XXX2.5
if (IS_AUTOKEY_MODE(NORMAL)) {
allqueue(REDRAWIPO, 0);
@@ -2107,6 +2142,8 @@ static int flyEnd(bContext *C, FlyInfo *fly)
rv3d->rflag &= ~(RV3D_FLYMODE|RV3D_NAVIGATING);
//XXX2.5 BIF_view3d_previewrender_signal(fly->sa, PR_DBASE|PR_DISPRECT); /* not working at the moment not sure why */
+ if(fly->obtfm)
+ MEM_freeN(fly->obtfm);
if(fly->state == FLY_CONFIRM) {
MEM_freeN(fly);
@@ -2250,6 +2287,8 @@ static int flyApply(FlyInfo *fly)
ARegion *ar = fly->ar;
Scene *scene= fly->scene;
+ float prev_view_mat[4][4];
+
float mat[3][3], /* 3x3 copy of the view matrix so we can move allong the view axis */
dvec[3]={0,0,0}, /* this is the direction thast added to the view offset per redraw */
@@ -2265,7 +2304,9 @@ static int flyApply(FlyInfo *fly)
unsigned char
apply_rotation= 1; /* if the user presses shift they can look about without movinf the direction there looking*/
-
+ if(fly->root_parent)
+ view3d_persp_mat4(rv3d, prev_view_mat);
+
/* the dist defines a vector that is infront of the offset
to rotate the view about.
this is no good for fly mode because we
@@ -2458,42 +2499,73 @@ static int flyApply(FlyInfo *fly)
interp_v3_v3v3(dvec, dvec_tmp, fly->dvec_prev, (1.0f/(1.0f+(time_redraw*5.0f))));
if (rv3d->persp==RV3D_CAMOB) {
- if (v3d->camera->protectflag & OB_LOCK_LOCX)
- dvec[0] = 0.0;
- if (v3d->camera->protectflag & OB_LOCK_LOCY)
- dvec[1] = 0.0;
- if (v3d->camera->protectflag & OB_LOCK_LOCZ)
- dvec[2] = 0.0;
+ Object *lock_ob= fly->root_parent ? fly->root_parent : fly->v3d->camera;
+ if (lock_ob->protectflag & OB_LOCK_LOCX) dvec[0] = 0.0;
+ if (lock_ob->protectflag & OB_LOCK_LOCY) dvec[1] = 0.0;
+ if (lock_ob->protectflag & OB_LOCK_LOCZ) dvec[2] = 0.0;
}
add_v3_v3v3(rv3d->ofs, rv3d->ofs, dvec);
-#if 0 //XXX2.5
+
+ /* todo, dynamic keys */
+#if 0
if (fly->zlock && fly->xlock)
- headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
+ ED_area_headerprint(fly->ar, "FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
else if (fly->zlock)
- headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
+ ED_area_headerprint(fly->ar, "FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
else if (fly->xlock)
- headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
+ ED_area_headerprint(fly->ar, "FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
else
- headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
+ ED_area_headerprint(fly->ar, "FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
#endif
/* we are in camera view so apply the view ofs and quat to the view matrix and set the camera to the view */
if (rv3d->persp==RV3D_CAMOB) {
- rv3d->persp= RV3D_PERSP; /*set this so setviewmatrixview3d uses the ofs and quat instead of the camera */
- setviewmatrixview3d(scene, v3d, rv3d);
- setcameratoview3d(v3d, rv3d, v3d->camera);
- rv3d->persp= RV3D_CAMOB;
-
+ ID *id_key;
+ /* transform the parent or the camera? */
+ if(fly->root_parent) {
+ Object *ob_update;
+
+ float view_mat[4][4];
+ float prev_view_imat[4][4];
+ float diff_mat[4][4];
+ float parent_mat[4][4];
+
+ invert_m4_m4(prev_view_imat, prev_view_mat);
+ view3d_persp_mat4(rv3d, view_mat);
+ mul_m4_m4m4(diff_mat, prev_view_imat, view_mat);
+ mul_m4_m4m4(parent_mat, fly->root_parent->obmat, diff_mat);
+ object_apply_mat4(fly->root_parent, parent_mat);
+
+ // where_is_object(scene, fly->root_parent);
+
+ ob_update= v3d->camera->parent;
+ while(ob_update) {
+ DAG_id_flush_update(&ob_update->id, OB_RECALC_OB);
+ ob_update= ob_update->parent;
+ }
+
+ copy_m4_m4(prev_view_mat, view_mat);
+
+ id_key= &fly->root_parent->id;
+
+ }
+ else {
+ float view_mat[4][4];
+ view3d_persp_mat4(rv3d, view_mat);
+ object_apply_mat4(v3d->camera, view_mat);
+ id_key= &v3d->camera->id;
+ }
+
/* record the motion */
- if (autokeyframe_cfra_can_key(scene, &v3d->camera->id)) {
+ if (autokeyframe_cfra_can_key(scene, id_key)) {
bCommonKeySrc cks;
ListBase dsources = {&cks, &cks};
int cfra = CFRA;
/* init common-key-source for use by KeyingSets */
memset(&cks, 0, sizeof(bCommonKeySrc));
- cks.id= &v3d->camera->id;
+ cks.id= id_key;
/* insert keyframes
* 1) on the first frame
@@ -2612,10 +2684,9 @@ void view3d_align_axis_to_vector(View3D *v3d, RegionView3D *rv3d, int axisidx, f
if(axisidx > 0) alignaxis[axisidx-1]= 1.0;
else alignaxis[-axisidx-1]= -1.0;
-
- VECCOPY(norm, vec);
- normalize_v3(norm);
-
+
+ normalize_v3_v3(norm, vec);
+
angle= (float)acos(dot_v3v3(alignaxis, norm));
cross_v3_v3v3(axis, alignaxis, norm);
axis_angle_to_quat( new_quat,axis, -angle);
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index d63054756d9..09c99a47a46 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -718,7 +718,7 @@ int transformEvent(TransInfo *t, wmEvent *event)
}
// Modal numinput events
- t->redraw |= handleNumInput(&(t->num), event, t->snap[1]);
+ t->redraw |= handleNumInput(&(t->num), event);
}
/* else do non-mapped events */
else if (event->val==KM_PRESS) {
@@ -971,7 +971,7 @@ int transformEvent(TransInfo *t, wmEvent *event)
}
// Numerical input events
- t->redraw |= handleNumInput(&(t->num), event, t->snap[1]);
+ t->redraw |= handleNumInput(&(t->num), event);
// NDof input events
switch(handleNDofInput(&(t->ndof), event))
@@ -2081,6 +2081,8 @@ void initWarp(TransInfo *t)
t->snap[1] = 5.0f;
t->snap[2] = 1.0f;
+ t->num.increment = 1.0f;
+
t->flag |= T_NO_CONSTRAINT;
/* we need min/max in view space */
@@ -2237,6 +2239,8 @@ void initShear(TransInfo *t)
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
+ t->num.increment = 0.1f;
+
t->flag |= T_NO_CONSTRAINT;
}
@@ -2363,6 +2367,8 @@ void initResize(TransInfo *t)
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
+
+ t->num.increment = t->snap[1];
}
static void headerResize(TransInfo *t, float vec[3], char *str) {
@@ -2614,6 +2620,8 @@ void initToSphere(TransInfo *t)
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
+ t->num.increment = t->snap[1];
+
t->num.flag |= NUM_NULL_ONE | NUM_NO_NEGATIVE;
t->flag |= T_NO_CONSTRAINT;
@@ -2705,11 +2713,12 @@ void initRotation(TransInfo *t)
t->snap[1] = (float)((5.0/180)*M_PI);
t->snap[2] = t->snap[1] * 0.2f;
+ t->num.increment = 1.0f;
+
if (t->flag & T_2D_EDIT)
t->flag |= T_NO_CONSTRAINT;
- VECCOPY(t->axis, t->viewinv[2]);
- mul_v3_fl(t->axis, -1.0f);
+ negate_v3_v3(t->axis, t->viewinv[2]);
normalize_v3(t->axis);
}
@@ -2967,8 +2976,7 @@ int Rotation(TransInfo *t, short mval[2])
t->con.applyRot(t, NULL, t->axis, &final);
} else {
/* reset axis if constraint is not set */
- VECCOPY(t->axis, t->viewinv[2]);
- mul_v3_fl(t->axis, -1.0f);
+ negate_v3_v3(t->axis, t->viewinv[2]);
normalize_v3(t->axis);
}
@@ -3032,6 +3040,8 @@ void initTrackball(TransInfo *t)
t->snap[1] = (float)((5.0/180)*M_PI);
t->snap[2] = t->snap[1] * 0.2f;
+ t->num.increment = 1.0f;
+
t->flag |= T_NO_CONSTRAINT;
}
@@ -3149,6 +3159,8 @@ void initTranslation(TransInfo *t)
t->snap[0] = 0.0f;
t->snap[1] = t->snap[2] = 1.0f;
}
+
+ t->num.increment = t->snap[1];
}
static void headerTranslation(TransInfo *t, float vec[3], char *str) {
@@ -3339,6 +3351,8 @@ void initShrinkFatten(TransInfo *t)
t->snap[1] = 1.0f;
t->snap[2] = t->snap[1] * 0.1f;
+ t->num.increment = t->snap[1];
+
t->flag |= T_NO_CONSTRAINT;
}
}
@@ -3413,6 +3427,8 @@ void initTilt(TransInfo *t)
t->snap[1] = (float)((5.0/180)*M_PI);
t->snap[2] = t->snap[1] * 0.2f;
+ t->num.increment = t->snap[1];
+
t->flag |= T_NO_CONSTRAINT;
}
@@ -3482,6 +3498,8 @@ void initCurveShrinkFatten(TransInfo *t)
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
+ t->num.increment = t->snap[1];
+
t->flag |= T_NO_ZERO;
t->num.flag |= NUM_NO_ZERO;
@@ -3551,6 +3569,8 @@ void initPushPull(TransInfo *t)
t->snap[0] = 0.0f;
t->snap[1] = 1.0f;
t->snap[2] = t->snap[1] * 0.1f;
+
+ t->num.increment = t->snap[1];
}
@@ -3639,6 +3659,8 @@ void initBevel(TransInfo *t)
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
+ t->num.increment = t->snap[1];
+
/* DON'T KNOW WHY THIS IS NEEDED */
if (G.editBMesh->imval[0] == 0 && G.editBMesh->imval[1] == 0) {
/* save the initial mouse co */
@@ -3748,6 +3770,8 @@ void initBevelWeight(TransInfo *t)
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
+ t->num.increment = t->snap[1];
+
t->flag |= T_NO_CONSTRAINT;
}
@@ -3819,6 +3843,8 @@ void initCrease(TransInfo *t)
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
+ t->num.increment = t->snap[1];
+
t->flag |= T_NO_CONSTRAINT;
}
@@ -3893,6 +3919,8 @@ void initBoneSize(TransInfo *t)
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
+
+ t->num.increment = t->snap[1];
}
static void headerBoneSize(TransInfo *t, float vec[3], char *str) {
@@ -4009,6 +4037,8 @@ void initBoneEnvelope(TransInfo *t)
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
+ t->num.increment = t->snap[1];
+
t->flag |= T_NO_CONSTRAINT;
}
@@ -4586,6 +4616,8 @@ void initEdgeSlide(TransInfo *t)
t->snap[1] = (float)((5.0/180)*M_PI);
t->snap[2] = t->snap[1] * 0.2f;
+ t->num.increment = t->snap[1];
+
t->flag |= T_NO_CONSTRAINT;
}
@@ -4754,6 +4786,8 @@ void initBoneRoll(TransInfo *t)
t->snap[1] = (float)((5.0/180)*M_PI);
t->snap[2] = t->snap[1] * 0.2f;
+ t->num.increment = 1.0f;
+
t->flag |= T_NO_CONSTRAINT;
}
@@ -4814,6 +4848,8 @@ void initBakeTime(TransInfo *t)
t->snap[0] = 0.0f;
t->snap[1] = 1.0f;
t->snap[2] = t->snap[1] * 0.1f;
+
+ t->num.increment = t->snap[1];
}
int BakeTime(TransInfo *t, short mval[2])
@@ -5031,6 +5067,8 @@ void initSeqSlide(TransInfo *t)
t->snap[0] = 0.0f;
t->snap[1] = floor(t->scene->r.frs_sec / t->scene->r.frs_sec_base);
t->snap[2] = 10.0f;
+
+ t->num.increment = t->snap[1];
}
static void headerSeqSlide(TransInfo *t, float val[2], char *str)
@@ -5246,6 +5284,8 @@ void initTimeTranslate(TransInfo *t)
/* initialise snap like for everything else */
t->snap[0] = 0.0f;
t->snap[1] = t->snap[2] = 1.0f;
+
+ t->num.increment = t->snap[1];
}
static void headerTimeTranslate(TransInfo *t, char *str)
@@ -5392,6 +5432,8 @@ void initTimeSlide(TransInfo *t)
/* initialise snap like for everything else */
t->snap[0] = 0.0f;
t->snap[1] = t->snap[2] = 1.0f;
+
+ t->num.increment = t->snap[1];
}
static void headerTimeSlide(TransInfo *t, float sval, char *str)
@@ -5524,6 +5566,8 @@ void initTimeScale(TransInfo *t)
/* initialise snap like for everything else */
t->snap[0] = 0.0f;
t->snap[1] = t->snap[2] = 1.0f;
+
+ t->num.increment = t->snap[1];
}
static void headerTimeScale(TransInfo *t, char *str) {
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 9d0cfdc5ac0..9d236bd47db 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -1116,6 +1116,7 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
td->loc = NULL;
td->ext = NULL;
+ td->ob = t->obedit;
td++;
}
@@ -1131,6 +1132,7 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
td->loc = NULL;
td->ext = NULL;
+ td->ob = t->obedit;
td++;
}
@@ -1165,6 +1167,7 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
normalize_m3(td->axismtx);
td->ext = NULL;
+ td->ob = t->obedit;
td++;
}
@@ -1181,6 +1184,7 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
td->flag= TD_SELECTED;
td->ext = NULL;
+ td->ob = t->obedit;
td++;
}
@@ -1209,6 +1213,7 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
td->ext = NULL;
td->val = NULL;
+ td->ob = t->obedit;
td++;
}
@@ -1231,6 +1236,7 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
td->ext = NULL;
td->val = NULL;
+ td->ob = t->obedit;
td++;
}
@@ -4712,7 +4718,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
Object *ob;
// short redrawipo=0, resetslowpar=1;
int cancelled= (t->state == TRANS_CANCEL);
- short duplicate= (t->undostr && strstr(t->undostr, "Duplicate")) ? 1 : 0;
+ short duplicate= (t->undostr && strstr(t->undostr, "Duplicate")) ? 1 : 0; /* see bugreport #21229 for reasons for this data */
/* early out when nothing happened */
if (t->total == 0 || t->mode == TFM_DUMMY)
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 27eb48614d2..d358614b1eb 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -859,7 +859,8 @@ void drawLine(TransInfo *t, float *center, float *dir, char axis, short options)
setlinestyle(0);
glBegin(GL_LINE_STRIP);
glVertex3fv(v1);
- glVertex3fv(v2);
+ glVertex3fv(center);
+// glVertex3fv(v2);
glEnd();
glPopMatrix();
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index 4c0f192ed40..2e60db8048e 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -817,9 +817,8 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
quat_to_mat4( mat,ml_sel->quat);
VECCOPY(normal, mat[2]);
- VECCOPY(plane, mat[1]);
- mul_v3_fl(plane, -1.0);
+ negate_v3_v3(plane, mat[1]);
result = ORIENTATION_NORMAL;
}
@@ -887,7 +886,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
add_v3_v3v3(plane, plane, pchan->pose_mat[1]);
}
}
- mul_v3_fl(plane, -1.0);
+ negate_v3(plane);
/* we need the transpose of the inverse for a normal... */
copy_m3_m4(imat, ob->obmat);
diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c
index d6e2621a235..fc193373327 100644
--- a/source/blender/editors/util/numinput.c
+++ b/source/blender/editors/util/numinput.c
@@ -159,7 +159,7 @@ void applyNumInput(NumInput *n, float *vec)
}
}
-char handleNumInput(NumInput *n, wmEvent *event, float increment)
+char handleNumInput(NumInput *n, wmEvent *event)
{
float Val = 0;
short idx = n->idx, idx_max = n->idx_max;
@@ -170,13 +170,13 @@ char handleNumInput(NumInput *n, wmEvent *event, float increment)
if (!n->ctrl[idx])
n->ctrl[idx] = 1;
- n->val[idx] += increment;
+ n->val[idx] += n->increment;
break;
case NUM_MODAL_INCREMENT_DOWN:
if (!n->ctrl[idx])
n->ctrl[idx] = 1;
- n->val[idx] -= increment;
+ n->val[idx] -= n->increment;
break;
default:
return 0;
@@ -300,6 +300,8 @@ char handleNumInput(NumInput *n, wmEvent *event, float increment)
}
}
+ printf("%f\n", n->val[idx]);
+
/* REDRAW SINCE NUMBERS HAVE CHANGED */
return 1;
}
diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c
index f6ad69c50eb..8ed70b5509f 100644
--- a/source/blender/imbuf/intern/divers.c
+++ b/source/blender/imbuf/intern/divers.c
@@ -270,7 +270,7 @@ void IMB_float_from_rect(struct ImBuf *ibuf)
if(to==NULL) return;
if(tof==NULL) {
- imb_addrectfloatImBuf(ibuf);
+ if (imb_addrectfloatImBuf(ibuf) == 0) return;
tof = ibuf->rect_float;
}
diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h
index 06ace29dbfe..8e04107afe0 100644
--- a/source/blender/makesdna/DNA_cloth_types.h
+++ b/source/blender/makesdna/DNA_cloth_types.h
@@ -66,6 +66,8 @@ typedef struct ClothSimSettings
float goalspring;
float goalfrict;
float velocity_smooth; /* smoothing of velocities for hair */
+ float collider_friction; /* friction with colliders */
+
int stepsPerFrame; /* Number of time steps per frame. */
int flags; /* flags, see CSIMSETT_FLAGS enum above. */
int preroll; /* How many frames of simulation to do before we start. */
@@ -76,7 +78,6 @@ typedef struct ClothSimSettings
short vgroup_struct; /* vertex group for scaling structural stiffness */
short presets; /* used for presets on GUI */
short reset;
- int pad;
struct EffectorWeights *effector_weights;
} ClothSimSettings;
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index d35de0497d9..5af90e2db6d 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -492,6 +492,7 @@ typedef struct GameData {
#define GAME_GLSL_NO_NODES (1 << 10)
#define GAME_GLSL_NO_EXTRA_TEX (1 << 11)
#define GAME_IGNORE_DEPRECATION_WARNINGS (1 << 12)
+#define GAME_ENABLE_ANIMATION_RECORD (1 << 13)
/* GameData.matmode */
#define GAME_MAT_TEXFACE 0
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index a2d18ed5d0a..85c6e73a909 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -276,10 +276,10 @@ typedef struct bTheme {
} bTheme;
/* for the moment only the name. may want to store options with this later */
-typedef struct bExtension {
- struct bExtension *next, *prev;
+typedef struct bAddon {
+ struct bAddon *next, *prev;
char module[64];
-} bExtension;
+} bAddon;
typedef struct SolidLight {
int flag, pad;
@@ -327,7 +327,7 @@ typedef struct UserDef {
struct ListBase uifonts;
struct ListBase uistyles;
struct ListBase keymaps;
- struct ListBase extensions;
+ struct ListBase addons;
char keyconfigstr[64];
short undosteps;
@@ -378,7 +378,7 @@ extern UserDef U; /* from blenkernel blender.c */
#define USER_SECTION_SYSTEM 3
#define USER_SECTION_THEME 4
#define USER_SECTION_INPUT 5
-#define USER_SECTION_EXTENSIONS 6
+#define USER_SECTION_ADDONS 6
/* flag */
#define USER_AUTOSAVE (1 << 0)
@@ -403,7 +403,7 @@ extern UserDef U; /* from blenkernel blender.c */
#define USER_ADD_VIEWALIGNED (1 << 19)
#define USER_RELPATHS (1 << 20)
#define USER_DRAGIMMEDIATE (1 << 21)
-#define USER_DONT_DOSCRIPTLINKS (1 << 22)
+#define USER_SCRIPT_AUTOEXEC_DISABLE (1 << 22)
#define USER_FILENOUI (1 << 23)
#define USER_NONEGFRAMES (1 << 24)
@@ -456,8 +456,10 @@ extern UserDef U; /* from blenkernel blender.c */
#define AUTOKEY_MODE_NORMAL 3
#define AUTOKEY_MODE_EDITKEYS 5
-/* Auto-Keying flag */
- /* U.autokey_flag (not strictly used when autokeying only - is also used when keyframing these days) */
+/* Auto-Keying flag
+ * U.autokey_flag (not strictly used when autokeying only - is also used when keyframing these days)
+ * note: AUTOKEY_FLAG_* is used with a macro, search for lines like IS_AUTOKEY_FLAG(INSERTAVAIL)
+ */
#define AUTOKEY_FLAG_INSERTAVAIL (1<<0)
#define AUTOKEY_FLAG_INSERTNEEDED (1<<1)
#define AUTOKEY_FLAG_AUTOMATKEY (1<<2)
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index 9df3e053d9f..a53645e7442 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -271,8 +271,9 @@ typedef struct wmOperator {
IDProperty *properties; /* saved, user-settable properties */
/* runtime */
- struct wmOperatorType *type; /* operator type definition from idname */
+ struct wmOperatorType *type;/* operator type definition from idname */
void *customdata; /* custom storage, only while operator runs */
+ void *py_instance; /* python stores the class instance here */
struct PointerRNA *ptr; /* rna pointer to access properties */
struct ReportList *reports; /* errors and warnings storage */
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index bce449cc66a..eb92b23bd5d 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -49,6 +49,7 @@ extern StructRNA RNA_ActionConstraint;
extern StructRNA RNA_ActionGroup;
extern StructRNA RNA_Actuator;
extern StructRNA RNA_ActuatorSensor;
+extern StructRNA RNA_Addon;
extern StructRNA RNA_AlwaysSensor;
extern StructRNA RNA_AndController;
extern StructRNA RNA_AnimData;
@@ -196,7 +197,6 @@ extern StructRNA RNA_EnumPropertyItem;
extern StructRNA RNA_EnvironmentMap;
extern StructRNA RNA_EnvironmentMapTexture;
extern StructRNA RNA_Event;
-extern StructRNA RNA_Extension;
extern StructRNA RNA_ExplodeModifier;
extern StructRNA RNA_ExpressionController;
extern StructRNA RNA_FCurve;
@@ -374,11 +374,11 @@ extern StructRNA RNA_RenderEngine;
extern StructRNA RNA_RenderLayer;
extern StructRNA RNA_RenderPass;
extern StructRNA RNA_RenderResult;
+extern StructRNA RNA_RenderSettings;
extern StructRNA RNA_RGBANodeSocket;
extern StructRNA RNA_RigidBodyJointConstraint;
extern StructRNA RNA_Scene;
extern StructRNA RNA_SceneGameData;
-extern StructRNA RNA_SceneRenderData;
extern StructRNA RNA_SceneRenderLayer;
extern StructRNA RNA_SceneSequence;
extern StructRNA RNA_Screen;
@@ -665,6 +665,7 @@ StructRNA *RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop);
int RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop);
int RNA_property_editable_index(PointerRNA *ptr, PropertyRNA *prop, int index);
+int RNA_property_editable_flag(PointerRNA *ptr, PropertyRNA *prop); /* without lib check, only checks the flag */
int RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop);
int RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop);
@@ -809,6 +810,7 @@ void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values)
int RNA_enum_get(PointerRNA *ptr, const char *name);
void RNA_enum_set(PointerRNA *ptr, const char *name, int value);
+void RNA_enum_set_identifier(PointerRNA *ptr, const char *name, const char *id);
int RNA_enum_is_equal(struct bContext *C, PointerRNA *ptr, const char *name, const char *enumname);
/* lower level functions that donr use a PointerRNA */
diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h
index 2ed365ad79f..ddd6dfef653 100644
--- a/source/blender/makesrna/RNA_enum_types.h
+++ b/source/blender/makesrna/RNA_enum_types.h
@@ -88,6 +88,7 @@ EnumPropertyItem *rna_TransformOrientation_itemf(struct bContext *C, struct Poin
/* Generic functions, return an enum from library data, index is the position
* in the linked list can add more for different types as needed */
+EnumPropertyItem *RNA_action_itemf(struct bContext *C, struct PointerRNA *ptr, int *free);
EnumPropertyItem *RNA_group_itemf(struct bContext *C, struct PointerRNA *ptr, int *free);
EnumPropertyItem *RNA_scene_itemf(struct bContext *C, struct PointerRNA *ptr, int *free);
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 81e34dad7c0..4a50be6f58b 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -1135,19 +1135,21 @@ int RNA_property_ui_icon(PropertyRNA *prop)
int RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
{
- ID *id;
+ ID *id= ptr->id.data;
int flag;
prop= rna_ensure_property(prop);
+ flag= prop->editable ? prop->editable(ptr) : prop->flag;
+ return (flag & PROP_EDITABLE) && (!id || !id->lib || (prop->flag & PROP_LIB_EXCEPTION));
+}
- if(prop->editable)
- flag= prop->editable(ptr);
- else
- flag= prop->flag;
-
- id= ptr->id.data;
+int RNA_property_editable_flag(PointerRNA *ptr, PropertyRNA *prop)
+{
+ int flag;
- return (flag & PROP_EDITABLE) && (!id || !id->lib || (prop->flag & PROP_LIB_EXCEPTION));
+ prop= rna_ensure_property(prop);
+ flag= prop->editable ? prop->editable(ptr) : prop->flag;
+ return (flag & PROP_EDITABLE);
}
/* same as RNA_property_editable(), except this checks individual items in an array */
@@ -1937,8 +1939,12 @@ void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr
else {
PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
- if(pprop->set && !((prop->flag & PROP_NEVER_NULL) && ptr_value.data == NULL))
+ if( pprop->set &&
+ !((prop->flag & PROP_NEVER_NULL) && ptr_value.data == NULL) &&
+ !((prop->flag & PROP_ID_SELF_CHECK) && ptr->id.data == ptr_value.id.data)
+ ) {
pprop->set(ptr, ptr_value);
+ }
}
}
@@ -3289,6 +3295,20 @@ void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
printf("RNA_enum_set: %s.%s not found.\n", ptr->type->identifier, name);
}
+void RNA_enum_set_identifier(PointerRNA *ptr, const char *name, const char *id)
+{
+ PropertyRNA *prop= RNA_struct_find_property(ptr, name);
+
+ if(prop) {
+ int value;
+ if(RNA_property_enum_value(NULL, ptr, prop, id, &value))
+ RNA_property_enum_set(ptr, prop, value);
+ else
+ printf("RNA_enum_set_identifier: %s.%s has no enum id '%s'.\n", ptr->type->identifier, name, id);
+ } else
+ printf("RNA_enum_set_identifier: %s.%s not found.\n", ptr->type->identifier, name);
+}
+
int RNA_enum_is_equal(bContext *C, PointerRNA *ptr, const char *name, const char *enumname)
{
PropertyRNA *prop= RNA_struct_find_property(ptr, name);
diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c
index 208f91a452f..453d9b9a844 100644
--- a/source/blender/makesrna/intern/rna_animation.c
+++ b/source/blender/makesrna/intern/rna_animation.c
@@ -249,6 +249,7 @@ static void rna_def_keyingset(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Active Path Index", "Current Keying Set index");
/* Flags */
+ // XXX: depreceated
prop= RNA_def_property(srna, "builtin", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYINGSET_BUILTIN);
diff --git a/source/blender/makesrna/intern/rna_animation_api.c b/source/blender/makesrna/intern/rna_animation_api.c
index 7ce93658789..208e3b9ca4c 100644
--- a/source/blender/makesrna/intern/rna_animation_api.c
+++ b/source/blender/makesrna/intern/rna_animation_api.c
@@ -41,7 +41,7 @@
#include "BKE_animsys.h"
-static void rna_KeyingSet_add_destination(KeyingSet *keyingset, ReportList *reports,
+static void rna_KeyingSet_add_path(KeyingSet *keyingset, ReportList *reports,
ID *id, char rna_path[], int array_index, int entire_array,
int grouping_method, char group_name[])
{
@@ -53,11 +53,11 @@ static void rna_KeyingSet_add_destination(KeyingSet *keyingset, ReportList *repo
/* if data is valid, call the API function for this */
if (keyingset) {
- BKE_keyingset_add_destination(keyingset, id, group_name, rna_path, array_index, flag, grouping_method);
+ BKE_keyingset_add_path(keyingset, id, group_name, rna_path, array_index, flag, grouping_method);
keyingset->active_path= BLI_countlist(&keyingset->paths);
}
else {
- BKE_report(reports, RPT_ERROR, "Keying Set Destination could not be added.");
+ BKE_report(reports, RPT_ERROR, "Keying Set Path could not be added.");
}
}
@@ -69,7 +69,7 @@ void RNA_api_keyingset(StructRNA *srna)
PropertyRNA *parm;
/* Add Destination */
- func= RNA_def_function(srna, "add_destination", "rna_KeyingSet_add_destination");
+ func= RNA_def_function(srna, "add_destination", "rna_KeyingSet_add_path");
RNA_def_function_ui_description(func, "Add a new destination for the Keying Set.");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
/* ID-block for target */
diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c
index 961e0708adc..4ecb93eb1d6 100644
--- a/source/blender/makesrna/intern/rna_cloth.c
+++ b/source/blender/makesrna/intern/rna_cloth.c
@@ -225,6 +225,12 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Internal Friction", "");
RNA_def_property_update(prop, 0, "rna_cloth_update");
+ prop= RNA_def_property(srna, "collider_friction", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "collider_friction");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Collider Friction", "");
+ RNA_def_property_update(prop, 0, "rna_cloth_update");
+
/* mass */
prop= RNA_def_property(srna, "mass", PROP_FLOAT, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c
index 02bfb9f9493..499423276ab 100644
--- a/source/blender/makesrna/intern/rna_curve.c
+++ b/source/blender/makesrna/intern/rna_curve.c
@@ -805,27 +805,27 @@ static void rna_def_curve(BlenderRNA *brna)
prop= RNA_def_property(srna, "resolution_u", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "resolu");
- RNA_def_property_ui_range(prop, 1, 1024, 1, 0);
RNA_def_property_range(prop, 1, INT_MAX);
+ RNA_def_property_ui_range(prop, 1, 64, 1, 0);
RNA_def_property_ui_text(prop, "Resolution U", "Surface resolution in U direction");
RNA_def_property_update(prop, 0, "rna_Curve_resolution_u_update_data");
prop= RNA_def_property(srna, "resolution_v", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "resolv");
- RNA_def_property_ui_range(prop, 1, 1024, 1, 0);
+ RNA_def_property_ui_range(prop, 1, 64, 1, 0);
RNA_def_property_range(prop, 1, INT_MAX);
RNA_def_property_ui_text(prop, "Resolution V", "Surface resolution in V direction");
RNA_def_property_update(prop, 0, "rna_Curve_resolution_v_update_data");
prop= RNA_def_property(srna, "render_resolution_u", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "resolu_ren");
- RNA_def_property_ui_range(prop, 0, 1024, 1, 0);
RNA_def_property_range(prop, 0, INT_MAX);
+ RNA_def_property_ui_range(prop, 1, 64, 1, 0);
RNA_def_property_ui_text(prop, "Render Resolution U", "Surface resolution in U direction used while rendering. Zero skips this property");
prop= RNA_def_property(srna, "render_resolution_v", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "resolv_ren");
- RNA_def_property_ui_range(prop, 0, 1024, 1, 0);
+ RNA_def_property_ui_range(prop, 1, 64, 1, 0);
RNA_def_property_range(prop, 0, INT_MAX);
RNA_def_property_ui_text(prop, "Render Resolution V", "Surface resolution in V direction used while rendering. Zero skips this property");
@@ -965,13 +965,15 @@ static void rna_def_curve_nurb(BlenderRNA *brna)
prop= RNA_def_property(srna, "resolution_u", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "resolu");
- RNA_def_property_range(prop, 1, 1024);
+ RNA_def_property_range(prop, 1, INT_MAX);
+ RNA_def_property_ui_range(prop, 1, 64, 1, 0);
RNA_def_property_ui_text(prop, "Resolution U", "Curve or Surface subdivisions per segment");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
prop= RNA_def_property(srna, "resolution_v", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "resolv");
- RNA_def_property_range(prop, 1, 1024);
+ RNA_def_property_range(prop, 1, INT_MAX);
+ RNA_def_property_ui_range(prop, 1, 64, 1, 0);
RNA_def_property_ui_text(prop, "Resolution V", "Surface subdivisions per segment");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c
index e394fd4f710..533d954871c 100644
--- a/source/blender/makesrna/intern/rna_image_api.c
+++ b/source/blender/makesrna/intern/rna_image_api.c
@@ -37,33 +37,18 @@
#ifdef RNA_RUNTIME
#include "BKE_image.h"
+#include "BKE_packedFile.h"
#include "BKE_main.h"
#include "BKE_utildefines.h"
+#include "IMB_imbuf.h"
+
#include "DNA_image_types.h"
#include "DNA_scene_types.h"
#include "MEM_guardedalloc.h"
-/*
- User should check if returned path exists before copying a file there.
-
- TODO: it would be better to return a (abs, rel) tuple.
-*/
-static char *rna_Image_get_export_path(Image *image, char *dest_dir, int rel)
-{
- int length = FILE_MAX;
- char *path= MEM_callocN(length, "image file path");
-
- if (!BKE_get_image_export_path(image, dest_dir, rel ? NULL : path, length, rel ? path : NULL, length )) {
- MEM_freeN(path);
- return NULL;
- }
-
- return path;
-}
-
-static void rna_Image_save(Image *image, bContext *C, ReportList *reports, char *path, Scene *scene)
+static void rna_Image_save_render(Image *image, bContext *C, ReportList *reports, char *path, Scene *scene)
{
ImBuf *ibuf;
@@ -92,15 +77,25 @@ static void rna_Image_save(Image *image, bContext *C, ReportList *reports, char
}
}
-char *rna_Image_get_abs_filename(Image *image, bContext *C)
+static void rna_Image_save(Image *image, ReportList *reports)
{
- char *filename= MEM_callocN(FILE_MAX, "Image.get_abs_filename()");
-
- BLI_strncpy(filename, image->name, FILE_MAXDIR + FILE_MAXFILE);
- BLI_convertstringcode(filename, CTX_data_main(C)->name);
- BLI_convertstringframe(filename, CTX_data_scene(C)->r.cfra, 0);
-
- return filename;
+ ImBuf *ibuf= BKE_image_get_ibuf(image, NULL);
+ if(ibuf) {
+ if(image->packedfile) {
+ if (writePackedFile(reports, image->name, image->packedfile, 0) != RET_OK) {
+ BKE_reportf(reports, RPT_ERROR, "Image \"%s\" could saved packed file to \"%s\"", image->id.name+2, image->name);
+ }
+ }
+ else if (IMB_saveiff(ibuf, image->name, ibuf->flags)) {
+ ibuf->userflags &= ~IB_BITMAPDIRTY;
+ }
+ else {
+ BKE_reportf(reports, RPT_ERROR, "Image \"%s\" could not be saved to \"%s\"", image->id.name+2, image->name);
+ }
+ }
+ else {
+ BKE_reportf(reports, RPT_ERROR, "Image \"%s\" does not have any image data", image->id.name+2);
+ }
}
#else
@@ -110,27 +105,16 @@ void RNA_api_image(StructRNA *srna)
FunctionRNA *func;
PropertyRNA *parm;
- func= RNA_def_function(srna, "get_export_path", "rna_Image_get_export_path");
- RNA_def_function_ui_description(func, "Produce image export path.");
- parm= RNA_def_string(func, "dest_dir", "", 0, "", "Destination directory.");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- parm= RNA_def_boolean(func, "get_rel_path", 1, "", "Return relative path if True.");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- parm= RNA_def_string(func, "path", "", 0, "", "Absolute export path.");
- RNA_def_function_return(func, parm);
-
- func= RNA_def_function(srna, "get_abs_filename", "rna_Image_get_abs_filename");
- RNA_def_function_ui_description(func, "Get absolute filename.");
- RNA_def_function_flag(func, FUNC_USE_CONTEXT);
- parm= RNA_def_string_file_path(func, "abs_filename", NULL, 0, "", "Image/movie absolute filename.");
- RNA_def_function_return(func, parm);
-
- func= RNA_def_function(srna, "save", "rna_Image_save");
- RNA_def_function_ui_description(func, "Save image to a specific path.");
+ func= RNA_def_function(srna, "save_render", "rna_Image_save_render");
+ RNA_def_function_ui_description(func, "Save image to a specific path using a scenes render settings.");
RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS);
parm= RNA_def_string(func, "path", "", 0, "", "Save path.");
RNA_def_property_flag(parm, PROP_REQUIRED);
parm= RNA_def_pointer(func, "scene", "Scene", "", "Scene to take image parameters from.");
+
+ func= RNA_def_function(srna, "save", "rna_Image_save");
+ RNA_def_function_ui_description(func, "Save image to its source path.");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c
index f6197a8da15..5b9913ad311 100644
--- a/source/blender/makesrna/intern/rna_lamp.c
+++ b/source/blender/makesrna/intern/rna_lamp.c
@@ -346,12 +346,13 @@ static void rna_def_lamp(BlenderRNA *brna)
prop= RNA_def_property(srna, "distance", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "dist");
- RNA_def_property_ui_range(prop, 0, 1000, 1.0, 2);
+ RNA_def_property_range(prop, 0, INT_MAX);
+ RNA_def_property_ui_range(prop, 0, 1000, 1, 3);
RNA_def_property_ui_text(prop, "Distance", "Falloff distance - the light is at half the original intensity at this point");
RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop= RNA_def_property(srna, "energy", PROP_FLOAT, PROP_NONE);
- RNA_def_property_ui_range(prop, 0, 10.0, 10, 2);
+ RNA_def_property_ui_range(prop, 0, 10, 1, 3);
RNA_def_property_ui_text(prop, "Energy", "Amount of light that the lamp emits");
RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index e937a3b10c2..56c0819680d 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -30,6 +30,7 @@
#include <stdio.h>
#include "RNA_define.h"
+#include "RNA_access.h"
#include "RNA_types.h"
#include "RNA_enum_types.h"
@@ -38,6 +39,7 @@
#ifdef RNA_RUNTIME
#include "BKE_main.h"
+#include "BKE_curve.h"
#include "BKE_mesh.h"
#include "BKE_armature.h"
#include "BKE_library.h"
@@ -109,12 +111,54 @@ void rna_Main_scenes_remove(Main *bmain, bContext *C, ReportList *reports, struc
unlink_scene(bmain, scene, newscene);
}
-Object *rna_Main_objects_new(Main *bmain, char* name, int type)
-{
- Object *ob= add_only_object(type, name);
+Object *rna_Main_objects_new(Main *bmain, ReportList *reports, char* name, ID *data)
+{
+ Object *ob;
+ int type= OB_EMPTY;
+ if(data) {
+ switch(GS(data->name)) {
+ case ID_ME:
+ type= OB_MESH;
+ break;
+ case ID_CU:
+ type= curve_type((struct Curve *)data);
+ break;
+ case ID_MB:
+ type= OB_MBALL;
+ break;
+ case ID_LA:
+ type= OB_LAMP;
+ break;
+ case ID_CA:
+ type= OB_CAMERA;
+ break;
+ case ID_LT:
+ type= OB_LATTICE;
+ break;
+ case ID_AR:
+ type= OB_ARMATURE;
+ break;
+ default:
+ {
+ const char *idname;
+ if(RNA_enum_id_from_value(id_type_items, GS(data->name), &idname) == 0)
+ idname= "UNKNOWN";
+
+ BKE_reportf(reports, RPT_ERROR, "ID type '%s' is not valid for a object.", idname);
+ return NULL;
+ }
+ }
+
+ data->us++;
+ }
+
+ ob= add_only_object(type, name);
ob->id.us--;
+
+ ob->data= data;
return ob;
}
+
void rna_Main_objects_remove(Main *bmain, ReportList *reports, struct Object *object)
{
/*
@@ -337,10 +381,11 @@ void RNA_def_main_objects(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_struct_ui_text(srna, "Main Objects", "Collection of objects");
func= RNA_def_function(srna, "new", "rna_Main_objects_new");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
RNA_def_function_ui_description(func, "Add a new object to the main database");
parm= RNA_def_string(func, "name", "Object", 0, "", "New name for the datablock.");
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm= RNA_def_enum(func, "type", object_type_items, 0, "", "Type of Object.");
+ parm= RNA_def_pointer(func, "object_data", "ID", "", "Object data or None for an empty object.");
RNA_def_property_flag(parm, PROP_REQUIRED);
/* return type */
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 295119bf8a2..117a1d5bc60 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -1443,6 +1443,7 @@ static void rna_def_object(BlenderRNA *brna)
static float default_quat[4] = {1,0,0,0}; /* default quaternion values */
static float default_axisAngle[4] = {0,0,1,0}; /* default axis-angle rotation values */
+ static float default_scale[3] = {1,1,1}; /* default scale values */
int matrix_dimsize[]= {4, 4};
int boundbox_dimsize[]= {8, 3};
@@ -1603,6 +1604,7 @@ static void rna_def_object(BlenderRNA *brna)
prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "size");
RNA_def_property_editable_array_func(prop, "rna_Object_scale_editable");
+ RNA_def_property_float_array_default(prop, default_scale);
RNA_def_property_ui_text(prop, "Scale", "Scaling of the object");
RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update");
@@ -1724,8 +1726,9 @@ static void rna_def_object(BlenderRNA *brna)
prop= RNA_def_property(srna, "empty_draw_size", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "empty_drawsize");
- RNA_def_property_range(prop, 0.01, 10.0);
- RNA_def_property_ui_text(prop, "Empty Display Size", "Size of of display for empties in the viewport");
+ RNA_def_property_range(prop, 0.1f, 1000.0f);
+ RNA_def_property_ui_range(prop, 0.01, 100, 1, 1);
+ RNA_def_property_ui_text(prop, "Empty Display Size", "Size of display for empties in the viewport");
RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
/* render */
diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c
index 44bf85679c4..240d02f7f9e 100644
--- a/source/blender/makesrna/intern/rna_pose.c
+++ b/source/blender/makesrna/intern/rna_pose.c
@@ -663,6 +663,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
static float default_quat[4] = {1,0,0,0}; /* default quaternion values */
static float default_axisAngle[4] = {0,0,1,0}; /* default axis-angle rotation values */
+ static float default_scale[3] = {1,1,1}; /* default scale values */
StructRNA *srna;
PropertyRNA *prop;
@@ -722,6 +723,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "size");
RNA_def_property_editable_array_func(prop, "rna_PoseChannel_scale_editable");
+ RNA_def_property_float_array_default(prop, default_scale);
RNA_def_property_ui_text(prop, "Scale", "");
RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable"); // XXX... disabled, since proxy-locked layers are currently used for ensuring proxy-syncing too
RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update");
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 6c6a5b2c0cb..c5f31590029 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -354,12 +354,12 @@ static void rna_Scene_active_keying_set_index_range(PointerRNA *ptr, int *min, i
}
-static char *rna_SceneRenderData_path(PointerRNA *ptr)
+static char *rna_RenderSettings_path(PointerRNA *ptr)
{
- return BLI_sprintfN("render_data");
+ return BLI_sprintfN("render");
}
-static int rna_SceneRenderData_threads_get(PointerRNA *ptr)
+static int rna_RenderSettings_threads_get(PointerRNA *ptr)
{
RenderData *rd= (RenderData*)ptr->data;
@@ -369,7 +369,7 @@ static int rna_SceneRenderData_threads_get(PointerRNA *ptr)
return BLI_system_thread_count();
}
-static int rna_SceneRenderData_save_buffers_get(PointerRNA *ptr)
+static int rna_RenderSettings_save_buffers_get(PointerRNA *ptr)
{
RenderData *rd= (RenderData*)ptr->data;
if(rd->mode & R_BORDER)
@@ -378,14 +378,14 @@ static int rna_SceneRenderData_save_buffers_get(PointerRNA *ptr)
return (rd->scemode & (R_EXR_TILE_FILE|R_FULL_SAMPLE)) != 0;
}
-static int rna_SceneRenderData_full_sample_get(PointerRNA *ptr)
+static int rna_RenderSettings_full_sample_get(PointerRNA *ptr)
{
RenderData *rd= (RenderData*)ptr->data;
return (rd->scemode & R_FULL_SAMPLE) && !(rd->mode & R_BORDER);
}
-static void rna_SceneRenderData_file_format_set(PointerRNA *ptr, int value)
+static void rna_RenderSettings_file_format_set(PointerRNA *ptr, int value)
{
RenderData *rd= (RenderData*)ptr->data;
@@ -413,7 +413,7 @@ static void rna_SceneRender_file_ext_get(PointerRNA *ptr, char *str)
BKE_add_image_extension(str, rd->imtype);
}
-void rna_SceneRenderData_jpeg2k_preset_update(RenderData *rd)
+void rna_RenderSettings_jpeg2k_preset_update(RenderData *rd)
{
rd->subimtype &= ~(R_JPEG2K_12BIT|R_JPEG2K_16BIT | R_JPEG2K_CINE_PRESET|R_JPEG2K_CINE_48FPS);
@@ -435,37 +435,37 @@ void rna_SceneRenderData_jpeg2k_preset_update(RenderData *rd)
}
#ifdef WITH_OPENJPEG
-static void rna_SceneRenderData_jpeg2k_preset_set(PointerRNA *ptr, int value)
+static void rna_RenderSettings_jpeg2k_preset_set(PointerRNA *ptr, int value)
{
RenderData *rd= (RenderData*)ptr->data;
rd->jp2_preset= value;
- rna_SceneRenderData_jpeg2k_preset_update(rd);
+ rna_RenderSettings_jpeg2k_preset_update(rd);
}
-static void rna_SceneRenderData_jpeg2k_depth_set(PointerRNA *ptr, int value)
+static void rna_RenderSettings_jpeg2k_depth_set(PointerRNA *ptr, int value)
{
RenderData *rd= (RenderData*)ptr->data;
rd->jp2_depth= value;
- rna_SceneRenderData_jpeg2k_preset_update(rd);
+ rna_RenderSettings_jpeg2k_preset_update(rd);
}
#endif
#ifdef WITH_QUICKTIME
-static int rna_SceneRenderData_qtcodecsettings_codecType_get(PointerRNA *ptr)
+static int rna_RenderSettings_qtcodecsettings_codecType_get(PointerRNA *ptr)
{
RenderData *rd= (RenderData*)ptr->data;
return quicktime_rnatmpvalue_from_codectype(rd->qtcodecsettings.codecType);
}
-static void rna_SceneRenderData_qtcodecsettings_codecType_set(PointerRNA *ptr, int value)
+static void rna_RenderSettings_qtcodecsettings_codecType_set(PointerRNA *ptr, int value)
{
RenderData *rd= (RenderData*)ptr->data;
rd->qtcodecsettings.codecType = quicktime_codecType_from_rnatmpvalue(value);
}
-static EnumPropertyItem *rna_SceneRenderData_qtcodecsettings_codecType_itemf(bContext *C, PointerRNA *ptr, int *free)
+static EnumPropertyItem *rna_RenderSettings_qtcodecsettings_codecType_itemf(bContext *C, PointerRNA *ptr, int *free)
{
EnumPropertyItem *item= NULL;
EnumPropertyItem tmp = {0, "", 0, "", ""};
@@ -492,19 +492,19 @@ static EnumPropertyItem *rna_SceneRenderData_qtcodecsettings_codecType_itemf(bCo
}
#endif
-static int rna_SceneRenderData_active_layer_index_get(PointerRNA *ptr)
+static int rna_RenderSettings_active_layer_index_get(PointerRNA *ptr)
{
RenderData *rd= (RenderData*)ptr->data;
return rd->actlay;
}
-static void rna_SceneRenderData_active_layer_index_set(PointerRNA *ptr, int value)
+static void rna_RenderSettings_active_layer_index_set(PointerRNA *ptr, int value)
{
RenderData *rd= (RenderData*)ptr->data;
rd->actlay= value;
}
-static void rna_SceneRenderData_active_layer_index_range(PointerRNA *ptr, int *min, int *max)
+static void rna_RenderSettings_active_layer_index_range(PointerRNA *ptr, int *min, int *max)
{
RenderData *rd= (RenderData*)ptr->data;
@@ -513,7 +513,7 @@ static void rna_SceneRenderData_active_layer_index_range(PointerRNA *ptr, int *m
*max= MAX2(0, *max);
}
-static void rna_SceneRenderData_engine_set(PointerRNA *ptr, int value)
+static void rna_RenderSettings_engine_set(PointerRNA *ptr, int value)
{
RenderData *rd= (RenderData*)ptr->data;
RenderEngineType *type= BLI_findlink(&R_engines, value);
@@ -522,7 +522,7 @@ static void rna_SceneRenderData_engine_set(PointerRNA *ptr, int value)
BLI_strncpy(rd->engine, type->idname, sizeof(rd->engine));
}
-static EnumPropertyItem *rna_SceneRenderData_engine_itemf(bContext *C, PointerRNA *ptr, int *free)
+static EnumPropertyItem *rna_RenderSettings_engine_itemf(bContext *C, PointerRNA *ptr, int *free)
{
RenderEngineType *type;
EnumPropertyItem *item= NULL;
@@ -542,7 +542,7 @@ static EnumPropertyItem *rna_SceneRenderData_engine_itemf(bContext *C, PointerRN
return item;
}
-static int rna_SceneRenderData_engine_get(PointerRNA *ptr)
+static int rna_RenderSettings_engine_get(PointerRNA *ptr)
{
RenderData *rd= (RenderData*)ptr->data;
RenderEngineType *type;
@@ -555,7 +555,7 @@ static int rna_SceneRenderData_engine_get(PointerRNA *ptr)
return 0;
}
-static void rna_SceneRenderData_color_management_update(Main *bmain, Scene *unused, PointerRNA *ptr)
+static void rna_RenderSettings_color_management_update(Main *bmain, Scene *unused, PointerRNA *ptr)
{
/* reset image nodes */
Scene *scene= (Scene*)ptr->id.data;
@@ -595,12 +595,12 @@ static void rna_SceneRenderLayer_name_set(PointerRNA *ptr, const char *value)
}
}
-static int rna_SceneRenderData_multiple_engines_get(PointerRNA *ptr)
+static int rna_RenderSettings_multiple_engines_get(PointerRNA *ptr)
{
return (BLI_countlist(&R_engines) > 1);
}
-static int rna_SceneRenderData_use_game_engine_get(PointerRNA *ptr)
+static int rna_RenderSettings_use_game_engine_get(PointerRNA *ptr)
{
RenderData *rd= (RenderData*)ptr->data;
RenderEngineType *type;
@@ -1563,51 +1563,46 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
prop= RNA_def_property(srna, "use_occlusion_culling", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", (1 << 5)); //XXX mode hardcoded // WO_DBVT_CULLING
RNA_def_property_ui_text(prop, "DBVT culling", "Use optimized Bullet DBVT tree for view frustrum and occlusion culling");
- RNA_def_property_update(prop, NC_SCENE, NULL);
// not used // deprecated !!!!!!!!!!!!!
prop= RNA_def_property(srna, "activity_culling", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", (1 << 3)); //XXX mode hardcoded
RNA_def_property_ui_text(prop, "Activity Culling", "Activity culling is enabled");
- RNA_def_property_update(prop, NC_SCENE, NULL);
// not used // deprecated !!!!!!!!!!!!!
prop= RNA_def_property(srna, "activity_culling_box_radius", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "activityBoxRadius");
RNA_def_property_range(prop, 0.0, 1000.0);
RNA_def_property_ui_text(prop, "box radius", "Radius of the activity bubble, in Manhattan length. Objects outside the box are activity-culled");
- RNA_def_property_update(prop, NC_SCENE, NULL);
/* booleans */
- prop= RNA_def_property(srna, "all_frames", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", GAME_ENABLE_ALL_FRAMES);
- RNA_def_property_ui_text(prop, "All Frames", "Render as many frames as possible, rather than respecting framerate");
- RNA_def_property_update(prop, NC_SCENE, NULL);
-
prop= RNA_def_property(srna, "show_debug_properties", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GAME_SHOW_DEBUG_PROPS);
RNA_def_property_ui_text(prop, "Show Debug Properties", "Show properties marked for debugging while the game runs");
- RNA_def_property_update(prop, NC_SCENE, NULL);
prop= RNA_def_property(srna, "show_framerate_profile", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GAME_SHOW_FRAMERATE);
RNA_def_property_ui_text(prop, "Show Framerate and Profile", "Show framerate and profiling information while the game runs");
- RNA_def_property_update(prop, NC_SCENE, NULL);
prop= RNA_def_property(srna, "show_physics_visualization", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GAME_SHOW_PHYSICS);
RNA_def_property_ui_text(prop, "Show Physics Visualization", "Show a visualization of physics bounds and interactions");
- RNA_def_property_update(prop, NC_SCENE, NULL);
- prop= RNA_def_property(srna, "display_lists", PROP_BOOLEAN, PROP_NONE);
+ prop= RNA_def_property(srna, "use_frame_rate", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GAME_ENABLE_ALL_FRAMES);
+ RNA_def_property_ui_text(prop, "Use Frame Rate", "Respect the frame rate rather then rendering as many frames as possible");
+
+ prop= RNA_def_property(srna, "use_display_lists", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GAME_DISPLAY_LISTS);
RNA_def_property_ui_text(prop, "Display Lists", "Use display lists to speed up rendering by keeping geometry on the GPU");
- RNA_def_property_update(prop, NC_SCENE, NULL);
- prop= RNA_def_property(srna, "deprecation_warnings", PROP_BOOLEAN, PROP_NONE);
+ prop= RNA_def_property(srna, "use_deprecation_warnings", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GAME_IGNORE_DEPRECATION_WARNINGS);
RNA_def_property_ui_text(prop, "Deprecation Warnings", "Print warnings when using deprecated features in the python API");
- RNA_def_property_update(prop, NC_SCENE, NULL);
+
+ prop= RNA_def_property(srna, "use_animation_record", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GAME_ENABLE_ANIMATION_RECORD);
+ RNA_def_property_ui_text(prop, "Record Animation", "Record animation to fcurves");
/* materials */
prop= RNA_def_property(srna, "material_mode", PROP_ENUM, PROP_NONE);
@@ -1894,10 +1889,10 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
{0, "BLENDER_RENDER", 0, "Blender Render", ""},
{0, NULL, 0, NULL, NULL}};
- srna= RNA_def_struct(brna, "SceneRenderData", NULL);
+ srna= RNA_def_struct(brna, "RenderSettings", NULL);
RNA_def_struct_sdna(srna, "RenderData");
RNA_def_struct_nested(brna, srna, "Scene");
- RNA_def_struct_path_func(srna, "rna_SceneRenderData_path");
+ RNA_def_struct_path_func(srna, "rna_RenderSettings_path");
RNA_def_struct_ui_text(srna, "Render Data", "Rendering settings for a Scene datablock");
prop= RNA_def_property(srna, "color_mode", PROP_ENUM, PROP_NONE);
@@ -2019,14 +2014,14 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop= RNA_def_property(srna, "jpeg2k_preset", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "jp2_preset");
RNA_def_property_enum_items(prop, jp2_preset_items);
- RNA_def_property_enum_funcs(prop, NULL, "rna_SceneRenderData_jpeg2k_preset_set", NULL);
+ RNA_def_property_enum_funcs(prop, NULL, "rna_RenderSettings_jpeg2k_preset_set", NULL);
RNA_def_property_ui_text(prop, "Preset", "Use a DCI Standard preset for saving jpeg2000");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
prop= RNA_def_property(srna, "jpeg2k_depth", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "jp2_depth");
RNA_def_property_enum_items(prop, jp2_depth_items);
- RNA_def_property_enum_funcs(prop, NULL, "rna_SceneRenderData_jpeg2k_depth_set", NULL);
+ RNA_def_property_enum_funcs(prop, NULL, "rna_RenderSettings_jpeg2k_depth_set", NULL);
RNA_def_property_ui_text(prop, "Depth", "Bit depth per channel");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
@@ -2042,9 +2037,9 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop= RNA_def_property(srna, "quicktime_codec_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "qtcodecsettings.codecType");
RNA_def_property_enum_items(prop, quicktime_codec_type_items);
- RNA_def_property_enum_funcs(prop, "rna_SceneRenderData_qtcodecsettings_codecType_get",
- "rna_SceneRenderData_qtcodecsettings_codecType_set",
- "rna_SceneRenderData_qtcodecsettings_codecType_itemf");
+ RNA_def_property_enum_funcs(prop, "rna_RenderSettings_qtcodecsettings_codecType_get",
+ "rna_RenderSettings_qtcodecsettings_codecType_set",
+ "rna_RenderSettings_qtcodecsettings_codecType_itemf");
RNA_def_property_ui_text(prop, "Codec", "QuickTime codec type");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
@@ -2286,7 +2281,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop= RNA_def_property(srna, "threads", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "threads");
RNA_def_property_range(prop, 1, BLENDER_MAX_THREADS);
- RNA_def_property_int_funcs(prop, "rna_SceneRenderData_threads_get", NULL, NULL);
+ RNA_def_property_int_funcs(prop, "rna_RenderSettings_threads_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Threads", "Number of CPU threads to use simultaneously while rendering (for multi-core/CPU systems)");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
@@ -2364,7 +2359,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop= RNA_def_property(srna, "color_management", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "color_mgt_flag", R_COLOR_MANAGEMENT);
RNA_def_property_ui_text(prop, "Color Management", "Use color profiles and gamma corrected imaging pipeline");
- RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS|NC_MATERIAL|ND_SHADING, "rna_SceneRenderData_color_management_update");
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS|NC_MATERIAL|ND_SHADING, "rna_RenderSettings_color_management_update");
prop= RNA_def_property(srna, "use_file_extension", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_EXTENSION);
@@ -2374,7 +2369,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop= RNA_def_property(srna, "file_format", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "imtype");
RNA_def_property_enum_items(prop, image_type_items);
- RNA_def_property_enum_funcs(prop, NULL, "rna_SceneRenderData_file_format_set", NULL);
+ RNA_def_property_enum_funcs(prop, NULL, "rna_RenderSettings_file_format_set", NULL);
RNA_def_property_ui_text(prop, "File Format", "File format to save the rendered images as");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
@@ -2396,13 +2391,13 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop= RNA_def_property(srna, "save_buffers", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_EXR_TILE_FILE);
- RNA_def_property_boolean_funcs(prop, "rna_SceneRenderData_save_buffers_get", NULL);
+ RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_save_buffers_get", NULL);
RNA_def_property_ui_text(prop, "Save Buffers","Save tiles for all RenderLayers and SceneNodes to files in the temp directory (saves memory, required for Full Sample)");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
prop= RNA_def_property(srna, "full_sample", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_FULL_SAMPLE);
- RNA_def_property_boolean_funcs(prop, "rna_SceneRenderData_full_sample_get", NULL);
+ RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_full_sample_get", NULL);
RNA_def_property_ui_text(prop, "Full Sample","Save for every anti-aliasing sample the entire RenderLayer results. This solves anti-aliasing issues with compositing");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
@@ -2570,24 +2565,24 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop= RNA_def_property(srna, "active_layer_index", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "actlay");
- RNA_def_property_int_funcs(prop, "rna_SceneRenderData_active_layer_index_get", "rna_SceneRenderData_active_layer_index_set", "rna_SceneRenderData_active_layer_index_range");
+ RNA_def_property_int_funcs(prop, "rna_RenderSettings_active_layer_index_get", "rna_RenderSettings_active_layer_index_set", "rna_RenderSettings_active_layer_index_range");
RNA_def_property_ui_text(prop, "Active Layer Index", "Active index in render layer array");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
/* engine */
prop= RNA_def_property(srna, "engine", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, engine_items);
- RNA_def_property_enum_funcs(prop, "rna_SceneRenderData_engine_get", "rna_SceneRenderData_engine_set", "rna_SceneRenderData_engine_itemf");
+ RNA_def_property_enum_funcs(prop, "rna_RenderSettings_engine_get", "rna_RenderSettings_engine_set", "rna_RenderSettings_engine_itemf");
RNA_def_property_ui_text(prop, "Engine", "Engine to use for rendering");
RNA_def_property_update(prop, NC_WINDOW, NULL);
prop= RNA_def_property(srna, "multiple_engines", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_funcs(prop, "rna_SceneRenderData_multiple_engines_get", NULL);
+ RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_multiple_engines_get", NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Multiple Engines", "More than one rendering engine is available");
prop= RNA_def_property(srna, "use_game_engine", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_funcs(prop, "rna_SceneRenderData_use_game_engine_get", NULL);
+ RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_use_game_engine_get", NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Use Game Engine", "Current rendering engine is a game engine");
@@ -2779,7 +2774,7 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_int_funcs(prop, NULL, "rna_Scene_start_frame_set", NULL);
RNA_def_property_range(prop, MINFRAME, MAXFRAME);
RNA_def_property_ui_text(prop, "Start Frame", "First frame of the playback/rendering range");
- RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+ RNA_def_property_update(prop, NC_SCENE|ND_FRAME, NULL);
prop= RNA_def_property(srna, "end_frame", PROP_INT, PROP_TIME);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -2787,15 +2782,15 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_int_funcs(prop, NULL, "rna_Scene_end_frame_set", NULL);
RNA_def_property_range(prop, MINFRAME, MAXFRAME);
RNA_def_property_ui_text(prop, "End Frame", "Final frame of the playback/rendering range");
- RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+ RNA_def_property_update(prop, NC_SCENE|ND_FRAME, NULL);
prop= RNA_def_property(srna, "frame_step", PROP_INT, PROP_TIME);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_int_sdna(prop, NULL, "r.frame_step");
RNA_def_property_range(prop, 0, MAXFRAME);
- RNA_def_property_ui_range(prop, 0, 100, 1, 0);
+ RNA_def_property_ui_range(prop, 1, 100, 1, 0);
RNA_def_property_ui_text(prop, "Frame Step", "Number of frames to skip forward while rendering/playing back each frame");
- RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+ RNA_def_property_update(prop, NC_SCENE|ND_FRAME, NULL);
/* Preview Range (frame-range for UI playback) */
prop=RNA_def_property(srna, "use_preview_range", PROP_BOOLEAN, PROP_NONE);
@@ -2803,21 +2798,21 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "r.flag", SCER_PRV_RANGE);
RNA_def_property_boolean_funcs(prop, NULL, "rna_Scene_use_preview_range_set");
RNA_def_property_ui_text(prop, "Use Preview Range", "");
- RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+ RNA_def_property_update(prop, NC_SCENE|ND_FRAME, NULL);
prop= RNA_def_property(srna, "preview_range_start_frame", PROP_INT, PROP_TIME);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_int_sdna(prop, NULL, "r.psfra");
RNA_def_property_int_funcs(prop, NULL, "rna_Scene_preview_range_start_frame_set", NULL);
RNA_def_property_ui_text(prop, "Preview Range Start Frame", "");
- RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+ RNA_def_property_update(prop, NC_SCENE|ND_FRAME, NULL);
prop= RNA_def_property(srna, "preview_range_end_frame", PROP_INT, PROP_TIME);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_int_sdna(prop, NULL, "r.pefra");
RNA_def_property_int_funcs(prop, NULL, "rna_Scene_preview_range_end_frame_set", NULL);
RNA_def_property_ui_text(prop, "Preview Range End Frame", "");
- RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+ RNA_def_property_update(prop, NC_SCENE|ND_FRAME, NULL);
/* Stamp */
prop= RNA_def_property(srna, "stamp_note", PROP_STRING, PROP_NONE);
@@ -2913,10 +2908,10 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Physics_update");
/* Render Data */
- prop= RNA_def_property(srna, "render_data", PROP_POINTER, PROP_NONE);
+ prop= RNA_def_property(srna, "render", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "r");
- RNA_def_property_struct_type(prop, "SceneRenderData");
+ RNA_def_property_struct_type(prop, "RenderSettings");
RNA_def_property_ui_text(prop, "Render Data", "");
/* Markers */
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index ee2c96bcbd2..6f6ee5216ae 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -47,6 +47,7 @@
#include "BKE_depsgraph.h"
#include "DNA_object_types.h"
#include "GPU_draw.h"
+#include "BKE_global.h"
#include "MEM_guardedalloc.h"
@@ -55,6 +56,13 @@ static void rna_userdef_update(Main *bmain, Scene *scene, PointerRNA *ptr)
WM_main_add_notifier(NC_WINDOW, NULL);
}
+static void rna_userdef_script_autoexec_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ UserDef *userdef = (UserDef*)ptr->data;
+ if (userdef->flag & USER_SCRIPT_AUTOEXEC_DISABLE) G.f &= ~G_SCRIPT_AUTOEXEC;
+ else G.f |= G_SCRIPT_AUTOEXEC;
+}
+
static void rna_userdef_mipmap_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
GPU_set_mipmap(!(U.gameflags & USER_DISABLE_MIPMAP));
@@ -211,16 +219,16 @@ static void rna_userdef_autosave_update(Main *bmain, Scene *scene, PointerRNA *p
rna_userdef_update(bmain, scene, ptr);
}
-static bExtension *rna_userdef_extension_new(void)
+static bAddon *rna_userdef_addon_new(void)
{
- bExtension *bext= MEM_callocN(sizeof(bExtension), "bext");
- BLI_addtail(&U.extensions, bext);
+ bAddon *bext= MEM_callocN(sizeof(bAddon), "bAddon");
+ BLI_addtail(&U.addons, bext);
return bext;
}
-static void rna_userdef_extension_remove(bExtension *bext)
+static void rna_userdef_addon_remove(bAddon *bext)
{
- BLI_freelinkN(&U.extensions, bext);
+ BLI_freelinkN(&U.addons, bext);
}
@@ -1687,14 +1695,14 @@ static void rna_def_userdef_themes(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Bone Color Sets", "");
}
-static void rna_def_userdef_extensions(BlenderRNA *brna)
+static void rna_def_userdef_addon(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
- srna= RNA_def_struct(brna, "Extension", NULL);
- RNA_def_struct_sdna(srna, "bExtension");
- RNA_def_struct_ui_text(srna, "Extension", "Python extensions to be loaded automatically");
+ srna= RNA_def_struct(brna, "Addon", NULL);
+ RNA_def_struct_sdna(srna, "bAddon");
+ RNA_def_struct_ui_text(srna, "Addon", "Python addons to be loaded automatically");
prop= RNA_def_property(srna, "module", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Module", "Module name");
@@ -1727,7 +1735,6 @@ static void rna_def_userdef_dothemes(BlenderRNA *brna)
rna_def_userdef_theme_space_logic(brna);
rna_def_userdef_theme_colorset(brna);
rna_def_userdef_themes(brna);
- rna_def_userdef_extensions(brna);
}
static void rna_def_userdef_solidlight(BlenderRNA *brna)
@@ -2346,9 +2353,10 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_ALLWINCODECS);
RNA_def_property_ui_text(prop, "Enable All Codecs", "Enables automatic saving of preview images in the .blend file (Windows only)");
- prop= RNA_def_property(srna, "auto_run_python_scripts", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_DONT_DOSCRIPTLINKS);
+ prop= RNA_def_property(srna, "auto_execute_scripts", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", USER_SCRIPT_AUTOEXEC_DISABLE);
RNA_def_property_ui_text(prop, "Auto Run Python Scripts", "Allow any .blend file to run scripts automatically (unsafe with blend files from an untrusted source)");
+ RNA_def_property_update(prop, 0, "rna_userdef_script_autoexec_update");
prop= RNA_def_property(srna, "prefetch_frames", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "prefetchframes");
@@ -2649,27 +2657,27 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Save Preview Images", "Enables automatic saving of preview images in the .blend file");
}
-void rna_def_userdef_extension_collection(BlenderRNA *brna, PropertyRNA *cprop)
+void rna_def_userdef_addon_collection(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
FunctionRNA *func;
PropertyRNA *parm;
- RNA_def_property_srna(cprop, "UserExtensions");
- srna= RNA_def_struct(brna, "UserExtensions", NULL);
- RNA_def_struct_ui_text(srna, "User Extensions", "Collection of extensions");
+ RNA_def_property_srna(cprop, "Addons");
+ srna= RNA_def_struct(brna, "Addons", NULL);
+ RNA_def_struct_ui_text(srna, "User Add-Ons", "Collection of add-ons");
- func= RNA_def_function(srna, "new", "rna_userdef_extension_new");
+ func= RNA_def_function(srna, "new", "rna_userdef_addon_new");
RNA_def_function_flag(func, FUNC_NO_SELF);
- RNA_def_function_ui_description(func, "Add a new camera to the main database");
+ RNA_def_function_ui_description(func, "Add a new addon");
/* return type */
- parm= RNA_def_pointer(func, "extension", "Extension", "", "Extension datablock.");
+ parm= RNA_def_pointer(func, "addon", "Addon", "", "Addon datablock.");
RNA_def_function_return(func, parm);
- func= RNA_def_function(srna, "remove", "rna_userdef_extension_remove");
+ func= RNA_def_function(srna, "remove", "rna_userdef_addon_remove");
RNA_def_function_flag(func, FUNC_NO_SELF);
- RNA_def_function_ui_description(func, "Remove a camera from the current blendfile.");
- parm= RNA_def_pointer(func, "extension", "Extension", "", "Extension to remove.");
+ RNA_def_function_ui_description(func, "Remove addon.");
+ parm= RNA_def_pointer(func, "addon", "Addon", "", "Addon to remove.");
RNA_def_property_flag(parm, PROP_REQUIRED);
}
@@ -2682,7 +2690,7 @@ void RNA_def_userdef(BlenderRNA *brna)
{USER_SECTION_INTERFACE, "INTERFACE", 0, "Interface", ""},
{USER_SECTION_EDIT, "EDITING", 0, "Editing", ""},
{USER_SECTION_INPUT, "INPUT", 0, "Input", ""},
- {USER_SECTION_EXTENSIONS, "EXTENSIONS", 0, "Extensions", ""},
+ {USER_SECTION_ADDONS, "ADDONS", 0, "Add-Ons", ""},
{USER_SECTION_THEME, "THEMES", 0, "Themes", ""},
{USER_SECTION_FILE, "FILES", 0, "File", ""},
{USER_SECTION_SYSTEM, "SYSTEM", 0, "System", ""},
@@ -2711,11 +2719,11 @@ void RNA_def_userdef(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "ThemeStyle");
RNA_def_property_ui_text(prop, "Styles", "");
- prop= RNA_def_property(srna, "extensions", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_collection_sdna(prop, NULL, "extensions", NULL);
- RNA_def_property_struct_type(prop, "Extension");
- RNA_def_property_ui_text(prop, "Extension", "");
- rna_def_userdef_extension_collection(brna, prop);
+ prop= RNA_def_property(srna, "addons", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "addons", NULL);
+ RNA_def_property_struct_type(prop, "Addon");
+ RNA_def_property_ui_text(prop, "Addon", "");
+ rna_def_userdef_addon_collection(brna, prop);
/* nested structs */
@@ -2754,6 +2762,7 @@ void RNA_def_userdef(BlenderRNA *brna)
rna_def_userdef_input(brna);
rna_def_userdef_filepaths(brna);
rna_def_userdef_system(brna);
+ rna_def_userdef_addon(brna);
}
diff --git a/source/blender/python/generic/BGL.c b/source/blender/python/generic/BGL.c
index 2318549f2ec..340ebbe3dcd 100644
--- a/source/blender/python/generic/BGL.c
+++ b/source/blender/python/generic/BGL.c
@@ -36,9 +36,6 @@
#include <GL/glew.h>
#include "MEM_guardedalloc.h"
-static int type_size( int type );
-static Buffer *make_buffer( int type, int ndimensions, int *dimensions );
-
static char Method_Buffer_doc[] =
"(type, dimensions, [template]) - Create a new Buffer object\n\n\
(type) - The format to store data in\n\
@@ -82,7 +79,7 @@ static PyObject *Buffer_dimensions( PyObject * self );
static PyObject *Buffer_getattr( PyObject * self, char *name );
static PyObject *Buffer_repr( PyObject * self );
-PyTypeObject buffer_Type = {
+PyTypeObject BGL_bufferType = {
PyVarObject_HEAD_INIT(NULL, 0)
"buffer", /*tp_name */
sizeof( Buffer ), /*tp_basicsize */
@@ -120,7 +117,7 @@ static PyObject *Method_##funcname (PyObject *self, PyObject *args) {\
/* #endif */
/********/
-static int type_size(int type)
+int BGL_typeSize(int type)
{
switch (type) {
case GL_BYTE:
@@ -137,7 +134,7 @@ static int type_size(int type)
return -1;
}
-static Buffer *make_buffer(int type, int ndimensions, int *dimensions)
+Buffer *BGL_MakeBuffer(int type, int ndimensions, int *dimensions, void *initbuffer)
{
Buffer *buffer;
void *buf= NULL;
@@ -147,39 +144,49 @@ static Buffer *make_buffer(int type, int ndimensions, int *dimensions)
for (i=0; i<ndimensions; i++)
length*= dimensions[i];
- size= type_size(type);
+ size= BGL_typeSize(type);
buf= MEM_mallocN(length*size, "Buffer buffer");
-
- buffer= (Buffer *) PyObject_NEW(Buffer, &buffer_Type);
+
+ buffer= (Buffer *) PyObject_NEW(Buffer, &BGL_bufferType);
buffer->parent= NULL;
buffer->ndimensions= ndimensions;
- buffer->dimensions= dimensions;
+ buffer->dimensions= MEM_mallocN(ndimensions*sizeof(int), "Buffer dimensions");
+ memcpy(buffer->dimensions, dimensions, ndimensions*sizeof(int));
buffer->type= type;
buffer->buf.asvoid= buf;
- for (i= 0; i<length; i++) {
- if (type==GL_BYTE)
- buffer->buf.asbyte[i]= 0;
- else if (type==GL_SHORT)
- buffer->buf.asshort[i]= 0;
- else if (type==GL_INT)
- buffer->buf.asint[i]= 0;
- else if (type==GL_FLOAT)
- buffer->buf.asfloat[i]= 0.0f;
- else if (type==GL_DOUBLE)
- buffer->buf.asdouble[i]= 0.0;
+ if (initbuffer) {
+ memcpy(buffer->buf.asvoid, initbuffer, length*size);
+ } else {
+ memset(buffer->buf.asvoid, 0, length*size);
+ /*
+ for (i= 0; i<length; i++) {
+ if (type==GL_BYTE)
+ buffer->buf.asbyte[i]= 0;
+ else if (type==GL_SHORT)
+ buffer->buf.asshort[i]= 0;
+ else if (type==GL_INT)
+ buffer->buf.asint[i]= 0;
+ else if (type==GL_FLOAT)
+ buffer->buf.asfloat[i]= 0.0f;
+ else if (type==GL_DOUBLE)
+ buffer->buf.asdouble[i]= 0.0;
+ }
+ */
}
return buffer;
}
+#define MAX_DIMENSIONS 256
static PyObject *Method_Buffer (PyObject *self, PyObject *args)
{
PyObject *length_ob= NULL, *template= NULL;
Buffer *buffer;
+ int dimensions[MAX_DIMENSIONS];
int i, type;
- int *dimensions = 0, ndimensions = 0;
+ int ndimensions = 0;
if (!PyArg_ParseTuple(args, "iO|O", &type, &length_ob, &template)) {
PyErr_SetString(PyExc_AttributeError, "expected an int and one or two PyObjects");
@@ -192,11 +199,13 @@ static PyObject *Method_Buffer (PyObject *self, PyObject *args)
if (PyNumber_Check(length_ob)) {
ndimensions= 1;
- dimensions= MEM_mallocN(ndimensions*sizeof(int), "Buffer dimensions");
dimensions[0]= PyLong_AsLong(length_ob);
} else if (PySequence_Check(length_ob)) {
ndimensions= PySequence_Length(length_ob);
- dimensions= MEM_mallocN(ndimensions*sizeof(int), "Buffer dimensions");
+ if (ndimensions > MAX_DIMENSIONS) {
+ PyErr_SetString(PyExc_AttributeError, "too many dimensions, max is 256");
+ return NULL;
+ }
for (i=0; i<ndimensions; i++) {
PyObject *ob= PySequence_GetItem(length_ob, i);
@@ -206,7 +215,7 @@ static PyObject *Method_Buffer (PyObject *self, PyObject *args)
}
}
- buffer= make_buffer(type, ndimensions, dimensions);
+ buffer= BGL_MakeBuffer(type, ndimensions, dimensions, NULL);
if (template && ndimensions) {
if (Buffer_ass_slice((PyObject *) buffer, 0, dimensions[0], template)) {
Py_DECREF(buffer);
@@ -250,9 +259,9 @@ static PyObject *Buffer_item(PyObject *self, int i)
for (j=1; j<buf->ndimensions; j++) {
length*= buf->dimensions[j];
}
- size= type_size(buf->type);
+ size= BGL_typeSize(buf->type);
- newbuf= (Buffer *) PyObject_NEW(Buffer, &buffer_Type);
+ newbuf= (Buffer *) PyObject_NEW(Buffer, &BGL_bufferType);
Py_INCREF(self);
newbuf->parent= self;
@@ -1104,7 +1113,7 @@ PyObject *BGL_Init(void)
PyDict_SetItemString(PySys_GetObject("modules"), BGL_module_def.m_name, mod);
dict= PyModule_GetDict(mod);
- if( PyType_Ready( &buffer_Type) < 0)
+ if( PyType_Ready( &BGL_bufferType) < 0)
return NULL; /* should never happen */
#define EXPP_ADDCONST(x) PyDict_SetItemString(dict, #x, item=PyLong_FromLong((int)x)); Py_DECREF(item)
diff --git a/source/blender/python/generic/BGL.h b/source/blender/python/generic/BGL.h
index 32076f4fba8..89bade930ce 100644
--- a/source/blender/python/generic/BGL.h
+++ b/source/blender/python/generic/BGL.h
@@ -44,9 +44,16 @@
PyObject *BGL_Init(void);
+/*@ Create a buffer object */
+/*@ dimensions is an array of ndimensions integers representing the size of each dimension */
+/*@ initbuffer if not NULL holds a contiguous buffer with the correct format from which the buffer will be initialized */
+struct _Buffer *BGL_MakeBuffer( int type, int ndimensions, int *dimensions, void *initbuffer );
+/*@ Return the size of buffer element, type must be one of GL_BYTE, GL_SHORT, GL_INT, GL_FLOAT or GL_DOUBLE */
+/*@ returns -1 otherwise */
+int BGL_typeSize( int type );
+
/*@ Buffer Object */
/*@ For Python access to OpenGL functions requiring a pointer. */
-
typedef struct _Buffer {
PyObject_VAR_HEAD
PyObject * parent;
@@ -66,6 +73,8 @@ typedef struct _Buffer {
} buf;
} Buffer;
+/*@ The type object */
+extern PyTypeObject BGL_bufferType;
/*@ By golly George! It looks like fancy pants macro time!!! */
@@ -93,7 +102,7 @@ typedef struct _Buffer {
#define buffer_str "O!"
#define buffer_var(number) (bgl_buffer##number)->buf.asvoid
-#define buffer_ref(number) &buffer_Type, &bgl_buffer##number
+#define buffer_ref(number) &BGL_bufferType, &bgl_buffer##number
#define buffer_def(number) Buffer *bgl_buffer##number
/* GL Pointer fields, handled by buffer type */
@@ -101,62 +110,62 @@ typedef struct _Buffer {
#define GLbooleanP_str "O!"
#define GLbooleanP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLbooleanP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLbooleanP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLbooleanP_def(number) Buffer *bgl_buffer##number
#define GLbyteP_str "O!"
#define GLbyteP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLbyteP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLbyteP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLbyteP_def(number) Buffer *bgl_buffer##number
#define GLubyteP_str "O!"
#define GLubyteP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLubyteP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLubyteP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLubyteP_def(number) Buffer *bgl_buffer##number
#define GLintP_str "O!"
#define GLintP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLintP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLintP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLintP_def(number) Buffer *bgl_buffer##number
#define GLuintP_str "O!"
#define GLuintP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLuintP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLuintP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLuintP_def(number) Buffer *bgl_buffer##number
#define GLshortP_str "O!"
#define GLshortP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLshortP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLshortP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLshortP_def(number) Buffer *bgl_buffer##number
#define GLushortP_str "O!"
#define GLushortP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLushortP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLushortP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLushortP_def(number) Buffer *bgl_buffer##number
#define GLfloatP_str "O!"
#define GLfloatP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLfloatP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLfloatP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLfloatP_def(number) Buffer *bgl_buffer##number
#define GLdoubleP_str "O!"
#define GLdoubleP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLdoubleP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLdoubleP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLdoubleP_def(number) Buffer *bgl_buffer##number
#define GLclampfP_str "O!"
#define GLclampfP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLclampfP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLclampfP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLclampfP_def(number) Buffer *bgl_buffer##number
#define GLvoidP_str "O!"
#define GLvoidP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLvoidP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLvoidP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLvoidP_def(number) Buffer *bgl_buffer##number
#define buffer_str "O!"
#define buffer_var(number) (bgl_buffer##number)->buf.asvoid
-#define buffer_ref(number) &buffer_Type, &bgl_buffer##number
+#define buffer_ref(number) &BGL_bufferType, &bgl_buffer##number
#define buffer_def(number) Buffer *bgl_buffer##number
/*@The standard GL typedefs are used as prototypes, we can't
diff --git a/source/blender/python/generic/matrix.c b/source/blender/python/generic/matrix.c
index a20ed3e4f59..0b0b1470823 100644
--- a/source/blender/python/generic/matrix.c
+++ b/source/blender/python/generic/matrix.c
@@ -194,7 +194,7 @@ static float matrix_determinant(MatrixObject * self)
self->matrix[2][0], self->matrix[2][1],
self->matrix[2][2]);
} else {
- return determinant_m4((float (*)[4]) *self->matrix);
+ return determinant_m4((float (*)[4])self->contigPtr);
}
}
@@ -221,9 +221,9 @@ static PyObject *Matrix_toQuat(MatrixObject * self)
return NULL;
}
if(self->colSize == 3){
- mat3_to_quat( quat,(float (*)[3])*self->matrix);
+ mat3_to_quat( quat,(float (*)[3])self->contigPtr);
}else{
- mat4_to_quat( quat,(float (*)[4])*self->matrix);
+ mat4_to_quat( quat,(float (*)[4])self->contigPtr);
}
return newQuaternionObject(quat, Py_NEW, NULL);
@@ -267,9 +267,9 @@ PyObject *Matrix_toEuler(MatrixObject * self, PyObject *args)
/*must be 3-4 cols, 3-4 rows, square matrix*/
if(self->colSize ==3 && self->rowSize ==3) {
- mat= (float (*)[3]) *self->matrix;
+ mat= (float (*)[3])self->contigPtr;
}else if (self->colSize ==4 && self->rowSize ==4) {
- copy_m3_m4(tmat, (float (*)[4]) *self->matrix);
+ copy_m3_m4(tmat, (float (*)[4])self->contigPtr);
mat= tmat;
}else {
PyErr_SetString(PyExc_AttributeError, "Matrix.to_euler(): inappropriate matrix size - expects 3x3 or 4x4 matrix\n");
@@ -301,7 +301,7 @@ static char Matrix_Resize4x4_doc[] =
" Resize the matrix to 4x4.\n"
"\n"
" :return: an instance of itself.\n"
-" :rtype: :class:`Vector`\n";
+" :rtype: :class:`Matrix`\n";
PyObject *Matrix_Resize4x4(MatrixObject * self)
{
@@ -359,6 +359,59 @@ PyObject *Matrix_Resize4x4(MatrixObject * self)
Py_INCREF(self);
return (PyObject *)self;
}
+
+static char Matrix_to_4x4_doc[] =
+".. method:: to_4x4()\n"
+"\n"
+" Return a 4x4 copy of this matrix.\n"
+"\n"
+" :return: a new matrix.\n"
+" :rtype: :class:`Matrix`\n";
+PyObject *Matrix_to_4x4(MatrixObject * self)
+{
+ if(!BaseMath_ReadCallback(self))
+ return NULL;
+
+ if(self->colSize==4 && self->rowSize==4) {
+ return (PyObject *)newMatrixObject(self->contigPtr, 4, 4, Py_NEW, Py_TYPE(self));
+ }
+ else if(self->colSize==3 && self->rowSize==3) {
+ float mat[4][4];
+ copy_m4_m3(mat, (float (*)[3])self->contigPtr);
+ return (PyObject *)newMatrixObject((float *)mat, 4, 4, Py_NEW, Py_TYPE(self));
+ }
+ /* TODO, 2x2 matrix */
+
+ PyErr_SetString(PyExc_TypeError, "Matrix.to_4x4(): inappropriate matrix size");
+ return NULL;
+}
+
+static char Matrix_to_3x3_doc[] =
+".. method:: to_3x3()\n"
+"\n"
+" Return a 3x3 copy of this matrix.\n"
+"\n"
+" :return: a new matrix.\n"
+" :rtype: :class:`Matrix`\n";
+PyObject *Matrix_to_3x3(MatrixObject * self)
+{
+ if(!BaseMath_ReadCallback(self))
+ return NULL;
+
+ if(self->colSize==3 && self->rowSize==3) {
+ return (PyObject *)newMatrixObject(self->contigPtr, 3, 3, Py_NEW, Py_TYPE(self));
+ }
+ else if(self->colSize==4 && self->rowSize==4) {
+ float mat[3][3];
+ copy_m3_m4(mat, (float (*)[4])self->contigPtr);
+ return (PyObject *)newMatrixObject((float *)mat, 3, 3, Py_NEW, Py_TYPE(self));
+ }
+ /* TODO, 2x2 matrix */
+
+ PyErr_SetString(PyExc_TypeError, "Matrix.to_3x3(): inappropriate matrix size");
+ return NULL;
+}
+
/*---------------------------Matrix.translationPart() ------------*/
static char Matrix_TranslationPart_doc[] =
".. method:: translation_part()\n"
@@ -439,9 +492,9 @@ PyObject *Matrix_scalePart(MatrixObject * self)
/*must be 3-4 cols, 3-4 rows, square matrix*/
if(self->colSize == 4 && self->rowSize == 4)
- copy_m3_m4(mat, (float (*)[4])*self->matrix);
+ copy_m3_m4(mat, (float (*)[4])self->contigPtr);
else if(self->colSize == 3 && self->rowSize == 3)
- copy_m3_m3(mat, (float (*)[3])*self->matrix);
+ copy_m3_m3(mat, (float (*)[3])self->contigPtr);
else {
PyErr_SetString(PyExc_AttributeError, "Matrix.scale_part(): inappropriate matrix size - expects 3x3 or 4x4 matrix\n");
return NULL;
@@ -497,9 +550,9 @@ PyObject *Matrix_Invert(MatrixObject * self)
mat[2] = -self->matrix[1][0];
mat[3] = self->matrix[0][0];
} else if(self->rowSize == 3) {
- adjoint_m3_m3((float (*)[3]) mat,(float (*)[3]) *self->matrix);
+ adjoint_m3_m3((float (*)[3]) mat,(float (*)[3])self->contigPtr);
} else if(self->rowSize == 4) {
- adjoint_m4_m4((float (*)[4]) mat, (float (*)[4]) *self->matrix);
+ adjoint_m4_m4((float (*)[4]) mat, (float (*)[4])self->contigPtr);
}
/*divide by determinate*/
for(x = 0; x < (self->rowSize * self->colSize); x++) {
@@ -576,9 +629,9 @@ PyObject *Matrix_Transpose(MatrixObject * self)
self->matrix[1][0] = self->matrix[0][1];
self->matrix[0][1] = t;
} else if(self->rowSize == 3) {
- transpose_m3((float (*)[3])*self->matrix);
+ transpose_m3((float (*)[3])self->contigPtr);
} else {
- transpose_m4((float (*)[4])*self->matrix);
+ transpose_m4((float (*)[4])self->contigPtr);
}
BaseMath_WriteCallback(self);
@@ -641,9 +694,9 @@ PyObject *Matrix_Identity(MatrixObject * self)
self->matrix[1][0] = 0.0f;
self->matrix[1][1] = 1.0f;
} else if(self->rowSize == 3) {
- unit_m3((float (*)[3]) *self->matrix);
+ unit_m3((float (*)[3])self->contigPtr);
} else {
- unit_m4((float (*)[4]) *self->matrix);
+ unit_m4((float (*)[4])self->contigPtr);
}
if(!BaseMath_WriteCallback(self))
@@ -667,7 +720,7 @@ PyObject *Matrix_copy(MatrixObject * self)
if(!BaseMath_ReadCallback(self))
return NULL;
- return (PyObject*)newMatrixObject((float (*))*self->matrix, self->rowSize, self->colSize, Py_NEW, Py_TYPE(self));
+ return (PyObject*)newMatrixObject((float (*))self->contigPtr, self->rowSize, self->colSize, Py_NEW, Py_TYPE(self));
}
/*----------------------------print object (internal)-------------*/
@@ -1219,9 +1272,9 @@ static PyObject *Matrix_getMedianScale( MatrixObject * self, void *type )
/*must be 3-4 cols, 3-4 rows, square matrix*/
if(self->colSize == 4 && self->rowSize == 4)
- copy_m3_m4(mat, (float (*)[4])*self->matrix);
+ copy_m3_m4(mat, (float (*)[4])self->contigPtr);
else if(self->colSize == 3 && self->rowSize == 3)
- copy_m3_m3(mat, (float (*)[3])*self->matrix);
+ copy_m3_m3(mat, (float (*)[3])self->contigPtr);
else {
PyErr_SetString(PyExc_AttributeError, "Matrix.median_scale: inappropriate matrix size - expects 3x3 or 4x4 matrix\n");
return NULL;
@@ -1237,9 +1290,9 @@ static PyObject *Matrix_getIsNegative( MatrixObject * self, void *type )
/*must be 3-4 cols, 3-4 rows, square matrix*/
if(self->colSize == 4 && self->rowSize == 4)
- return PyBool_FromLong(is_negative_m4((float (*)[4])*self->matrix));
+ return PyBool_FromLong(is_negative_m4((float (*)[4])self->contigPtr));
else if(self->colSize == 3 && self->rowSize == 3)
- return PyBool_FromLong(is_negative_m3((float (*)[3])*self->matrix));
+ return PyBool_FromLong(is_negative_m3((float (*)[3])self->contigPtr));
else {
PyErr_SetString(PyExc_AttributeError, "Matrix.is_negative: inappropriate matrix size - expects 3x3 or 4x4 matrix\n");
return NULL;
@@ -1271,6 +1324,8 @@ static struct PyMethodDef Matrix_methods[] = {
{"rotation_part", (PyCFunction) Matrix_RotationPart, METH_NOARGS, Matrix_RotationPart_doc},
{"scale_part", (PyCFunction) Matrix_scalePart, METH_NOARGS, Matrix_scalePart_doc},
{"resize4x4", (PyCFunction) Matrix_Resize4x4, METH_NOARGS, Matrix_Resize4x4_doc},
+ {"to_4x4", (PyCFunction) Matrix_to_4x4, METH_NOARGS, Matrix_to_4x4_doc},
+ {"to_3x3", (PyCFunction) Matrix_to_3x3, METH_NOARGS, Matrix_to_3x3_doc},
{"to_euler", (PyCFunction) Matrix_toEuler, METH_VARARGS, Matrix_toEuler_doc},
{"to_quat", (PyCFunction) Matrix_toQuat, METH_NOARGS, Matrix_toQuat_doc},
{"copy", (PyCFunction) Matrix_copy, METH_NOARGS, Matrix_copy_doc},
diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c
index 356abeeb40f..f628e7e8569 100644
--- a/source/blender/python/intern/bpy_driver.c
+++ b/source/blender/python/intern/bpy_driver.c
@@ -30,6 +30,7 @@
#include "BPY_extern.h"
#include "BKE_fcurve.h"
+#include "BKE_global.h"
#include <Python.h>
@@ -86,7 +87,7 @@ static int bpy_pydriver_create_dict(void)
/* If there's a Blender text called pydrivers.py, import it.
* Users can add their own functions to this module.
*/
- if (G.f & G_DOSCRIPTLINKS) {
+ if (G.f & G_SCRIPT_AUTOEXEC) {
mod = importText("pydrivers"); /* can also use PyImport_Import() */
if (mod) {
PyDict_SetItemString(d, "pydrivers", mod);
@@ -158,14 +159,18 @@ float BPY_pydriver_eval (ChannelDriver *driver)
int i;
/* sanity checks - should driver be executed? */
- if ((driver == NULL) /*|| (G.f & G_DOSCRIPTLINKS)==0*/)
- return result;
+ /*if (G.f & G_SCRIPT_AUTOEXEC)==0) return result; */
/* get the py expression to be evaluated */
expr = driver->expression;
if ((expr == NULL) || (expr[0]=='\0'))
return result;
+ if(!(G.f & G_SCRIPT_AUTOEXEC)) {
+ printf("skipping driver '%s', automatic scripts are disabled\n", driver->expression);
+ return result;
+ }
+
gilstate = PyGILState_Ensure();
/* init global dictionary for py-driver evaluation settings */
@@ -207,6 +212,8 @@ float BPY_pydriver_eval (ChannelDriver *driver)
for (dvar= driver->variables.first, i=0; dvar; dvar= dvar->next) {
PyTuple_SET_ITEM(expr_vars, i++, PyUnicode_InternFromString(dvar->name));
}
+
+ driver->flag &= ~DRIVER_FLAG_RENAMEVAR;
}
else {
expr_vars= PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 1);
@@ -253,24 +260,20 @@ float BPY_pydriver_eval (ChannelDriver *driver)
/* process the result */
if (retval == NULL) {
- result = pydriver_error(driver);
- PyGILState_Release(gilstate);
- return result;
- }
+ pydriver_error(driver);
+ result = 0.0f;
+ } else if((result= (float)PyFloat_AsDouble(retval)) == -1.0f && PyErr_Occurred()) {
+ pydriver_error(driver);
+ Py_DECREF(retval);
+ result = 0.0f;
- result = (float)PyFloat_AsDouble(retval);
- Py_DECREF(retval);
-
- if ((result == -1) && PyErr_Occurred()) {
- result = pydriver_error(driver);
- PyGILState_Release(gilstate);
- return result;
}
-
- /* all fine, make sure the "invalid expression" flag is cleared */
- driver->flag &= ~DRIVER_FLAG_INVALID;
+ else {
+ /* all fine, make sure the "invalid expression" flag is cleared */
+ driver->flag &= ~DRIVER_FLAG_INVALID;
+ Py_DECREF(retval);
+ }
PyGILState_Release(gilstate);
-
return result;
}
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index 0b7c8759b5c..4160d56ba25 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -62,6 +62,7 @@
#include "BKE_text.h"
#include "BKE_context.h"
#include "BKE_main.h"
+#include "BKE_global.h" /* only for script checking */
#include "BPY_extern.h"
@@ -556,24 +557,26 @@ int BPY_button_eval(bContext *C, char *expr, double *value)
PyObject *dict, *mod, *retval;
int error_ret = 0;
- if (!value || !expr || expr[0]=='\0') return -1;
-
+ if (!value || !expr) return -1;
+
+ if(expr[0]=='\0') {
+ *value= 0.0;
+ return error_ret;
+ }
+
bpy_context_set(C, &gilstate);
dict= CreateGlobalDictionary(C, NULL);
-
- /* import some modules: builtins,math*/
- PyDict_SetItemString(dict, "__builtins__", PyEval_GetBuiltins());
mod = PyImport_ImportModule("math");
if (mod) {
PyDict_Merge(dict, PyModule_GetDict(mod), 0); /* 0 - dont overwrite existing values */
-
- /* Only keep for backwards compat! - just import all math into root, they are standard */
- PyDict_SetItemString(dict, "math", mod);
- PyDict_SetItemString(dict, "m", mod);
Py_DECREF(mod);
- }
+ }
+ else { /* highly unlikely but possibly */
+ PyErr_Print();
+ PyErr_Clear();
+ }
retval = PyRun_String(expr, Py_eval_input, dict, dict);
@@ -630,14 +633,19 @@ void BPY_load_user_modules(bContext *C)
for(text=CTX_data_main(C)->text.first; text; text= text->id.next) {
if(text->flags & TXT_ISSCRIPT && BLI_testextensie(text->id.name+2, ".py")) {
- PyObject *module= bpy_text_import(text);
-
- if (module==NULL) {
- PyErr_Print();
- PyErr_Clear();
+ if(!(G.f & G_SCRIPT_AUTOEXEC)) {
+ printf("scripts disabled for \"%s\", skipping '%s'\n", bmain->name, text->id.name+2);
}
else {
- Py_DECREF(module);
+ PyObject *module= bpy_text_import(text);
+
+ if (module==NULL) {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+ else {
+ Py_DECREF(module);
+ }
}
}
}
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 691010ade0d..2b31f06f51b 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -26,6 +26,7 @@
#include "bpy_rna.h"
#include "bpy_props.h"
#include "bpy_util.h"
+#include "bpy_rna_callback.h"
//#include "blendef.h"
#include "BLI_dynstr.h"
#include "BLI_listbase.h"
@@ -154,6 +155,19 @@ Mathutils_Callback mathutils_rna_matrix_cb = {
(BaseMathSetIndexFunc) NULL
};
+/* same as RNA_enum_value_from_id but raises an exception */
+int pyrna_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *value, const char *error_prefix)
+{
+ if(RNA_enum_value_from_id(item, identifier, value) == 0) {
+ char *enum_str= BPy_enum_as_string(item);
+ PyErr_Format(PyExc_TypeError, "%s: '%.200s' not found in (%s)", error_prefix, identifier, enum_str);
+ MEM_freeN(enum_str);
+ return -1;
+ }
+
+ return 0;
+}
+
#define PROP_ALL_VECTOR_SUBTYPES PROP_TRANSLATION: case PROP_DIRECTION: case PROP_VELOCITY: case PROP_ACCELERATION: case PROP_XYZ: case PROP_XYZ|PROP_UNIT_LENGTH
PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
@@ -474,16 +488,11 @@ int pyrna_set_to_enum_bitfield(EnumPropertyItem *items, PyObject *value, int *r_
char *param= _PyUnicode_AsString(key);
if(param==NULL) {
- PyErr_Format(PyExc_TypeError, "%s expected a string. found a %.200s", error_prefix, Py_TYPE(key)->tp_name);
+ PyErr_Format(PyExc_TypeError, "%.200s expected a string. found a %.200s", error_prefix, Py_TYPE(key)->tp_name);
return -1;
}
-
- if(RNA_enum_value_from_id(items, param, &ret) == 0) {
- char *enum_str= BPy_enum_as_string(items);
- PyErr_Format(PyExc_TypeError, "%s \"%.200s\" not found in (%.200s)", error_prefix, param, enum_str);
- MEM_freeN(enum_str);
+ if(pyrna_enum_value_from_id(items, param, &ret, error_prefix) < 0)
return -1;
- }
flag |= ret;
}
@@ -507,7 +516,7 @@ static int pyrna_prop_to_enum_bitfield(PointerRNA *ptr, PropertyRNA *prop, PyObj
}
else {
if(PySet_GET_SIZE(value)) {
- PyErr_Format(PyExc_TypeError, "%s: empty enum \"%.200s\" could not have any values assigned.", error_prefix, RNA_property_identifier(prop));
+ PyErr_Format(PyExc_TypeError, "%.200s: empty enum \"%.200s\" could not have any values assigned.", error_prefix, RNA_property_identifier(prop));
ret= -1;
}
else {
@@ -651,7 +660,7 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
ret = pyrna_prop_CreatePyObject(ptr, prop);
break;
default:
- PyErr_Format(PyExc_TypeError, "RNA Error: unknown type \"%d\" (pyrna_prop_to_py)", type);
+ PyErr_Format(PyExc_TypeError, "bpy_struct internal error: unknown type \"%d\" (pyrna_prop_to_py)", type);
ret = NULL;
break;
}
@@ -886,6 +895,9 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, ParameterList *parms, v
} else if((flag & PROP_NEVER_NULL) && value == Py_None) {
PyErr_Format(PyExc_TypeError, "%.200s does not support a 'None' assignment %.200s type", error_prefix, RNA_struct_identifier(ptype));
return -1;
+ } else if(value != Py_None && ((flag & PROP_ID_SELF_CHECK) && ptr->id.data == ((BPy_StructRNA*)value)->ptr.id.data)) {
+ PyErr_Format(PyExc_TypeError, "%.200s ID type does not support assignment to its self", error_prefix);
+ return -1;
} else {
BPy_StructRNA *param= (BPy_StructRNA*)value;
int raise_error= FALSE;
@@ -1084,7 +1096,7 @@ static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_s
if(RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum, &newptr))
return pyrna_struct_CreatePyObject(&newptr);
- PyErr_Format(PyExc_IndexError, "index %d out of range", keynum);
+ PyErr_Format(PyExc_IndexError, "bpy_prop_collection[index]: index %d out of range", keynum);
return NULL;
}
@@ -1097,7 +1109,7 @@ static PyObject *pyrna_prop_array_subscript_int(BPy_PropertyRNA *self, int keynu
if(keynum >= 0 && keynum < len)
return pyrna_prop_to_py_index(self, keynum);
- PyErr_Format(PyExc_IndexError, "index %d out of range", keynum);
+ PyErr_Format(PyExc_IndexError, "bpy_prop_array[index]: index %d out of range", keynum);
return NULL;
}
@@ -1107,7 +1119,7 @@ static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, char
if(RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
return pyrna_struct_CreatePyObject(&newptr);
- PyErr_Format(PyExc_KeyError, "key \"%.200s\" not found", keyname);
+ PyErr_Format(PyExc_KeyError, "bpy_prop_collection[key]: key \"%.200s\" not found", keyname);
return NULL;
}
/* static PyObject *pyrna_prop_array_subscript_str(BPy_PropertyRNA *self, char *keyname) */
@@ -1237,12 +1249,12 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject
return pyrna_prop_collection_subscript_slice(&self->ptr, self->prop, start, stop, len);
}
else {
- PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna");
+ PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported with rna");
return NULL;
}
}
else {
- PyErr_Format(PyExc_TypeError, "invalid rna key, key must be a string or an int instead of %.200s instance.", Py_TYPE(key)->tp_name);
+ PyErr_Format(PyExc_TypeError, "bpy_prop_collection[key]: invalid key, must be a string or an int instead of %.200s instance.", Py_TYPE(key)->tp_name);
return NULL;
}
}
@@ -1272,12 +1284,12 @@ static PyObject *pyrna_prop_array_subscript(BPy_PropertyRNA *self, PyObject *key
return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, start, stop, len);
}
else {
- PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna");
+ PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]: slice steps not supported with rna");
return NULL;
}
}
else {
- PyErr_SetString(PyExc_AttributeError, "invalid key, key must be an int");
+ PyErr_SetString(PyExc_AttributeError, "bpy_prop_array[key]: invalid key, key must be an int");
return NULL;
}
}
@@ -1291,17 +1303,17 @@ static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop, in
int ret= 0;
if(value_orig == NULL) {
- PyErr_SetString(PyExc_TypeError, "invalid slice assignment, deleting with list types is not supported by StructRNA.");
+ PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice] = value: deleting with list types is not supported by bpy_struct.");
return -1;
}
- if(!(value=PySequence_Fast(value_orig, "invalid slice assignment, type is not a sequence"))) {
+ if(!(value=PySequence_Fast(value_orig, "bpy_prop_array[slice] = value: type is not a sequence"))) {
return -1;
}
if(PySequence_Fast_GET_SIZE(value) != stop-start) {
Py_DECREF(value);
- PyErr_SetString(PyExc_TypeError, "invalid slice assignment, resizing StructRNA arrays isn't supported.");
+ PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice] = value: resizing bpy_struct arrays isn't supported.");
return -1;
}
@@ -1394,7 +1406,7 @@ static int prop_subscript_ass_array_int(BPy_PropertyRNA *self, Py_ssize_t keynum
if(keynum >= 0 && keynum < len)
return pyrna_py_to_prop_index(self, keynum, value);
- PyErr_SetString(PyExc_IndexError, "out of range");
+ PyErr_SetString(PyExc_IndexError, "bpy_prop_array[index] = value: index out of range");
return -1;
}
@@ -1402,8 +1414,8 @@ static int pyrna_prop_array_ass_subscript( BPy_PropertyRNA *self, PyObject *key,
{
/* char *keyname = NULL; */ /* not supported yet */
- if (!RNA_property_editable(&self->ptr, self->prop)) {
- PyErr_Format( PyExc_AttributeError, "PropertyRNA - attribute \"%.200s\" from \"%.200s\" is read-only", RNA_property_identifier(self->prop), RNA_struct_identifier(self->ptr.type) );
+ if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
+ PyErr_Format(PyExc_AttributeError, "bpy_prop_collection: attribute \"%.200s\" from \"%.200s\" is read-only", RNA_property_identifier(self->prop), RNA_struct_identifier(self->ptr.type) );
return -1;
}
@@ -1467,7 +1479,7 @@ static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *value
char *keyname = _PyUnicode_AsString(value);
if(keyname==NULL) {
- PyErr_SetString(PyExc_TypeError, "PropertyRNA - key in prop, key must be a string type");
+ PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.__contains__: expected a string");
return -1;
}
@@ -1483,12 +1495,12 @@ static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value)
char *name = _PyUnicode_AsString(value);
if (!name) {
- PyErr_SetString( PyExc_TypeError, "expected a string");
+ PyErr_SetString( PyExc_TypeError, "bpy_struct.__contains__: expected a string");
return -1;
}
if(RNA_struct_idproperties_check(self->ptr.type)==0) {
- PyErr_SetString( PyExc_TypeError, "this type doesnt support IDProperties");
+ PyErr_SetString( PyExc_TypeError, "bpy_struct: this type doesnt support IDProperties");
return -1;
}
@@ -1545,21 +1557,21 @@ static PyObject *pyrna_struct_subscript( BPy_StructRNA *self, PyObject *key )
}
if(name==NULL) {
- PyErr_SetString( PyExc_TypeError, "only strings are allowed as keys of ID properties");
+ PyErr_SetString( PyExc_TypeError, "bpy_struct[key]: only strings are allowed as keys of ID properties");
return NULL;
}
group= RNA_struct_idproperties(&self->ptr, 0);
if(group==NULL) {
- PyErr_Format( PyExc_KeyError, "key \"%s\" not found", name);
+ PyErr_Format( PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name);
return NULL;
}
idprop= IDP_GetPropertyFromGroup(group, name);
if(idprop==NULL) {
- PyErr_Format( PyExc_KeyError, "key \"%s\" not found", name);
+ PyErr_Format( PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name);
return NULL;
}
@@ -1571,7 +1583,7 @@ static int pyrna_struct_ass_subscript( BPy_StructRNA *self, PyObject *key, PyObj
IDProperty *group= RNA_struct_idproperties(&self->ptr, 1);
if(group==NULL) {
- PyErr_SetString(PyExc_TypeError, "id properties not supported for this type");
+ PyErr_SetString(PyExc_TypeError, "bpy_struct[key] = val: id properties not supported for this type");
return -1;
}
@@ -1589,7 +1601,7 @@ static PyObject *pyrna_struct_keys(BPy_PropertyRNA *self)
IDProperty *group;
if(RNA_struct_idproperties_check(self->ptr.type)==0) {
- PyErr_SetString( PyExc_TypeError, "this type doesnt support IDProperties");
+ PyErr_SetString( PyExc_TypeError, "bpy_struct.keys(): this type doesn't support IDProperties");
return NULL;
}
@@ -1606,7 +1618,7 @@ static PyObject *pyrna_struct_items(BPy_PropertyRNA *self)
IDProperty *group;
if(RNA_struct_idproperties_check(self->ptr.type)==0) {
- PyErr_SetString( PyExc_TypeError, "this type doesnt support IDProperties");
+ PyErr_SetString( PyExc_TypeError, "bpy_struct.items(): this type doesn't support IDProperties");
return NULL;
}
@@ -1624,7 +1636,7 @@ static PyObject *pyrna_struct_values(BPy_PropertyRNA *self)
IDProperty *group;
if(RNA_struct_idproperties_check(self->ptr.type)==0) {
- PyErr_SetString( PyExc_TypeError, "this type doesnt support IDProperties");
+ PyErr_SetString( PyExc_TypeError, "bpy_struct.values(): this type doesn't support IDProperties");
return NULL;
}
@@ -1636,47 +1648,81 @@ static PyObject *pyrna_struct_values(BPy_PropertyRNA *self)
return BPy_Wrap_GetValues(self->ptr.id.data, group);
}
-static PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args)
+/* internal use for insert and delete */
+int pyrna_struct_keyframe_parse(PointerRNA *ptr, PyObject *args, char *error_prefix,
+ char **path_full, int *index, float *cfra) /* return values */
{
- char *path, *path_full;
- int index= -1; /* default to all */
- float cfra = CTX_data_scene(BPy_GetContext())->r.cfra;
+ char *path;
PropertyRNA *prop;
- PyObject *result;
- if (!PyArg_ParseTuple(args, "s|if:keyframe_insert", &path, &index, &cfra))
- return NULL;
+ if (!PyArg_ParseTuple(args, "s|if", &path, &index, &cfra)) {
+ PyErr_Format(PyExc_TypeError, "%.200s expected a string and optionally an int and float arguments", error_prefix);
+ return -1;
+ }
- if (self->ptr.data==NULL) {
- PyErr_Format( PyExc_TypeError, "keyframe_insert, this struct has no data, cant be animated", path);
- return NULL;
+ if (ptr->data==NULL) {
+ PyErr_Format(PyExc_TypeError, "%.200s this struct has no data, can't be animated", error_prefix);
+ return -1;
}
- prop = RNA_struct_find_property(&self->ptr, path);
+ prop = RNA_struct_find_property(ptr, path);
if (prop==NULL) {
- PyErr_Format( PyExc_TypeError, "keyframe_insert, property \"%s\" not found", path);
- return NULL;
+ PyErr_Format( PyExc_TypeError, "%.200s property \"%s\" not found", error_prefix, path);
+ return -1;
}
- if (!RNA_property_animateable(&self->ptr, prop)) {
- PyErr_Format( PyExc_TypeError, "keyframe_insert, property \"%s\" not animatable", path);
- return NULL;
+ if (!RNA_property_animateable(ptr, prop)) {
+ PyErr_Format( PyExc_TypeError, "%.200s property \"%s\" not animatable", error_prefix, path);
+ return -1;
}
- path_full= RNA_path_from_ID_to_property(&self->ptr, prop);
+ *path_full= RNA_path_from_ID_to_property(ptr, prop);
- if (path_full==NULL) {
- PyErr_Format( PyExc_TypeError, "keyframe_insert, could not make path to \"%s\"", path);
- return NULL;
+ if (*path_full==NULL) {
+ PyErr_Format( PyExc_TypeError, "%.200s could not make path to \"%s\"", error_prefix, path);
+ return -1;
}
- result= PyBool_FromLong( insert_keyframe((ID *)self->ptr.id.data, NULL, NULL, path_full, index, cfra, 0));
+ if(*cfra==FLT_MAX)
+ *cfra= CTX_data_scene(BPy_GetContext())->r.cfra;
+
+ return 0; /* success */
+}
+
+static PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args)
+{
+ PyObject *result;
+ /* args, pyrna_struct_keyframe_parse handles these */
+ char *path_full= NULL;
+ int index= -1;
+ float cfra= FLT_MAX;
+
+ if(pyrna_struct_keyframe_parse(&self->ptr, args, "bpy_struct.keyframe_insert():", &path_full, &index, &cfra) == -1)
+ return NULL;
+
+ result= PyBool_FromLong(insert_keyframe((ID *)self->ptr.id.data, NULL, NULL, path_full, index, cfra, 0));
MEM_freeN(path_full);
return result;
}
+static PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args)
+{
+ PyObject *result;
+ /* args, pyrna_struct_keyframe_parse handles these */
+ char *path_full= NULL;
+ int index= -1;
+ float cfra= FLT_MAX;
+
+ if(pyrna_struct_keyframe_parse(&self->ptr, args, "bpy_struct.keyframe_delete():", &path_full, &index, &cfra) == -1)
+ return NULL;
+
+ result= PyBool_FromLong(delete_keyframe((ID *)self->ptr.id.data, NULL, NULL, path_full, index, cfra, 0));
+ MEM_freeN(path_full);
+
+ return result;
+}
static PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
{
@@ -1689,26 +1735,26 @@ static PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
return NULL;
if (self->ptr.data==NULL) {
- PyErr_Format( PyExc_TypeError, "driver_add, this struct has no data, cant be animated", path);
+ PyErr_Format( PyExc_TypeError, "bpy_struct.driver_add(): this struct has no data, cant be animated", path);
return NULL;
}
prop = RNA_struct_find_property(&self->ptr, path);
if (prop==NULL) {
- PyErr_Format( PyExc_TypeError, "driver_add, property \"%s\" not found", path);
+ PyErr_Format( PyExc_TypeError, "bpy_struct.driver_add(): property \"%s\" not found", path);
return NULL;
}
if (!RNA_property_animateable(&self->ptr, prop)) {
- PyErr_Format( PyExc_TypeError, "driver_add, property \"%s\" not animatable", path);
+ PyErr_Format( PyExc_TypeError, "bpy_struct.driver_add(): property \"%s\" not animatable", path);
return NULL;
}
path_full= RNA_path_from_ID_to_property(&self->ptr, prop);
if (path_full==NULL) {
- PyErr_Format( PyExc_TypeError, "driver_add, could not make path to \"%s\"", path);
+ PyErr_Format( PyExc_TypeError, "bpy_struct.driver_add(): could not make path to \"%s\"", path);
return NULL;
}
@@ -1778,7 +1824,7 @@ static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *value)
PropertyRNA *r_prop;
if(path==NULL) {
- PyErr_SetString( PyExc_TypeError, "items() is only valid for collection types" );
+ PyErr_SetString( PyExc_TypeError, "bpy_struct.items(): is only valid for collection types" );
return NULL;
}
@@ -1801,7 +1847,7 @@ static PyObject *pyrna_struct_path_to_id(BPy_StructRNA *self, PyObject *args)
if(name) {
prop= RNA_struct_find_property(&self->ptr, name);
if(prop==NULL) {
- PyErr_Format(PyExc_TypeError, "path_to_id(\"%.200s\") not found", name);
+ PyErr_Format(PyExc_TypeError, "%.200s.path_to_id(\"%.200s\") not found", RNA_struct_identifier(self->ptr.type), name);
return NULL;
}
@@ -1960,7 +2006,7 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA *self, PyObject *pyname )
if(name[0]=='_') { // rna can't start with a "_", so for __dict__ and similar we can skip using rna lookups
/* annoying exception, maybe we need to have different types for this... */
if((strcmp(name, "__getitem__")==0 || strcmp(name, "__setitem__")==0) && !RNA_struct_idproperties_check(self->ptr.type)) {
- PyErr_SetString(PyExc_AttributeError, "StructRNA - no __getitem__ support for this type");
+ PyErr_SetString(PyExc_AttributeError, "bpy_struct: no __getitem__ support for this type");
ret = NULL;
}
else {
@@ -1977,7 +2023,7 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA *self, PyObject *pyname )
else if (self->ptr.type == &RNA_Context) {
bContext *C = self->ptr.data;
if(C==NULL) {
- PyErr_Format( PyExc_AttributeError, "StructRNA Context is 'NULL', can't get \"%.200s\" from context", name);
+ PyErr_Format( PyExc_AttributeError, "bpy_struct: Context is 'NULL', can't get \"%.200s\" from context", name);
ret= NULL;
}
else {
@@ -2021,7 +2067,7 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA *self, PyObject *pyname )
}
else {
#if 0
- PyErr_Format( PyExc_AttributeError, "StructRNA - Attribute \"%.200s\" not found", name);
+ PyErr_Format( PyExc_AttributeError, "bpy_struct: attribute \"%.200s\" not found", name);
ret = NULL;
#endif
/* Include this incase this instance is a subtype of a python class
@@ -2056,30 +2102,13 @@ static int pyrna_struct_setattro( BPy_StructRNA *self, PyObject *pyname, PyObjec
if (prop==NULL) {
return PyObject_GenericSetAttr((PyObject *)self, pyname, value);
-#if 0
- // XXX - This currently allows anything to be assigned to an rna prop, need to see how this should be used
- // but for now it makes porting scripts confusing since it fails silently.
- // edit: allowing this for setting classes internal attributes.
- // edit: allow this for any attribute that alredy exists as a python attr
- if ( (name[0]=='_' /* || pyrna_struct_pydict_contains(self, pyname) */ ) &&
- !BPy_StructRNA_CheckExact(self) &&
-
- return 0;
- } else
- {
- PyErr_Format( PyExc_AttributeError, "StructRNA - Attribute \"%.200s\" not found", name);
- return -1;
- }
-#endif
- }
-
- if (!RNA_property_editable(&self->ptr, prop)) {
- PyErr_Format( PyExc_AttributeError, "StructRNA - Attribute \"%.200s\" from \"%.200s\" is read-only", RNA_property_identifier(prop), RNA_struct_identifier(self->ptr.type) );
+ } else if (!RNA_property_editable_flag(&self->ptr, prop)) {
+ PyErr_Format( PyExc_AttributeError, "bpy_struct: attribute \"%.200s\" from \"%.200s\" is read-only", RNA_property_identifier(prop), RNA_struct_identifier(self->ptr.type) );
return -1;
}
/* pyrna_py_to_prop sets its own exceptions */
- return pyrna_py_to_prop(&self->ptr, prop, NULL, NULL, value, "StructRNA - item.attr = val:");
+ return pyrna_py_to_prop(&self->ptr, prop, NULL, NULL, value, "bpy_struct: item.attr = val:");
}
static PyObject *pyrna_prop_dir(BPy_PropertyRNA *self)
@@ -2151,7 +2180,7 @@ static int pyrna_prop_collection_setattro( BPy_PropertyRNA *self, PyObject *pyna
}
}
- PyErr_Format( PyExc_AttributeError, "BPy_PropertyRNA - Attribute \"%.200s\" not found", name);
+ PyErr_Format( PyExc_AttributeError, "bpy_prop_collection: attribute \"%.200s\" not found", name);
return -1;
}
@@ -2162,7 +2191,7 @@ static PyObject *pyrna_prop_add(BPy_PropertyRNA *self)
RNA_property_collection_add(&self->ptr, self->prop, &r_ptr);
if(!r_ptr.data) {
- PyErr_SetString( PyExc_TypeError, "add() not supported for this collection");
+ PyErr_SetString( PyExc_TypeError, "bpy_prop_collection.add(): not supported for this collection");
return NULL;
}
else {
@@ -2176,12 +2205,12 @@ static PyObject *pyrna_prop_remove(BPy_PropertyRNA *self, PyObject *value)
int key= PyLong_AsSsize_t(value);
if (key==-1 && PyErr_Occurred()) {
- PyErr_SetString( PyExc_TypeError, "remove() expected one int argument");
+ PyErr_SetString( PyExc_TypeError, "bpy_prop_collection.remove(): expected one int argument");
return NULL;
}
if(!RNA_property_collection_remove(&self->ptr, self->prop, key)) {
- PyErr_SetString( PyExc_TypeError, "remove() not supported for this collection");
+ PyErr_SetString( PyExc_TypeError, "bpy_prop_collection.remove() not supported for this collection");
return NULL;
}
@@ -2219,96 +2248,74 @@ static PyGetSetDef pyrna_struct_getseters[] = {
static PyObject *pyrna_prop_keys(BPy_PropertyRNA *self)
{
- PyObject *ret;
- if (RNA_property_type(self->prop) != PROP_COLLECTION) {
- PyErr_SetString( PyExc_TypeError, "keys() is only valid for collection types" );
- ret = NULL;
- } else {
- PyObject *item;
- char name[256], *nameptr;
+ PyObject *ret= PyList_New(0);
+ PyObject *item;
+ char name[256], *nameptr;
- ret = PyList_New(0);
-
- RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
- nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name));
+ RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
+ nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name));
- if(nameptr) {
- /* add to python list */
- item = PyUnicode_FromString( nameptr );
- PyList_Append(ret, item);
- Py_DECREF(item);
- /* done */
-
- if(name != nameptr)
- MEM_freeN(nameptr);
- }
+ if(nameptr) {
+ /* add to python list */
+ item = PyUnicode_FromString( nameptr );
+ PyList_Append(ret, item);
+ Py_DECREF(item);
+ /* done */
+
+ if(name != nameptr)
+ MEM_freeN(nameptr);
}
- RNA_PROP_END;
}
+ RNA_PROP_END;
return ret;
}
static PyObject *pyrna_prop_items(BPy_PropertyRNA *self)
{
- PyObject *ret;
- if (RNA_property_type(self->prop) != PROP_COLLECTION) {
- PyErr_SetString( PyExc_TypeError, "items() is only valid for collection types" );
- ret = NULL;
- } else {
- PyObject *item;
- char name[256], *nameptr;
- int i= 0;
+ PyObject *ret= PyList_New(0);
+ PyObject *item;
+ char name[256], *nameptr;
+ int i= 0;
- ret = PyList_New(0);
-
- RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
- if(itemptr.data) {
- /* add to python list */
- item= PyTuple_New(2);
- nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name));
- if(nameptr) {
- PyTuple_SET_ITEM(item, 0, PyUnicode_FromString( nameptr ));
- if(name != nameptr)
- MEM_freeN(nameptr);
- }
- else {
- PyTuple_SET_ITEM(item, 0, PyLong_FromSsize_t(i)); /* a bit strange but better then returning an empty list */
- }
- PyTuple_SET_ITEM(item, 1, pyrna_struct_CreatePyObject(&itemptr));
-
- PyList_Append(ret, item);
- Py_DECREF(item);
-
- i++;
+ RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
+ if(itemptr.data) {
+ /* add to python list */
+ item= PyTuple_New(2);
+ nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name));
+ if(nameptr) {
+ PyTuple_SET_ITEM(item, 0, PyUnicode_FromString( nameptr ));
+ if(name != nameptr)
+ MEM_freeN(nameptr);
+ }
+ else {
+ PyTuple_SET_ITEM(item, 0, PyLong_FromSsize_t(i)); /* a bit strange but better then returning an empty list */
}
+ PyTuple_SET_ITEM(item, 1, pyrna_struct_CreatePyObject(&itemptr));
+
+ PyList_Append(ret, item);
+ Py_DECREF(item);
+
+ i++;
}
- RNA_PROP_END;
}
+ RNA_PROP_END;
return ret;
}
-
static PyObject *pyrna_prop_values(BPy_PropertyRNA *self)
{
- PyObject *ret;
+ PyObject *ret= PyList_New(0);
+ PyObject *item;
- if (RNA_property_type(self->prop) != PROP_COLLECTION) {
- PyErr_SetString( PyExc_TypeError, "values() is only valid for collection types" );
- ret = NULL;
- } else {
- PyObject *item;
- ret = PyList_New(0);
-
- RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
- item = pyrna_struct_CreatePyObject(&itemptr);
- PyList_Append(ret, item);
- Py_DECREF(item);
- }
- RNA_PROP_END;
+ RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
+ item = pyrna_struct_CreatePyObject(&itemptr);
+ PyList_Append(ret, item);
+ Py_DECREF(item);
}
-
+ RNA_PROP_END;
+
return ret;
}
@@ -2656,6 +2663,7 @@ static struct PyMethodDef pyrna_struct_methods[] = {
/* maybe this become and ID function */
{"keyframe_insert", (PyCFunction)pyrna_struct_keyframe_insert, METH_VARARGS, NULL},
+// {"keyframe_delete", (PyCFunction)pyrna_struct_keyframe_delete, METH_VARARGS, NULL}, // WIP
{"driver_add", (PyCFunction)pyrna_struct_driver_add, METH_VARARGS, NULL},
{"is_property_set", (PyCFunction)pyrna_struct_is_property_set, METH_VARARGS, NULL},
{"is_property_hidden", (PyCFunction)pyrna_struct_is_property_hidden, METH_VARARGS, NULL},
@@ -2663,6 +2671,11 @@ static struct PyMethodDef pyrna_struct_methods[] = {
{"path_to_id", (PyCFunction)pyrna_struct_path_to_id, METH_VARARGS, NULL},
{"recast_type", (PyCFunction)pyrna_struct_recast_type, METH_NOARGS, NULL},
{"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, NULL},
+
+ /* experemental */
+ {"callback_add", (PyCFunction)pyrna_callback_add, METH_VARARGS, NULL},
+ {"callback_remove", (PyCFunction)pyrna_callback_remove, METH_VARARGS, NULL},
+
{NULL, NULL, 0, NULL}
};
@@ -2700,7 +2713,7 @@ static PyObject * pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject
BPy_StructRNA *base = NULL;
- if (!PyArg_ParseTuple(args, "O!:Base BPy_StructRNA", &pyrna_struct_Type, &base))
+ if (!PyArg_ParseTuple(args, "O!:bpy_struct.__new__", &pyrna_struct_Type, &base))
return NULL;
if (type == &pyrna_struct_Type) {
@@ -2883,7 +2896,7 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
ParameterIterator iter;
PropertyRNA *parm;
PyObject *ret, *item;
- int i, args_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, kw_arg;
const char *parm_id;
PropertyRNA *pret_single= NULL;
@@ -2905,16 +2918,17 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
* the same ID as the functions. */
RNA_pointer_create(self_ptr->id.data, &RNA_Function, self_func, &funcptr);
- args_len= PyTuple_GET_SIZE(args);
+ pyargs_len= PyTuple_GET_SIZE(args);
+ pykw_len= kw ? PyDict_Size(kw) : 0;
RNA_parameter_list_create(&parms, self_ptr, self_func);
RNA_parameter_list_begin(&parms, &iter);
parms_len= RNA_parameter_list_size(&parms);
ret_len= 0;
- if(args_len + (kw ? PyDict_Size(kw):0) > parms_len) {
+ if(pyargs_len + pykw_len > parms_len) {
RNA_parameter_list_end(&iter);
- PyErr_Format(PyExc_TypeError, "%.200s.%.200s(): takes at most %d arguments, got %d", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), parms_len, args_len);
+ PyErr_Format(PyExc_TypeError, "%.200s.%.200s(): takes at most %d arguments, got %d", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), parms_len, pyargs_len + pykw_len);
err= -1;
}
@@ -2937,7 +2951,7 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
parm_id= RNA_property_identifier(parm);
item= NULL;
- if ((i < args_len) && (flag & PROP_REQUIRED)) {
+ if ((i < pyargs_len) && (flag & PROP_REQUIRED)) {
item= PyTuple_GET_ITEM(args, i);
i++;
@@ -2988,7 +3002,7 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
* the if below is quick, checking if it passed less keyword args then we gave.
* (Dont overwrite the error if we have one, otherwise can skip important messages and confuse with args)
*/
- if(err == 0 && kw && (PyDict_Size(kw) > kw_tot)) {
+ if(err == 0 && kw && (pykw_len > kw_tot)) {
PyObject *key, *value;
Py_ssize_t pos = 0;
@@ -3111,7 +3125,7 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
/*-----------------------BPy_StructRNA method def------------------------------*/
PyTypeObject pyrna_struct_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
- "StructRNA", /* tp_name */
+ "bpy_struct", /* tp_name */
sizeof( BPy_StructRNA ), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
@@ -3190,7 +3204,7 @@ PyTypeObject pyrna_struct_Type = {
/*-----------------------BPy_PropertyRNA method def------------------------------*/
PyTypeObject pyrna_prop_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
- "PropertyRNA", /* tp_name */
+ "bpy_prop", /* tp_name */
sizeof( BPy_PropertyRNA ), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
@@ -3270,7 +3284,7 @@ PyTypeObject pyrna_prop_Type = {
PyTypeObject pyrna_prop_array_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
- "PropertyArrayRNA", /* tp_name */
+ "bpy_prop_array", /* tp_name */
sizeof( BPy_PropertyRNA ), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
@@ -3350,7 +3364,7 @@ PyTypeObject pyrna_prop_array_Type = {
PyTypeObject pyrna_prop_collection_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
- "PropertyCollectionRNA", /* tp_name */
+ "bpy_prop_collection", /* tp_name */
sizeof( BPy_PropertyRNA ), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
@@ -3669,7 +3683,7 @@ PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr )
}
if( !pyrna ) {
- PyErr_SetString( PyExc_MemoryError, "couldn't create BPy_StructRNA object" );
+ PyErr_SetString( PyExc_MemoryError, "couldn't create bpy_struct object" );
return NULL;
}
@@ -3915,7 +3929,7 @@ static int deferred_register_prop(StructRNA *srna, PyObject *item, PyObject *key
if(PyArg_ParseTuple(item, "O!O!", &PyCapsule_Type, &py_func_ptr, &PyDict_Type, &py_kw)) {
if(*_PyUnicode_AsString(key)=='_') {
- PyErr_Format(PyExc_ValueError, "StructRNA \"%.200s\" registration error: %.200s could not register because the property starts with an '_'\n", RNA_struct_identifier(srna), _PyUnicode_AsString(key));
+ PyErr_Format(PyExc_ValueError, "bpy_struct \"%.200s\" registration error: %.200s could not register because the property starts with an '_'\n", RNA_struct_identifier(srna), _PyUnicode_AsString(key));
Py_DECREF(dummy_args);
return -1;
}
@@ -3936,7 +3950,7 @@ static int deferred_register_prop(StructRNA *srna, PyObject *item, PyObject *key
PyErr_Clear();
// PyLineSpit();
- PyErr_Format(PyExc_ValueError, "StructRNA \"%.200s\" registration error: %.200s could not register\n", RNA_struct_identifier(srna), _PyUnicode_AsString(key));
+ PyErr_Format(PyExc_ValueError, "bpy_struct \"%.200s\" registration error: %.200s could not register\n", RNA_struct_identifier(srna), _PyUnicode_AsString(key));
Py_DECREF(dummy_args);
return -1;
@@ -4143,7 +4157,8 @@ extern void BPY_update_modules( void ); //XXX temp solution
static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *parms)
{
PyObject *args;
- PyObject *ret= NULL, *py_class, *py_class_instance, *item, *parmitem;
+ PyObject *ret= NULL, *py_srna= NULL, *py_class, *py_class_instance= NULL, *parmitem;
+ void **py_class_instance_store= NULL;
PropertyRNA *parm;
ParameterIterator iter;
PointerRNA funcptr;
@@ -4159,23 +4174,49 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par
py_class= RNA_struct_py_type_get(ptr->type);
- item = pyrna_struct_CreatePyObject(ptr);
- if(item == NULL) {
+ /* exception, operators store their PyObjects for re-use */
+ if(ptr->data) {
+ if(RNA_struct_is_a(ptr->type, &RNA_Operator)) {
+ wmOperator *op= ptr->data;
+ if(op->py_instance) {
+ py_class_instance= op->py_instance;
+ Py_INCREF(py_class_instance);
+ }
+ else {
+ /* store the instance here once its created */
+ py_class_instance_store= &op->py_instance;
+ }
+ }
+ }
+ /* end exception */
+
+ if(py_class_instance==NULL)
+ py_srna= pyrna_struct_CreatePyObject(ptr);
+
+ if(py_class_instance) {
+ /* special case, instance is cached */
+ }
+ else if(py_srna == NULL) {
py_class_instance = NULL;
}
- else if(item == Py_None) { /* probably wont ever happen but possible */
- Py_DECREF(item);
+ else if(py_srna == Py_None) { /* probably wont ever happen but possible */
+ Py_DECREF(py_srna);
py_class_instance = NULL;
}
else {
args = PyTuple_New(1);
- PyTuple_SET_ITEM(args, 0, item);
+ PyTuple_SET_ITEM(args, 0, py_srna);
py_class_instance = PyObject_Call(py_class, args, NULL);
Py_DECREF(args);
+
+ if(py_class_instance_store) {
+ *py_class_instance_store = py_class_instance;
+ Py_INCREF(py_class_instance);
+ }
}
if (py_class_instance) { /* Initializing the class worked, now run its invoke function */
- item= PyObject_GetAttrString(py_class, RNA_function_identifier(func));
+ PyObject *item= PyObject_GetAttrString(py_class, RNA_function_identifier(func));
// flag= RNA_function_flag(func);
if(item) {
diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h
index 77f6ec00d48..770e88e1a1d 100644
--- a/source/blender/python/intern/bpy_rna.h
+++ b/source/blender/python/intern/bpy_rna.h
@@ -84,6 +84,8 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop);
PyObject *pyrna_enum_bitfield_to_py(struct EnumPropertyItem *items, int value);
int pyrna_set_to_enum_bitfield(EnumPropertyItem *items, PyObject *value, int *r_value, const char *error_prefix);
+int pyrna_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *value, const char *error_prefix);
+
/* function for registering types */
PyObject *pyrna_basetype_register(PyObject *self, PyObject *args);
PyObject *pyrna_basetype_unregister(PyObject *self, PyObject *args);
diff --git a/source/blender/python/intern/bpy_rna_callback.c b/source/blender/python/intern/bpy_rna_callback.c
new file mode 100644
index 00000000000..ee0c5cb143b
--- /dev/null
+++ b/source/blender/python/intern/bpy_rna_callback.c
@@ -0,0 +1,111 @@
+/**
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "Python.h"
+
+#include "bpy_rna.h"
+#include "bpy_util.h"
+
+#include "BLI_path_util.h"
+#include "DNA_screen_types.h"
+#include "BKE_context.h"
+#include "ED_space_api.h"
+
+EnumPropertyItem region_draw_mode_items[] = {
+ {REGION_DRAW_POST_VIEW, "POST_VIEW", 0, "Pose View", ""},
+ {REGION_DRAW_POST_PIXEL, "POST_PIXEL", 0, "Post Pixel", ""},
+ {REGION_DRAW_PRE_VIEW, "PRE_VIEW", 0, "Pre View", ""},
+ {0, NULL, 0, NULL, NULL}};
+
+
+void cb_region_draw(const bContext *C, ARegion *ar, void *customdata)
+{
+ PyObject *cb_func, *cb_args, *result;
+ PyGILState_STATE gilstate;
+
+ bpy_context_set((bContext *)C, &gilstate);
+
+ cb_func= PyTuple_GET_ITEM((PyObject *)customdata, 0);
+ cb_args= PyTuple_GET_ITEM((PyObject *)customdata, 1);
+ result = PyObject_CallObject(cb_func, cb_args);
+
+ if(result) {
+ Py_DECREF(result);
+ }
+ else {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+
+ bpy_context_clear((bContext *)C, &gilstate);
+}
+
+PyObject *pyrna_callback_add(BPy_StructRNA *self, PyObject *args)
+{
+ void *handle;
+
+ PyObject *cb_func, *cb_args;
+ char *cb_event_str= NULL;
+ int cb_event;
+
+ if (!PyArg_ParseTuple(args, "OO|s:bpy_struct.callback_add", &cb_func, &cb_args, &cb_event_str))
+ return NULL;
+
+ if(RNA_struct_is_a(self->ptr.type, &RNA_Region)) {
+
+ if(pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") < 0)
+ return NULL;
+
+ handle= ED_region_draw_cb_activate(((ARegion *)self->ptr.data)->type, cb_region_draw, (void *)args, cb_event);
+ Py_INCREF(args);
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError, "callbcak_add(): type does not suppport cllbacks");
+ return NULL;
+ }
+
+ return PyCapsule_New((void *)handle, NULL, NULL);
+}
+
+PyObject *pyrna_callback_remove(BPy_StructRNA *self, PyObject *args)
+{
+ PyObject *py_handle;
+ PyObject *py_args;
+ void *handle;
+ void *customdata;
+
+ if (!PyArg_ParseTuple(args, "O!:callback_remove", &PyCapsule_Type, &py_handle))
+ return NULL;
+
+ handle= PyCapsule_GetPointer(py_handle, NULL);
+
+ if(RNA_struct_is_a(self->ptr.type, &RNA_Region)) {
+ customdata= ED_region_draw_cb_customdata(handle);
+ Py_DECREF((PyObject *)customdata);
+
+ ED_region_draw_cb_exit(((ARegion *)self->ptr.data)->type, handle);
+ }
+
+ Py_RETURN_NONE;
+}
diff --git a/source/blender/python/intern/bpy_rna_callback.h b/source/blender/python/intern/bpy_rna_callback.h
new file mode 100644
index 00000000000..b6d771b23b2
--- /dev/null
+++ b/source/blender/python/intern/bpy_rna_callback.h
@@ -0,0 +1,29 @@
+/**
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+struct BPy_StructRNA;
+struct PyObject;
+
+struct PyObject *pyrna_callback_add(struct BPy_StructRNA *self, struct PyObject *args);
+struct PyObject *pyrna_callback_remove(struct BPy_StructRNA *self, struct PyObject *args);
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index c44d83f4f06..0a292c7acd5 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -2405,7 +2405,7 @@ static void init_render_mball(Render *re, ObjectRen *obr)
ver->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
ver->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
normalize_v3(ver->n);
- //if(ob->transflag & OB_NEG_SCALE) mul_v3_fl(ver->n. -1.0);
+ //if(ob->transflag & OB_NEG_SCALE) negate_v3(ver->n);
if(need_orco) ver->orco= orco;
}
diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c
index 10cbd82fb1b..954ff373c89 100644
--- a/source/blender/render/intern/source/shadbuf.c
+++ b/source/blender/render/intern/source/shadbuf.c
@@ -986,8 +986,9 @@ static float readdeepvisibility(DeepSample *dsample, int tot, int z, int bias, f
if(a == 0)
return 1.0f; /* completely in front of all samples */
+ /* converting to float early here because ds->z - prevds->z can overflow */
prevds= ds-1;
- t= (float)(z-bias - prevds->z)/(float)(ds->z - prevds->z);
+ t= ((float)(z-bias) - (float)prevds->z)/((float)ds->z - (float)prevds->z);
return t*ds->v + (1.0f-t)*prevds->v;
}
diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c
index 1622ee2bf4c..70e0fd41b7d 100644
--- a/source/blender/render/intern/source/volumetric.c
+++ b/source/blender/render/intern/source/volumetric.c
@@ -488,7 +488,7 @@ void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float *
if (ELEM(lar->type, LA_SUN, LA_HEMI))
VECCOPY(lv, lar->vec);
- mul_v3_fl(lv, -1.0f);
+ negate_v3(lv);
if (shi->mat->vol.shade_type == MA_VOL_SHADE_SHADOWED) {
mul_v3_fl(lacol, vol_get_shadow(shi, lar, co));
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index e2b2c17beee..048487fcd68 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -54,6 +54,7 @@
#include "wm.h"
#include "ED_screen.h"
+#include "BPY_extern.h"
#include "RNA_types.h"
@@ -63,6 +64,12 @@
void WM_operator_free(wmOperator *op)
{
+ if(op->py_instance) {
+ /* do this first incase there are any __del__ functions or
+ * similar that use properties */
+ BPY_DECREF(op->py_instance);
+ }
+
if(op->ptr) {
op->properties= op->ptr->data;
MEM_freeN(op->ptr);
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 74679ce89a6..b72bc02aca6 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -28,6 +28,7 @@
#include <stdlib.h>
#include <string.h>
+#include <math.h>
#include "DNA_listBase.h"
#include "DNA_screen_types.h"
@@ -1533,23 +1534,32 @@ void wm_event_do_handlers(bContext *C)
wm_event_free_all(win);
else
{
- if(win->screen->scene)
+ Scene* scene = win->screen->scene;
+ if(scene)
{
int playing = sound_scene_playing(win->screen->scene);
if(playing != -1)
{
+ CTX_wm_window_set(C, win);
+ CTX_wm_screen_set(C, win->screen);
+ CTX_data_scene_set(C, scene);
if(((playing == 1) && (!win->screen->animtimer)) || ((playing == 0) && (win->screen->animtimer)))
{
- CTX_wm_window_set(C, win);
- CTX_wm_screen_set(C, win->screen);
- CTX_data_scene_set(C, win->screen->scene);
-
ED_screen_animation_play(C, -1, 1);
-
- CTX_data_scene_set(C, NULL);
- CTX_wm_screen_set(C, NULL);
- CTX_wm_window_set(C, NULL);
}
+ if(playing == 0)
+ {
+ int ncfra = floor(sound_sync_scene(scene) * FPS);
+ if(ncfra != scene->r.cfra)
+ {
+ scene->r.cfra = ncfra;
+ ED_update_for_newframe(C, 1);
+ WM_event_add_notifier(C, NC_WINDOW, NULL);
+ }
+ }
+ CTX_data_scene_set(C, NULL);
+ CTX_wm_screen_set(C, NULL);
+ CTX_wm_window_set(C, NULL);
}
}
}
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 16776517e40..2ab6f78daa5 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -241,6 +241,10 @@ static void wm_init_userdef(bContext *C)
UI_init_userdef();
MEM_CacheLimiter_set_maximum(U.memcachelimit * 1024 * 1024);
sound_init(CTX_data_main(C));
+
+ /* set the python auto-execute setting from user prefs */
+ if (U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) G.f &= ~G_SCRIPT_AUTOEXEC;
+ else G.f |= G_SCRIPT_AUTOEXEC;
}
void WM_read_file(bContext *C, char *name, ReportList *reports)
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index b52588f2e75..29359b1ddb9 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -1120,7 +1120,10 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *arg_unuse
else display_name= recent->filename;
uiItemStringO(col, display_name, ICON_FILE_BLEND, "WM_OT_open_mainfile", "path", recent->filename);
}
-
+ uiItemL(col, "Recovery", 0);
+ uiItemO(col, NULL, ICON_FILE_BLEND, "WM_OT_recover_last_session");
+ uiItemO(col, NULL, ICON_FILE_BLEND, "WM_OT_recover_auto_save");
+
uiItemL(col, "", 0);
uiCenteredBoundsBlock(block, 0.0f);
@@ -1323,10 +1326,17 @@ static void open_set_load_ui(wmOperator *op)
RNA_boolean_set(op->ptr, "load_ui", !(U.flag & USER_FILENOUI));
}
+static void open_set_use_scripts(wmOperator *op)
+{
+ if(!RNA_property_is_set(op->ptr, "use_scripts"))
+ RNA_boolean_set(op->ptr, "use_scripts", !(U.flag & USER_SCRIPT_AUTOEXEC_DISABLE));
+}
+
static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
RNA_string_set(op->ptr, "path", G.sce);
open_set_load_ui(op);
+ open_set_use_scripts(op);
WM_event_add_fileselect(C, op);
@@ -1339,11 +1349,17 @@ static int wm_open_mainfile_exec(bContext *C, wmOperator *op)
RNA_string_get(op->ptr, "path", path);
open_set_load_ui(op);
+ open_set_use_scripts(op);
if(RNA_boolean_get(op->ptr, "load_ui"))
G.fileflags &= ~G_FILE_NO_UI;
else
G.fileflags |= G_FILE_NO_UI;
+
+ if(RNA_boolean_get(op->ptr, "use_scripts"))
+ G.f |= G_SCRIPT_AUTOEXEC;
+ else
+ G.f &= ~G_SCRIPT_AUTOEXEC;
// XXX wm in context is not set correctly after WM_read_file -> crash
// do it before for now, but is this correct with multiple windows?
@@ -1367,6 +1383,7 @@ static void WM_OT_open_mainfile(wmOperatorType *ot)
WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER, FILE_OPENFILE);
RNA_def_boolean(ot->srna, "load_ui", 1, "Load UI", "Load user interface setup in the .blend file");
+ RNA_def_boolean(ot->srna, "use_scripts", 1, "Trusted Source", "Allow blend file execute scripts automatically, default available from system preferences");
}
/* **************** link/append *************** */
@@ -2997,7 +3014,11 @@ static EnumPropertyItem *rna_id_itemf(bContext *C, PointerRNA *ptr, int *free, I
return item;
}
-/* can add more */
+/* can add more as needed */
+EnumPropertyItem *RNA_action_itemf(bContext *C, PointerRNA *ptr, int *free)
+{
+ return rna_id_itemf(C, ptr, free, C ? (ID *)CTX_data_main(C)->action.first : NULL);
+}
EnumPropertyItem *RNA_group_itemf(bContext *C, PointerRNA *ptr, int *free)
{
return rna_id_itemf(C, ptr, free, C ? (ID *)CTX_data_main(C)->group.first : NULL);
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index d3a760002ae..8f626ea66a5 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -88,6 +88,7 @@ int WM_enum_search_invoke(struct bContext *C, struct wmOperator *op, struct wmEv
void WM_event_add_notifier(const struct bContext *C, unsigned int type, void *reference){}
void WM_main_add_notifier(unsigned int type, void *reference){}
void ED_armature_bone_rename(struct bArmature *arm, char *oldnamep, char *newnamep){}
+struct wmEventHandler *WM_event_add_modal_handler(struct bContext *C, struct wmOperator *op){return (struct wmEventHandler *)NULL;};
void ED_armature_edit_bone_remove(struct bArmature *arm, struct EditBone *exBone){}
void object_test_constraints (struct Object *owner){}
void ED_object_parent(struct Object *ob, struct Object *par, int type, const char *substr){}
@@ -265,6 +266,7 @@ void WM_operator_bl_idname(char *to, const char *from){}
void WM_operator_py_idname(char *to, const char *from){}
void WM_operator_ui_popup(struct bContext *C, struct wmOperator *op, int width, int height){}
short insert_keyframe (struct ID *id, struct bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag){return 0;}
+short delete_keyframe(struct ID *id, struct bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag){return 0;};
char *WM_operator_pystring(struct bContext *C, struct wmOperatorType *ot, struct PointerRNA *opptr, int all_args){return NULL;}
struct wmKeyMapItem *WM_modalkeymap_add_item(struct wmKeyMap *km, int type, int val, int modifier, int keymodifier, int value){return NULL;}
struct wmKeyMap *WM_modalkeymap_add(struct wmKeyConfig *keyconf, char *idname, EnumPropertyItem *items){return NULL;}
@@ -300,7 +302,7 @@ void smoke_get_index(void) {return;}
void smoke_step(void) {return;}
*/
-char blender_path(){return (char) NULL;}
+char blender_path[] = "";
/* CSG */
struct CSG_BooleanOperation * CSG_NewBooleanFunction( void ){return (struct CSG_BooleanOperation *) NULL;}
diff --git a/source/creator/creator.c b/source/creator/creator.c
index 929a3ff0655..dd68128a55f 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -303,7 +303,7 @@ static int end_arguments(int argc, char **argv, void *data)
static int disable_python(int argc, char **argv, void *data)
{
- G.f &= ~G_DOSCRIPTLINKS;
+ G.f &= ~G_SCRIPT_AUTOEXEC;
return 0;
}
@@ -769,8 +769,14 @@ static int set_skip_frame(int argc, char **argv, void *data)
static int run_python(int argc, char **argv, void *data)
{
- bContext *C = data;
#ifndef DISABLE_PYTHON
+ bContext *C = data;
+
+ /* Make the path absolute because its needed for relative linked blends to be found */
+ char filename[FILE_MAXDIR + FILE_MAXFILE];
+ BLI_strncpy(filename, argv[1], sizeof(filename));
+ BLI_convertstringcwd(filename);
+
/* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
if (argc > 1) {
/* XXX, temp setting the WM is ugly, splash also does this :S */
@@ -780,13 +786,13 @@ static int run_python(int argc, char **argv, void *data)
if(wm->windows.first) {
CTX_wm_window_set(C, wm->windows.first);
- BPY_run_python_script(C, argv[1], NULL, NULL); // use reports?
+ BPY_run_python_script(C, filename, NULL, NULL); // use reports?
CTX_wm_window_set(C, prevwin);
}
else {
fprintf(stderr, "Python script \"%s\" running with missing context data.\n", argv[1]);
- BPY_run_python_script(C, argv[1], NULL, NULL); // use reports?
+ BPY_run_python_script(C, filename, NULL, NULL); // use reports?
}
return 1;
} else {
@@ -805,12 +811,11 @@ static int load_file(int argc, char **argv, void *data)
/* Make the path absolute because its needed for relative linked blends to be found */
char filename[FILE_MAXDIR + FILE_MAXFILE];
-
BLI_strncpy(filename, argv[0], sizeof(filename));
BLI_convertstringcwd(filename);
if (G.background) {
- int retval = BKE_read_file(C, argv[0], NULL, NULL);
+ int retval = BKE_read_file(C, filename, NULL, NULL);
/*we successfully loaded a blend file, get sure that
pointcache works */
@@ -948,7 +953,7 @@ int main(int argc, char **argv)
/* first test for background */
- G.f |= G_DOSCRIPTLINKS; /* script links enabled by default */
+ G.f |= G_SCRIPT_AUTOEXEC; /* script links enabled by default */
ba = BLI_argsInit(argc, argv); /* skip binary path */
setupArguments(C, ba, &syshandle);
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
index 8a2aea4567e..1688be6d528 100644
--- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
+++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
@@ -168,10 +168,12 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
bool usefixed = (SYS_GetCommandLineInt(syshandle, "fixedtime", 0) != 0);
bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0);
bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0);
- bool game2ipo = (SYS_GetCommandLineInt(syshandle, "game2ipo", 0) != 0);
+ bool animation_record = (SYS_GetCommandLineInt(syshandle, "animation_record", 0) != 0);
bool displaylists = (SYS_GetCommandLineInt(syshandle, "displaylists", 0) != 0);
bool nodepwarnings = (SYS_GetCommandLineInt(syshandle, "ignore_deprecation_warnings", 0) != 0);
bool novertexarrays = (SYS_GetCommandLineInt(syshandle, "novertexarrays", 0) != 0);
+ if(animation_record) usefixed= true; /* override since you's always want fixed time for sim recording */
+
// create the canvas, rasterizer and rendertools
RAS_ICanvas* canvas = new KX_BlenderCanvas(win, area_rect);
canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE);
@@ -316,27 +318,13 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
exitrequested = KX_EXIT_REQUEST_QUIT_GAME;
}
}
-
- Scene *blscene = NULL;
- if (!bfd)
- {
- blscene = (Scene*) blenderdata->scene.first;
- for (Scene *sce= (Scene*) blenderdata->scene.first; sce; sce= (Scene*) sce->id.next)
- {
- if (startscenename == (sce->id.name+2))
- {
- blscene = sce;
- break;
- }
- }
- } else {
- blscene = bfd->curscene;
- }
+
+ Scene *blscene= bfd ? bfd->curscene : (Scene *)BLI_findstring(&blenderdata->scene, startscenename, offsetof(ID, name) + 2);
if (blscene)
{
int startFrame = blscene->r.cfra;
- ketsjiengine->SetGame2IpoMode(game2ipo,startFrame);
+ ketsjiengine->SetAnimRecordMode(animation_record, startFrame);
// Quad buffered needs a special window.
if(blscene->gm.stereoflag == STEREO_ENABLED){
@@ -423,7 +411,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
// Set the animation playback rate for ipo's and actions
// the framerate below should patch with FPS macro defined in blendef.h
// Could be in StartEngine set the framerate, we need the scene to do this
- ketsjiengine->SetAnimFrameRate( (((double) blscene->r.frs_sec) / blscene->r.frs_sec_base) );
+ ketsjiengine->SetAnimFrameRate(FPS);
// the mainloop
printf("\nBlender Game Engine Started\n\n");
@@ -457,7 +445,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
* should this really be?
*/
if (event->type==MOUSEMOVE) {
- /* Note nice! XXX 2.5 event hack */
+ /* Note, not nice! XXX 2.5 event hack */
val = event->x - ar->winrct.xmin;
mousedevice->ConvertBlenderEvent(MOUSEX, val);
@@ -581,224 +569,3 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
#endif
}
-
-extern "C" void StartKetsjiShellSimulation(struct wmWindow *win,
- struct ARegion *ar,
- char* scenename,
- struct Main* maggie,
- int always_use_expand_framing)
-{
- int exitrequested = KX_EXIT_REQUEST_NO_REQUEST;
-
- Main* blenderdata = maggie;
-
- RAS_Rect area_rect;
- area_rect.SetLeft(ar->winrct.xmin);
- area_rect.SetBottom(ar->winrct.ymin);
- area_rect.SetRight(ar->winrct.xmax);
- area_rect.SetTop(ar->winrct.ymax);
-
- char* startscenename = scenename;
- char pathname[FILE_MAXDIR+FILE_MAXFILE];
- STR_String exitstring = "";
-
- BLI_strncpy(pathname, blenderdata->name, sizeof(pathname));
-
-#ifndef DISABLE_PYTHON
- // Acquire Python's GIL (global interpreter lock)
- // so we can safely run Python code and API calls
- PyGILState_STATE gilstate = PyGILState_Ensure();
- PyObject *pyGlobalDict = PyDict_New(); /* python utility storage, spans blend file loading */
-#endif
-
- bgl::InitExtensions(true);
-
- do
- {
-
- // get some preferences
- SYS_SystemHandle syshandle = SYS_GetSystem();
- /*
- bool properties = (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0);
- bool usefixed = (SYS_GetCommandLineInt(syshandle, "fixedtime", 0) != 0);
- bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0);
- bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0);
- */
- bool game2ipo = true;//(SYS_GetCommandLineInt(syshandle, "game2ipo", 0) != 0);
- bool displaylists = (SYS_GetCommandLineInt(syshandle, "displaylists", 0) != 0);
- bool usemat = false;
-
- // create the canvas, rasterizer and rendertools
- RAS_ICanvas* canvas = new KX_BlenderCanvas(win, area_rect);
- //canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE);
- RAS_IRenderTools* rendertools = new KX_BlenderRenderTools();
- RAS_IRasterizer* rasterizer = NULL;
-
- if(displaylists) {
- if (GLEW_VERSION_1_1)
- rasterizer = new RAS_ListRasterizer(canvas, true, true);
- else
- rasterizer = new RAS_ListRasterizer(canvas);
- }
- else if (GLEW_VERSION_1_1)
- rasterizer = new RAS_VAOpenGLRasterizer(canvas, false);
- else
- rasterizer = new RAS_OpenGLRasterizer(canvas);
-
- // create the inputdevices
- KX_BlenderKeyboardDevice* keyboarddevice = new KX_BlenderKeyboardDevice();
- KX_BlenderMouseDevice* mousedevice = new KX_BlenderMouseDevice();
-
- // create a networkdevice
- NG_NetworkDeviceInterface* networkdevice = new
- NG_LoopBackNetworkDeviceInterface();
-
- // create a ketsji/blendersystem (only needed for timing and stuff)
- KX_BlenderSystem* kxsystem = new KX_BlenderSystem();
-
- // create the ketsjiengine
- KX_KetsjiEngine* ketsjiengine = new KX_KetsjiEngine(kxsystem);
-
- Scene *blscene = NULL;
-
- blscene = (Scene*) maggie->scene.first;
- for (Scene *sce= (Scene*) maggie->scene.first; sce; sce= (Scene*) sce->id.next)
- {
- if (startscenename == (sce->id.name+2))
- {
- blscene = sce;
- break;
- }
- }
-
- int cframe = 1, startFrame;
- if (blscene)
- {
- cframe=blscene->r.cfra;
- startFrame = blscene->r.sfra;
- blscene->r.cfra=startFrame;
- // update_for_newframe(); // XXX scene_update_for_newframe wont cut it!
- ketsjiengine->SetGame2IpoMode(game2ipo,startFrame);
- }
-
- // Quad buffered needs a special window.
- if(blscene->gm.stereoflag == STEREO_ENABLED){
- if (blscene->gm.stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED)
- rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) blscene->gm.stereomode);
- }
- rasterizer->SetBackColor(blscene->gm.framing.col[0], blscene->gm.framing.col[1], blscene->gm.framing.col[2], 0.0f);
-
- if (exitrequested != KX_EXIT_REQUEST_QUIT_GAME)
- {
- // create a scene converter, create and convert the startingscene
- KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(maggie, ketsjiengine);
- ketsjiengine->SetSceneConverter(sceneconverter);
- sceneconverter->addInitFromFrame=true;
-
- if (always_use_expand_framing)
- sceneconverter->SetAlwaysUseExpandFraming(true);
-
- if(usemat)
- sceneconverter->SetMaterials(true);
-
- KX_Scene* startscene = new KX_Scene(keyboarddevice,
- mousedevice,
- networkdevice,
- startscenename,
- blscene);
-
-#ifndef DISABLE_PYTHON
- // some python things
- PyObject *gameLogic, *gameLogic_keys;
- setupGamePython(ketsjiengine, startscene, blenderdata, pyGlobalDict, &gameLogic, &gameLogic_keys, 0, NULL);
-#endif // DISABLE_PYTHON
-
- if (sceneconverter)
- {
- // convert and add scene
- sceneconverter->ConvertScene(
- startscene,
- rendertools,
- canvas);
- ketsjiengine->AddScene(startscene);
-
- // start the engine
- ketsjiengine->StartEngine(false);
-
- ketsjiengine->SetUseFixedTime(true);
-
- ketsjiengine->SetTicRate(
- (double) blscene->r.frs_sec /
- (double) blscene->r.frs_sec_base);
-
- // the mainloop
- while ((blscene->r.cfra<=blscene->r.efra)&&(!exitrequested))
- {
- printf("frame %i\n",blscene->r.cfra);
- // first check if we want to exit
- exitrequested = ketsjiengine->GetExitCode();
-
- // kick the engine
- ketsjiengine->NextFrame();
- blscene->r.cfra=blscene->r.cfra+1;
- // update_for_newframe(); // XXX scene_update_for_newframe wont cut it
-
- }
- exitstring = ketsjiengine->GetExitString();
- }
- if (sceneconverter)
- {
- delete sceneconverter;
- sceneconverter = NULL;
- }
- }
- blscene->r.cfra=cframe;
- // set the cursor back to normal
- canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL);
-
- // clean up some stuff
- if (ketsjiengine)
- {
- delete ketsjiengine;
- ketsjiengine = NULL;
- }
- if (kxsystem)
- {
- delete kxsystem;
- kxsystem = NULL;
- }
- if (networkdevice)
- {
- delete networkdevice;
- networkdevice = NULL;
- }
- if (keyboarddevice)
- {
- delete keyboarddevice;
- keyboarddevice = NULL;
- }
- if (mousedevice)
- {
- delete mousedevice;
- mousedevice = NULL;
- }
- if (rasterizer)
- {
- delete rasterizer;
- rasterizer = NULL;
- }
- if (rendertools)
- {
- delete rendertools;
- rendertools = NULL;
- }
-
- } while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME);
-
-#ifndef DISABLE_PYTHON
- Py_DECREF(pyGlobalDict);
-
- // Release Python's GIL
- PyGILState_Release(gilstate);
-#endif
-}
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
index 5852d618886..3ee4248343c 100644
--- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
@@ -82,13 +82,16 @@ extern "C"
#include "MEM_guardedalloc.h"
//XXX #include "BSE_editipo.h"
//XXX #include "BSE_editipo_types.h"
-#include "DNA_ipo_types.h"
+// #include "DNA_ipo_types.h"
#include "BKE_global.h"
+#include "BKE_animsys.h"
#include "BKE_library.h"
#include "BKE_ipo.h" // eval_icu
#include "BKE_material.h" // copy_material
#include "BKE_mesh.h" // copy_mesh
#include "DNA_space_types.h"
+#include "DNA_anim_types.h"
+#include "../../blender/editors/include/ED_keyframing.h"
}
/* Only for dynamic loading and merging */
@@ -208,17 +211,14 @@ Scene *KX_BlenderSceneConverter::GetBlenderSceneForName(const STR_String& name)
* Find the specified scene by name, or the first
* scene if nothing matches (shouldn't happen).
*/
-
- for (sce= (Scene*) m_maggie->scene.first; sce; sce= (Scene*) sce->id.next)
- if (name == (sce->id.name+2))
- return sce;
+ if((sce= (Scene *)BLI_findstring(&m_maggie->scene, name.ReadPtr(), offsetof(ID, name) + 2)))
+ return sce;
for (vector<Main*>::iterator it=m_DynamicMaggie.begin(); !(it==m_DynamicMaggie.end()); it++) {
Main *main= *it;
- for (sce= (Scene*) main->scene.first; sce; sce= (Scene*) sce->id.next)
- if (name == (sce->id.name+2))
- return sce;
+ if((sce= (Scene *)BLI_findstring(&main->scene, name.ReadPtr(), offsetof(ID, name) + 2)))
+ return sce;
}
return (Scene*)m_maggie->scene.first;
@@ -624,57 +624,12 @@ void KX_BlenderSceneConverter::RegisterWorldInfo(
m_worldinfos.push_back(pair<KX_Scene*,KX_WorldInfo*>(m_currentScene,worldinfo));
}
-/*
- * When deleting an IPO curve from Python, check if the IPO is being
- * edited and if so clear the pointer to the old curve.
- */
-void KX_BlenderSceneConverter::localDel_ipoCurve ( IpoCurve * icu )
-{
-#if 0 //XXX
- if (!G.sipo)
- return;
-
- int i;
- EditIpo *ei= (EditIpo *)G.sipo->editipo;
- if (!ei) return;
-
- for(i=0; i<G.sipo->totipo; i++, ei++) {
- if ( ei->icu == icu ) {
- ei->flag &= ~(IPO_SELECT | IPO_EDIT);
- ei->icu= 0;
- return;
- }
- }
-#endif
-}
-
//quick hack
extern "C"
{
- Ipo *add_ipo( char *name, int idcode );
- //XXX char *getIpoCurveName( IpoCurve * icu );
- //XXX struct IpoCurve *verify_ipocurve(struct ID *, short, char *, char *, char *, int);
- //XXX void testhandles_ipocurve(struct IpoCurve *icu);
- void insert_vert_icu(struct IpoCurve *, float, float, short);
- float eval_icu(struct IpoCurve *icu, float ipotime);
- //void mat3_to_eul( float *eul,float tmat[][3]);
void mat3_to_compatible_eul( float *eul, float *oldrot,float mat[][3]);
}
-IpoCurve* findIpoCurve(IpoCurve* first, const char* searchName)
-{
- IpoCurve* icu1;
- for( icu1 = first; icu1; icu1 = icu1->next )
- {
- /*XXX char* curveName = getIpoCurveName( icu1 );
- if( !strcmp( curveName, searchName) )
- {
- return icu1;
- }*/
- }
- return 0;
-}
-
void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo)
{
@@ -698,6 +653,7 @@ void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo)
Object* blenderObject = gameObj->GetBlenderObject();
if (blenderObject)
{
+#if 0
//erase existing ipo's
Ipo* ipo = blenderObject->ipo;//findIpoForName(blenderObject->id.name+2);
if (ipo)
@@ -731,11 +687,7 @@ void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo)
blenderObject->ipo = ipo;
}
-
-
-
-
-
+#endif
}
}
@@ -814,8 +766,28 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber)
//KX_IPhysicsController* physCtrl = gameObj->GetPhysicsController();
Object* blenderObject = gameObj->GetBlenderObject();
- if (blenderObject && blenderObject->ipo)
+
+ if(blenderObject->adt==NULL)
+ BKE_id_add_animdata(&blenderObject->id);
+
+ if (blenderObject && blenderObject->adt)
{
+ const MT_Point3& position = gameObj->NodeGetWorldPosition();
+ //const MT_Vector3& scale = gameObj->NodeGetWorldScaling();
+ const MT_Matrix3x3& orn = gameObj->NodeGetWorldOrientation();
+
+ position.getValue(blenderObject->loc);
+
+ float tmat[3][3];
+ for (int r=0;r<3;r++)
+ for (int c=0;c<3;c++)
+ tmat[r][c] = orn[c][r];
+
+ mat3_to_compatible_eul(blenderObject->rot, blenderObject->rot, tmat);
+
+ insert_keyframe(&blenderObject->id, NULL, NULL, "location", -1, frameNumber, INSERTKEY_FAST);
+ insert_keyframe(&blenderObject->id, NULL, NULL, "rotation_euler", -1, frameNumber, INSERTKEY_FAST);
+
#if 0
const MT_Point3& position = gameObj->NodeGetWorldPosition();
//const MT_Vector3& scale = gameObj->NodeGetWorldScaling();
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.h b/source/gameengine/Converter/KX_BlenderSceneConverter.h
index e880c8b824c..3dd3afb5662 100644
--- a/source/gameengine/Converter/KX_BlenderSceneConverter.h
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.h
@@ -43,7 +43,6 @@ class RAS_MeshObject;
class RAS_IPolyMaterial;
class BL_InterpolatorList;
class BL_Material;
-struct IpoCurve;
struct Main;
struct Scene;
@@ -74,9 +73,6 @@ class KX_BlenderSceneConverter : public KX_ISceneConverter
bool m_usemat;
bool m_useglslmat;
- void localDel_ipoCurve ( IpoCurve * icu );
-// struct Ipo* findIpoForName(char* objName);
-
public:
KX_BlenderSceneConverter(
Main* maggie,
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
index 81a1e699f71..43b26cf9a06 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
@@ -586,7 +586,7 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode)
if (!m_networkdevice)
goto initFailed;
- sound_init();
+ sound_init(m_maggie);
// create a ketsjisystem (only needed for timing and stuff)
m_kxsystem = new GPG_System (m_system);
@@ -710,8 +710,8 @@ bool GPG_Application::startEngine(void)
// Set the animation playback rate for ipo's and actions
// the framerate below should patch with FPS macro defined in blendef.h
// Could be in StartEngine set the framerate, we need the scene to do this
-// XXX m_ketsjiengine->SetAnimFrameRate( (((double) scene->r.frs_sec) / scene->r.frs_sec_base) );
-
+ Scene *scene= startscene->GetBlenderScene(); // needed for macro
+ m_ketsjiengine->SetAnimFrameRate(FPS);
}
if (!m_engineRunning)
diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
index a1fa810e73a..95370beeeb3 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
@@ -65,6 +65,7 @@ extern "C"
#include "BLO_readfile.h"
#include "BLO_readblenfile.h"
#include "IMB_imbuf.h"
+#include "BKE_text.h"
int GHOST_HACK_getFirstFile(char buf[]);
@@ -195,6 +196,17 @@ void usage(const char* program)
printf(" anaglyph (Red-Blue glasses)\n");
printf(" vinterlace (Vertical interlace for autostereo display)\n");
printf(" depending on the type of stereo you want\n\n");
+ printf(" -D: start player in dome mode\n");
+ printf(" --Optional parameters--\n");
+ printf(" angle = field of view in degrees\n");
+ printf(" tilt = tilt angle in degrees\n");
+ printf(" warpdata = a file to use for warping the image (absolute path)\n");
+ printf(" mode: fisheye (Fisheye)\n");
+ printf(" truncatedfront (Front-Truncated)\n");
+ printf(" truncatedrear (Rear-Truncated)\n");
+ printf(" cubemap (Cube Map)\n");
+ printf(" sphericalpanoramic (Spherical Panoramic)\n");
+ printf(" depending on the type of dome you are using\n\n");
#ifndef _WIN32
printf(" -i: parent windows ID \n\n");
#endif
@@ -310,6 +322,12 @@ int main(int argc, char** argv)
RAS_IRasterizer::StereoMode stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
bool stereoWindow = false;
bool stereoParFound = false;
+ int stereoFlag = STEREO_NOSTEREO;
+ int domeFov = -1;
+ int domeTilt = -200;
+ int domeMode = 0;
+ char* domeWarp = NULL;
+ Text *domeText = NULL;
int windowLeft = 100;
int windowTop = 100;
int windowWidth = 640;
@@ -525,30 +543,31 @@ int main(int argc, char** argv)
stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
// only the hardware pageflip method needs a stereo window
- if(!strcmp(argv[i], "hwpageflip")) {
+ else if(!strcmp(argv[i], "hwpageflip")) {
stereomode = RAS_IRasterizer::RAS_STEREO_QUADBUFFERED;
stereoWindow = true;
}
- if(!strcmp(argv[i], "syncdoubling"))
+ else if(!strcmp(argv[i], "syncdoubling"))
stereomode = RAS_IRasterizer::RAS_STEREO_ABOVEBELOW;
- if(!strcmp(argv[i], "anaglyph"))
+ else if(!strcmp(argv[i], "anaglyph"))
stereomode = RAS_IRasterizer::RAS_STEREO_ANAGLYPH;
- if(!strcmp(argv[i], "sidebyside"))
+ else if(!strcmp(argv[i], "sidebyside"))
stereomode = RAS_IRasterizer::RAS_STEREO_SIDEBYSIDE;
- if(!strcmp(argv[i], "vinterlace"))
+ else if(!strcmp(argv[i], "vinterlace"))
stereomode = RAS_IRasterizer::RAS_STEREO_VINTERLACE;
#if 0
// future stuff
- if(strcmp(argv[i], "stencil")
+ else if(!strcmp(argv[i], "stencil")
stereomode = RAS_STEREO_STENCIL;
#endif
i++;
stereoParFound = true;
+ stereoFlag = STEREO_ENABLED;
}
else
{
@@ -556,8 +575,49 @@ int main(int argc, char** argv)
printf("error: too few options for stereo argument.\n");
}
break;
+ case 'D':
+ stereoFlag = STEREO_DOME;
+ stereomode = RAS_IRasterizer::RAS_STEREO_DOME;
+ i++;
+ if ((i + 1) < argc)
+ {
+ if(!strcmp(argv[i], "angle")){
+ i++;
+ domeFov = atoi(argv[i++]);
+ }
+ if(!strcmp(argv[i], "tilt")){
+ i++;
+ domeTilt = atoi(argv[i++]);
+ }
+ if(!strcmp(argv[i], "warpdata")){
+ i++;
+ domeWarp = argv[i++];
+ }
+ if(!strcmp(argv[i], "mode")){
+ i++;
+ if(!strcmp(argv[i], "fisheye"))
+ domeMode = DOME_FISHEYE;
+
+ else if(!strcmp(argv[i], "truncatedfront"))
+ domeMode = DOME_TRUNCATED_FRONT;
+
+ else if(!strcmp(argv[i], "truncatedrear"))
+ domeMode = DOME_TRUNCATED_REAR;
+
+ else if(!strcmp(argv[i], "cubemap"))
+ domeMode = DOME_ENVMAP;
+
+ else if(!strcmp(argv[i], "sphericalpanoramic"))
+ domeMode = DOME_PANORAM_SPH;
+
+ else
+ printf("error: %s is not a valid dome mode.\n", argv[i]);
+ }
+ i++;
+ }
+ break;
default:
- printf("Unkown argument: %s\n", argv[i++]);
+ printf("Unknown argument: %s\n", argv[i++]);
break;
}
}
@@ -714,6 +774,28 @@ int main(int argc, char** argv)
stereoWindow = true;
}
}
+ else
+ scene->gm.stereoflag = STEREO_ENABLED;
+
+ if (stereoFlag == STEREO_DOME){
+ stereomode = RAS_IRasterizer::RAS_STEREO_DOME;
+ scene->gm.stereoflag = STEREO_DOME;
+ if (domeFov > 89)
+ scene->gm.dome.angle = domeFov;
+ if (domeTilt > -180)
+ scene->gm.dome.tilt = domeTilt;
+ if (domeMode > 0)
+ scene->gm.dome.mode = domeMode;
+ if (domeWarp)
+ {
+ //XXX to do: convert relative to absolute path
+ domeText= add_text(domeWarp, "");
+ if(!domeText)
+ printf("error: invalid warpdata text file - %s\n", domeWarp);
+ else
+ scene->gm.dome.warptext = domeText;
+ }
+ }
// GPG_Application app (system, maggie, startscenename);
app.SetGameEngineData(maggie, scene, argc, argv); /* this argc cant be argc_py_clamped, since python uses it */
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index af30d32a0aa..18ae80c78c3 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -154,7 +154,7 @@ KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system)
m_showBackground(false),
m_show_debug_properties(false),
- m_game2ipo(false),
+ m_animation_record(false),
// Default behavior is to hide the cursor every frame.
m_hideCursor(false),
@@ -398,7 +398,7 @@ void KX_KetsjiEngine::StartEngine(bool clearIpo)
m_maxPhysicsFrame = 5;
}
- if (m_game2ipo)
+ if (m_animation_record)
{
m_sceneconverter->ResetPhysicsObjectsAnimationIpo(clearIpo);
m_sceneconverter->WritePhysicsObjectToAnimationIpo(m_currentFrame);
@@ -657,7 +657,7 @@ else
scene->UpdateParents(m_frameTime);
- if (m_game2ipo)
+ if (m_animation_record)
{
m_sceneconverter->WritePhysicsObjectToAnimationIpo(++m_currentFrame);
}
@@ -1334,7 +1334,7 @@ void KX_KetsjiEngine::StopEngine()
if (m_bInitialized)
{
- if (m_game2ipo)
+ if (m_animation_record)
{
// printf("TestHandlesPhysicsObjectToAnimationIpo\n");
m_sceneconverter->TestHandlesPhysicsObjectToAnimationIpo();
@@ -1734,10 +1734,10 @@ void KX_KetsjiEngine::SetUseFixedTime(bool bUseFixedTime)
}
-void KX_KetsjiEngine::SetGame2IpoMode(bool game2ipo,int startFrame)
+void KX_KetsjiEngine::SetAnimRecordMode(bool animation_record, int startFrame)
{
- m_game2ipo = game2ipo;
- if (game2ipo)
+ m_animation_record = animation_record;
+ if (animation_record)
{
//when recording physics keyframes, always run at a fixed framerate
m_bFixedTime = true;
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h
index 96ca092c8c1..a6ca5fb6519 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.h
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h
@@ -170,7 +170,7 @@ private:
bool m_show_debug_properties;
/** record physics into keyframes */
- bool m_game2ipo;
+ bool m_animation_record;
/** Hide cursor every frame? */
bool m_hideCursor;
@@ -208,7 +208,7 @@ public:
PyObject* GetPyNamespace(){return m_pythondictionary;};
#endif
void SetSceneConverter(KX_ISceneConverter* sceneconverter);
- void SetGame2IpoMode(bool game2ipo,int startFrame);
+ void SetAnimRecordMode(bool animation_record, int startFrame);
RAS_IRasterizer* GetRasterizer(){return m_rasterizer;};
RAS_ICanvas* GetCanvas(){return m_canvas;};
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index 562d67bcca2..0275c3e1f7a 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -504,7 +504,6 @@ static PyObject* gPyAddScene(PyObject*, PyObject* args)
{
char* name;
int overlay = 1;
- KX_Scene* scene = NULL;
if (!PyArg_ParseTuple(args, "s|i:addScene", &name , &overlay))
return NULL;
diff --git a/source/gameengine/Rasterizer/RAS_CameraData.h b/source/gameengine/Rasterizer/RAS_CameraData.h
index addbd2b73b6..01f8d491a35 100644
--- a/source/gameengine/Rasterizer/RAS_CameraData.h
+++ b/source/gameengine/Rasterizer/RAS_CameraData.h
@@ -51,12 +51,12 @@ struct RAS_CameraData
m_clipstart(clipstart),
m_clipend(clipend),
m_perspective(perspective),
- m_focallength(focallength),
m_viewport(viewport),
m_viewportleft(viewportleft),
m_viewportbottom(viewportbottom),
m_viewportright(viewportright),
- m_viewporttop(viewporttop)
+ m_viewporttop(viewporttop),
+ m_focallength(focallength)
{
}
};
diff --git a/source/gameengine/VideoTexture/CMakeLists.txt b/source/gameengine/VideoTexture/CMakeLists.txt
index 1268d887eee..eaee00753ff 100644
--- a/source/gameengine/VideoTexture/CMakeLists.txt
+++ b/source/gameengine/VideoTexture/CMakeLists.txt
@@ -42,6 +42,7 @@ SET(INC
../../../source/blender/editors/include
../../../source/blender/imbuf
../../../source/blender/python
+ ../../../source/blender/python/generic
../../../source/blender/gpu
../../../source/kernel/gen_system
../../../intern/string
diff --git a/source/gameengine/VideoTexture/Exception.cpp b/source/gameengine/VideoTexture/Exception.cpp
index 8b4808ffbe9..124c8ae27d8 100644
--- a/source/gameengine/VideoTexture/Exception.cpp
+++ b/source/gameengine/VideoTexture/Exception.cpp
@@ -202,6 +202,8 @@ void registerAllExceptions(void)
errNFoundDesc.registerDesc();
MaterialNotAvailDesc.registerDesc();
ImageSizesNotMatchDesc.registerDesc();
+ ImageHasExportsDesc.registerDesc();
+ InvalidColorChannelDesc.registerDesc();
SceneInvalidDesc.registerDesc();
CameraInvalidDesc.registerDesc();
ObserverInvalidDesc.registerDesc();
diff --git a/source/gameengine/VideoTexture/Exception.h b/source/gameengine/VideoTexture/Exception.h
index 4a57a7f20e4..74dc444c0a9 100644
--- a/source/gameengine/VideoTexture/Exception.h
+++ b/source/gameengine/VideoTexture/Exception.h
@@ -200,6 +200,8 @@ protected:
extern ExpDesc MaterialNotAvailDesc;
extern ExpDesc ImageSizesNotMatchDesc;
+extern ExpDesc ImageHasExportsDesc;
+extern ExpDesc InvalidColorChannelDesc;
extern ExpDesc SceneInvalidDesc;
extern ExpDesc CameraInvalidDesc;
extern ExpDesc ObserverInvalidDesc;
diff --git a/source/gameengine/VideoTexture/ImageBase.cpp b/source/gameengine/VideoTexture/ImageBase.cpp
index 1c5425c932c..908aa5ddd5e 100644
--- a/source/gameengine/VideoTexture/ImageBase.cpp
+++ b/source/gameengine/VideoTexture/ImageBase.cpp
@@ -21,6 +21,10 @@ http://www.gnu.org/copyleft/lesser.txt.
*/
#include "ImageBase.h"
+extern "C" {
+#include "BGL.h"
+}
+#include "GL/glew.h"
#include <vector>
#include <string.h>
@@ -32,7 +36,9 @@ http://www.gnu.org/copyleft/lesser.txt.
#include "Exception.h"
-
+#if (defined(WIN32) || defined(WIN64)) && !defined(FREE_WINDOWS)
+#define strcasecmp _stricmp
+#endif
// ImageBase class implementation
@@ -42,6 +48,7 @@ m_avail(false), m_scale(false), m_scaleChange(false), m_flip(false),
m_staticSources(staticSrc), m_pyfilter(NULL)
{
m_size[0] = m_size[1] = 0;
+ m_exports = 0;
}
@@ -161,6 +168,11 @@ void ImageBase::setFilter (PyFilter * filt)
m_pyfilter = filt;
}
+ExceptionID ImageHasExports;
+ExceptionID InvalidColorChannel;
+
+ExpDesc ImageHasExportsDesc (ImageHasExports, "Image has exported buffers, cannot resize");
+ExpDesc InvalidColorChannelDesc (InvalidColorChannel, "Invalid or too many color channels specified. At most 4 values within R, G, B, A, 0, 1");
// initialize image data
void ImageBase::init (short width, short height)
@@ -175,6 +187,9 @@ void ImageBase::init (short width, short height)
// if sizes differ
if (width != m_size[0] || height != m_size[1])
{
+ if (m_exports > 0)
+ THRWEXCP(ImageHasExports,S_OK);
+
// new buffer size
unsigned int newSize = width * height;
// if new buffer is larger than previous
@@ -352,6 +367,12 @@ void Image_dealloc (PyImage * self)
// release object attributes
if (self->m_image != NULL)
{
+ if (self->m_image->m_exports > 0)
+ {
+ PyErr_SetString(PyExc_SystemError,
+ "deallocated Image object has exported buffers");
+ PyErr_Print();
+ }
// if release requires deleting of object, do it
if (self->m_image->release())
delete self->m_image;
@@ -360,17 +381,88 @@ void Image_dealloc (PyImage * self)
}
// get image data
-PyObject * Image_getImage (PyImage * self, void * closure)
+PyObject * Image_getImage (PyImage * self, char * mode)
{
try
{
- // get image
unsigned int * image = self->m_image->getImage();
- return Py_BuildValue("s#", image, self->m_image->getBuffSize());
+ if (image)
+ {
+ // build BGL buffer
+ int dimensions = self->m_image->getBuffSize();
+ Buffer * buffer;
+ if (mode == NULL || !strcasecmp(mode, "RGBA"))
+ {
+ buffer = BGL_MakeBuffer( GL_BYTE, 1, &dimensions, image);
+ }
+ else
+ {
+ int i, c, ncolor, pixels;
+ int offset[4];
+ unsigned char *s, *d;
+ // scan the mode to get the channels requested, no more than 4
+ for (i=ncolor=0; mode[i] != 0 && ncolor < 4; i++)
+ {
+ switch (toupper(mode[i]))
+ {
+ case 'R':
+ offset[ncolor++] = 0;
+ break;
+ case 'G':
+ offset[ncolor++] = 1;
+ break;
+ case 'B':
+ offset[ncolor++] = 2;
+ break;
+ case 'A':
+ offset[ncolor++] = 3;
+ break;
+ case '0':
+ offset[ncolor++] = -1;
+ break;
+ case '1':
+ offset[ncolor++] = -2;
+ break;
+ // if you add more color code, change the switch further down
+ default:
+ THRWEXCP(InvalidColorChannel,S_OK);
+ }
+ }
+ if (mode[i] != 0) {
+ THRWEXCP(InvalidColorChannel,S_OK);
+ }
+ // first get the number of pixels
+ pixels = dimensions / 4;
+ // multiple by the number of channels, each is one byte
+ dimensions = pixels * ncolor;
+ // get an empty buffer
+ buffer = BGL_MakeBuffer( GL_BYTE, 1, &dimensions, NULL);
+ // and fill it
+ for (i=0, d=(unsigned char*)buffer->buf.asbyte, s=(unsigned char*)image;
+ i<pixels;
+ ++i, d+=ncolor, s+=4)
+ {
+ for (c=0; c<ncolor; c++)
+ {
+ switch (offset[c])
+ {
+ case 0: d[c] = s[0]; break;
+ case 1: d[c] = s[1]; break;
+ case 2: d[c] = s[2]; break;
+ case 3: d[c] = s[3]; break;
+ case -1: d[c] = 0; break;
+ case -2: d[c] = 0xFF; break;
+ }
+ }
+ }
+ }
+ return (PyObject*)buffer;
+ }
}
catch (Exception & exp)
{
exp.report();
+ return NULL;
}
Py_RETURN_NONE;
}
@@ -533,3 +625,73 @@ int Image_setFilter (PyImage * self, PyObject * value, void * closure)
// return success
return 0;
}
+PyObject * Image_valid(PyImage * self, void * closure)
+{
+ if (self->m_image->isImageAvailable())
+ {
+ Py_RETURN_TRUE;
+ }
+ else
+ {
+ Py_RETURN_FALSE;
+ }
+}
+
+int Image_getbuffer(PyImage *self, Py_buffer *view, int flags)
+{
+ unsigned int * image;
+ int ret;
+
+ try
+ {
+ // can throw in case of resize
+ image = self->m_image->getImage();
+ }
+ catch (Exception & exp)
+ {
+ // cannot return -1, this creates a crash in Python, for now we will just return an empty buffer
+ //exp.report();
+ //return -1;
+ goto error;
+ }
+
+ if (!image)
+ {
+ // same remark, see above
+ //PyErr_SetString(PyExc_BufferError, "Image buffer is not available");
+ //return -1;
+ goto error;
+ }
+ if (view == NULL)
+ {
+ self->m_image->m_exports++;
+ return 0;
+ }
+ ret = PyBuffer_FillInfo(view, (PyObject*)self, image, self->m_image->getBuffSize(), 0, flags);
+ if (ret >= 0)
+ self->m_image->m_exports++;
+ return ret;
+
+error:
+ // Return a empty buffer to avoid a crash in Python 3.1
+ // The bug is fixed in Python SVN 77916, as soon as the python revision used by Blender is
+ // updated, you can simply return -1 and set the error
+ static char* buf = "";
+ ret = PyBuffer_FillInfo(view, (PyObject*)self, buf, 0, 0, flags);
+ if (ret >= 0)
+ self->m_image->m_exports++;
+ return ret;
+
+}
+
+void Image_releaseBuffer(PyImage *self, Py_buffer *buffer)
+{
+ self->m_image->m_exports--;
+}
+
+PyBufferProcs imageBufferProcs =
+{
+ (getbufferproc)Image_getbuffer,
+ (releasebufferproc)Image_releaseBuffer
+};
+
diff --git a/source/gameengine/VideoTexture/ImageBase.h b/source/gameengine/VideoTexture/ImageBase.h
index 70b1929b91d..43a56290bee 100644
--- a/source/gameengine/VideoTexture/ImageBase.h
+++ b/source/gameengine/VideoTexture/ImageBase.h
@@ -53,6 +53,9 @@ public:
/// release contained objects, if returns true, object should be deleted
virtual bool release (void);
+ /// is an image available
+ bool isImageAvailable(void)
+ { return m_avail; }
/// get image
unsigned int * getImage (unsigned int texId = 0, double timestamp=-1.0);
/// get image size
@@ -85,6 +88,9 @@ public:
/// calculate size (nearest power of 2)
static short calcSize (short size);
+ /// number of buffer pointing to m_image, public because not handled by this class
+ int m_exports;
+
protected:
/// image buffer
unsigned int * m_image;
@@ -295,8 +301,6 @@ private:
ImageSource (void) {}
};
-
-
// list of python image types
extern PyTypeList pyImageTypes;
@@ -320,7 +324,7 @@ PyObject * Image_allocNew (PyTypeObject * type, PyObject * args, PyObject * kwds
void Image_dealloc (PyImage * self);
// get image data
-PyObject * Image_getImage (PyImage * self, void * closure);
+PyObject * Image_getImage (PyImage * self, char * mode);
// get image size
PyObject * Image_getSize (PyImage * self, void * closure);
// refresh image - invalidate current content
@@ -344,6 +348,9 @@ PyObject * Image_setSource (PyImage * self, PyObject * args);
PyObject * Image_getFilter (PyImage * self, void * closure);
// set pixel filter object
int Image_setFilter (PyImage * self, PyObject * value, void * closure);
-
+// check if a buffer can be extracted
+PyObject * Image_valid(PyImage * self, void * closure);
+// for buffer access to PyImage objects
+extern PyBufferProcs imageBufferProcs;
#endif
diff --git a/source/gameengine/VideoTexture/ImageBuff.cpp b/source/gameengine/VideoTexture/ImageBuff.cpp
index eccac9d9f89..3e9e7af6c07 100644
--- a/source/gameengine/VideoTexture/ImageBuff.cpp
+++ b/source/gameengine/VideoTexture/ImageBuff.cpp
@@ -26,7 +26,7 @@ http://www.gnu.org/copyleft/lesser.txt.
#include <structmember.h>
#include "ImageBuff.h"
-
+#include "Exception.h"
#include "ImageBase.h"
#include "FilterSource.h"
@@ -34,6 +34,7 @@ http://www.gnu.org/copyleft/lesser.txt.
extern "C" {
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
+#include "BGL.h"
};
// default filter
@@ -42,6 +43,41 @@ FilterRGB24 defFilter;
// forward declaration;
extern PyTypeObject ImageBuffType;
+static int ImageBuff_init (PyObject * pySelf, PyObject * args, PyObject * kwds)
+{
+ short width = -1;
+ short height = -1;
+ unsigned char color = 0;
+ PyObject *py_scale = Py_False;
+ ImageBuff *image;
+
+ PyImage * self = reinterpret_cast<PyImage*>(pySelf);
+ // create source object
+ if (self->m_image != NULL)
+ delete self->m_image;
+ image = new ImageBuff();
+ self->m_image = image;
+
+ if (PyArg_ParseTuple(args, "hh|bO!:ImageBuff", &width, &height, &color, &PyBool_Type, &py_scale))
+ {
+ // initialize image buffer
+ image->setScale(py_scale == Py_True);
+ image->clear(width, height, color);
+ }
+ else
+ {
+ // check if at least one argument was passed
+ if (width != -1 || height != -1)
+ // yes and they didn't match => it's an error
+ return -1;
+ // empty argument list is okay
+ PyErr_Clear();
+ }
+ // initialization succeded
+ return 0;
+
+}
+
ImageBuff::~ImageBuff (void)
{
if (m_imbuf)
@@ -73,6 +109,34 @@ void ImageBuff::load (unsigned char * img, short width, short height)
m_avail = true;
}
+void ImageBuff::clear (short width, short height, unsigned char color)
+{
+ unsigned char *p;
+ int size;
+
+ // loading a new buffer implies to reset the imbuf if any, because the size may change
+ if (m_imbuf)
+ {
+ IMB_freeImBuf(m_imbuf);
+ m_imbuf = NULL;
+ }
+ // initialize image buffer
+ init(width, height);
+ // the width/height may be different due to scaling
+ size = (m_size[0] * m_size[1]);
+ // initialize memory with color for all channels
+ memset(m_image, color, size*4);
+ // and change the alpha channel
+ p = &((unsigned char*)m_image)[3];
+ for (size; size>0; size--)
+ {
+ *p = 0xFF;
+ p += 4;
+ }
+ // image is available
+ m_avail = true;
+}
+
// img must point to a array of RGBA data of size width*height
void ImageBuff::plot (unsigned char * img, short width, short height, short x, short y, short mode)
{
@@ -137,7 +201,7 @@ static bool testPyBuffer(Py_buffer* buffer, int width, int height, unsigned int
}
if (buffer->len != width*height*pixsize)
{
- PyErr_SetString(PyExc_ValueError, "Buffer hasn't correct size");
+ PyErr_SetString(PyExc_ValueError, "Buffer hasn't the correct size");
return false;
}
// multi dimension are ok as long as there is no hole in the memory
@@ -160,43 +224,91 @@ static bool testPyBuffer(Py_buffer* buffer, int width, int height, unsigned int
return true;
}
+static bool testBGLBuffer(Buffer* buffer, int width, int height, unsigned int pixsize)
+{
+ unsigned int size = BGL_typeSize(buffer->type);
+ for (int i=0; i<buffer->ndimensions; i++)
+ {
+ size *= buffer->dimensions[i];
+ }
+ if (size != width*height*pixsize)
+ {
+ PyErr_SetString(PyExc_ValueError, "Buffer hasn't the correct size");
+ return false;
+ }
+ return true;
+}
+
+
// load image
static PyObject * load (PyImage * self, PyObject * args)
{
// parameters: string image buffer, its size, width, height
Py_buffer buffer;
+ Buffer *bglBuffer;
short width;
short height;
+ unsigned int pixSize;
+
+ // calc proper buffer size
+ // use pixel size from filter
+ if (self->m_image->getFilter() != NULL)
+ pixSize = self->m_image->getFilter()->m_filter->firstPixelSize();
+ else
+ pixSize = defFilter.firstPixelSize();
+
// parse parameters
if (!PyArg_ParseTuple(args, "s*hh:load", &buffer, &width, &height))
{
- // report error
- return NULL;
+ PyErr_Clear();
+ // check if it is BGL buffer
+ if (!PyArg_ParseTuple(args, "O!hh:load", &BGL_bufferType, &bglBuffer, &width, &height))
+ {
+ // report error
+ return NULL;
+ }
+ else
+ {
+ if (testBGLBuffer(bglBuffer, width, height, pixSize))
+ {
+ try
+ {
+ // if correct, load image
+ getImageBuff(self)->load((unsigned char*)bglBuffer->buf.asvoid, width, height);
+ }
+ catch (Exception & exp)
+ {
+ exp.report();
+ }
+ }
+ }
}
- // else check buffer size
else
{
- // calc proper buffer size
- unsigned int pixSize;
- // use pixel size from filter
- if (self->m_image->getFilter() != NULL)
- pixSize = self->m_image->getFilter()->m_filter->firstPixelSize();
- else
- pixSize = defFilter.firstPixelSize();
// check if buffer size is correct
if (testPyBuffer(&buffer, width, height, pixSize))
{
- // if correct, load image
- getImageBuff(self)->load((unsigned char*)buffer.buf, width, height);
+ try
+ {
+ // if correct, load image
+ getImageBuff(self)->load((unsigned char*)buffer.buf, width, height);
+ }
+ catch (Exception & exp)
+ {
+ exp.report();
+ }
}
PyBuffer_Release(&buffer);
}
+ if (PyErr_Occurred())
+ return NULL;
Py_RETURN_NONE;
}
static PyObject * plot (PyImage * self, PyObject * args)
{
PyImage * other;
+ Buffer* bglBuffer;
Py_buffer buffer;
//unsigned char * buff;
//unsigned int buffSize;
@@ -214,17 +326,31 @@ static PyObject * plot (PyImage * self, PyObject * args)
getImageBuff(self)->plot((unsigned char*)buffer.buf, width, height, x, y, mode);
}
PyBuffer_Release(&buffer);
+ if (PyErr_Occurred())
+ return NULL;
Py_RETURN_NONE;
}
PyErr_Clear();
// try the other format
- if (!PyArg_ParseTuple(args, "O!hh|h:plot", &ImageBuffType, &other, &x, &y, &mode))
+ if (PyArg_ParseTuple(args, "O!hh|h:plot", &ImageBuffType, &other, &x, &y, &mode))
{
- PyErr_SetString(PyExc_TypeError, "Expecting ImageBuff or string,width,height as first arguments, postion x, y and mode and last arguments");
+ getImageBuff(self)->plot(getImageBuff(other), x, y, mode);
+ Py_RETURN_NONE;
+ }
+ PyErr_Clear();
+ // try the last format (BGL buffer)
+ if (!PyArg_ParseTuple(args, "O!hhhh|h:plot", &BGL_bufferType, &bglBuffer, &width, &height, &x, &y, &mode))
+ {
+ PyErr_SetString(PyExc_TypeError, "Expecting ImageBuff or Py buffer or BGL buffer as first argument; width, height next; postion x, y and mode as last arguments");
return NULL;
}
- getImageBuff(self)->plot(getImageBuff(other), x, y, mode);
- Py_RETURN_NONE;
+ if (testBGLBuffer(bglBuffer, width, height, 4))
+ {
+ getImageBuff(self)->plot((unsigned char*)bglBuffer->buf.asvoid, width, height, x, y, mode);
+ }
+ if (PyErr_Occurred())
+ return NULL;
+ Py_RETURN_NONE;
}
// methods structure
@@ -237,6 +363,7 @@ static PyMethodDef imageBuffMethods[] =
// attributes structure
static PyGetSetDef imageBuffGetSets[] =
{ // attributes from ImageBase class
+ {(char*)"valid", (getter)Image_valid, NULL, (char*)"bool to tell if an image is available", NULL},
{(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL},
{(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL},
{(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL},
@@ -267,7 +394,7 @@ PyTypeObject ImageBuffType =
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
+ &imageBufferProcs, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"Image source from image buffer", /* tp_doc */
0, /* tp_traverse */
@@ -284,7 +411,7 @@ PyTypeObject ImageBuffType =
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
- (initproc)Image_init<ImageBuff>, /* tp_init */
+ (initproc)ImageBuff_init, /* tp_init */
0, /* tp_alloc */
Image_allocNew, /* tp_new */
};
diff --git a/source/gameengine/VideoTexture/ImageBuff.h b/source/gameengine/VideoTexture/ImageBuff.h
index e18edc44288..271647361e8 100644
--- a/source/gameengine/VideoTexture/ImageBuff.h
+++ b/source/gameengine/VideoTexture/ImageBuff.h
@@ -44,6 +44,8 @@ public:
/// load image from buffer
void load (unsigned char * img, short width, short height);
+ /// clear image with color set on RGB channels and 0xFF on alpha channel
+ void clear (short width, short height, unsigned char color);
/// plot image from extern RGBA buffer to image at position x,y using one of IMB_BlendMode
void plot (unsigned char * img, short width, short height, short x, short y, short mode);
diff --git a/source/gameengine/VideoTexture/ImageMix.cpp b/source/gameengine/VideoTexture/ImageMix.cpp
index a4a61e7f55a..7b304dda3ce 100644
--- a/source/gameengine/VideoTexture/ImageMix.cpp
+++ b/source/gameengine/VideoTexture/ImageMix.cpp
@@ -154,6 +154,7 @@ static PyMethodDef imageMixMethods[] =
// attributes structure
static PyGetSetDef imageMixGetSets[] =
{ // attributes from ImageBase class
+ {(char*)"valid", (getter)Image_valid, NULL, (char*)"bool to tell if an image is available", NULL},
{(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL},
{(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL},
{(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL},
@@ -184,7 +185,7 @@ PyTypeObject ImageMixType =
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
+ &imageBufferProcs, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"Image mixer", /* tp_doc */
0, /* tp_traverse */
diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp
index 0a01ce11a0e..7580563a74f 100644
--- a/source/gameengine/VideoTexture/ImageRender.cpp
+++ b/source/gameengine/VideoTexture/ImageRender.cpp
@@ -365,6 +365,7 @@ static PyGetSetDef imageRenderGetSets[] =
{(char*)"alpha", (getter)ImageViewport_getAlpha, (setter)ImageViewport_setAlpha, (char*)"use alpha in texture", NULL},
{(char*)"whole", (getter)ImageViewport_getWhole, (setter)ImageViewport_setWhole, (char*)"use whole viewport to render", NULL},
// attributes from ImageBase class
+ {(char*)"valid", (getter)Image_valid, NULL, (char*)"bool to tell if an image is available", NULL},
{(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL},
{(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL},
{(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL},
@@ -395,7 +396,7 @@ PyTypeObject ImageRenderType =
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
+ &imageBufferProcs, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"Image source from render", /* tp_doc */
0, /* tp_traverse */
@@ -526,6 +527,7 @@ static PyGetSetDef imageMirrorGetSets[] =
{(char*)"alpha", (getter)ImageViewport_getAlpha, (setter)ImageViewport_setAlpha, (char*)"use alpha in texture", NULL},
{(char*)"whole", (getter)ImageViewport_getWhole, (setter)ImageViewport_setWhole, (char*)"use whole viewport to render", NULL},
// attributes from ImageBase class
+ {(char*)"valid", (getter)Image_valid, NULL, (char*)"bool to tell if an image is available", NULL},
{(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL},
{(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL},
{(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL},
@@ -652,8 +654,7 @@ ImageRender::ImageRender (KX_Scene * scene, KX_GameObject * observer, KX_GameObj
}
// compute rotation matrix between local coord and mirror coord
// to match camera orientation, we select mirror z = -normal, y = up, x = y x z
- copy_v3_v3(mirrorMat[2], mirrorNormal);
- mul_v3_fl(mirrorMat[2], -1.0f);
+ negate_v3_v3(mirrorMat[2], mirrorNormal);
copy_v3_v3(mirrorMat[1], mirrorUp);
cross_v3_v3v3(mirrorMat[0], mirrorMat[1], mirrorMat[2]);
// transpose to make it a orientation matrix from local space to mirror space
@@ -729,7 +730,7 @@ PyTypeObject ImageMirrorType =
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
+ &imageBufferProcs, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"Image source from mirror", /* tp_doc */
0, /* tp_traverse */
diff --git a/source/gameengine/VideoTexture/ImageViewport.cpp b/source/gameengine/VideoTexture/ImageViewport.cpp
index c39173a96f9..5a4e8af1b0c 100644
--- a/source/gameengine/VideoTexture/ImageViewport.cpp
+++ b/source/gameengine/VideoTexture/ImageViewport.cpp
@@ -177,8 +177,16 @@ int ImageViewport_setWhole (PyImage * self, PyObject * value, void * closure)
PyErr_SetString(PyExc_TypeError, "The value must be a bool");
return -1;
}
- // set whole
- if (self->m_image != NULL) getImageViewport(self)->setWhole(value == Py_True);
+ try
+ {
+ // set whole, can throw in case of resize and buffer exports
+ if (self->m_image != NULL) getImageViewport(self)->setWhole(value == Py_True);
+ }
+ catch (Exception & exp)
+ {
+ exp.report();
+ return -1;
+ }
// success
return 0;
}
@@ -257,7 +265,16 @@ int ImageViewport_setCaptureSize (PyImage * self, PyObject * value, void * closu
short(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 0))),
short(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 1)))
};
- getImageViewport(self)->setCaptureSize(size);
+ try
+ {
+ // can throw in case of resize and buffer exports
+ getImageViewport(self)->setCaptureSize(size);
+ }
+ catch (Exception & exp)
+ {
+ exp.report();
+ return -1;
+ }
// success
return 0;
}
@@ -277,6 +294,7 @@ static PyGetSetDef imageViewportGetSets[] =
{(char*)"capsize", (getter)ImageViewport_getCaptureSize, (setter)ImageViewport_setCaptureSize, (char*)"size of viewport area being captured", NULL},
{(char*)"alpha", (getter)ImageViewport_getAlpha, (setter)ImageViewport_setAlpha, (char*)"use alpha in texture", NULL},
// attributes from ImageBase class
+ {(char*)"valid", (getter)Image_valid, NULL, (char*)"bool to tell if an image is available", NULL},
{(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL},
{(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL},
{(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL},
@@ -307,7 +325,7 @@ PyTypeObject ImageViewportType =
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
+ &imageBufferProcs, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"Image source from viewport", /* tp_doc */
0, /* tp_traverse */
diff --git a/source/gameengine/VideoTexture/Makefile b/source/gameengine/VideoTexture/Makefile
index 90457df720f..1cb147860cd 100644
--- a/source/gameengine/VideoTexture/Makefile
+++ b/source/gameengine/VideoTexture/Makefile
@@ -41,6 +41,7 @@ CPPFLAGS += -I$(NAN_GLEW)/include
CPPFLAGS += -I$(OPENGL_HEADERS)
CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
CPPFLAGS += -I../../blender/python
+CPPFLAGS += -I../../blender/python/generic
CPPFLAGS += -I$(NAN_STRING)/include
CPPFLAGS += -I$(NAN_MOTO)/include
CPPFLAGS += -I../Rasterizer/RAS_OpenGLRasterizer
diff --git a/source/gameengine/VideoTexture/SConscript b/source/gameengine/VideoTexture/SConscript
index 59c311d5240..70c7dfc6d3a 100644
--- a/source/gameengine/VideoTexture/SConscript
+++ b/source/gameengine/VideoTexture/SConscript
@@ -10,7 +10,7 @@ incs += ' #source/gameengine/GameLogic #source/gameengine/SceneGraph #source/gam
incs += ' #source/gameengine/Rasterizer/RAS_OpenGLRasterizer'
incs += ' #source/gameengine/BlenderRoutines'
incs += ' #source/blender/editors/include #source/blender/blenlib #source/blender/blenkernel'
-incs += ' #source/blender/makesdna #source/blender/imbuf #source/blender/python'
+incs += ' #source/blender/makesdna #source/blender/imbuf #source/blender/python #source/blender/python/generic'
incs += ' #source/blender/gpu #source/kernel/gen_system #intern/string #intern/moto/include'
incs += ' #intern/guardedalloc #extern/glew/include'
diff --git a/source/gameengine/VideoTexture/Texture.cpp b/source/gameengine/VideoTexture/Texture.cpp
index f59b92409f5..b8ed38c435d 100644
--- a/source/gameengine/VideoTexture/Texture.cpp
+++ b/source/gameengine/VideoTexture/Texture.cpp
@@ -455,7 +455,7 @@ PyTypeObject TextureType =
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
+ &imageBufferProcs, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"Texture objects", /* tp_doc */
0, /* tp_traverse */
diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp
index 4c87b1764d6..6f7e9b82911 100644
--- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp
+++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp
@@ -304,6 +304,10 @@ void *VideoFFmpeg::cacheThread(void *data)
CachePacket *cachePacket;
bool endOfFile = false;
int frameFinished = 0;
+ double timeBase = av_q2d(video->m_formatCtx->streams[video->m_videoStream]->time_base);
+ int64_t startTs = video->m_formatCtx->streams[video->m_videoStream]->start_time;
+ if (startTs == AV_NOPTS_VALUE)
+ startTs = 0;
while (!video->m_stopThread)
{
@@ -390,7 +394,8 @@ void *VideoFFmpeg::cacheThread(void *data)
currentFrame->frame->data,
currentFrame->frame->linesize);
// move frame to queue, this frame is necessarily the next one
- currentFrame->framePosition = ++video->m_curPosition;
+ video->m_curPosition = (long)((cachePacket->packet.dts-startTs) * (video->m_baseFrameRate*timeBase) + 0.5);
+ currentFrame->framePosition = video->m_curPosition;
pthread_mutex_lock(&video->m_cacheMutex);
BLI_addtail(&video->m_frameCacheBase, currentFrame);
pthread_mutex_unlock(&video->m_cacheMutex);
@@ -723,28 +728,23 @@ void VideoFFmpeg::setFrameRate (float rate)
// image calculation
-void VideoFFmpeg::calcImage (unsigned int texId, double ts)
-{
- loadFrame(ts);
-}
-
-
// load frame from video
-void VideoFFmpeg::loadFrame (double ts)
+void VideoFFmpeg::calcImage (unsigned int texId, double ts)
{
if (m_status == SourcePlaying)
{
// get actual time
double startTime = PIL_check_seconds_timer();
double actTime;
- if (m_isFile && ts >= 0.0)
+ // timestamp passed from audio actuators can sometimes be slightly negative
+ if (m_isFile && ts >= -0.5)
{
// allow setting timestamp only when not streaming
actTime = ts;
- if (m_eof && actTime * actFrameRate() < m_lastFrame)
+ if (actTime * actFrameRate() < m_lastFrame)
{
- // user is asking to rewind while the playback is already finished in the cache.
- // we must clean the cache otherwise the eof condition will prevent any further reading.
+ // user is asking to rewind, force a cache clear to make sure we will do a seek
+ // note that this does not decrement m_repeat if ts didn't reach m_range[1]
stopCache();
}
}
@@ -846,8 +846,9 @@ AVFrame *VideoFFmpeg::grabFrame(long position)
int frameFinished;
int posFound = 1;
bool frameLoaded = false;
- long long targetTs = 0;
+ int64_t targetTs = 0;
CacheFrame *frame;
+ int64_t dts = 0;
if (m_cacheStarted)
{
@@ -881,6 +882,10 @@ AVFrame *VideoFFmpeg::grabFrame(long position)
{
return frame->frame;
}
+ if (frame->framePosition > position)
+ // this can happen after rewind if the seek didn't find the first frame
+ // the frame in the buffer is ahead of time, just leave it there
+ return NULL;
// this frame is not useful, release it
pthread_mutex_lock(&m_cacheMutex);
BLI_remlink(&m_frameCacheBase, frame);
@@ -888,6 +893,11 @@ AVFrame *VideoFFmpeg::grabFrame(long position)
pthread_mutex_unlock(&m_cacheMutex);
} while (true);
}
+ double timeBase = av_q2d(m_formatCtx->streams[m_videoStream]->time_base);
+ int64_t startTs = m_formatCtx->streams[m_videoStream]->start_time;
+ if (startTs == AV_NOPTS_VALUE)
+ startTs = 0;
+
// come here when there is no cache or cache has been stopped
// locate the frame, by seeking if necessary (seeking is only possible for files)
if (m_isFile)
@@ -907,7 +917,9 @@ AVFrame *VideoFFmpeg::grabFrame(long position)
m_frame, &frameFinished,
packet.data, packet.size);
if (frameFinished)
- m_curPosition++;
+ {
+ m_curPosition = (long)((packet.dts-startTs) * (m_baseFrameRate*timeBase) + 0.5);
+ }
}
av_free_packet(&packet);
if (position == m_curPosition+1)
@@ -917,16 +929,13 @@ AVFrame *VideoFFmpeg::grabFrame(long position)
// if the position is not in preseek, do a direct jump
if (position != m_curPosition + 1)
{
- double timeBase = av_q2d(m_formatCtx->streams[m_videoStream]->time_base);
int64_t pos = (int64_t)((position - m_preseek) / (m_baseFrameRate*timeBase));
- int64_t startTs = m_formatCtx->streams[m_videoStream]->start_time;
int seekres;
if (pos < 0)
pos = 0;
- if (startTs != AV_NOPTS_VALUE)
- pos += startTs;
+ pos += startTs;
if (position <= m_curPosition || !m_eof)
{
@@ -958,9 +967,7 @@ AVFrame *VideoFFmpeg::grabFrame(long position)
}
}
// this is the timestamp of the frame we're looking for
- targetTs = (int64_t)(position / (m_baseFrameRate * timeBase));
- if (startTs != AV_NOPTS_VALUE)
- targetTs += startTs;
+ targetTs = (int64_t)(position / (m_baseFrameRate * timeBase)) + startTs;
posFound = 0;
avcodec_flush_buffers(m_codecCtx);
@@ -984,14 +991,17 @@ AVFrame *VideoFFmpeg::grabFrame(long position)
avcodec_decode_video(m_codecCtx,
m_frame, &frameFinished,
packet.data, packet.size);
-
+ // remember dts to compute exact frame number
+ dts = packet.dts;
if (frameFinished && !posFound)
{
- if (packet.dts >= targetTs)
+ if (dts >= targetTs)
+ {
posFound = 1;
+ }
}
- if(frameFinished && posFound == 1)
+ if (frameFinished && posFound == 1)
{
AVFrame * input = m_frame;
@@ -1034,7 +1044,7 @@ AVFrame *VideoFFmpeg::grabFrame(long position)
m_eof = m_isFile && !frameLoaded;
if (frameLoaded)
{
- m_curPosition = position;
+ m_curPosition = (long)((dts-startTs) * (m_baseFrameRate*timeBase) + 0.5);
if (m_isThreaded)
{
// normal case for file: first locate, then start cache
@@ -1162,6 +1172,7 @@ static PyGetSetDef videoGetSets[] =
{(char*)"repeat", (getter)Video_getRepeat, (setter)Video_setRepeat, (char*)"repeat count, -1 for infinite repeat", NULL},
{(char*)"framerate", (getter)Video_getFrameRate, (setter)Video_setFrameRate, (char*)"frame rate", NULL},
// attributes from ImageBase class
+ {(char*)"valid", (getter)Image_valid, NULL, (char*)"bool to tell if an image is available", NULL},
{(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL},
{(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL},
{(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL},
@@ -1193,7 +1204,7 @@ PyTypeObject VideoFFmpegType =
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
+ &imageBufferProcs, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"FFmpeg video source", /* tp_doc */
0, /* tp_traverse */
@@ -1282,6 +1293,7 @@ static PyGetSetDef imageGetSets[] =
{ // methods from VideoBase class
{(char*)"status", (getter)Video_getStatus, NULL, (char*)"video status", NULL},
// attributes from ImageBase class
+ {(char*)"valid", (getter)Image_valid, NULL, (char*)"bool to tell if an image is available", NULL},
{(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL},
{(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL},
{(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL},
@@ -1311,7 +1323,7 @@ PyTypeObject ImageFFmpegType =
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
+ &imageBufferProcs, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"FFmpeg image source", /* tp_doc */
0, /* tp_traverse */
diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.h b/source/gameengine/VideoTexture/VideoFFmpeg.h
index 355c58c496b..b9bf69039c7 100644
--- a/source/gameengine/VideoTexture/VideoFFmpeg.h
+++ b/source/gameengine/VideoTexture/VideoFFmpeg.h
@@ -159,9 +159,6 @@ protected:
/// image calculation
virtual void calcImage (unsigned int texId, double ts);
- /// load frame from video
- void loadFrame (double ts);
-
/// set actual position
void setPositions (void);
diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp
index 998d63506b0..01e783edc10 100644
--- a/source/gameengine/VideoTexture/blendVideoTex.cpp
+++ b/source/gameengine/VideoTexture/blendVideoTex.cpp
@@ -86,7 +86,8 @@ static PyObject * imageToArray (PyObject * self, PyObject *args)
{
// parameter is Image object
PyObject * pyImg;
- if (!PyArg_ParseTuple(args, "O:imageToArray", &pyImg) || !pyImageTypes.in(pyImg->ob_type))
+ char *mode = NULL;
+ if (!PyArg_ParseTuple(args, "O|s:imageToArray", &pyImg, &mode) || !pyImageTypes.in(pyImg->ob_type))
{
// if object is incorect, report error
PyErr_SetString(PyExc_TypeError, "VideoTexture.imageToArray(image): The value must be a image source object");
@@ -94,16 +95,7 @@ static PyObject * imageToArray (PyObject * self, PyObject *args)
}
// get image structure
PyImage * img = reinterpret_cast<PyImage*>(pyImg);
- // create array object
- unsigned int * imgBuff = img->m_image->getImage();
- // if image is available, convert it to array
- if (imgBuff != NULL)
- // Nasty problem here: the image buffer is an array of integers
- // in the processor endian format. The user must take care of that in the script.
- // Need to find an elegant solution to this problem
- return Py_BuildValue("s#", imgBuff, img->m_image->getBuffSize());
- // otherwise return None
- Py_RETURN_NONE;
+ return Image_getImage(img, mode);
}
@@ -113,7 +105,7 @@ static PyMethodDef moduleMethods[] =
{"materialID", getMaterialID, METH_VARARGS, "Gets object's Blender Material ID"},
{"getLastError", getLastError, METH_NOARGS, "Gets last error description"},
{"setLogFile", setLogFile, METH_VARARGS, "Sets log file name"},
- {"imageToArray", imageToArray, METH_VARARGS, "get array from image source"},
+ {"imageToArray", imageToArray, METH_VARARGS, "get buffer from image source, color channels are selectable"},
{NULL} /* Sentinel */
};
diff --git a/source/nan_definitions.mk b/source/nan_definitions.mk
index 7727e2352a1..a3748ae247f 100644
--- a/source/nan_definitions.mk
+++ b/source/nan_definitions.mk
@@ -109,7 +109,7 @@ ifndef CONFIG_GUESS
else
export NAN_FFMPEG ?= $(LCGDIR)/ffmpeg
ifeq ($(OS), darwin)
- export NAN_FFMPEGLIBS ?= $(NAN_FFMPEG)/lib/libavformat.a $(NAN_FFMPEG)/lib/libavcodec.a $(NAN_FFMPEG)/lib/libswscale.a $(NAN_FFMPEG)/lib/libavutil.a $(NAN_FFMPEG)/lib/libavdevice.a $(NAN_FFMPEG)/lib/libmp3lame.a $(NAN_FFMPEG)/lib/libx264.a $(NAN_FFMPEG)/lib/libxvidcore.a
+ export NAN_FFMPEGLIBS ?= $(NAN_FFMPEG)/lib/libavformat.a $(NAN_FFMPEG)/lib/libavcodec.a $(NAN_FFMPEG)/lib/libswscale.a $(NAN_FFMPEG)/lib/libavutil.a $(NAN_FFMPEG)/lib/libavdevice.a $(NAN_FFMPEG)/lib/libmp3lame.a $(NAN_FFMPEG)/lib/libx264.a $(NAN_FFMPEG)/lib/libxvidcore.a $(NAN_FFMPEG)/lib/libtheora.a $(NAN_FFMPEG)/lib/libtheoradec.a $(NAN_FFMPEG)/lib/libtheoraenc.a $(NAN_FFMPEG)/lib/libvorbis.a $(NAN_FFMPEG)/lib/libvorbisenc.a $(NAN_FFMPEG)/lib/libvorbisfile.a $(NAN_FFMPEG)/lib/libogg.a -lbz2
else
export NAN_FFMPEGLIBS ?= $(NAN_FFMPEG)/lib/libavformat.a $(NAN_FFMPEG)/lib/libavcodec.a $(NAN_FFMPEG)/lib/libswscale.a $(NAN_FFMPEG)/lib/libavutil.a $(NAN_FFMPEG)/lib/libavdevice.a
endif