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--extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp25
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h2
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp138
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.h11
-rw-r--r--intern/audaspace/FX/AUD_AccumulatorFactory.cpp49
-rw-r--r--intern/audaspace/FX/AUD_AccumulatorFactory.h59
-rw-r--r--intern/audaspace/FX/AUD_AccumulatorReader.cpp99
-rw-r--r--intern/audaspace/FX/AUD_AccumulatorReader.h75
-rw-r--r--intern/audaspace/FX/AUD_ButterworthFactory.cpp49
-rw-r--r--intern/audaspace/FX/AUD_ButterworthFactory.h59
-rw-r--r--intern/audaspace/FX/AUD_ButterworthReader.cpp124
-rw-r--r--intern/audaspace/FX/AUD_ButterworthReader.h83
-rw-r--r--intern/audaspace/FX/AUD_DelayReader.cpp21
-rw-r--r--intern/audaspace/FX/AUD_DoubleReader.cpp9
-rw-r--r--intern/audaspace/FX/AUD_EnvelopeFactory.cpp58
-rw-r--r--intern/audaspace/FX/AUD_EnvelopeFactory.h82
-rw-r--r--intern/audaspace/FX/AUD_EnvelopeReader.cpp86
-rw-r--r--intern/audaspace/FX/AUD_EnvelopeReader.h84
-rw-r--r--intern/audaspace/FX/AUD_FaderReader.cpp59
-rw-r--r--intern/audaspace/FX/AUD_FaderReader.h6
-rw-r--r--intern/audaspace/FX/AUD_HighpassFactory.cpp51
-rw-r--r--intern/audaspace/FX/AUD_HighpassFactory.h66
-rw-r--r--intern/audaspace/FX/AUD_HighpassReader.cpp116
-rw-r--r--intern/audaspace/FX/AUD_HighpassReader.h83
-rw-r--r--intern/audaspace/FX/AUD_LoopReader.cpp12
-rw-r--r--intern/audaspace/FX/AUD_LowpassFactory.cpp51
-rw-r--r--intern/audaspace/FX/AUD_LowpassFactory.h66
-rw-r--r--intern/audaspace/FX/AUD_LowpassReader.cpp115
-rw-r--r--intern/audaspace/FX/AUD_LowpassReader.h83
-rw-r--r--intern/audaspace/FX/AUD_PitchFactory.h2
-rw-r--r--intern/audaspace/FX/AUD_RectifyReader.cpp37
-rw-r--r--intern/audaspace/FX/AUD_RectifyReader.h6
-rw-r--r--intern/audaspace/FX/AUD_ReverseReader.cpp18
-rw-r--r--intern/audaspace/FX/AUD_SquareFactory.cpp57
-rw-r--r--intern/audaspace/FX/AUD_SquareFactory.h (renamed from intern/audaspace/SDL/AUD_SDLMixer.h)54
-rw-r--r--intern/audaspace/FX/AUD_SquareReader.cpp63
-rw-r--r--intern/audaspace/FX/AUD_SquareReader.h65
-rw-r--r--intern/audaspace/FX/AUD_SumFactory.cpp43
-rw-r--r--intern/audaspace/FX/AUD_SumFactory.h (renamed from intern/audaspace/SDL/AUD_SDLMixerFactory.h)21
-rw-r--r--intern/audaspace/FX/AUD_SumReader.cpp68
-rw-r--r--intern/audaspace/FX/AUD_SumReader.h64
-rw-r--r--intern/audaspace/FX/AUD_VolumeFactory.h2
-rw-r--r--intern/audaspace/FX/AUD_VolumeReader.cpp32
-rw-r--r--intern/audaspace/FX/AUD_VolumeReader.h6
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.cpp112
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.h13
-rw-r--r--intern/audaspace/SConscript3
-rw-r--r--intern/audaspace/SDL/AUD_SDLDevice.cpp8
-rw-r--r--intern/audaspace/SDL/AUD_SDLDevice.h3
-rw-r--r--intern/audaspace/SDL/AUD_SDLMixer.cpp83
-rw-r--r--intern/audaspace/SDL/AUD_SDLMixerReader.cpp216
-rw-r--r--intern/audaspace/SDL/AUD_SDLMixerReader.h128
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleFactory.cpp8
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleFactory.h7
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleReader.cpp25
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleReader.h8
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp195
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGReader.h13
-rw-r--r--intern/audaspace/fftw/AUD_BandPassFactory.cpp12
-rw-r--r--intern/audaspace/fftw/AUD_BandPassReader.cpp8
-rw-r--r--intern/audaspace/intern/AUD_Buffer.cpp8
-rw-r--r--intern/audaspace/intern/AUD_Buffer.h2
-rw-r--r--intern/audaspace/intern/AUD_BufferReader.cpp6
-rw-r--r--intern/audaspace/intern/AUD_C-API.cpp88
-rw-r--r--intern/audaspace/intern/AUD_C-API.h16
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperFactory.cpp6
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperFactory.h6
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperReader.cpp15
-rw-r--r--intern/audaspace/intern/AUD_ConverterFactory.cpp8
-rw-r--r--intern/audaspace/intern/AUD_ConverterFactory.h6
-rw-r--r--intern/audaspace/intern/AUD_ConverterFunctions.cpp172
-rw-r--r--intern/audaspace/intern/AUD_ConverterFunctions.h125
-rw-r--r--intern/audaspace/intern/AUD_ConverterReader.cpp195
-rw-r--r--intern/audaspace/intern/AUD_ConverterReader.h4
-rw-r--r--intern/audaspace/intern/AUD_FloatMixer.h100
-rw-r--r--intern/audaspace/intern/AUD_IDevice.h2
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleFactory.cpp (renamed from intern/audaspace/SDL/AUD_SDLMixerFactory.cpp)40
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleFactory.h44
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleReader.cpp133
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleReader.h94
-rw-r--r--intern/audaspace/intern/AUD_Mixer.cpp (renamed from intern/audaspace/intern/AUD_FloatMixer.cpp)44
-rw-r--r--intern/audaspace/intern/AUD_Mixer.h (renamed from intern/audaspace/intern/AUD_IMixer.h)76
-rw-r--r--intern/audaspace/intern/AUD_MixerFactory.cpp10
-rw-r--r--intern/audaspace/intern/AUD_MixerFactory.h12
-rw-r--r--intern/audaspace/intern/AUD_NULLDevice.cpp2
-rw-r--r--intern/audaspace/intern/AUD_NULLDevice.h4
-rw-r--r--intern/audaspace/intern/AUD_ReadDevice.cpp12
-rw-r--r--intern/audaspace/intern/AUD_ReadDevice.h4
-rw-r--r--intern/audaspace/intern/AUD_SinusReader.cpp19
-rw-r--r--intern/audaspace/intern/AUD_SoftwareDevice.cpp39
-rw-r--r--intern/audaspace/intern/AUD_SoftwareDevice.h18
-rw-r--r--intern/audaspace/intern/AUD_Space.h36
-rw-r--r--intern/audaspace/intern/AUD_StreamBufferFactory.cpp4
-rw-r--r--intern/audaspace/jack/AUD_JackDevice.cpp9
-rw-r--r--intern/audaspace/jack/AUD_JackDevice.h2
-rw-r--r--intern/audaspace/make/msvc_9_0/audaspace.vcproj158
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileReader.cpp61
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileReader.h5
-rw-r--r--intern/ghost/GHOST_C-api.h5
-rw-r--r--intern/ghost/GHOST_ISystem.h18
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp5
-rw-r--r--intern/ghost/intern/GHOST_SystemCarbon.cpp1
-rw-r--r--intern/ghost/intern/GHOST_SystemCarbon.h1
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.h19
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.mm28
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp2
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.h6
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp3
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.h1
-rw-r--r--intern/ghost/intern/GHOST_Window.cpp6
-rw-r--r--intern/ghost/intern/GHOST_Window.h23
-rw-r--r--intern/ghost/intern/GHOST_WindowCarbon.cpp3
-rw-r--r--intern/ghost/intern/GHOST_WindowCarbon.h3
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.h22
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.mm68
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp5
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.h4
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp29
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.h4
-rw-r--r--intern/ghost/intern/Makefile2
-rw-r--r--projectfiles_vc9/blender/editors/ED_editors.vcproj4
-rw-r--r--release/scripts/io/engine_render_pov.py2
-rw-r--r--release/scripts/io/export_3ds.py2
-rw-r--r--release/scripts/io/export_fbx.py7
-rw-r--r--release/scripts/io/export_obj.py29
-rw-r--r--release/scripts/io/export_ply.py4
-rw-r--r--release/scripts/io/export_x3d.py2
-rw-r--r--release/scripts/io/import_scene_3ds.py9
-rw-r--r--release/scripts/io/import_scene_obj.py9
-rw-r--r--release/scripts/io/netrender/__init__.py3
-rw-r--r--release/scripts/io/netrender/balancing.py74
-rw-r--r--release/scripts/io/netrender/client.py6
-rw-r--r--release/scripts/io/netrender/master.py200
-rw-r--r--release/scripts/io/netrender/master_html.py127
-rw-r--r--release/scripts/io/netrender/netrender.css13
-rw-r--r--release/scripts/io/netrender/netrender.js103
-rw-r--r--release/scripts/io/netrender/operators.py21
-rw-r--r--release/scripts/io/netrender/slave.py36
-rw-r--r--release/scripts/io/netrender/ui.py204
-rw-r--r--release/scripts/io/netrender/utils.py38
-rw-r--r--release/scripts/modules/bpy/__init__.py6
-rw-r--r--release/scripts/modules/bpy/app.py26
-rw-r--r--release/scripts/modules/bpy/ops.py11
-rw-r--r--release/scripts/modules/bpy_types.py31
-rw-r--r--release/scripts/modules/retopo.py215
-rw-r--r--release/scripts/modules/rigify/__init__.py20
-rw-r--r--release/scripts/modules/rigify/arm_biped_generic.py102
-rw-r--r--release/scripts/modules/rigify/copy.py42
-rw-r--r--release/scripts/modules/rigify/finger_curl.py83
-rw-r--r--release/scripts/modules/rigify/leg_biped_generic.py116
-rw-r--r--release/scripts/modules/rigify/leg_quadruped_generic.py16
-rw-r--r--release/scripts/modules/rigify/neck_flex.py67
-rw-r--r--release/scripts/modules/rigify/palm_curl.py68
-rw-r--r--release/scripts/modules/rigify/spine_pivot_flex.py75
-rw-r--r--release/scripts/modules/rigify_utils.py18
-rw-r--r--release/scripts/modules/rna_info.py11
-rw-r--r--release/scripts/modules/rna_prop_ui.py13
-rw-r--r--release/scripts/op/add_mesh_torus.py4
-rw-r--r--release/scripts/op/object.py14
-rw-r--r--release/scripts/op/screen_play_rendered_anim.py50
-rw-r--r--release/scripts/op/wm.py35
-rw-r--r--release/scripts/ui/properties_data_armature.py10
-rw-r--r--release/scripts/ui/properties_data_bone.py33
-rw-r--r--release/scripts/ui/properties_data_camera.py8
-rw-r--r--release/scripts/ui/properties_data_curve.py8
-rw-r--r--release/scripts/ui/properties_data_lamp.py8
-rw-r--r--release/scripts/ui/properties_data_lattice.py8
-rw-r--r--release/scripts/ui/properties_data_mesh.py26
-rw-r--r--release/scripts/ui/properties_data_metaball.py9
-rw-r--r--release/scripts/ui/properties_material.py8
-rw-r--r--release/scripts/ui/properties_object.py37
-rw-r--r--release/scripts/ui/properties_object_constraint.py10
-rw-r--r--release/scripts/ui/properties_particle.py11
-rw-r--r--release/scripts/ui/properties_physics_field.py1
-rw-r--r--release/scripts/ui/properties_render.py54
-rw-r--r--release/scripts/ui/properties_scene.py8
-rw-r--r--release/scripts/ui/properties_texture.py45
-rw-r--r--release/scripts/ui/properties_world.py8
-rw-r--r--release/scripts/ui/space_dopesheet.py3
-rw-r--r--release/scripts/ui/space_image.py1
-rw-r--r--release/scripts/ui/space_info.py2
-rw-r--r--release/scripts/ui/space_nla.py5
-rw-r--r--release/scripts/ui/space_node.py1
-rw-r--r--release/scripts/ui/space_sequencer.py9
-rw-r--r--release/scripts/ui/space_userpref.py577
-rw-r--r--release/scripts/ui/space_view3d.py3
-rw-r--r--release/scripts/ui/space_view3d_toolbar.py39
-rw-r--r--source/Makefile21
-rw-r--r--source/blender/Makefile6
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h13
-rw-r--r--source/blender/blenkernel/BKE_anim.h20
-rw-r--r--source/blender/blenkernel/BKE_brush.h8
-rw-r--r--source/blender/blenkernel/BKE_colortools.h9
-rw-r--r--source/blender/blenkernel/BKE_fcurve.h34
-rw-r--r--source/blender/blenkernel/BKE_global.h1
-rw-r--r--source/blender/blenkernel/BKE_idprop.h5
-rw-r--r--source/blender/blenkernel/BKE_image.h7
-rw-r--r--source/blender/blenkernel/BKE_node.h1
-rw-r--r--source/blender/blenkernel/BKE_object.h2
-rw-r--r--source/blender/blenkernel/BKE_particle.h1
-rw-r--r--source/blender/blenkernel/BKE_sound.h2
-rw-r--r--source/blender/blenkernel/BKE_utildefines.h2
-rw-r--r--source/blender/blenkernel/BKE_writeavi.h7
-rw-r--r--source/blender/blenkernel/BKE_writeffmpeg.h1
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c221
-rw-r--r--source/blender/blenkernel/intern/action.c37
-rw-r--r--source/blender/blenkernel/intern/anim.c329
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c26
-rw-r--r--source/blender/blenkernel/intern/armature.c15
-rw-r--r--source/blender/blenkernel/intern/boids.c20
-rw-r--r--source/blender/blenkernel/intern/brush.c101
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c18
-rw-r--r--source/blender/blenkernel/intern/colortools.c122
-rw-r--r--source/blender/blenkernel/intern/constraint.c57
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c49
-rw-r--r--source/blender/blenkernel/intern/fcurve.c654
-rw-r--r--source/blender/blenkernel/intern/gpencil.c6
-rw-r--r--source/blender/blenkernel/intern/idprop.c25
-rw-r--r--source/blender/blenkernel/intern/image.c22
-rw-r--r--source/blender/blenkernel/intern/ipo.c170
-rw-r--r--source/blender/blenkernel/intern/library.c4
-rw-r--r--source/blender/blenkernel/intern/material.c3
-rw-r--r--source/blender/blenkernel/intern/modifier.c242
-rw-r--r--source/blender/blenkernel/intern/node.c48
-rw-r--r--source/blender/blenkernel/intern/object.c54
-rw-r--r--source/blender/blenkernel/intern/particle.c4
-rw-r--r--source/blender/blenkernel/intern/particle_system.c6
-rw-r--r--source/blender/blenkernel/intern/sequencer.c18
-rw-r--r--source/blender/blenkernel/intern/sound.c4
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c3
-rw-r--r--source/blender/blenkernel/intern/texture.c52
-rw-r--r--source/blender/blenkernel/intern/writeavi.c25
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c7
-rw-r--r--source/blender/blenlib/BLI_bpath.h12
-rw-r--r--source/blender/blenlib/BLI_math_color.h3
-rw-r--r--source/blender/blenlib/BLI_math_geom.h4
-rw-r--r--source/blender/blenlib/BLI_math_vector.h2
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c4
-rw-r--r--source/blender/blenlib/intern/bpath.c152
-rw-r--r--source/blender/blenlib/intern/math_color.c20
-rw-r--r--source/blender/blenlib/intern/math_geom.c129
-rw-r--r--source/blender/blenlib/intern/math_vector_inline.c12
-rw-r--r--source/blender/blenlib/intern/pbvh.c11
-rw-r--r--source/blender/blenloader/intern/readfile.c243
-rw-r--r--source/blender/blenloader/intern/writefile.c64
-rw-r--r--source/blender/collada/DocumentExporter.cpp686
-rw-r--r--source/blender/collada/DocumentImporter.cpp39
-rw-r--r--source/blender/collada/Makefile42
-rw-r--r--source/blender/editors/CMakeLists.txt5
-rw-r--r--source/blender/editors/animation/anim_channels_defines.c204
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c26
-rw-r--r--source/blender/editors/animation/anim_markers.c11
-rw-r--r--source/blender/editors/animation/drivers.c6
-rw-r--r--source/blender/editors/animation/keyframes_edit.c5
-rw-r--r--source/blender/editors/animation/keyframes_general.c21
-rw-r--r--source/blender/editors/armature/poseSlide.c37
-rw-r--r--source/blender/editors/armature/poseobject.c1
-rw-r--r--source/blender/editors/gpencil/gpencil_buttons.c25
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c86
-rw-r--r--source/blender/editors/include/ED_anim_api.h8
-rw-r--r--source/blender/editors/include/ED_mesh.h2
-rw-r--r--source/blender/editors/include/ED_view3d.h5
-rw-r--r--source/blender/editors/include/UI_interface.h18
-rw-r--r--source/blender/editors/include/UI_interface_icons.h4
-rw-r--r--source/blender/editors/include/UI_resources.h2
-rw-r--r--source/blender/editors/interface/interface.c7
-rw-r--r--source/blender/editors/interface/interface_anim.c2
-rw-r--r--source/blender/editors/interface/interface_handlers.c75
-rw-r--r--source/blender/editors/interface/interface_icons.c26
-rw-r--r--source/blender/editors/interface/interface_intern.h8
-rw-r--r--source/blender/editors/interface/interface_layout.c26
-rw-r--r--source/blender/editors/interface/interface_ops.c140
-rw-r--r--source/blender/editors/interface/interface_regions.c733
-rw-r--r--source/blender/editors/interface/interface_templates.c178
-rw-r--r--source/blender/editors/interface/interface_widgets.c149
-rw-r--r--source/blender/editors/interface/resources.c20
-rw-r--r--source/blender/editors/interface/view2d_ops.c12
-rw-r--r--source/blender/editors/mesh/editmesh_add.c2
-rw-r--r--source/blender/editors/mesh/editmesh_mods.c23
-rw-r--r--source/blender/editors/mesh/mesh_intern.h2
-rw-r--r--source/blender/editors/mesh/mesh_ops.c2
-rw-r--r--source/blender/editors/mesh/meshtools.c202
-rw-r--r--source/blender/editors/object/Makefile2
-rw-r--r--source/blender/editors/object/SConscript8
-rw-r--r--source/blender/editors/object/object_bake.c341
-rw-r--r--source/blender/editors/object/object_edit.c28
-rw-r--r--source/blender/editors/object/object_group.c3
-rw-r--r--source/blender/editors/object/object_intern.h4
-rw-r--r--source/blender/editors/object/object_modifier.c1
-rw-r--r--source/blender/editors/object/object_ops.c3
-rw-r--r--source/blender/editors/object/object_relations.c6
-rw-r--r--source/blender/editors/object/object_shapekey.c2
-rw-r--r--source/blender/editors/object/object_transform.c1
-rw-r--r--source/blender/editors/physics/Makefile8
-rw-r--r--source/blender/editors/physics/particle_edit.c67
-rw-r--r--source/blender/editors/render/render_preview.c4
-rw-r--r--source/blender/editors/screen/CMakeLists.txt5
-rw-r--r--source/blender/editors/screen/Makefile5
-rw-r--r--source/blender/editors/screen/area.c8
-rw-r--r--source/blender/editors/screen/screen_ops.c39
-rw-r--r--source/blender/editors/screen/screendump.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c60
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h2
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c20
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c5
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c9
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c79
-rw-r--r--source/blender/editors/sound/sound_ops.c2
-rw-r--r--source/blender/editors/space_action/action_edit.c4
-rw-r--r--source/blender/editors/space_action/action_intern.h2
-rw-r--r--source/blender/editors/space_action/action_ops.c4
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c2
-rw-r--r--source/blender/editors/space_buttons/buttons_header.c2
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c11
-rw-r--r--source/blender/editors/space_console/console_intern.h1
-rw-r--r--source/blender/editors/space_console/console_ops.c38
-rw-r--r--source/blender/editors/space_console/space_console.c21
-rw-r--r--source/blender/editors/space_file/writeimage.c2
-rw-r--r--source/blender/editors/space_graph/Makefile10
-rw-r--r--source/blender/editors/space_graph/SConscript1
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c226
-rw-r--r--source/blender/editors/space_graph/graph_edit.c143
-rw-r--r--source/blender/editors/space_graph/graph_intern.h1
-rw-r--r--source/blender/editors/space_graph/graph_ops.c1
-rw-r--r--source/blender/editors/space_image/image_buttons.c2
-rw-r--r--source/blender/editors/space_image/image_draw.c2
-rw-r--r--source/blender/editors/space_image/image_ops.c6
-rw-r--r--source/blender/editors/space_image/space_image.c2
-rw-r--r--source/blender/editors/space_info/info_ops.c32
-rw-r--r--source/blender/editors/space_node/drawnode.c34
-rw-r--r--source/blender/editors/space_node/node_draw.c6
-rw-r--r--source/blender/editors/space_node/node_edit.c526
-rw-r--r--source/blender/editors/space_node/node_header.c13
-rw-r--r--source/blender/editors/space_node/node_intern.h2
-rw-r--r--source/blender/editors/space_node/node_ops.c4
-rw-r--r--source/blender/editors/space_node/node_select.c56
-rw-r--r--source/blender/editors/space_outliner/outliner.c24
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c10
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c51
-rw-r--r--source/blender/editors/space_text/space_text.c17
-rw-r--r--source/blender/editors/space_text/text_ops.c10
-rw-r--r--source/blender/editors/space_view3d/drawanimviz.c564
-rw-r--r--source/blender/editors/space_view3d/drawarmature.c17
-rw-r--r--source/blender/editors/space_view3d/drawobject.c551
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c97
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c199
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c18
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h13
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c12
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c11
-rw-r--r--source/blender/editors/space_view3d/view3d_toolbar.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c18
-rw-r--r--source/blender/editors/transform/transform.c35
-rw-r--r--source/blender/editors/transform/transform.h2
-rw-r--r--source/blender/editors/transform/transform_conversions.c7
-rw-r--r--source/blender/editors/transform/transform_generics.c5
-rw-r--r--source/blender/editors/transform/transform_ops.c36
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp2
-rw-r--r--source/blender/gpu/GPU_draw.h4
-rw-r--r--source/blender/gpu/intern/gpu_draw.c365
-rw-r--r--source/blender/imbuf/intern/amiga.c1
-rw-r--r--source/blender/imbuf/intern/bmp.c1
-rw-r--r--source/blender/imbuf/intern/dds/dds_api.cpp1
-rw-r--r--source/blender/imbuf/intern/divers.c75
-rw-r--r--source/blender/imbuf/intern/hamx.c1
-rw-r--r--source/blender/imbuf/intern/iris.c1
-rw-r--r--source/blender/imbuf/intern/jpeg.c1
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp3
-rw-r--r--source/blender/imbuf/intern/png.c1
-rw-r--r--source/blender/imbuf/intern/radiance_hdr.c1
-rw-r--r--source/blender/imbuf/intern/readimage.c1
-rw-r--r--source/blender/imbuf/intern/targa.c1
-rw-r--r--source/blender/imbuf/intern/tiff.c1
-rw-r--r--source/blender/makesdna/DNA_ID.h4
-rw-r--r--source/blender/makesdna/DNA_action_types.h133
-rw-r--r--source/blender/makesdna/DNA_anim_types.h106
-rw-r--r--source/blender/makesdna/DNA_armature_types.h7
-rw-r--r--source/blender/makesdna/DNA_brush_types.h8
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h23
-rw-r--r--source/blender/makesdna/DNA_gpencil_types.h7
-rw-r--r--source/blender/makesdna/DNA_lamp_types.h2
-rw-r--r--source/blender/makesdna/DNA_material_types.h2
-rw-r--r--source/blender/makesdna/DNA_node_types.h8
-rw-r--r--source/blender/makesdna/DNA_object_force.h3
-rw-r--r--source/blender/makesdna/DNA_object_types.h7
-rw-r--r--source/blender/makesdna/DNA_scene_types.h2
-rw-r--r--source/blender/makesdna/DNA_screen_types.h18
-rw-r--r--source/blender/makesdna/DNA_space_types.h1
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h14
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h6
-rw-r--r--source/blender/makesdna/intern/Makefile4
-rw-r--r--source/blender/makesrna/RNA_access.h9
-rw-r--r--source/blender/makesrna/RNA_define.h1
-rw-r--r--source/blender/makesrna/RNA_types.h1
-rw-r--r--source/blender/makesrna/intern/Makefile4
-rw-r--r--source/blender/makesrna/intern/makesrna.c63
-rw-r--r--source/blender/makesrna/intern/rna_ID.c1
-rw-r--r--source/blender/makesrna/intern/rna_access.c91
-rw-r--r--source/blender/makesrna/intern/rna_action.c4
-rw-r--r--source/blender/makesrna/intern/rna_animviz.c350
-rw-r--r--source/blender/makesrna/intern/rna_armature_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_brush.c37
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c174
-rw-r--r--source/blender/makesrna/intern/rna_define.c18
-rw-r--r--source/blender/makesrna/intern/rna_fcurve.c164
-rw-r--r--source/blender/makesrna/intern/rna_gpencil.c24
-rw-r--r--source/blender/makesrna/intern/rna_image.c24
-rw-r--r--source/blender/makesrna/intern/rna_image_api.c36
-rw-r--r--source/blender/makesrna/intern/rna_internal.h35
-rw-r--r--source/blender/makesrna/intern/rna_internal_types.h5
-rw-r--r--source/blender/makesrna/intern/rna_key.c8
-rw-r--r--source/blender/makesrna/intern/rna_main.c67
-rw-r--r--source/blender/makesrna/intern/rna_main_api.c435
-rw-r--r--source/blender/makesrna/intern/rna_material.c9
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c22
-rw-r--r--source/blender/makesrna/intern/rna_mesh_api.c11
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c6
-rw-r--r--source/blender/makesrna/intern/rna_object.c19
-rw-r--r--source/blender/makesrna/intern/rna_object_api.c74
-rw-r--r--source/blender/makesrna/intern/rna_object_force.c6
-rw-r--r--source/blender/makesrna/intern/rna_pose.c17
-rw-r--r--source/blender/makesrna/intern/rna_scene.c82
-rw-r--r--source/blender/makesrna/intern/rna_scene_api.c24
-rw-r--r--source/blender/makesrna/intern/rna_screen.c9
-rw-r--r--source/blender/makesrna/intern/rna_sculpt_paint.c4
-rw-r--r--source/blender/makesrna/intern/rna_space.c16
-rw-r--r--source/blender/makesrna/intern/rna_texture.c2
-rw-r--r--source/blender/makesrna/intern/rna_ui_api.c14
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c37
-rw-r--r--source/blender/makesrna/intern/rna_wm.c107
-rw-r--r--source/blender/makesrna/intern/rna_wm_api.c29
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_image.c32
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_outputFile.c2
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_rgb.c2
-rw-r--r--source/blender/nodes/intern/SHD_nodes/SHD_rgb.c2
-rw-r--r--source/blender/python/generic/euler.c2
-rw-r--r--source/blender/python/generic/matrix.c25
-rw-r--r--source/blender/python/generic/quat.c2
-rw-r--r--source/blender/python/generic/vector.c2
-rw-r--r--source/blender/python/intern/bpy_driver.c69
-rw-r--r--source/blender/python/intern/bpy_interface.c3
-rw-r--r--source/blender/python/intern/bpy_operator.c6
-rw-r--r--source/blender/python/intern/bpy_operator_wrap.c570
-rw-r--r--source/blender/python/intern/bpy_operator_wrap.h4
-rw-r--r--source/blender/python/intern/bpy_rna.c411
-rw-r--r--source/blender/python/intern/bpy_rna.h3
-rw-r--r--source/blender/python/intern/bpy_util.c89
-rw-r--r--source/blender/python/intern/bpy_util.h10
-rw-r--r--source/blender/python/sphinx_doc_gen.py25
-rw-r--r--source/blender/quicktime/apple/Makefile6
-rw-r--r--source/blender/quicktime/apple/qtkit_export.m17
-rw-r--r--source/blender/quicktime/apple/quicktime_export.c6
-rw-r--r--source/blender/quicktime/apple/quicktime_import.c2
-rw-r--r--source/blender/quicktime/quicktime_export.h1
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h5
-rw-r--r--source/blender/render/extern/include/RE_shader_ext.h2
-rw-r--r--source/blender/render/intern/source/convertblender.c12
-rw-r--r--source/blender/render/intern/source/envmap.c2
-rw-r--r--source/blender/render/intern/source/pipeline.c131
-rw-r--r--source/blender/render/intern/source/rayshade.c7
-rw-r--r--source/blender/render/intern/source/rendercore.c34
-rw-r--r--source/blender/render/intern/source/shadeoutput.c2
-rw-r--r--source/blender/render/intern/source/texture.c3
-rw-r--r--source/blender/render/intern/source/volume_precache.c147
-rw-r--r--source/blender/render/intern/source/volumetric.c2
-rw-r--r--source/blender/windowmanager/CMakeLists.txt5
-rw-r--r--source/blender/windowmanager/WM_types.h5
-rw-r--r--source/blender/windowmanager/intern/Makefile4
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c2
-rw-r--r--source/blender/windowmanager/intern/wm_gesture.c65
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c78
-rw-r--r--source/blender/windowmanager/intern/wm_window.c6
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c18
-rw-r--r--source/darwin/Makefile6
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp17
-rw-r--r--source/gameengine/GamePlayer/common/CMakeLists.txt2
-rw-r--r--source/gameengine/GamePlayer/common/SConscript2
-rw-r--r--source/gameengine/GamePlayer/ghost/CMakeLists.txt2
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Application.cpp3
-rw-r--r--source/gameengine/GamePlayer/ghost/SConscript2
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp23
-rw-r--r--source/gameengine/PyDoc/Rasterizer.py4
-rw-r--r--source/nan_compile.mk68
-rw-r--r--source/nan_definitions.mk68
-rw-r--r--source/nan_link.mk18
-rw-r--r--tools/btools.py3
487 files changed, 14462 insertions, 7880 deletions
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
index 7159f552829..5c645f82a45 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
@@ -412,31 +412,6 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
// restore
collisionObject->internalSetTemporaryCollisionShape(saveCollisionShape);
}
- } else {
- if (collisionShape->isSoftBody()) {
- btSoftBody* softBody = static_cast<btSoftBody*>(collisionObject);
- btSoftBody::sRayCast softResult;
- if (softBody->rayTest(rayFromTrans.getOrigin(), rayToTrans.getOrigin(), softResult))
- {
- btCollisionWorld::LocalShapeInfo shapeInfo;
- shapeInfo.m_shapePart = 0;
- shapeInfo.m_triangleIndex = softResult.index;
- // get the normal
- btVector3 normal = softBody->m_faces[softResult.index].m_normal;
- btVector3 rayDir = rayToTrans.getOrigin() - rayFromTrans.getOrigin();
- if (normal.dot(rayDir) > 0) {
- // normal always point toward origin of the ray
- normal = -normal;
- }
- btCollisionWorld::LocalRayResult rayResult
- (collisionObject,
- &shapeInfo,
- normal,
- softResult.fraction);
- bool normalInWorldSpace = true;
- resultCallback.addSingleResult(rayResult,normalInWorldSpace);
- }
- }
}
}
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h
index 87f7137a55b..24343938e5c 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h
@@ -354,7 +354,7 @@ public:
/// rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback
/// This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback.
- void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const;
+ virtual void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const;
// convexTest performs a swept convex cast on all objects in the btCollisionWorld, and calls the resultCallback
// This allows for several queries: first hit, all hits, any hit, dependent on the value return by the callback.
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp b/extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp
index a0069b95145..982ec3e5eb3 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp
+++ b/extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp
@@ -22,6 +22,7 @@ subject to the following restrictions:
#include "btSoftBodyHelpers.h"
+//#define USE_BRUTEFORCE_RAYBROADPHASE 1
@@ -140,3 +141,140 @@ void btSoftRigidDynamicsWorld::debugDrawWorld()
}
}
}
+
+
+struct btSoftSingleRayCallback : public btBroadphaseRayCallback
+{
+ btVector3 m_rayFromWorld;
+ btVector3 m_rayToWorld;
+ btTransform m_rayFromTrans;
+ btTransform m_rayToTrans;
+ btVector3 m_hitNormal;
+
+ const btSoftRigidDynamicsWorld* m_world;
+ btCollisionWorld::RayResultCallback& m_resultCallback;
+
+ btSoftSingleRayCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld,const btSoftRigidDynamicsWorld* world,btCollisionWorld::RayResultCallback& resultCallback)
+ :m_rayFromWorld(rayFromWorld),
+ m_rayToWorld(rayToWorld),
+ m_world(world),
+ m_resultCallback(resultCallback)
+ {
+ m_rayFromTrans.setIdentity();
+ m_rayFromTrans.setOrigin(m_rayFromWorld);
+ m_rayToTrans.setIdentity();
+ m_rayToTrans.setOrigin(m_rayToWorld);
+
+ btVector3 rayDir = (rayToWorld-rayFromWorld);
+
+ rayDir.normalize ();
+ ///what about division by zero? --> just set rayDirection[i] to INF/1e30
+ m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
+ m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
+ m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
+ m_signs[0] = m_rayDirectionInverse[0] < 0.0;
+ m_signs[1] = m_rayDirectionInverse[1] < 0.0;
+ m_signs[2] = m_rayDirectionInverse[2] < 0.0;
+
+ m_lambda_max = rayDir.dot(m_rayToWorld-m_rayFromWorld);
+
+ }
+
+
+
+ virtual bool process(const btBroadphaseProxy* proxy)
+ {
+ ///terminate further ray tests, once the closestHitFraction reached zero
+ if (m_resultCallback.m_closestHitFraction == btScalar(0.f))
+ return false;
+
+ btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
+
+ //only perform raycast if filterMask matches
+ if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
+ {
+ //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
+ //btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
+#if 0
+#ifdef RECALCULATE_AABB
+ btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
+ collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
+#else
+ //getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax);
+ const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin;
+ const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax;
+#endif
+#endif
+ //btScalar hitLambda = m_resultCallback.m_closestHitFraction;
+ //culling already done by broadphase
+ //if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal))
+ {
+ m_world->rayTestSingle(m_rayFromTrans,m_rayToTrans,
+ collisionObject,
+ collisionObject->getCollisionShape(),
+ collisionObject->getWorldTransform(),
+ m_resultCallback);
+ }
+ }
+ return true;
+ }
+};
+
+void btSoftRigidDynamicsWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
+{
+ BT_PROFILE("rayTest");
+ /// use the broadphase to accelerate the search for objects, based on their aabb
+ /// and for each object with ray-aabb overlap, perform an exact ray test
+ btSoftSingleRayCallback rayCB(rayFromWorld,rayToWorld,this,resultCallback);
+
+#ifndef USE_BRUTEFORCE_RAYBROADPHASE
+ m_broadphasePairCache->rayTest(rayFromWorld,rayToWorld,rayCB);
+#else
+ for (int i=0;i<this->getNumCollisionObjects();i++)
+ {
+ rayCB.process(m_collisionObjects[i]->getBroadphaseHandle());
+ }
+#endif //USE_BRUTEFORCE_RAYBROADPHASE
+
+}
+
+
+void btSoftRigidDynamicsWorld::rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
+ btCollisionObject* collisionObject,
+ const btCollisionShape* collisionShape,
+ const btTransform& colObjWorldTransform,
+ RayResultCallback& resultCallback)
+{
+ if (collisionShape->isSoftBody()) {
+ btSoftBody* softBody = btSoftBody::upcast(collisionObject);
+ if (softBody) {
+ btSoftBody::sRayCast softResult;
+ if (softBody->rayTest(rayFromTrans.getOrigin(), rayToTrans.getOrigin(), softResult))
+ {
+ if (softResult.fraction<= resultCallback.m_closestHitFraction)
+ {
+ btCollisionWorld::LocalShapeInfo shapeInfo;
+ shapeInfo.m_shapePart = 0;
+ shapeInfo.m_triangleIndex = softResult.index;
+ // get the normal
+ btVector3 normal = softBody->m_faces[softResult.index].m_normal;
+ btVector3 rayDir = rayToTrans.getOrigin() - rayFromTrans.getOrigin();
+ if (normal.dot(rayDir) > 0) {
+ // normal must always point toward origin of the ray
+ normal = -normal;
+ }
+ btCollisionWorld::LocalRayResult rayResult
+ (collisionObject,
+ &shapeInfo,
+ normal,
+ softResult.fraction);
+ bool normalInWorldSpace = true;
+ resultCallback.addSingleResult(rayResult,normalInWorldSpace);
+ }
+ }
+ }
+ }
+ else {
+ btCollisionWorld::rayTestSingle(rayFromTrans,rayToTrans,collisionObject,collisionShape,colObjWorldTransform,resultCallback);
+ }
+}
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.h b/extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.h
index edb848e2481..14220ee7564 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.h
+++ b/extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.h
@@ -77,6 +77,17 @@ public:
return m_softBodies;
}
+ virtual void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const;
+
+ /// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest.
+ /// In a future implementation, we consider moving the ray test as a virtual method in btCollisionShape.
+ /// This allows more customization.
+ static void rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
+ btCollisionObject* collisionObject,
+ const btCollisionShape* collisionShape,
+ const btTransform& colObjWorldTransform,
+ RayResultCallback& resultCallback);
+
};
#endif //BT_SOFT_RIGID_DYNAMICS_WORLD_H
diff --git a/intern/audaspace/FX/AUD_AccumulatorFactory.cpp b/intern/audaspace/FX/AUD_AccumulatorFactory.cpp
new file mode 100644
index 00000000000..20709c57ee5
--- /dev/null
+++ b/intern/audaspace/FX/AUD_AccumulatorFactory.cpp
@@ -0,0 +1,49 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_AccumulatorFactory.h"
+#include "AUD_AccumulatorReader.h"
+
+AUD_AccumulatorFactory::AUD_AccumulatorFactory(AUD_IFactory* factory,
+ bool additive) :
+ AUD_EffectFactory(factory),
+ m_additive(additive) {}
+
+AUD_AccumulatorFactory::AUD_AccumulatorFactory(bool additive) :
+ AUD_EffectFactory(0),
+ m_additive(additive) {}
+
+AUD_IReader* AUD_AccumulatorFactory::createReader()
+{
+ AUD_IReader* reader = getReader();
+
+ if(reader != 0)
+ {
+ reader = new AUD_AccumulatorReader(reader, m_additive);
+ AUD_NEW("reader")
+ }
+
+ return reader;
+}
diff --git a/intern/audaspace/FX/AUD_AccumulatorFactory.h b/intern/audaspace/FX/AUD_AccumulatorFactory.h
new file mode 100644
index 00000000000..e475a19ccf6
--- /dev/null
+++ b/intern/audaspace/FX/AUD_AccumulatorFactory.h
@@ -0,0 +1,59 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_ACCUMULATORFACTORY
+#define AUD_ACCUMULATORFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory creates an accumulator reader.
+ */
+class AUD_AccumulatorFactory : public AUD_EffectFactory
+{
+private:
+ /**
+ * Whether the accumulator is additive.
+ */
+ bool m_additive;
+
+public:
+ /**
+ * Creates a new accumulator factory.
+ * \param factory The input factory.
+ * \param additive Whether the accumulator is additive.
+ */
+ AUD_AccumulatorFactory(AUD_IFactory* factory, bool additive = false);
+
+ /**
+ * Creates a new accumulator factory.
+ * \param additive Whether the accumulator is additive.
+ */
+ AUD_AccumulatorFactory(bool additive = false);
+
+ virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_ACCUMULATORFACTORY
diff --git a/intern/audaspace/FX/AUD_AccumulatorReader.cpp b/intern/audaspace/FX/AUD_AccumulatorReader.cpp
new file mode 100644
index 00000000000..67ab4157f9c
--- /dev/null
+++ b/intern/audaspace/FX/AUD_AccumulatorReader.cpp
@@ -0,0 +1,99 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_AccumulatorReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+
+#define CC specs.channels + channel
+
+AUD_AccumulatorReader::AUD_AccumulatorReader(AUD_IReader* reader,
+ bool additive) :
+ AUD_EffectReader(reader),
+ m_additive(additive)
+{
+ AUD_Specs specs = reader->getSpecs();
+ int samplesize = AUD_SAMPLE_SIZE(specs);
+
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+
+ m_sums = new AUD_Buffer(samplesize); AUD_NEW("buffer")
+ memset(m_sums->getBuffer(), 0, samplesize);
+
+ m_prevs = new AUD_Buffer(samplesize); AUD_NEW("buffer")
+ memset(m_prevs->getBuffer(), 0, samplesize);
+}
+
+AUD_AccumulatorReader::~AUD_AccumulatorReader()
+{
+ delete m_buffer; AUD_DELETE("buffer")
+ delete m_sums; AUD_DELETE("buffer")
+ delete m_prevs; AUD_DELETE("buffer")
+}
+
+void AUD_AccumulatorReader::read(int & length, sample_t* & buffer)
+{
+ sample_t* buf;
+ sample_t* sums;
+ sample_t* prevs;
+ sums = m_sums->getBuffer();
+ prevs = m_prevs->getBuffer();
+
+ AUD_Specs specs = m_reader->getSpecs();
+
+ m_reader->read(length, buf);
+ if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs))
+ m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
+
+ buffer = m_buffer->getBuffer();
+
+ if(m_additive)
+ {
+ for(int channel = 0; channel < specs.channels; channel++)
+ {
+ for(int i = 0; i < length; i++)
+ {
+ if(buf[i * CC] > prevs[channel])
+ sums[channel] += buf[i * CC] - prevs[channel];
+ buffer[i * CC] = sums[channel] + buf[i * CC];
+ prevs[channel] = buf[i * CC];
+ }
+ }
+ }
+ else
+ {
+ for(int channel = 0; channel < specs.channels; channel++)
+ {
+ for(int i = 0; i < length * specs.channels; i++)
+ {
+ if(buf[i * CC] > prevs[channel])
+ sums[channel] += buf[i * CC] - prevs[channel];
+ buffer[i * CC] = sums[channel];
+ prevs[channel] = buf[i * CC];
+ }
+ }
+ }
+}
diff --git a/intern/audaspace/FX/AUD_AccumulatorReader.h b/intern/audaspace/FX/AUD_AccumulatorReader.h
new file mode 100644
index 00000000000..8ad1dda30f6
--- /dev/null
+++ b/intern/audaspace/FX/AUD_AccumulatorReader.h
@@ -0,0 +1,75 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_ACCUMULATORREADER
+#define AUD_ACCUMULATORREADER
+
+#include "AUD_EffectReader.h"
+class AUD_Buffer;
+
+/**
+ * This class represents an accumulator.
+ */
+class AUD_AccumulatorReader : public AUD_EffectReader
+{
+private:
+ /**
+ * The playback buffer.
+ */
+ AUD_Buffer *m_buffer;
+
+ /**
+ * The sums of the specific channels.
+ */
+ AUD_Buffer *m_sums;
+
+ /**
+ * The previous results of the specific channels.
+ */
+ AUD_Buffer *m_prevs;
+
+ /**
+ * Whether the accumulator is additive.
+ */
+ bool m_additive;
+
+public:
+ /**
+ * Creates a new accumulator reader.
+ * \param reader The reader to read from.
+ * \param additive Whether the accumulator is additive.
+ * \exception AUD_Exception Thrown if the reader specified is NULL.
+ */
+ AUD_AccumulatorReader(AUD_IReader* reader, bool additive);
+
+ /**
+ * Destroys the reader.
+ */
+ virtual ~AUD_AccumulatorReader();
+
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_ACCUMULATORREADER
diff --git a/intern/audaspace/FX/AUD_ButterworthFactory.cpp b/intern/audaspace/FX/AUD_ButterworthFactory.cpp
new file mode 100644
index 00000000000..fd0a53def7c
--- /dev/null
+++ b/intern/audaspace/FX/AUD_ButterworthFactory.cpp
@@ -0,0 +1,49 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_ButterworthFactory.h"
+#include "AUD_ButterworthReader.h"
+
+AUD_ButterworthFactory::AUD_ButterworthFactory(AUD_IFactory* factory,
+ float frequency) :
+ AUD_EffectFactory(factory),
+ m_frequency(frequency) {}
+
+AUD_ButterworthFactory::AUD_ButterworthFactory(float frequency) :
+ AUD_EffectFactory(0),
+ m_frequency(frequency) {}
+
+AUD_IReader* AUD_ButterworthFactory::createReader()
+{
+ AUD_IReader* reader = getReader();
+
+ if(reader != 0)
+ {
+ reader = new AUD_ButterworthReader(reader, m_frequency);
+ AUD_NEW("reader")
+ }
+
+ return reader;
+}
diff --git a/intern/audaspace/FX/AUD_ButterworthFactory.h b/intern/audaspace/FX/AUD_ButterworthFactory.h
new file mode 100644
index 00000000000..69169531d70
--- /dev/null
+++ b/intern/audaspace/FX/AUD_ButterworthFactory.h
@@ -0,0 +1,59 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_BUTTERWORTHFACTORY
+#define AUD_BUTTERWORTHFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory creates a butterworth filter reader.
+ */
+class AUD_ButterworthFactory : public AUD_EffectFactory
+{
+private:
+ /**
+ * The attack value in seconds.
+ */
+ float m_frequency;
+
+public:
+ /**
+ * Creates a new butterworth factory.
+ * \param factory The input factory.
+ * \param frequency The cutoff frequency.
+ */
+ AUD_ButterworthFactory(AUD_IFactory* factory, float frequency);
+
+ /**
+ * Creates a new butterworth factory.
+ * \param frequency The cutoff frequency.
+ */
+ AUD_ButterworthFactory(float frequency);
+
+ virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_BUTTERWORTHFACTORY
diff --git a/intern/audaspace/FX/AUD_ButterworthReader.cpp b/intern/audaspace/FX/AUD_ButterworthReader.cpp
new file mode 100644
index 00000000000..2129dfef798
--- /dev/null
+++ b/intern/audaspace/FX/AUD_ButterworthReader.cpp
@@ -0,0 +1,124 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_ButterworthReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+#include <cmath>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+#define BWPB41 0.76536686473
+#define BWPB42 1.84775906502
+#define CC channels + channel
+
+AUD_ButterworthReader::AUD_ButterworthReader(AUD_IReader* reader,
+ float frequency) :
+ AUD_EffectReader(reader)
+{
+ AUD_Specs specs = reader->getSpecs();
+ int samplesize = AUD_SAMPLE_SIZE(specs);
+
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+
+ m_outvalues = new AUD_Buffer(samplesize * 5); AUD_NEW("buffer")
+ memset(m_outvalues->getBuffer(), 0, samplesize * 5);
+
+ m_invalues = new AUD_Buffer(samplesize * 5); AUD_NEW("buffer")
+ memset(m_invalues->getBuffer(), 0, samplesize * 5);
+
+ m_position = 0;
+
+ // calculate coefficients
+ float omega = 2 * tan(frequency * M_PI / specs.rate);
+ float o2 = omega * omega;
+ float o4 = o2 * o2;
+ float x1 = o2 + 2 * BWPB41 * omega + 4;
+ float x2 = o2 + 2 * BWPB42 * omega + 4;
+ float y1 = o2 - 2 * BWPB41 * omega + 4;
+ float y2 = o2 - 2 * BWPB42 * omega + 4;
+ float o228 = 2 * o2 - 8;
+ float norm = x1 * x2;
+ m_coeff[0][0] = 0;
+ m_coeff[0][1] = (x1 + x2) * o228 / norm;
+ m_coeff[0][2] = (x1 * y2 + x2 * y1 + o228 * o228) / norm;
+ m_coeff[0][3] = (y1 + y2) * o228 / norm;
+ m_coeff[0][4] = y1 * y2 / norm;
+ m_coeff[1][4] = m_coeff[1][0] = o4 / norm;
+ m_coeff[1][3] = m_coeff[1][1] = 4 * o4 / norm;
+ m_coeff[1][2] = 6 * o4 / norm;
+}
+
+AUD_ButterworthReader::~AUD_ButterworthReader()
+{
+ delete m_buffer; AUD_DELETE("buffer")
+
+ delete m_outvalues; AUD_DELETE("buffer")
+ delete m_invalues; AUD_DELETE("buffer");
+}
+
+void AUD_ButterworthReader::read(int & length, sample_t* & buffer)
+{
+ sample_t* buf;
+ sample_t* outvalues;
+ sample_t* invalues;
+
+ outvalues = m_outvalues->getBuffer();
+ invalues = m_invalues->getBuffer();
+
+ AUD_Specs specs = m_reader->getSpecs();
+
+ m_reader->read(length, buf);
+
+ if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs))
+ m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
+
+ buffer = m_buffer->getBuffer();
+ int channels = specs.channels;
+
+ for(int channel = 0; channel < channels; channel++)
+ {
+ for(int i = 0; i < length; i++)
+ {
+ invalues[m_position * CC] = buf[i * CC];
+ outvalues[m_position * CC] = 0;
+
+ for(int j = 0; j < 4; j++)
+ {
+ outvalues[m_position * CC] += m_coeff[1][j] *
+ invalues[((m_position + j) % 5) * CC] -
+ m_coeff[0][j] *
+ outvalues[((m_position + j) % 5) * CC];
+ }
+
+ buffer[i * CC] = outvalues[m_position * CC];
+
+ m_position = (m_position + 4) % 5;
+ }
+ }
+}
diff --git a/intern/audaspace/FX/AUD_ButterworthReader.h b/intern/audaspace/FX/AUD_ButterworthReader.h
new file mode 100644
index 00000000000..b1cbd4e3820
--- /dev/null
+++ b/intern/audaspace/FX/AUD_ButterworthReader.h
@@ -0,0 +1,83 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_BUTTERWORTHREADER
+#define AUD_BUTTERWORTHREADER
+
+#include "AUD_EffectReader.h"
+class AUD_Buffer;
+
+/**
+ * This class represents a butterworth filter.
+ */
+class AUD_ButterworthReader : public AUD_EffectReader
+{
+private:
+ /**
+ * The playback buffer.
+ */
+ AUD_Buffer *m_buffer;
+
+ /**
+ * The last out values buffer.
+ */
+ AUD_Buffer *m_outvalues;
+
+ /**
+ * The last in values buffer.
+ */
+ AUD_Buffer *m_invalues;
+
+ /**
+ * The position for buffer cycling.
+ */
+ int m_position;
+
+ /**
+ * Filter coefficients.
+ */
+ float m_coeff[2][5];
+
+public:
+ /**
+ * Creates a new butterworth reader.
+ * \param reader The reader to read from.
+ * \param attack The attack value in seconds.
+ * \param release The release value in seconds.
+ * \param threshold The threshold value.
+ * \param arthreshold The attack/release threshold value.
+ * \exception AUD_Exception Thrown if the reader specified is NULL.
+ */
+ AUD_ButterworthReader(AUD_IReader* reader, float frequency);
+
+ /**
+ * Destroys the reader.
+ */
+ virtual ~AUD_ButterworthReader();
+
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_BUTTERWORTHREADER
diff --git a/intern/audaspace/FX/AUD_DelayReader.cpp b/intern/audaspace/FX/AUD_DelayReader.cpp
index 38d3b893b5c..f2521f645aa 100644
--- a/intern/audaspace/FX/AUD_DelayReader.cpp
+++ b/intern/audaspace/FX/AUD_DelayReader.cpp
@@ -77,31 +77,26 @@ void AUD_DelayReader::read(int & length, sample_t* & buffer)
{
if(m_remdelay > 0)
{
- int samplesize = AUD_SAMPLE_SIZE(m_reader->getSpecs());
+ AUD_Specs specs = m_reader->getSpecs();
+ int samplesize = AUD_SAMPLE_SIZE(specs);
- if(m_buffer->getSize() < length*samplesize)
- m_buffer->resize(length*samplesize);
+ if(m_buffer->getSize() < length * samplesize)
+ m_buffer->resize(length * samplesize);
if(length > m_remdelay)
{
- if(getSpecs().format == AUD_FORMAT_U8)
- memset(m_buffer->getBuffer(), 0x80, m_remdelay*samplesize);
- else
- memset(m_buffer->getBuffer(), 0, m_remdelay*samplesize);
+ memset(m_buffer->getBuffer(), 0, m_remdelay * samplesize);
int len = length - m_remdelay;
m_reader->read(len, buffer);
- memcpy(m_buffer->getBuffer()+m_remdelay*samplesize,
- buffer, len*samplesize);
+ memcpy(m_buffer->getBuffer() + m_remdelay * specs.channels,
+ buffer, len * samplesize);
if(len < length-m_remdelay)
length = m_remdelay + len;
m_remdelay = 0;
}
else
{
- if(getSpecs().format == AUD_FORMAT_U8)
- memset(m_buffer->getBuffer(), 0x80, length*samplesize);
- else
- memset(m_buffer->getBuffer(), 0, length*samplesize);
+ memset(m_buffer->getBuffer(), 0, length * samplesize);
m_remdelay -= length;
}
buffer = m_buffer->getBuffer();
diff --git a/intern/audaspace/FX/AUD_DoubleReader.cpp b/intern/audaspace/FX/AUD_DoubleReader.cpp
index 8d3afbf2f1d..1e51a094427 100644
--- a/intern/audaspace/FX/AUD_DoubleReader.cpp
+++ b/intern/audaspace/FX/AUD_DoubleReader.cpp
@@ -137,15 +137,16 @@ void AUD_DoubleReader::read(int & length, sample_t* & buffer)
m_reader1->read(len, buffer);
if(len < length)
{
- int samplesize = AUD_SAMPLE_SIZE(m_reader1->getSpecs());
+ AUD_Specs specs = m_reader1->getSpecs();
+ int samplesize = AUD_SAMPLE_SIZE(specs);
if(m_buffer->getSize() < length * samplesize)
m_buffer->resize(length * samplesize);
- memcpy(m_buffer->getBuffer(), buffer, len*samplesize);
+ memcpy(m_buffer->getBuffer(), buffer, len * samplesize);
len = length - len;
length -= len;
m_reader2->read(len, buffer);
- memcpy(m_buffer->getBuffer() + length*samplesize,
- buffer, len*samplesize);
+ memcpy(m_buffer->getBuffer() + length * specs.channels, buffer,
+ len * samplesize);
length += len;
buffer = m_buffer->getBuffer();
m_finished1 = true;
diff --git a/intern/audaspace/FX/AUD_EnvelopeFactory.cpp b/intern/audaspace/FX/AUD_EnvelopeFactory.cpp
new file mode 100644
index 00000000000..c3b2c3f24fe
--- /dev/null
+++ b/intern/audaspace/FX/AUD_EnvelopeFactory.cpp
@@ -0,0 +1,58 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_EnvelopeFactory.h"
+#include "AUD_EnvelopeReader.h"
+
+AUD_EnvelopeFactory::AUD_EnvelopeFactory(AUD_IFactory* factory, float attack,
+ float release, float threshold,
+ float arthreshold) :
+ AUD_EffectFactory(factory),
+ m_attack(attack),
+ m_release(release),
+ m_threshold(threshold),
+ m_arthreshold(arthreshold) {}
+
+AUD_EnvelopeFactory::AUD_EnvelopeFactory(float attack, float release,
+ float threshold, float arthreshold) :
+ AUD_EffectFactory(0),
+ m_attack(attack),
+ m_release(release),
+ m_threshold(threshold),
+ m_arthreshold(arthreshold) {}
+
+AUD_IReader* AUD_EnvelopeFactory::createReader()
+{
+ AUD_IReader* reader = getReader();
+
+ if(reader != 0)
+ {
+ reader = new AUD_EnvelopeReader(reader, m_attack, m_release,
+ m_threshold, m_arthreshold);
+ AUD_NEW("reader")
+ }
+
+ return reader;
+}
diff --git a/intern/audaspace/FX/AUD_EnvelopeFactory.h b/intern/audaspace/FX/AUD_EnvelopeFactory.h
new file mode 100644
index 00000000000..c79e5472e30
--- /dev/null
+++ b/intern/audaspace/FX/AUD_EnvelopeFactory.h
@@ -0,0 +1,82 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_ENVELOPEFACTORY
+#define AUD_ENVELOPEFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory creates an envelope follower reader.
+ */
+class AUD_EnvelopeFactory : public AUD_EffectFactory
+{
+private:
+ /**
+ * The attack value in seconds.
+ */
+ float m_attack;
+
+ /**
+ * The release value in seconds.
+ */
+ float m_release;
+
+ /**
+ * The threshold value.
+ */
+ float m_threshold;
+
+ /**
+ * The attack/release threshold value.
+ */
+ float m_arthreshold;
+
+public:
+ /**
+ * Creates a new envelope factory.
+ * \param factory The input factory.
+ * \param attack The attack value in seconds.
+ * \param release The release value in seconds.
+ * \param threshold The threshold value.
+ * \param arthreshold The attack/release threshold value.
+ */
+ AUD_EnvelopeFactory(AUD_IFactory* factory, float attack, float release,
+ float threshold, float arthreshold);
+
+ /**
+ * Creates a new envelope factory.
+ * \param attack The attack value in seconds.
+ * \param release The release value in seconds.
+ * \param threshold The threshold value.
+ * \param arthreshold The attack/release threshold value.
+ */
+ AUD_EnvelopeFactory(float attack, float release, float threshold,
+ float arthreshold);
+
+ virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_ENVELOPEFACTORY
diff --git a/intern/audaspace/FX/AUD_EnvelopeReader.cpp b/intern/audaspace/FX/AUD_EnvelopeReader.cpp
new file mode 100644
index 00000000000..71ccbfd6503
--- /dev/null
+++ b/intern/audaspace/FX/AUD_EnvelopeReader.cpp
@@ -0,0 +1,86 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_EnvelopeReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+#include <cmath>
+
+AUD_EnvelopeReader::AUD_EnvelopeReader(AUD_IReader* reader, float attack,
+ float release, float threshold,
+ float arthreshold) :
+ AUD_EffectReader(reader),
+ m_threshold(threshold)
+{
+ AUD_Specs specs = reader->getSpecs();
+ int samplesize = AUD_SAMPLE_SIZE(specs);
+
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+
+ m_envelopes = new AUD_Buffer(samplesize);
+ AUD_NEW("buffer")
+ memset(m_envelopes->getBuffer(), 0, samplesize);
+
+ m_bAttack = pow(arthreshold, 1.0f/(specs.rate * attack));
+ m_bRelease = pow(arthreshold, 1.0f/(specs.rate * release));
+}
+
+AUD_EnvelopeReader::~AUD_EnvelopeReader()
+{
+ delete m_buffer; AUD_DELETE("buffer")
+ delete m_envelopes; AUD_DELETE("buffer")
+}
+
+void AUD_EnvelopeReader::read(int & length, sample_t* & buffer)
+{
+ sample_t* buf;
+ sample_t* envelopes;
+ envelopes = m_envelopes->getBuffer();
+
+ AUD_Specs specs = m_reader->getSpecs();
+
+ m_reader->read(length, buf);
+ if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs))
+ m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
+
+ buffer = m_buffer->getBuffer();
+
+ sample_t value;
+
+ for(int channel = 0; channel < specs.channels; channel++)
+ {
+ for(int i = 0; i < length; i++)
+ {
+ value = fabs(buf[i * specs.channels + channel]);
+ if(value < m_threshold)
+ value = 0.0f;
+
+ buffer[i * specs.channels + channel] = envelopes[channel] =
+ ((value > envelopes[channel]) ? m_bAttack : m_bRelease) *
+ (envelopes[channel] - value) + value;
+ }
+ }
+}
diff --git a/intern/audaspace/FX/AUD_EnvelopeReader.h b/intern/audaspace/FX/AUD_EnvelopeReader.h
new file mode 100644
index 00000000000..ff9dd23d34c
--- /dev/null
+++ b/intern/audaspace/FX/AUD_EnvelopeReader.h
@@ -0,0 +1,84 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_ENVELOPEREADER
+#define AUD_ENVELOPEREADER
+
+#include "AUD_EffectReader.h"
+class AUD_Buffer;
+
+/**
+ * This class represents an envelope follower.
+ */
+class AUD_EnvelopeReader : public AUD_EffectReader
+{
+private:
+ /**
+ * The playback buffer.
+ */
+ AUD_Buffer *m_buffer;
+
+ /**
+ * The last envelopes buffer.
+ */
+ AUD_Buffer *m_envelopes;
+
+ /**
+ * Attack b value.
+ */
+ float m_bAttack;
+
+ /**
+ * Release b value.
+ */
+ float m_bRelease;
+
+ /**
+ * Threshold value.
+ */
+ float m_threshold;
+
+public:
+ /**
+ * Creates a new envelope reader.
+ * \param reader The reader to read from.
+ * \param attack The attack value in seconds.
+ * \param release The release value in seconds.
+ * \param threshold The threshold value.
+ * \param arthreshold The attack/release threshold value.
+ * \exception AUD_Exception Thrown if the reader specified is NULL.
+ */
+ AUD_EnvelopeReader(AUD_IReader* reader, float attack, float release,
+ float threshold, float arthreshold);
+
+ /**
+ * Destroys the reader.
+ */
+ virtual ~AUD_EnvelopeReader();
+
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_ENVELOPEREADER
diff --git a/intern/audaspace/FX/AUD_FaderReader.cpp b/intern/audaspace/FX/AUD_FaderReader.cpp
index d5096e7fae1..6c7ea6e0a01 100644
--- a/intern/audaspace/FX/AUD_FaderReader.cpp
+++ b/intern/audaspace/FX/AUD_FaderReader.cpp
@@ -35,35 +35,6 @@ AUD_FaderReader::AUD_FaderReader(AUD_IReader* reader, AUD_FadeType type,
m_start(start),
m_length(length)
{
- int bigendian = 1;
- bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
-
- switch(m_reader->getSpecs().format)
- {
- case AUD_FORMAT_S16:
- m_adjust = AUD_volume_adjust<int16_t>;
- break;
- case AUD_FORMAT_S32:
- m_adjust = AUD_volume_adjust<int32_t>;
- break;
- case AUD_FORMAT_FLOAT32:
- m_adjust = AUD_volume_adjust<float>;
- break;
- case AUD_FORMAT_FLOAT64:
- m_adjust = AUD_volume_adjust<double>;
- break;
- case AUD_FORMAT_U8:
- m_adjust = AUD_volume_adjust_u8;
- break;
- case AUD_FORMAT_S24:
- m_adjust = bigendian ? AUD_volume_adjust_s24_be :
- AUD_volume_adjust_s24_le;
- break;
- default:
- delete m_reader;
- AUD_THROW(AUD_ERROR_READER);
- }
-
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
}
@@ -93,9 +64,7 @@ void AUD_FaderReader::read(int & length, sample_t* & buffer)
if(m_type != AUD_FADE_OUT)
{
buffer = m_buffer->getBuffer();
- memset(buffer,
- specs.format == AUD_FORMAT_U8 ? 0x80 : 0,
- length * samplesize);
+ memset(buffer, 0, length * samplesize);
}
}
else if(position / (float)specs.rate >= m_start+m_length)
@@ -103,9 +72,7 @@ void AUD_FaderReader::read(int & length, sample_t* & buffer)
if(m_type == AUD_FADE_OUT)
{
buffer = m_buffer->getBuffer();
- memset(buffer,
- specs.format == AUD_FORMAT_U8 ? 0x80 : 0,
- length * samplesize);
+ memset(buffer, 0, length * samplesize);
}
}
else
@@ -113,19 +80,21 @@ void AUD_FaderReader::read(int & length, sample_t* & buffer)
sample_t* buf = m_buffer->getBuffer();
float volume;
- for(int i = 0; i < length; i++)
+ for(int i = 0; i < length * specs.channels; i++)
{
- volume = (((position+i)/(float)specs.rate)-m_start) / m_length;
- if(volume > 1.0f)
- volume = 1.0f;
- else if(volume < 0.0f)
- volume = 0.0f;
+ if(i % specs.channels == 0)
+ {
+ volume = (((position+i)/(float)specs.rate)-m_start) / m_length;
+ if(volume > 1.0f)
+ volume = 1.0f;
+ else if(volume < 0.0f)
+ volume = 0.0f;
- if(m_type == AUD_FADE_OUT)
- volume = 1.0f - volume;
+ if(m_type == AUD_FADE_OUT)
+ volume = 1.0f - volume;
+ }
- m_adjust(buf + i * samplesize, buffer + i * samplesize,
- specs.channels, volume);
+ buf[i] = buffer[i] * volume;
}
buffer = buf;
diff --git a/intern/audaspace/FX/AUD_FaderReader.h b/intern/audaspace/FX/AUD_FaderReader.h
index 773643b2f5d..a75ac6e7a47 100644
--- a/intern/audaspace/FX/AUD_FaderReader.h
+++ b/intern/audaspace/FX/AUD_FaderReader.h
@@ -27,7 +27,6 @@
#define AUD_FADERREADER
#include "AUD_EffectReader.h"
-#include "AUD_ConverterFunctions.h"
class AUD_Buffer;
/**
@@ -58,11 +57,6 @@ private:
*/
float m_length;
- /**
- * Volume adjustment function.
- */
- AUD_volume_adjust_f m_adjust;
-
public:
/**
* Creates a new fader reader.
diff --git a/intern/audaspace/FX/AUD_HighpassFactory.cpp b/intern/audaspace/FX/AUD_HighpassFactory.cpp
new file mode 100644
index 00000000000..384d36beab7
--- /dev/null
+++ b/intern/audaspace/FX/AUD_HighpassFactory.cpp
@@ -0,0 +1,51 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_HighpassFactory.h"
+#include "AUD_HighpassReader.h"
+
+AUD_HighpassFactory::AUD_HighpassFactory(AUD_IFactory* factory, float frequency,
+ float Q) :
+ AUD_EffectFactory(factory),
+ m_frequency(frequency),
+ m_Q(Q) {}
+
+AUD_HighpassFactory::AUD_HighpassFactory(float frequency, float Q) :
+ AUD_EffectFactory(0),
+ m_frequency(frequency),
+ m_Q(Q) {}
+
+AUD_IReader* AUD_HighpassFactory::createReader()
+{
+ AUD_IReader* reader = getReader();
+
+ if(reader != 0)
+ {
+ reader = new AUD_HighpassReader(reader, m_frequency, m_Q);
+ AUD_NEW("reader")
+ }
+
+ return reader;
+}
diff --git a/intern/audaspace/FX/AUD_HighpassFactory.h b/intern/audaspace/FX/AUD_HighpassFactory.h
new file mode 100644
index 00000000000..5e31053ed6c
--- /dev/null
+++ b/intern/audaspace/FX/AUD_HighpassFactory.h
@@ -0,0 +1,66 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_HIGHPASSFACTORY
+#define AUD_HIGHPASSFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory creates a highpass filter reader.
+ */
+class AUD_HighpassFactory : public AUD_EffectFactory
+{
+private:
+ /**
+ * The attack value in seconds.
+ */
+ float m_frequency;
+
+ /**
+ * The Q factor.
+ */
+ float m_Q;
+
+public:
+ /**
+ * Creates a new highpass factory.
+ * \param factory The input factory.
+ * \param frequency The cutoff frequency.
+ * \param Q The Q factor.
+ */
+ AUD_HighpassFactory(AUD_IFactory* factory, float frequency, float Q = 1.0f);
+
+ /**
+ * Creates a new highpass factory.
+ * \param frequency The cutoff frequency.
+ * \param Q The Q factor.
+ */
+ AUD_HighpassFactory(float frequency, float Q = 1.0f);
+
+ virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_HIGHPASSFACTORY
diff --git a/intern/audaspace/FX/AUD_HighpassReader.cpp b/intern/audaspace/FX/AUD_HighpassReader.cpp
new file mode 100644
index 00000000000..36b1bb8082e
--- /dev/null
+++ b/intern/audaspace/FX/AUD_HighpassReader.cpp
@@ -0,0 +1,116 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_HighpassReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+#include <cmath>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+#define CC channels + channel
+
+AUD_HighpassReader::AUD_HighpassReader(AUD_IReader* reader, float frequency,
+ float Q) :
+ AUD_EffectReader(reader)
+{
+ AUD_Specs specs = reader->getSpecs();
+ int samplesize = AUD_SAMPLE_SIZE(specs);
+
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+
+ m_outvalues = new AUD_Buffer(samplesize * AUD_HIGHPASS_ORDER);
+ AUD_NEW("buffer")
+ memset(m_outvalues->getBuffer(), 0, samplesize * AUD_HIGHPASS_ORDER);
+
+ m_invalues = new AUD_Buffer(samplesize * AUD_HIGHPASS_ORDER);
+ AUD_NEW("buffer")
+ memset(m_invalues->getBuffer(), 0, samplesize * AUD_HIGHPASS_ORDER);
+
+ m_position = 0;
+
+ // calculate coefficients
+ float w0 = 2 * M_PI * frequency / specs.rate;
+ float alpha = sin(w0) / (2 * Q);
+ float norm = 1 + alpha;
+ m_coeff[0][0] = 0;
+ m_coeff[0][1] = -2 * cos(w0) / norm;
+ m_coeff[0][2] = (1 - alpha) / norm;
+ m_coeff[1][2] = m_coeff[1][0] = (1 + cos(w0)) / (2 * norm);
+ m_coeff[1][1] = (-1 - cos(w0)) / norm;
+}
+
+AUD_HighpassReader::~AUD_HighpassReader()
+{
+ delete m_buffer; AUD_DELETE("buffer")
+
+ delete m_outvalues; AUD_DELETE("buffer")
+ delete m_invalues; AUD_DELETE("buffer");
+}
+
+void AUD_HighpassReader::read(int & length, sample_t* & buffer)
+{
+ sample_t* buf;
+ sample_t* outvalues;
+ sample_t* invalues;
+
+ outvalues = m_outvalues->getBuffer();
+ invalues = m_invalues->getBuffer();
+
+ AUD_Specs specs = m_reader->getSpecs();
+
+ m_reader->read(length, buf);
+
+ if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs))
+ m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
+
+ buffer = m_buffer->getBuffer();
+ int channels = specs.channels;
+
+ for(int channel = 0; channel < channels; channel++)
+ {
+ for(int i = 0; i < length; i++)
+ {
+ invalues[m_position * CC] = buf[i * CC];
+ outvalues[m_position * CC] = 0;
+
+ for(int j = 0; j < AUD_HIGHPASS_ORDER; j++)
+ {
+ outvalues[m_position * CC] += m_coeff[1][j] *
+ invalues[((m_position + j) % AUD_HIGHPASS_ORDER) * CC] -
+ m_coeff[0][j] *
+ outvalues[((m_position + j) % AUD_HIGHPASS_ORDER) * CC];
+ }
+
+ buffer[i * CC] = outvalues[m_position * CC];
+
+ m_position = (m_position + AUD_HIGHPASS_ORDER-1) %
+ AUD_HIGHPASS_ORDER;
+ }
+ }
+}
diff --git a/intern/audaspace/FX/AUD_HighpassReader.h b/intern/audaspace/FX/AUD_HighpassReader.h
new file mode 100644
index 00000000000..dc28a62e45b
--- /dev/null
+++ b/intern/audaspace/FX/AUD_HighpassReader.h
@@ -0,0 +1,83 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_HIGHPASSREADER
+#define AUD_HIGHPASSREADER
+
+#include "AUD_EffectReader.h"
+class AUD_Buffer;
+
+#define AUD_HIGHPASS_ORDER 3
+
+/**
+ * This class represents a highpass filter.
+ */
+class AUD_HighpassReader : public AUD_EffectReader
+{
+private:
+ /**
+ * The playback buffer.
+ */
+ AUD_Buffer *m_buffer;
+
+ /**
+ * The last out values buffer.
+ */
+ AUD_Buffer *m_outvalues;
+
+ /**
+ * The last in values buffer.
+ */
+ AUD_Buffer *m_invalues;
+
+ /**
+ * The position for buffer cycling.
+ */
+ int m_position;
+
+ /**
+ * Filter coefficients.
+ */
+ float m_coeff[2][AUD_HIGHPASS_ORDER];
+
+public:
+ /**
+ * Creates a new highpass reader.
+ * \param reader The reader to read from.
+ * \param frequency The cutoff frequency.
+ * \param Q The Q factor.
+ * \exception AUD_Exception Thrown if the reader specified is NULL.
+ */
+ AUD_HighpassReader(AUD_IReader* reader, float frequency, float Q);
+
+ /**
+ * Destroys the reader.
+ */
+ virtual ~AUD_HighpassReader();
+
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_HIGHPASSREADER
diff --git a/intern/audaspace/FX/AUD_LoopReader.cpp b/intern/audaspace/FX/AUD_LoopReader.cpp
index 9e270321013..7d70fc20221 100644
--- a/intern/audaspace/FX/AUD_LoopReader.cpp
+++ b/intern/audaspace/FX/AUD_LoopReader.cpp
@@ -27,7 +27,6 @@
#include "AUD_Buffer.h"
#include <cstring>
-#include <stdio.h>
AUD_LoopReader::AUD_LoopReader(AUD_IReader* reader, int loop) :
AUD_EffectReader(reader), m_loop(loop)
@@ -62,7 +61,8 @@ bool AUD_LoopReader::notify(AUD_Message &message)
void AUD_LoopReader::read(int & length, sample_t* & buffer)
{
- int samplesize = AUD_SAMPLE_SIZE(m_reader->getSpecs());
+ AUD_Specs specs = m_reader->getSpecs();
+ int samplesize = AUD_SAMPLE_SIZE(specs);
int len = length;
@@ -72,10 +72,10 @@ void AUD_LoopReader::read(int & length, sample_t* & buffer)
{
int pos = 0;
- if(m_buffer->getSize() < length*samplesize)
- m_buffer->resize(length*samplesize);
+ if(m_buffer->getSize() < length * samplesize)
+ m_buffer->resize(length * samplesize);
- memcpy(m_buffer->getBuffer() + pos * samplesize,
+ memcpy(m_buffer->getBuffer() + pos * specs.channels,
buffer, len * samplesize);
pos += len;
@@ -93,7 +93,7 @@ void AUD_LoopReader::read(int & length, sample_t* & buffer)
if(!len)
break;
- memcpy(m_buffer->getBuffer() + pos * samplesize,
+ memcpy(m_buffer->getBuffer() + pos * specs.channels,
buffer, len * samplesize);
pos += len;
diff --git a/intern/audaspace/FX/AUD_LowpassFactory.cpp b/intern/audaspace/FX/AUD_LowpassFactory.cpp
new file mode 100644
index 00000000000..05dc5ff3994
--- /dev/null
+++ b/intern/audaspace/FX/AUD_LowpassFactory.cpp
@@ -0,0 +1,51 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_LowpassFactory.h"
+#include "AUD_LowpassReader.h"
+
+AUD_LowpassFactory::AUD_LowpassFactory(AUD_IFactory* factory, float frequency,
+ float Q) :
+ AUD_EffectFactory(factory),
+ m_frequency(frequency),
+ m_Q(Q) {}
+
+AUD_LowpassFactory::AUD_LowpassFactory(float frequency, float Q) :
+ AUD_EffectFactory(0),
+ m_frequency(frequency),
+ m_Q(Q) {}
+
+AUD_IReader* AUD_LowpassFactory::createReader()
+{
+ AUD_IReader* reader = getReader();
+
+ if(reader != 0)
+ {
+ reader = new AUD_LowpassReader(reader, m_frequency, m_Q);
+ AUD_NEW("reader")
+ }
+
+ return reader;
+}
diff --git a/intern/audaspace/FX/AUD_LowpassFactory.h b/intern/audaspace/FX/AUD_LowpassFactory.h
new file mode 100644
index 00000000000..8a419823de0
--- /dev/null
+++ b/intern/audaspace/FX/AUD_LowpassFactory.h
@@ -0,0 +1,66 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_LOWPASSFACTORY
+#define AUD_LOWPASSFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory creates a lowpass filter reader.
+ */
+class AUD_LowpassFactory : public AUD_EffectFactory
+{
+private:
+ /**
+ * The attack value in seconds.
+ */
+ float m_frequency;
+
+ /**
+ * The Q factor.
+ */
+ float m_Q;
+
+public:
+ /**
+ * Creates a new lowpass factory.
+ * \param factory The input factory.
+ * \param frequency The cutoff frequency.
+ * \param Q The Q factor.
+ */
+ AUD_LowpassFactory(AUD_IFactory* factory, float frequency, float Q = 1.0f);
+
+ /**
+ * Creates a new lowpass factory.
+ * \param frequency The cutoff frequency.
+ * \param Q The Q factor.
+ */
+ AUD_LowpassFactory(float frequency, float Q = 1.0f);
+
+ virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_LOWPASSFACTORY
diff --git a/intern/audaspace/FX/AUD_LowpassReader.cpp b/intern/audaspace/FX/AUD_LowpassReader.cpp
new file mode 100644
index 00000000000..6dc0bf66a96
--- /dev/null
+++ b/intern/audaspace/FX/AUD_LowpassReader.cpp
@@ -0,0 +1,115 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_LowpassReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+#include <cmath>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+#define CC channels + channel
+
+AUD_LowpassReader::AUD_LowpassReader(AUD_IReader* reader, float frequency,
+ float Q) :
+ AUD_EffectReader(reader)
+{
+ AUD_Specs specs = reader->getSpecs();
+ int samplesize = AUD_SAMPLE_SIZE(specs);
+
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+
+ m_outvalues = new AUD_Buffer(samplesize * AUD_LOWPASS_ORDER);
+ AUD_NEW("buffer")
+ memset(m_outvalues->getBuffer(), 0, samplesize * AUD_LOWPASS_ORDER);
+
+ m_invalues = new AUD_Buffer(samplesize * AUD_LOWPASS_ORDER);
+ AUD_NEW("buffer")
+ memset(m_invalues->getBuffer(), 0, samplesize * AUD_LOWPASS_ORDER);
+
+ m_position = 0;
+
+ // calculate coefficients
+ float w0 = 2 * M_PI * frequency / specs.rate;
+ float alpha = sin(w0) / (2 * Q);
+ float norm = 1 + alpha;
+ m_coeff[0][0] = 0;
+ m_coeff[0][1] = -2 * cos(w0) / norm;
+ m_coeff[0][2] = (1 - alpha) / norm;
+ m_coeff[1][2] = m_coeff[1][0] = (1 - cos(w0)) / (2 * norm);
+ m_coeff[1][1] = (1 - cos(w0)) / norm;
+}
+
+AUD_LowpassReader::~AUD_LowpassReader()
+{
+ delete m_buffer; AUD_DELETE("buffer")
+
+ delete m_outvalues; AUD_DELETE("buffer")
+ delete m_invalues; AUD_DELETE("buffer");
+}
+
+void AUD_LowpassReader::read(int & length, sample_t* & buffer)
+{
+ sample_t* buf;
+ sample_t* outvalues;
+ sample_t* invalues;
+
+ outvalues = m_outvalues->getBuffer();
+ invalues = m_invalues->getBuffer();
+
+ AUD_Specs specs = m_reader->getSpecs();
+
+ m_reader->read(length, buf);
+
+ if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs))
+ m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
+
+ buffer = m_buffer->getBuffer();
+ int channels = specs.channels;
+
+ for(int channel = 0; channel < channels; channel++)
+ {
+ for(int i = 0; i < length; i++)
+ {
+ invalues[m_position * CC] = buf[i * CC];
+ outvalues[m_position * CC] = 0;
+
+ for(int j = 0; j < AUD_LOWPASS_ORDER; j++)
+ {
+ outvalues[m_position * CC] += m_coeff[1][j] *
+ invalues[((m_position + j) % AUD_LOWPASS_ORDER) * CC] -
+ m_coeff[0][j] *
+ outvalues[((m_position + j) % AUD_LOWPASS_ORDER) * CC];
+ }
+
+ buffer[i * CC] = outvalues[m_position * CC];
+
+ m_position = (m_position + AUD_LOWPASS_ORDER-1) % AUD_LOWPASS_ORDER;
+ }
+ }
+}
diff --git a/intern/audaspace/FX/AUD_LowpassReader.h b/intern/audaspace/FX/AUD_LowpassReader.h
new file mode 100644
index 00000000000..a490ba52c1c
--- /dev/null
+++ b/intern/audaspace/FX/AUD_LowpassReader.h
@@ -0,0 +1,83 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_LOWPASSREADER
+#define AUD_LOWPASSREADER
+
+#include "AUD_EffectReader.h"
+class AUD_Buffer;
+
+#define AUD_LOWPASS_ORDER 3
+
+/**
+ * This class represents a lowpass filter.
+ */
+class AUD_LowpassReader : public AUD_EffectReader
+{
+private:
+ /**
+ * The playback buffer.
+ */
+ AUD_Buffer *m_buffer;
+
+ /**
+ * The last out values buffer.
+ */
+ AUD_Buffer *m_outvalues;
+
+ /**
+ * The last in values buffer.
+ */
+ AUD_Buffer *m_invalues;
+
+ /**
+ * The position for buffer cycling.
+ */
+ int m_position;
+
+ /**
+ * Filter coefficients.
+ */
+ float m_coeff[2][AUD_LOWPASS_ORDER];
+
+public:
+ /**
+ * Creates a new lowpass reader.
+ * \param reader The reader to read from.
+ * \param frequency The cutoff frequency.
+ * \param Q The Q factor.
+ * \exception AUD_Exception Thrown if the reader specified is NULL.
+ */
+ AUD_LowpassReader(AUD_IReader* reader, float frequency, float Q);
+
+ /**
+ * Destroys the reader.
+ */
+ virtual ~AUD_LowpassReader();
+
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_LOWPASSREADER
diff --git a/intern/audaspace/FX/AUD_PitchFactory.h b/intern/audaspace/FX/AUD_PitchFactory.h
index 3209aa46983..96c4d0d7e92 100644
--- a/intern/audaspace/FX/AUD_PitchFactory.h
+++ b/intern/audaspace/FX/AUD_PitchFactory.h
@@ -45,7 +45,7 @@ public:
* \param factory The input factory.
* \param pitch The desired pitch.
*/
- AUD_PitchFactory(AUD_IFactory* factory = 0, float pitch = 1.0);
+ AUD_PitchFactory(AUD_IFactory* factory = 0, float pitch = 1.0f);
/**
* Creates a new pitch factory.
diff --git a/intern/audaspace/FX/AUD_RectifyReader.cpp b/intern/audaspace/FX/AUD_RectifyReader.cpp
index 9839aefa838..5d3ce80e811 100644
--- a/intern/audaspace/FX/AUD_RectifyReader.cpp
+++ b/intern/audaspace/FX/AUD_RectifyReader.cpp
@@ -26,39 +26,11 @@
#include "AUD_RectifyReader.h"
#include "AUD_Buffer.h"
-#include <cstring>
+#include <cmath>
AUD_RectifyReader::AUD_RectifyReader(AUD_IReader* reader) :
AUD_EffectReader(reader)
{
- int bigendian = 1;
- bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
-
- switch(m_reader->getSpecs().format)
- {
- case AUD_FORMAT_S16:
- m_rectify = AUD_rectify<int16_t>;
- break;
- case AUD_FORMAT_S32:
- m_rectify = AUD_rectify<int32_t>;
- break;
- case AUD_FORMAT_FLOAT32:
- m_rectify = AUD_rectify<float>;
- break;
- case AUD_FORMAT_FLOAT64:
- m_rectify = AUD_rectify<double>;
- break;
- case AUD_FORMAT_U8:
- m_rectify = AUD_rectify_u8;
- break;
- case AUD_FORMAT_S24:
- m_rectify = bigendian ? AUD_rectify_s24_be : AUD_rectify_s24_le;
- break;
- default:
- delete m_reader;
- AUD_THROW(AUD_ERROR_READER);
- }
-
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
}
@@ -73,10 +45,11 @@ void AUD_RectifyReader::read(int & length, sample_t* & buffer)
AUD_Specs specs = m_reader->getSpecs();
m_reader->read(length, buf);
- if(m_buffer->getSize() < length*AUD_SAMPLE_SIZE(specs))
- m_buffer->resize(length*AUD_SAMPLE_SIZE(specs));
+ if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs))
+ m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
buffer = m_buffer->getBuffer();
- m_rectify(buffer, buf, length * specs.channels);
+ for(int i = 0; i < length * specs.channels; i++)
+ buffer[i] = fabs(buf[i]);
}
diff --git a/intern/audaspace/FX/AUD_RectifyReader.h b/intern/audaspace/FX/AUD_RectifyReader.h
index 17423811cdc..afbe2e59cab 100644
--- a/intern/audaspace/FX/AUD_RectifyReader.h
+++ b/intern/audaspace/FX/AUD_RectifyReader.h
@@ -27,7 +27,6 @@
#define AUD_RECTIFYREADER
#include "AUD_EffectReader.h"
-#include "AUD_ConverterFunctions.h"
class AUD_Buffer;
/**
@@ -41,11 +40,6 @@ private:
*/
AUD_Buffer *m_buffer;
- /**
- * Rectifying function.
- */
- AUD_rectify_f m_rectify;
-
public:
/**
* Creates a new rectify reader.
diff --git a/intern/audaspace/FX/AUD_ReverseReader.cpp b/intern/audaspace/FX/AUD_ReverseReader.cpp
index 043480b91b9..82d6c70ce53 100644
--- a/intern/audaspace/FX/AUD_ReverseReader.cpp
+++ b/intern/audaspace/FX/AUD_ReverseReader.cpp
@@ -65,7 +65,7 @@ int AUD_ReverseReader::getPosition()
void AUD_ReverseReader::read(int & length, sample_t* & buffer)
{
// first correct the length
- if(m_position+length > m_length)
+ if(m_position + length > m_length)
length = m_length-m_position;
if(length <= 0)
@@ -74,7 +74,8 @@ void AUD_ReverseReader::read(int & length, sample_t* & buffer)
return;
}
- int samplesize = AUD_SAMPLE_SIZE(getSpecs());
+ AUD_Specs specs = getSpecs();
+ int samplesize = AUD_SAMPLE_SIZE(specs);
// resize buffer if needed
if(m_buffer->getSize() < length * samplesize)
@@ -86,23 +87,20 @@ void AUD_ReverseReader::read(int & length, sample_t* & buffer)
int len = length;
// read from reader
- m_reader->seek(m_length-m_position-len);
+ m_reader->seek(m_length - m_position - len);
m_reader->read(len, buf);
// set null if reader didn't give enough data
if(len < length)
{
- if(getSpecs().format == AUD_FORMAT_U8)
- memset(buffer, 0x80, (length-len)*samplesize);
- else
- memset(buffer, 0, (length-len)*samplesize);
- buffer += length-len;
+ memset(buffer, 0, (length - len) * samplesize);
+ buffer += (length - len) * specs.channels;
}
// copy the samples reverted
for(int i = 0; i < len; i++)
- memcpy(buffer + i * samplesize,
- buf + (len - 1 - i) * samplesize,
+ memcpy(buffer + i * specs.channels,
+ buf + (len - 1 - i) * specs.channels,
samplesize);
m_position += length;
diff --git a/intern/audaspace/FX/AUD_SquareFactory.cpp b/intern/audaspace/FX/AUD_SquareFactory.cpp
new file mode 100644
index 00000000000..638acaa9a32
--- /dev/null
+++ b/intern/audaspace/FX/AUD_SquareFactory.cpp
@@ -0,0 +1,57 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_SquareFactory.h"
+#include "AUD_SquareReader.h"
+
+AUD_SquareFactory::AUD_SquareFactory(AUD_IFactory* factory, float threshold) :
+ AUD_EffectFactory(factory),
+ m_threshold(threshold) {}
+
+AUD_SquareFactory::AUD_SquareFactory(float threshold) :
+ AUD_EffectFactory(0),
+ m_threshold(threshold) {}
+
+float AUD_SquareFactory::getThreshold()
+{
+ return m_threshold;
+}
+
+void AUD_SquareFactory::setThreshold(float threshold)
+{
+ m_threshold = threshold;
+}
+
+AUD_IReader* AUD_SquareFactory::createReader()
+{
+ AUD_IReader* reader = getReader();
+
+ if(reader != 0)
+ {
+ reader = new AUD_SquareReader(reader, m_threshold); AUD_NEW("reader")
+ }
+
+ return reader;
+}
diff --git a/intern/audaspace/SDL/AUD_SDLMixer.h b/intern/audaspace/FX/AUD_SquareFactory.h
index 2cc4e51f66d..dfbe5ae2887 100644
--- a/intern/audaspace/SDL/AUD_SDLMixer.h
+++ b/intern/audaspace/FX/AUD_SquareFactory.h
@@ -23,54 +23,48 @@
* ***** END LGPL LICENSE BLOCK *****
*/
-#ifndef AUD_SDLMIXER
-#define AUD_SDLMIXER
+#ifndef AUD_SQUAREFACTORY
+#define AUD_SQUAREFACTORY
-#include "AUD_IMixer.h"
-class AUD_SDLMixerFactory;
-#include <list>
-
-struct AUD_SDLMixerBuffer
-{
- sample_t* buffer;
- int length;
- float volume;
-};
+#include "AUD_EffectFactory.h"
/**
- * This class is able to mix audiosignals with the help of SDL.
+ * This factory Transforms any signal to a square signal.
*/
-class AUD_SDLMixer : public AUD_IMixer
+class AUD_SquareFactory : public AUD_EffectFactory
{
private:
/**
- * The mixer factory that prepares all readers for superposition.
+ * The threshold.
*/
- AUD_SDLMixerFactory* m_factory;
+ float m_threshold;
+public:
/**
- * The list of buffers to superpose.
+ * Creates a new square factory.
+ * \param factory The input factory.
+ * \param threshold The threshold.
*/
- std::list<AUD_SDLMixerBuffer> m_buffers;
+ AUD_SquareFactory(AUD_IFactory* factory = 0, float threshold = 0.0f);
/**
- * The size of an output sample.
+ * Creates a new square factory.
+ * \param threshold The threshold.
*/
- int m_samplesize;
+ AUD_SquareFactory(float threshold);
-public:
/**
- * Creates the mixer.
+ * Returns the threshold.
*/
- AUD_SDLMixer();
+ float getThreshold();
- virtual ~AUD_SDLMixer();
+ /**
+ * Sets the threshold.
+ * \param threshold The new threshold value. Should be between 0.0 and 1.0.
+ */
+ void setThreshold(float threshold);
- virtual AUD_IReader* prepare(AUD_IReader* reader);
- virtual void setSpecs(AUD_Specs specs);
- virtual void add(sample_t* buffer, AUD_Specs specs, int length,
- float volume);
- virtual void superpose(sample_t* buffer, int length, float volume);
+ virtual AUD_IReader* createReader();
};
-#endif //AUD_SDLMIXER
+#endif //AUD_SQUAREFACTORY
diff --git a/intern/audaspace/FX/AUD_SquareReader.cpp b/intern/audaspace/FX/AUD_SquareReader.cpp
new file mode 100644
index 00000000000..2d4dc52fe27
--- /dev/null
+++ b/intern/audaspace/FX/AUD_SquareReader.cpp
@@ -0,0 +1,63 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_SquareReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+
+AUD_SquareReader::AUD_SquareReader(AUD_IReader* reader, float threshold) :
+ AUD_EffectReader(reader),
+ m_threshold(threshold)
+{
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+}
+
+AUD_SquareReader::~AUD_SquareReader()
+{
+ delete m_buffer; AUD_DELETE("buffer")
+}
+
+void AUD_SquareReader::read(int & length, sample_t* & buffer)
+{
+ sample_t* buf;
+ AUD_Specs specs = m_reader->getSpecs();
+
+ m_reader->read(length, buf);
+ if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs))
+ m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
+
+ buffer = m_buffer->getBuffer();
+
+ for(int i = 0; i < length * specs.channels; i++)
+ {
+ if(buf[i] >= m_threshold)
+ buffer[i] = 1.0f;
+ else if(buf[i] <= -m_threshold)
+ buffer[i] = -1.0f;
+ else
+ buffer[i] = 0.0f;
+ }
+}
diff --git a/intern/audaspace/FX/AUD_SquareReader.h b/intern/audaspace/FX/AUD_SquareReader.h
new file mode 100644
index 00000000000..63dda351445
--- /dev/null
+++ b/intern/audaspace/FX/AUD_SquareReader.h
@@ -0,0 +1,65 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_SQUAREREADER
+#define AUD_SQUAREREADER
+
+#include "AUD_EffectReader.h"
+class AUD_Buffer;
+
+/**
+ * This class changes another signal into a square signal.
+ */
+class AUD_SquareReader : public AUD_EffectReader
+{
+private:
+ /**
+ * The playback buffer.
+ */
+ AUD_Buffer *m_buffer;
+
+ /**
+ * The threshold level.
+ */
+ float m_threshold;
+
+public:
+ /**
+ * Creates a new square reader.
+ * \param reader The reader to read from.
+ * \param threshold The size of the buffer.
+ * \exception AUD_Exception Thrown if the reader specified is NULL.
+ */
+ AUD_SquareReader(AUD_IReader* reader, float threshold);
+
+ /**
+ * Destroys the reader.
+ */
+ virtual ~AUD_SquareReader();
+
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_SQUAREREADER
diff --git a/intern/audaspace/FX/AUD_SumFactory.cpp b/intern/audaspace/FX/AUD_SumFactory.cpp
new file mode 100644
index 00000000000..f7990aab8a1
--- /dev/null
+++ b/intern/audaspace/FX/AUD_SumFactory.cpp
@@ -0,0 +1,43 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_SumFactory.h"
+#include "AUD_SumReader.h"
+
+AUD_SumFactory::AUD_SumFactory(AUD_IFactory* factory) :
+ AUD_EffectFactory(factory) {}
+
+AUD_IReader* AUD_SumFactory::createReader()
+{
+ AUD_IReader* reader = getReader();
+
+ if(reader != 0)
+ {
+ reader = new AUD_SumReader(reader);
+ AUD_NEW("reader")
+ }
+
+ return reader;
+}
diff --git a/intern/audaspace/SDL/AUD_SDLMixerFactory.h b/intern/audaspace/FX/AUD_SumFactory.h
index 44b36d06859..5cb48e26b10 100644
--- a/intern/audaspace/SDL/AUD_SDLMixerFactory.h
+++ b/intern/audaspace/FX/AUD_SumFactory.h
@@ -23,23 +23,24 @@
* ***** END LGPL LICENSE BLOCK *****
*/
-#ifndef AUD_SDLMIXERFACTORY
-#define AUD_SDLMIXERFACTORY
+#ifndef AUD_SUMFACTORY
+#define AUD_SUMFACTORY
-#include "AUD_MixerFactory.h"
+#include "AUD_EffectFactory.h"
/**
- * This factory creates a resampling reader that uses SDL's resampling
- * functionality which unfortunately is very very very limited.
+ * This factory creates a sum reader.
*/
-class AUD_SDLMixerFactory : public AUD_MixerFactory
+class AUD_SumFactory : public AUD_EffectFactory
{
public:
- AUD_SDLMixerFactory(AUD_IReader* reader, AUD_Specs specs);
- AUD_SDLMixerFactory(AUD_IFactory* factory, AUD_Specs specs);
- AUD_SDLMixerFactory(AUD_Specs specs);
+ /**
+ * Creates a new sum factory.
+ * \param factory The input factory.
+ */
+ AUD_SumFactory(AUD_IFactory* factory = 0);
virtual AUD_IReader* createReader();
};
-#endif //AUD_SDLMIXERFACTORY
+#endif //AUD_SUMFACTORY
diff --git a/intern/audaspace/FX/AUD_SumReader.cpp b/intern/audaspace/FX/AUD_SumReader.cpp
new file mode 100644
index 00000000000..08747790fc9
--- /dev/null
+++ b/intern/audaspace/FX/AUD_SumReader.cpp
@@ -0,0 +1,68 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_SumReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+
+#define CC specs.channels + channel
+
+AUD_SumReader::AUD_SumReader(AUD_IReader* reader) :
+ AUD_EffectReader(reader)
+{
+ AUD_Specs specs = reader->getSpecs();
+ int samplesize = AUD_SAMPLE_SIZE(specs);
+
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+
+ m_sums = new AUD_Buffer(samplesize); AUD_NEW("buffer")
+ memset(m_sums->getBuffer(), 0, samplesize);
+}
+
+AUD_SumReader::~AUD_SumReader()
+{
+ delete m_buffer; AUD_DELETE("buffer")
+ delete m_sums; AUD_DELETE("buffer")
+}
+
+void AUD_SumReader::read(int & length, sample_t* & buffer)
+{
+ sample_t* buf;
+ sample_t* sums;
+ sums = m_sums->getBuffer();
+
+ AUD_Specs specs = m_reader->getSpecs();
+
+ m_reader->read(length, buf);
+ if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs))
+ m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
+
+ buffer = m_buffer->getBuffer();
+
+ for(int channel = 0; channel < specs.channels; channel++)
+ for(int i = 0; i < length * specs.channels; i++)
+ buffer[i * CC] = sums[channel] = sums[channel] + buf[i * CC];
+}
diff --git a/intern/audaspace/FX/AUD_SumReader.h b/intern/audaspace/FX/AUD_SumReader.h
new file mode 100644
index 00000000000..76ccf2f863a
--- /dev/null
+++ b/intern/audaspace/FX/AUD_SumReader.h
@@ -0,0 +1,64 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_SUMREADER
+#define AUD_SUMREADER
+
+#include "AUD_EffectReader.h"
+class AUD_Buffer;
+
+/**
+ * This class represents an summer.
+ */
+class AUD_SumReader : public AUD_EffectReader
+{
+private:
+ /**
+ * The playback buffer.
+ */
+ AUD_Buffer *m_buffer;
+
+ /**
+ * The sums of the specific channels.
+ */
+ AUD_Buffer *m_sums;
+
+public:
+ /**
+ * Creates a new sum reader.
+ * \param reader The reader to read from.
+ * \exception AUD_Exception Thrown if the reader specified is NULL.
+ */
+ AUD_SumReader(AUD_IReader* reader);
+
+ /**
+ * Destroys the reader.
+ */
+ virtual ~AUD_SumReader();
+
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_SUMREADER
diff --git a/intern/audaspace/FX/AUD_VolumeFactory.h b/intern/audaspace/FX/AUD_VolumeFactory.h
index d2812536d83..09f91241b47 100644
--- a/intern/audaspace/FX/AUD_VolumeFactory.h
+++ b/intern/audaspace/FX/AUD_VolumeFactory.h
@@ -47,7 +47,7 @@ public:
* \param factory The input factory.
* \param volume The desired volume.
*/
- AUD_VolumeFactory(AUD_IFactory* factory = 0, float volume = 1.0);
+ AUD_VolumeFactory(AUD_IFactory* factory = 0, float volume = 1.0f);
/**
* Creates a new volume factory.
diff --git a/intern/audaspace/FX/AUD_VolumeReader.cpp b/intern/audaspace/FX/AUD_VolumeReader.cpp
index fc3f20152a6..f094c1e4ea3 100644
--- a/intern/audaspace/FX/AUD_VolumeReader.cpp
+++ b/intern/audaspace/FX/AUD_VolumeReader.cpp
@@ -32,35 +32,6 @@ AUD_VolumeReader::AUD_VolumeReader(AUD_IReader* reader, float volume) :
AUD_EffectReader(reader),
m_volume(volume)
{
- int bigendian = 1;
- bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
-
- switch(m_reader->getSpecs().format)
- {
- case AUD_FORMAT_S16:
- m_adjust = AUD_volume_adjust<int16_t>;
- break;
- case AUD_FORMAT_S32:
- m_adjust = AUD_volume_adjust<int32_t>;
- break;
- case AUD_FORMAT_FLOAT32:
- m_adjust = AUD_volume_adjust<float>;
- break;
- case AUD_FORMAT_FLOAT64:
- m_adjust = AUD_volume_adjust<double>;
- break;
- case AUD_FORMAT_U8:
- m_adjust = AUD_volume_adjust_u8;
- break;
- case AUD_FORMAT_S24:
- m_adjust = bigendian ? AUD_volume_adjust_s24_be :
- AUD_volume_adjust_s24_le;
- break;
- default:
- delete m_reader;
- AUD_THROW(AUD_ERROR_READER);
- }
-
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
}
@@ -93,5 +64,6 @@ void AUD_VolumeReader::read(int & length, sample_t* & buffer)
buffer = m_buffer->getBuffer();
- m_adjust(buffer, buf, length * specs.channels, m_volume);
+ for(int i = 0; i < length * specs.channels; i++)
+ buffer[i] = buf[i] * m_volume;
}
diff --git a/intern/audaspace/FX/AUD_VolumeReader.h b/intern/audaspace/FX/AUD_VolumeReader.h
index f38ae4d265c..489f85b10f2 100644
--- a/intern/audaspace/FX/AUD_VolumeReader.h
+++ b/intern/audaspace/FX/AUD_VolumeReader.h
@@ -27,7 +27,6 @@
#define AUD_VOLUMEREADER
#include "AUD_EffectReader.h"
-#include "AUD_ConverterFunctions.h"
class AUD_Buffer;
/**
@@ -46,11 +45,6 @@ private:
*/
float m_volume;
- /**
- * Volume adjustment function.
- */
- AUD_volume_adjust_f m_adjust;
-
public:
/**
* Creates a new volume reader.
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
index aa9f425d6fb..0d90b014943 100644
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
+++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
@@ -25,7 +25,6 @@
#include "AUD_OpenALDevice.h"
#include "AUD_IReader.h"
-#include "AUD_IMixer.h"
#include "AUD_ConverterFactory.h"
#include "AUD_SourceCaps.h"
@@ -119,7 +118,7 @@ void AUD_OpenALDevice::updateStreams()
sample_t* buffer;
ALint info;
- AUD_Specs specs;
+ AUD_DeviceSpecs specs = m_specs;
while(1)
{
@@ -145,7 +144,7 @@ void AUD_OpenALDevice::updateStreams()
if(info)
{
- specs = sound->reader->getSpecs();
+ specs.specs = sound->reader->getSpecs();
// for all empty buffers
while(info--)
@@ -177,8 +176,8 @@ void AUD_OpenALDevice::updateStreams()
// fill with new data
alBufferData(sound->buffers[sound->current],
sound->format,
- buffer,
- length * AUD_SAMPLE_SIZE(specs),
+ buffer, length *
+ AUD_DEVICE_SAMPLE_SIZE(specs),
specs.rate);
if(alGetError() != AL_NO_ERROR)
@@ -264,7 +263,7 @@ bool AUD_OpenALDevice::isValid(AUD_Handle* handle)
return false;
}
-AUD_OpenALDevice::AUD_OpenALDevice(AUD_Specs specs, int buffersize)
+AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize)
{
// cannot determine how many channels or which format OpenAL uses, but
// it at least is able to play 16 bit stereo audio
@@ -289,14 +288,17 @@ AUD_OpenALDevice::AUD_OpenALDevice(AUD_Specs specs, int buffersize)
// check for specific formats and channel counts to be played back
if(alIsExtensionPresent("AL_EXT_FLOAT32") == AL_TRUE)
+ {
specs.format = AUD_FORMAT_FLOAT32;
+ m_converter = NULL;
+ }
+ else
+ m_converter = new AUD_ConverterFactory(specs); AUD_NEW("factory")
m_useMC = alIsExtensionPresent("AL_EXT_MCFORMATS") == AL_TRUE;
alGetError();
- m_converter = new AUD_ConverterFactory(specs); AUD_NEW("factory")
-
m_specs = specs;
m_buffersize = buffersize;
m_playing = false;
@@ -378,12 +380,13 @@ AUD_OpenALDevice::~AUD_OpenALDevice()
alcDestroyContext(m_context);
alcCloseDevice(m_device);
- delete m_converter; AUD_DELETE("factory")
+ if(m_converter)
+ delete m_converter; AUD_DELETE("factory")
pthread_mutex_destroy(&m_mutex);
}
-AUD_Specs AUD_OpenALDevice::getSpecs()
+AUD_DeviceSpecs AUD_OpenALDevice::getSpecs()
{
return m_specs;
}
@@ -393,45 +396,8 @@ bool AUD_OpenALDevice::getFormat(ALenum &format, AUD_Specs specs)
bool valid = true;
format = 0;
- switch(specs.format)
+ switch(m_specs.format)
{
- case AUD_FORMAT_U8:
- switch(specs.channels)
- {
- case AUD_CHANNELS_MONO:
- format = AL_FORMAT_MONO8;
- break;
- case AUD_CHANNELS_STEREO:
- format = AL_FORMAT_STEREO8;
- break;
- case AUD_CHANNELS_SURROUND4:
- if(m_useMC)
- {
- format = alGetEnumValue("AL_FORMAT_QUAD8");
- break;
- }
- case AUD_CHANNELS_SURROUND51:
- if(m_useMC)
- {
- format = alGetEnumValue("AL_FORMAT_51CHN8");
- break;
- }
- case AUD_CHANNELS_SURROUND61:
- if(m_useMC)
- {
- format = alGetEnumValue("AL_FORMAT_61CHN8");
- break;
- }
- case AUD_CHANNELS_SURROUND71:
- if(m_useMC)
- {
- format = alGetEnumValue("AL_FORMAT_71CHN8");
- break;
- }
- default:
- valid = false;
- }
- break;
case AUD_FORMAT_S16:
switch(specs.channels)
{
@@ -591,23 +557,16 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
if(reader == NULL)
AUD_THROW(AUD_ERROR_READER);
- AUD_Specs specs;
-
- specs = reader->getSpecs();
+ AUD_DeviceSpecs specs = m_specs;
+ specs.specs = reader->getSpecs();
// check format
- bool valid = true;
+ bool valid = specs.channels != AUD_CHANNELS_INVALID;
- if(specs.format == AUD_FORMAT_INVALID)
- valid = false;
- else if(specs.format == AUD_FORMAT_S24 ||
- specs.format == AUD_FORMAT_S32 ||
- specs.format == AUD_FORMAT_FLOAT32 ||
- specs.format == AUD_FORMAT_FLOAT64)
+ if(m_converter)
{
m_converter->setReader(reader);
reader = m_converter->createReader();
- specs = reader->getSpecs();
}
// create the handle
@@ -618,7 +577,7 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
sound->isBuffered = false;
sound->data_end = false;
- valid &= getFormat(sound->format, specs);
+ valid &= getFormat(sound->format, specs.specs);
if(!valid)
{
@@ -647,7 +606,8 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
length = m_buffersize;
reader->read(length, buf);
alBufferData(sound->buffers[i], sound->format, buf,
- length * AUD_SAMPLE_SIZE(specs), specs.rate);
+ length * AUD_DEVICE_SAMPLE_SIZE(specs),
+ specs.rate);
if(alGetError() != AL_NO_ERROR)
AUD_THROW(AUD_ERROR_OPENAL);
}
@@ -875,14 +835,16 @@ bool AUD_OpenALDevice::seek(AUD_Handle* handle, float position)
{
sample_t* buf;
int length;
- AUD_Specs specs = alhandle->reader->getSpecs();
+ AUD_DeviceSpecs specs = m_specs;
+ specs.specs = alhandle->reader->getSpecs();
for(int i = 0; i < AUD_OPENAL_CYCLE_BUFFERS; i++)
{
length = m_buffersize;
alhandle->reader->read(length, buf);
alBufferData(alhandle->buffers[i], alhandle->format,
- buf, length * AUD_SAMPLE_SIZE(specs),
+ buf,
+ length * AUD_DEVICE_SAMPLE_SIZE(specs),
specs.rate);
if(alGetError() != AL_NO_ERROR)
@@ -906,7 +868,7 @@ bool AUD_OpenALDevice::seek(AUD_Handle* handle, float position)
float AUD_OpenALDevice::getPosition(AUD_Handle* handle)
{
- float position = 0.0;
+ float position = 0.0f;
lock();
@@ -1021,6 +983,7 @@ bool AUD_OpenALDevice::setCapability(int capability, void *value)
// load the factory into an OpenAL buffer
if(factory)
{
+ // check if the factory is already buffered
lock();
for(AUD_BFIterator i = m_bufferedFactories->begin();
i != m_bufferedFactories->end(); i++)
@@ -1040,32 +1003,25 @@ bool AUD_OpenALDevice::setCapability(int capability, void *value)
if(reader == NULL)
return false;
- AUD_Specs specs;
-
- specs = reader->getSpecs();
+ AUD_DeviceSpecs specs = m_specs;
+ specs.specs = reader->getSpecs();
// determine format
bool valid = reader->getType() == AUD_TYPE_BUFFER;
if(valid)
{
- if(specs.format == AUD_FORMAT_INVALID)
- valid = false;
- else if(specs.format == AUD_FORMAT_S24 ||
- specs.format == AUD_FORMAT_S32 ||
- specs.format == AUD_FORMAT_FLOAT32 ||
- specs.format == AUD_FORMAT_FLOAT64)
+ if(m_converter)
{
m_converter->setReader(reader);
reader = m_converter->createReader();
- specs = reader->getSpecs();
}
}
ALenum format;
if(valid)
- valid = getFormat(format, specs);
+ valid = getFormat(format, specs.specs);
if(!valid)
{
@@ -1094,7 +1050,7 @@ bool AUD_OpenALDevice::setCapability(int capability, void *value)
reader->read(length, buf);
alBufferData(bf->buffer, format, buf,
- length * AUD_SAMPLE_SIZE(specs),
+ length * AUD_DEVICE_SAMPLE_SIZE(specs),
specs.rate);
if(alGetError() != AL_NO_ERROR)
AUD_THROW(AUD_ERROR_OPENAL);
@@ -1327,7 +1283,7 @@ bool AUD_OpenALDevice::setSourceSetting(AUD_Handle* handle,
result = true;
break;
case AUD_3DSS_IS_RELATIVE:
- alSourcei(source, AL_SOURCE_RELATIVE, value > 0.0);
+ alSourcei(source, AL_SOURCE_RELATIVE, value > 0.0f);
result = true;
break;
case AUD_3DSS_MAX_DISTANCE:
@@ -1385,7 +1341,7 @@ float AUD_OpenALDevice::getSourceSetting(AUD_Handle* handle,
{
ALint i;
alGetSourcei(source, AL_SOURCE_RELATIVE, &i);
- result = i ? 1.0 : 0.0;
+ result = i ? 1.0f : 0.0f;
break;
}
case AUD_3DSS_MAX_DISTANCE:
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.h b/intern/audaspace/OpenAL/AUD_OpenALDevice.h
index 074cd3d1924..cb8c83ab810 100644
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.h
+++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.h
@@ -56,7 +56,7 @@ private:
/**
* The specification of the device.
*/
- AUD_Specs m_specs;
+ AUD_DeviceSpecs m_specs;
/**
* Whether the device has the AL_EXT_MCFORMATS extension.
@@ -64,8 +64,8 @@ private:
bool m_useMC;
/**
- * The converter factory for readers with wrong input format.
- */
+ * The converter factory for readers with wrong input format.
+ */
AUD_ConverterFactory* m_converter;
/**
@@ -118,7 +118,7 @@ private:
/**
* Gets the format according to the specs.
* \param format The variable to put the format into.
- * \param specs The specs to read the format from.
+ * \param specs The specs to read the channel count from.
* \return Whether the format is valid or not.
*/
bool getFormat(ALenum &format, AUD_Specs specs);
@@ -132,7 +132,8 @@ public:
* \note The buffersize will be multiplicated by three for this device.
* \exception AUD_Exception Thrown if the audio device cannot be opened.
*/
- AUD_OpenALDevice(AUD_Specs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);
+ AUD_OpenALDevice(AUD_DeviceSpecs specs,
+ int buffersize = AUD_DEFAULT_BUFFER_SIZE);
/**
* Streaming thread main function.
@@ -141,7 +142,7 @@ public:
virtual ~AUD_OpenALDevice();
- virtual AUD_Specs getSpecs();
+ virtual AUD_DeviceSpecs getSpecs();
virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
virtual bool pause(AUD_Handle* handle);
virtual bool resume(AUD_Handle* handle);
diff --git a/intern/audaspace/SConscript b/intern/audaspace/SConscript
index ac3f8ca71a0..bbd2442c480 100644
--- a/intern/audaspace/SConscript
+++ b/intern/audaspace/SConscript
@@ -36,4 +36,7 @@ if env['WITH_BF_FFTW3']:
incs += ' fftw ' + env['BF_FFTW3_INC']
defs.append('WITH_FFTW3')
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
+ incs += ' ' + env['BF_PTHREADS_INC']
+
env.BlenderLib ('bf_audaspace', sources, Split(incs), defs, libtype=['intern','player'], priority = [25,215] )
diff --git a/intern/audaspace/SDL/AUD_SDLDevice.cpp b/intern/audaspace/SDL/AUD_SDLDevice.cpp
index dd443e7f5c7..1a385af8a0c 100644
--- a/intern/audaspace/SDL/AUD_SDLDevice.cpp
+++ b/intern/audaspace/SDL/AUD_SDLDevice.cpp
@@ -23,7 +23,6 @@
* ***** END LGPL LICENSE BLOCK *****
*/
-#include "AUD_SDLMixer.h"
#include "AUD_SDLDevice.h"
#include "AUD_IReader.h"
@@ -31,10 +30,10 @@ void AUD_SDLDevice::SDL_mix(void *data, Uint8* buffer, int length)
{
AUD_SDLDevice* device = (AUD_SDLDevice*)data;
- device->mix((sample_t*)buffer, length/AUD_SAMPLE_SIZE(device->m_specs));
+ device->mix((data_t*)buffer,length/AUD_DEVICE_SAMPLE_SIZE(device->m_specs));
}
-AUD_SDLDevice::AUD_SDLDevice(AUD_Specs specs, int buffersize)
+AUD_SDLDevice::AUD_SDLDevice(AUD_DeviceSpecs specs, int buffersize)
{
if(specs.channels == AUD_CHANNELS_INVALID)
specs.channels = AUD_CHANNELS_STEREO;
@@ -69,9 +68,6 @@ AUD_SDLDevice::AUD_SDLDevice(AUD_Specs specs, int buffersize)
else
AUD_THROW(AUD_ERROR_SDL);
- m_mixer = new AUD_SDLMixer(); AUD_NEW("mixer")
- m_mixer->setSpecs(m_specs);
-
create();
}
diff --git a/intern/audaspace/SDL/AUD_SDLDevice.h b/intern/audaspace/SDL/AUD_SDLDevice.h
index e2c6f7631b7..4b7de1996e8 100644
--- a/intern/audaspace/SDL/AUD_SDLDevice.h
+++ b/intern/audaspace/SDL/AUD_SDLDevice.h
@@ -55,7 +55,8 @@ public:
* \note The specification really used for opening the device may differ.
* \exception AUD_Exception Thrown if the audio device cannot be opened.
*/
- AUD_SDLDevice(AUD_Specs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);
+ AUD_SDLDevice(AUD_DeviceSpecs specs,
+ int buffersize = AUD_DEFAULT_BUFFER_SIZE);
/**
* Closes the SDL audio device.
diff --git a/intern/audaspace/SDL/AUD_SDLMixer.cpp b/intern/audaspace/SDL/AUD_SDLMixer.cpp
deleted file mode 100644
index cacc0c7063c..00000000000
--- a/intern/audaspace/SDL/AUD_SDLMixer.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * $Id$
- *
- * ***** BEGIN LGPL LICENSE BLOCK *****
- *
- * Copyright 2009 Jörg Hermann Müller
- *
- * This file is part of AudaSpace.
- *
- * AudaSpace is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * AudaSpace 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
- *
- * ***** END LGPL LICENSE BLOCK *****
- */
-
-#include "AUD_SDLMixer.h"
-#include "AUD_SDLMixerFactory.h"
-
-#include <SDL.h>
-
-AUD_SDLMixer::AUD_SDLMixer()
-{
- m_factory = NULL;
-}
-
-AUD_SDLMixer::~AUD_SDLMixer()
-{
- if(m_factory)
- {
- delete m_factory; AUD_DELETE("factory")
- }
-}
-
-AUD_IReader* AUD_SDLMixer::prepare(AUD_IReader* reader)
-{
- m_factory->setReader(reader);
- return m_factory->createReader();
-}
-
-void AUD_SDLMixer::setSpecs(AUD_Specs specs)
-{
- m_samplesize = AUD_SAMPLE_SIZE(specs);
- if(m_factory)
- {
- delete m_factory; AUD_DELETE("factory")
- }
- m_factory = new AUD_SDLMixerFactory(specs); AUD_NEW("factory")
-}
-
-void AUD_SDLMixer::add(sample_t* buffer, AUD_Specs specs, int length,
- float volume)
-{
- AUD_SDLMixerBuffer buf;
- buf.buffer = buffer;
- buf.length = length;
- buf.volume = volume;
- m_buffers.push_back(buf);
-}
-
-void AUD_SDLMixer::superpose(sample_t* buffer, int length, float volume)
-{
- AUD_SDLMixerBuffer buf;
-
- while(!m_buffers.empty())
- {
- buf = m_buffers.front();
- m_buffers.pop_front();
- SDL_MixAudio((Uint8*)buffer,
- (Uint8*)buf.buffer,
- buf.length * m_samplesize,
- (int)(SDL_MIX_MAXVOLUME * volume * buf.volume));
- }
-}
diff --git a/intern/audaspace/SDL/AUD_SDLMixerReader.cpp b/intern/audaspace/SDL/AUD_SDLMixerReader.cpp
deleted file mode 100644
index 0a47e36533a..00000000000
--- a/intern/audaspace/SDL/AUD_SDLMixerReader.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * $Id$
- *
- * ***** BEGIN LGPL LICENSE BLOCK *****
- *
- * Copyright 2009 Jörg Hermann Müller
- *
- * This file is part of AudaSpace.
- *
- * AudaSpace is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * AudaSpace 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
- *
- * ***** END LGPL LICENSE BLOCK *****
- */
-
-#include "AUD_SDLMixerReader.h"
-#include "AUD_Buffer.h"
-
-#include <cstring>
-
-inline Uint16 AUD_TO_SDL(AUD_SampleFormat format)
-{
- // SDL only supports 8 and 16 bit audio
- switch(format)
- {
- case AUD_FORMAT_U8:
- return AUDIO_U8;
- case AUD_FORMAT_S16:
- return AUDIO_S16SYS;
- default:
- AUD_THROW(AUD_ERROR_SDL);
- }
-}
-
-// greatest common divisor
-inline int gcd(int a, int b)
-{
- int c;
-
- // make sure a is the bigger
- if(b > a)
- {
- c = b;
- b = a;
- a = c;
- }
-
- // greetings from Euclides
- while(b != 0)
- {
- c = a % b;
- a = b;
- b = c;
- }
- return a;
-}
-
-AUD_SDLMixerReader::AUD_SDLMixerReader(AUD_IReader* reader,
- AUD_Specs specs)
-{
- if(reader == NULL)
- AUD_THROW(AUD_ERROR_READER);
-
- m_reader = reader;
- m_tspecs = specs;
- m_sspecs = reader->getSpecs();
-
- try
- {
- // SDL only supports 8 and 16 bit sample formats
- if(SDL_BuildAudioCVT(&m_cvt,
- AUD_TO_SDL(m_sspecs.format),
- m_sspecs.channels,
- m_sspecs.rate,
- AUD_TO_SDL(specs.format),
- specs.channels,
- specs.rate) == -1)
- AUD_THROW(AUD_ERROR_SDL);
- }
- catch(AUD_Exception)
- {
- delete m_reader; AUD_DELETE("reader")
- throw;
- }
-
- m_eor = false;
- m_rsposition = 0;
- m_rssize = 0;
- m_ssize = m_sspecs.rate / gcd(specs.rate, m_sspecs.rate);
- m_tsize = m_tspecs.rate * m_ssize / m_sspecs.rate;
-
- m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
- m_rsbuffer = new AUD_Buffer(); AUD_NEW("buffer")
-}
-
-AUD_SDLMixerReader::~AUD_SDLMixerReader()
-{
- delete m_reader; AUD_DELETE("reader")
- delete m_buffer; AUD_DELETE("buffer")
- delete m_rsbuffer; AUD_DELETE("buffer")
-}
-
-bool AUD_SDLMixerReader::isSeekable()
-{
- return m_reader->isSeekable();
-}
-
-void AUD_SDLMixerReader::seek(int position)
-{
- m_reader->seek(position * m_ssize / m_tsize);
- m_eor = false;
-}
-
-int AUD_SDLMixerReader::getLength()
-{
- return m_reader->getLength() * m_tsize / m_ssize;
-}
-
-int AUD_SDLMixerReader::getPosition()
-{
- return m_reader->getPosition() * m_tsize / m_ssize;
-}
-
-AUD_Specs AUD_SDLMixerReader::getSpecs()
-{
- return m_tspecs;
-}
-
-AUD_ReaderType AUD_SDLMixerReader::getType()
-{
- return m_reader->getType();
-}
-
-bool AUD_SDLMixerReader::notify(AUD_Message &message)
-{
- return m_reader->notify(message);
-}
-
-void AUD_SDLMixerReader::read(int & length, sample_t* & buffer)
-{
- // sample count for the target buffer without getting a shift
- int tns = length + m_tsize - length % m_tsize;
- // sample count for the source buffer without getting a shift
- int sns = tns * m_ssize / m_tsize;
- // target sample size
- int tss = AUD_SAMPLE_SIZE(m_tspecs);
- // source sample size
- int sss = AUD_SAMPLE_SIZE(m_sspecs);
-
- // input is output buffer
- int buf_size = AUD_MAX(tns*tss, sns*sss);
-
- // resize if necessary
- if(m_rsbuffer->getSize() < buf_size)
- m_rsbuffer->resize(buf_size, true);
-
- if(m_buffer->getSize() < length*tss)
- m_buffer->resize(length*tss);
-
- buffer = m_buffer->getBuffer();
- int size;
- int index = 0;
- sample_t* buf;
-
- while(index < length)
- {
- if(m_rsposition == m_rssize)
- {
- // no more data
- if(m_eor)
- length = index;
- // mix
- else
- {
- // read from source
- size = sns;
- m_reader->read(size, buf);
-
- // prepare
- m_cvt.buf = m_rsbuffer->getBuffer();
- m_cvt.len = size*sss;
- memcpy(m_cvt.buf, buf, size*sss);
-
- // convert
- SDL_ConvertAudio(&m_cvt);
-
- // end of reader
- if(size < sns)
- m_eor = true;
-
- m_rsposition = 0;
- m_rssize = size * m_tsize / m_ssize;
- }
- }
-
- // size to copy
- size = AUD_MIN(m_rssize-m_rsposition, length-index);
-
- // copy
- memcpy(m_buffer->getBuffer() + index * tss,
- m_rsbuffer->getBuffer() + m_rsposition * tss,
- size*tss);
- m_rsposition += size;
- index += size;
- }
-}
diff --git a/intern/audaspace/SDL/AUD_SDLMixerReader.h b/intern/audaspace/SDL/AUD_SDLMixerReader.h
deleted file mode 100644
index 56668d02171..00000000000
--- a/intern/audaspace/SDL/AUD_SDLMixerReader.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * $Id$
- *
- * ***** BEGIN LGPL LICENSE BLOCK *****
- *
- * Copyright 2009 Jörg Hermann Müller
- *
- * This file is part of AudaSpace.
- *
- * AudaSpace is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * AudaSpace 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
- *
- * ***** END LGPL LICENSE BLOCK *****
- */
-
-#ifndef AUD_SDLMIXERREADER
-#define AUD_SDLMIXERREADER
-
-#include "AUD_IReader.h"
-class AUD_Buffer;
-
-#include <SDL.h>
-
-/**
- * This class mixes a sound source with help of the SDL library.
- * Unfortunately SDL is only capable of 8 and 16 bit audio, mono and stereo, as
- * well as resampling only 2^n sample rate relationships where n is a natural
- * number.
- * \warning Although SDL can only resample 2^n sample rate relationships, this
- * class doesn't check for compliance, so in case of other factors,
- * the behaviour is undefined.
- */
-class AUD_SDLMixerReader : public AUD_IReader
-{
-private:
- /**
- * The reader that is being mixed.
- */
- AUD_IReader* m_reader;
-
- /**
- * The current reading position in the resampling buffer.
- */
- int m_rsposition;
-
- /**
- * The count of mixed samples in the resampling buffer.
- */
- int m_rssize;
-
- /**
- * The smallest count of source samples to get a fractionless resampling
- * factor.
- */
- int m_ssize;
-
- /**
- * The smallest count of target samples to get a fractionless resampling
- * factor.
- */
- int m_tsize;
-
- /**
- * The sound output buffer.
- */
- AUD_Buffer *m_buffer;
-
- /**
- * The resampling buffer.
- */
- AUD_Buffer *m_rsbuffer;
-
- /**
- * The target specification.
- */
- AUD_Specs m_tspecs;
-
- /**
- * The sample specification of the source.
- */
- AUD_Specs m_sspecs;
-
- /**
- * Saves whether the end of the source has been reached.
- */
- bool m_eor;
-
- /**
- * The SDL_AudioCVT structure used for resampling.
- */
- SDL_AudioCVT m_cvt;
-
-public:
- /**
- * Creates a resampling reader.
- * \param reader The reader to mix.
- * \param specs The target specification.
- * \exception AUD_Exception Thrown if the source specification cannot be
- * mixed to the target specification or if the reader is
- * NULL.
- */
- AUD_SDLMixerReader(AUD_IReader* reader, AUD_Specs specs);
- /**
- * Destroys the reader.
- */
- ~AUD_SDLMixerReader();
-
- virtual bool isSeekable();
- virtual void seek(int position);
- virtual int getLength();
- virtual int getPosition();
- virtual AUD_Specs getSpecs();
- virtual AUD_ReaderType getType();
- virtual bool notify(AUD_Message &message);
- virtual void read(int & length, sample_t* & buffer);
-};
-
-#endif //AUD_SDLMIXERREADER
diff --git a/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp b/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp
index bcace340b24..caafbd14327 100644
--- a/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp
+++ b/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp
@@ -27,14 +27,14 @@
#include "AUD_SRCResampleReader.h"
AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_IReader* reader,
- AUD_Specs specs) :
+ AUD_DeviceSpecs specs) :
AUD_ResampleFactory(reader, specs) {}
AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_IFactory* factory,
- AUD_Specs specs) :
+ AUD_DeviceSpecs specs) :
AUD_ResampleFactory(factory, specs) {}
-AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_Specs specs) :
+AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_DeviceSpecs specs) :
AUD_ResampleFactory(specs) {}
AUD_IReader* AUD_SRCResampleFactory::createReader()
@@ -45,7 +45,7 @@ AUD_IReader* AUD_SRCResampleFactory::createReader()
{
if(reader->getSpecs().rate != m_specs.rate)
{
- reader = new AUD_SRCResampleReader(reader, m_specs);
+ reader = new AUD_SRCResampleReader(reader, m_specs.specs);
AUD_NEW("reader")
}
}
diff --git a/intern/audaspace/SRC/AUD_SRCResampleFactory.h b/intern/audaspace/SRC/AUD_SRCResampleFactory.h
index c23c1d2c82e..4b16c70169c 100644
--- a/intern/audaspace/SRC/AUD_SRCResampleFactory.h
+++ b/intern/audaspace/SRC/AUD_SRCResampleFactory.h
@@ -31,14 +31,13 @@
/**
* This factory creates a resampling reader that uses libsamplerate for
* resampling.
- * \note The format of the input must be float.
*/
class AUD_SRCResampleFactory : public AUD_ResampleFactory
{
public:
- AUD_SRCResampleFactory(AUD_IReader* reader, AUD_Specs specs);
- AUD_SRCResampleFactory(AUD_IFactory* factory, AUD_Specs specs);
- AUD_SRCResampleFactory(AUD_Specs specs);
+ AUD_SRCResampleFactory(AUD_IReader* reader, AUD_DeviceSpecs specs);
+ AUD_SRCResampleFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
+ AUD_SRCResampleFactory(AUD_DeviceSpecs specs);
virtual AUD_IReader* createReader();
};
diff --git a/intern/audaspace/SRC/AUD_SRCResampleReader.cpp b/intern/audaspace/SRC/AUD_SRCResampleReader.cpp
index f7564d3c010..940f4245316 100644
--- a/intern/audaspace/SRC/AUD_SRCResampleReader.cpp
+++ b/intern/audaspace/SRC/AUD_SRCResampleReader.cpp
@@ -26,9 +26,9 @@
#include "AUD_SRCResampleReader.h"
#include "AUD_Buffer.h"
-#include <math.h>
+#include <cmath>
#include <cstring>
-#include <stdio.h>
+#include <cstdio>
static long src_callback(void *cb_data, float **data)
{
@@ -41,15 +41,8 @@ AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_IReader* reader,
{
m_sspecs = reader->getSpecs();
- if(m_sspecs.format != AUD_FORMAT_FLOAT32)
- {
- delete m_reader; AUD_DELETE("reader")
- AUD_THROW(AUD_ERROR_READER);
- }
-
m_tspecs = specs;
m_tspecs.channels = m_sspecs.channels;
- m_tspecs.format = m_sspecs.format;
m_factor = (double)m_tspecs.rate / (double)m_sspecs.rate;
int error;
@@ -71,9 +64,9 @@ AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_IReader* reader,
AUD_SRCResampleReader::~AUD_SRCResampleReader()
{
- delete m_buffer; AUD_DELETE("buffer")
-
src_delete(m_src);
+
+ delete m_buffer; AUD_DELETE("buffer")
}
long AUD_SRCResampleReader::doCallback(float** data)
@@ -83,7 +76,7 @@ long AUD_SRCResampleReader::doCallback(float** data)
m_reader->read(length, buffer);
- *data = (float*)buffer;
+ *data = buffer;
return length;
}
@@ -110,10 +103,12 @@ AUD_Specs AUD_SRCResampleReader::getSpecs()
void AUD_SRCResampleReader::read(int & length, sample_t* & buffer)
{
- if(m_buffer->getSize() < length * m_tspecs.channels * 4)
- m_buffer->resize(length * m_tspecs.channels * 4);
+ int size = length * AUD_SAMPLE_SIZE(m_tspecs);
+
+ if(m_buffer->getSize() < size)
+ m_buffer->resize(size);
buffer = m_buffer->getBuffer();
- length = src_callback_read(m_src, m_factor, length, (float*)buffer);
+ length = src_callback_read(m_src, m_factor, length, buffer);
}
diff --git a/intern/audaspace/SRC/AUD_SRCResampleReader.h b/intern/audaspace/SRC/AUD_SRCResampleReader.h
index 1bacdb3965c..4fe30b48c6e 100644
--- a/intern/audaspace/SRC/AUD_SRCResampleReader.h
+++ b/intern/audaspace/SRC/AUD_SRCResampleReader.h
@@ -32,13 +32,7 @@ class AUD_Buffer;
#include <samplerate.h>
/**
- * This class mixes a sound source with help of the SDL library.
- * Unfortunately SDL is only capable of 8 and 16 bit audio, mono and stereo, as
- * well as resampling only 2^n sample rate relationships where n is a natural
- * number.
- * \warning Although SDL can only resample 2^n sample rate relationships, this
- * class doesn't check for compliance, so in case of other factors,
- * the behaviour is undefined.
+ * This resampling reader uses libsamplerate for resampling.
*/
class AUD_SRCResampleReader : public AUD_EffectReader
{
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
index 0384ba5e0e6..027ac015eb5 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
@@ -34,26 +34,6 @@ extern "C" {
#include <libavformat/avformat.h>
}
-// This function transforms a FFMPEG SampleFormat to our own sample format
-static inline AUD_SampleFormat FFMPEG_TO_AUD(SampleFormat fmt)
-{
- switch(fmt)
- {
- case SAMPLE_FMT_U8:
- return AUD_FORMAT_U8;
- case SAMPLE_FMT_S16:
- return AUD_FORMAT_S16;
- case SAMPLE_FMT_S32:
- return AUD_FORMAT_S32;
- case SAMPLE_FMT_FLT:
- return AUD_FORMAT_FLOAT32;
- case SAMPLE_FMT_DBL:
- return AUD_FORMAT_FLOAT64;
- default:
- return AUD_FORMAT_INVALID;
- }
-}
-
int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer* buffer)
{
// save packet parameters
@@ -78,11 +58,11 @@ int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer* buffer)
// read samples from the packet
data_size = buf_size - buf_pos;
/*read_length = avcodec_decode_audio3(m_codecCtx,
- (int16_t*)(buffer->getBuffer()+buf_pos),
+ (int16_t*)(((data_t*)buffer->getBuffer())+buf_pos),
&data_size,
packet);*/
read_length = avcodec_decode_audio2(m_codecCtx,
- (int16_t*)(buffer->getBuffer()+buf_pos),
+ (int16_t*)(((data_t*)buffer->getBuffer())+buf_pos),
&data_size,
audio_pkg_data,
audio_pkg_size);
@@ -101,78 +81,108 @@ int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer* buffer)
return buf_pos;
}
-AUD_FFMPEGReader::AUD_FFMPEGReader(const char* filename)
+void AUD_FFMPEGReader::init()
{
m_position = 0;
m_pkgbuf_left = 0;
- m_byteiocontext = NULL;
- // open file
- if(av_open_input_file(&m_formatCtx, filename, NULL, 0, NULL)!=0)
- AUD_THROW(AUD_ERROR_FILE);
+ if(av_find_stream_info(m_formatCtx)<0)
+ AUD_THROW(AUD_ERROR_FFMPEG);
- try
- {
- if(av_find_stream_info(m_formatCtx)<0)
- AUD_THROW(AUD_ERROR_FFMPEG);
+ // find audio stream and codec
+ m_stream = -1;
- // find audio stream and codec
- m_stream = -1;
+ for(unsigned int i = 0; i < m_formatCtx->nb_streams; i++)
+ if((m_formatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)
+ && (m_stream < 0))
+ {
+ m_stream=i;
+ break;
+ }
+ if(m_stream == -1)
+ AUD_THROW(AUD_ERROR_FFMPEG);
- for(unsigned int i = 0; i < m_formatCtx->nb_streams; i++)
- if((m_formatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)
- && (m_stream < 0))
- {
- m_stream=i;
- break;
- }
- if(m_stream == -1)
- AUD_THROW(AUD_ERROR_FFMPEG);
+ m_codecCtx = m_formatCtx->streams[m_stream]->codec;
- m_codecCtx = m_formatCtx->streams[m_stream]->codec;
+ // get a decoder and open it
+ AVCodec *aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
+ if(!aCodec)
+ AUD_THROW(AUD_ERROR_FFMPEG);
- // get a decoder and open it
- AVCodec *aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
- if(!aCodec)
- AUD_THROW(AUD_ERROR_FFMPEG);
+ if(avcodec_open(m_codecCtx, aCodec)<0)
+ AUD_THROW(AUD_ERROR_FFMPEG);
- if(avcodec_open(m_codecCtx, aCodec)<0)
- AUD_THROW(AUD_ERROR_FFMPEG);
+ // XXX this prints file information to stdout:
+ //dump_format(m_formatCtx, 0, NULL, 0);
- // XXX this prints file information to stdout:
- //dump_format(m_formatCtx, 0, filename, 0);
+ m_specs.channels = (AUD_Channels) m_codecCtx->channels;
- m_specs.channels = (AUD_Channels) m_codecCtx->channels;
- m_specs.format = FFMPEG_TO_AUD(m_codecCtx->sample_fmt);
- m_specs.rate = (AUD_SampleRate) m_codecCtx->sample_rate;
- }
- catch(AUD_Exception)
+ switch(m_codecCtx->sample_fmt)
{
- av_close_input_file(m_formatCtx);
- throw;
+ case SAMPLE_FMT_U8:
+ m_convert = AUD_convert_u8_float;
+ m_specs.format = AUD_FORMAT_U8;
+ break;
+ case SAMPLE_FMT_S16:
+ m_convert = AUD_convert_s16_float;
+ m_specs.format = AUD_FORMAT_S16;
+ break;
+ case SAMPLE_FMT_S32:
+ m_convert = AUD_convert_s32_float;
+ m_specs.format = AUD_FORMAT_S32;
+ break;
+ case SAMPLE_FMT_FLT:
+ m_convert = AUD_convert_copy<float>;
+ m_specs.format = AUD_FORMAT_FLOAT32;
+ break;
+ case SAMPLE_FMT_DBL:
+ m_convert = AUD_convert_double_float;
+ m_specs.format = AUD_FORMAT_FLOAT64;
+ break;
+ default:
+ AUD_THROW(AUD_ERROR_FILE);
}
+ m_specs.rate = (AUD_SampleRate) m_codecCtx->sample_rate;
+
// last but not least if there hasn't been any error, create the buffers
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
m_pkgbuf = new AUD_Buffer(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1);
AUD_NEW("buffer")
}
+AUD_FFMPEGReader::AUD_FFMPEGReader(const char* filename)
+{
+ m_byteiocontext = NULL;
+
+ // open file
+ if(av_open_input_file(&m_formatCtx, filename, NULL, 0, NULL)!=0)
+ AUD_THROW(AUD_ERROR_FILE);
+
+ try
+ {
+ init();
+ }
+ catch(AUD_Exception)
+ {
+ av_close_input_file(m_formatCtx);
+ throw;
+ }
+}
+
AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer)
{
- m_position = 0;
- m_pkgbuf_left = 0;
m_byteiocontext = (ByteIOContext*)av_mallocz(sizeof(ByteIOContext));
AUD_NEW("byteiocontext")
m_membuffer = buffer;
- if(init_put_byte(m_byteiocontext, buffer.get()->getBuffer(), buffer.get()->getSize(), 0,
- NULL, NULL, NULL, NULL) != 0)
+ if(init_put_byte(m_byteiocontext, (data_t*)buffer.get()->getBuffer(),
+ buffer.get()->getSize(), 0, NULL, NULL, NULL, NULL) != 0)
AUD_THROW(AUD_ERROR_FILE);
AVProbeData probe_data;
probe_data.filename = "";
- probe_data.buf = buffer.get()->getBuffer();
+ probe_data.buf = (data_t*)buffer.get()->getBuffer();
probe_data.buf_size = buffer.get()->getSize();
AVInputFormat* fmt = av_probe_input_format(&probe_data, 1);
@@ -182,38 +192,7 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer)
try
{
- if(av_find_stream_info(m_formatCtx)<0)
- AUD_THROW(AUD_ERROR_FFMPEG);
-
- // find audio stream and codec
- m_stream = -1;
-
- for(unsigned int i = 0; i < m_formatCtx->nb_streams; i++)
- if((m_formatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)
- && (m_stream < 0))
- {
- m_stream=i;
- break;
- }
- if(m_stream == -1)
- AUD_THROW(AUD_ERROR_FFMPEG);
-
- m_codecCtx = m_formatCtx->streams[m_stream]->codec;
-
- // get a decoder and open it
- AVCodec *aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
- if(!aCodec)
- AUD_THROW(AUD_ERROR_FFMPEG);
-
- if(avcodec_open(m_codecCtx, aCodec)<0)
- AUD_THROW(AUD_ERROR_FFMPEG);
-
- // XXX this prints stream information to stdout:
- //dump_format(m_formatCtx, 0, NULL, 0);
-
- m_specs.channels = (AUD_Channels) m_codecCtx->channels;
- m_specs.format = FFMPEG_TO_AUD(m_codecCtx->sample_fmt);
- m_specs.rate = (AUD_SampleRate) m_codecCtx->sample_rate;
+ init();
}
catch(AUD_Exception)
{
@@ -221,11 +200,6 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer)
av_free(m_byteiocontext); AUD_DELETE("byteiocontext")
throw;
}
-
- // last but not least if there hasn't been any error, create the buffers
- m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
- m_pkgbuf = new AUD_Buffer(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1);
- AUD_NEW("buffer")
}
AUD_FFMPEGReader::~AUD_FFMPEGReader()
@@ -316,7 +290,7 @@ int AUD_FFMPEGReader::getPosition()
AUD_Specs AUD_FFMPEGReader::getSpecs()
{
- return m_specs;
+ return m_specs.specs;
}
AUD_ReaderType AUD_FFMPEGReader::getType()
@@ -336,11 +310,11 @@ void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
int data_size = 0;
int pkgbuf_pos;
int left = length;
- int sample_size = AUD_SAMPLE_SIZE(m_specs);
+ int sample_size = AUD_DEVICE_SAMPLE_SIZE(m_specs);
// resize output buffer if necessary
- if(m_buffer->getSize() < length*sample_size)
- m_buffer->resize(length*sample_size);
+ if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(m_specs))
+ m_buffer->resize(length * AUD_SAMPLE_SIZE(m_specs));
buffer = m_buffer->getBuffer();
pkgbuf_pos = m_pkgbuf_left;
@@ -350,8 +324,9 @@ void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
if(pkgbuf_pos > 0)
{
data_size = AUD_MIN(pkgbuf_pos, left * sample_size);
- memcpy(buffer, m_pkgbuf->getBuffer(), data_size);
- buffer += data_size;
+ m_convert((data_t*) buffer, (data_t*) m_pkgbuf->getBuffer(),
+ data_size / AUD_FORMAT_SIZE(m_specs.format));
+ buffer += data_size / AUD_FORMAT_SIZE(m_specs.format);
left -= data_size/sample_size;
}
@@ -366,8 +341,9 @@ void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
// copy to output buffer
data_size = AUD_MIN(pkgbuf_pos, left * sample_size);
- memcpy(buffer, m_pkgbuf->getBuffer(), data_size);
- buffer += data_size;
+ m_convert((data_t*) buffer, (data_t*) m_pkgbuf->getBuffer(),
+ data_size / AUD_FORMAT_SIZE(m_specs.format));
+ buffer += data_size / AUD_FORMAT_SIZE(m_specs.format);
left -= data_size/sample_size;
}
av_free_packet(&packet);
@@ -376,7 +352,8 @@ void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
if(pkgbuf_pos > data_size)
{
m_pkgbuf_left = pkgbuf_pos-data_size;
- memmove(m_pkgbuf->getBuffer(), m_pkgbuf->getBuffer()+data_size,
+ memmove(m_pkgbuf->getBuffer(),
+ ((data_t*)m_pkgbuf->getBuffer())+data_size,
pkgbuf_pos-data_size);
}
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
index 6e303934f36..f992fdf7a34 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
@@ -26,6 +26,7 @@
#ifndef AUD_FFMPEGREADER
#define AUD_FFMPEGREADER
+#include "AUD_ConverterFunctions.h"
#include "AUD_IReader.h"
#include "AUD_Reference.h"
class AUD_Buffer;
@@ -59,7 +60,7 @@ private:
/**
* The specification of the audio data.
*/
- AUD_Specs m_specs;
+ AUD_DeviceSpecs m_specs;
/**
* The buffer for package reading.
@@ -92,6 +93,11 @@ private:
int m_stream;
/**
+ * Converter function.
+ */
+ AUD_convert_f m_convert;
+
+ /**
* The memory file to read from, only saved to keep the buffer alive.
*/
AUD_Reference<AUD_Buffer> m_membuffer;
@@ -104,6 +110,11 @@ private:
*/
int decode(AVPacket* packet, AUD_Buffer* buffer);
+ /**
+ * Initializes the object.
+ */
+ void init();
+
public:
/**
* Creates a new reader.
diff --git a/intern/audaspace/fftw/AUD_BandPassFactory.cpp b/intern/audaspace/fftw/AUD_BandPassFactory.cpp
index 5a957081208..2950cdf8bad 100644
--- a/intern/audaspace/fftw/AUD_BandPassFactory.cpp
+++ b/intern/audaspace/fftw/AUD_BandPassFactory.cpp
@@ -63,16 +63,8 @@ AUD_IReader* AUD_BandPassFactory::createReader()
if(reader != 0)
{
- if(reader->getSpecs().format == AUD_FORMAT_FLOAT32)
- {
- reader = new AUD_BandPassReader(reader, m_low, m_high);
- AUD_NEW("reader")
- }
- else
- {
- delete reader; AUD_DELETE("reader")
- return 0;
- }
+ reader = new AUD_BandPassReader(reader, m_low, m_high);
+ AUD_NEW("reader")
}
return reader;
diff --git a/intern/audaspace/fftw/AUD_BandPassReader.cpp b/intern/audaspace/fftw/AUD_BandPassReader.cpp
index 34d7193866f..67729914c6d 100644
--- a/intern/audaspace/fftw/AUD_BandPassReader.cpp
+++ b/intern/audaspace/fftw/AUD_BandPassReader.cpp
@@ -77,7 +77,6 @@ void AUD_BandPassReader::read(int & length, sample_t* & buffer)
}
m_length = length;
- printf("WINDOW: %d\n", m_length);
if(m_length * sizeof(double) > m_in->getSize())
{
@@ -95,22 +94,21 @@ void AUD_BandPassReader::read(int & length, sample_t* & buffer)
FFTW_ESTIMATE);
}
- float* source = (float*) buffer;
double* target = (double*) m_in->getBuffer();
- float* target2 = (float*) m_buffer->getBuffer();
+ sample_t* target2 = m_buffer->getBuffer();
fftw_complex* complex = (fftw_complex*) m_out->getBuffer();
float frequency;
for(int channel = 0; channel < specs.channels; channel++)
{
for(int i = 0; i < m_length; i++)
- target[i] = source[i * specs.channels + channel];
+ target[i] = buffer[i * specs.channels + channel];
fftw_execute(m_forward);
for(int i = 0; i < m_length / 2 + 1; i++)
{
- frequency = i * specs.rate / (m_length / 2.0 + 1.0);
+ frequency = i * specs.rate / (m_length / 2.0f + 1.0f);
if((frequency < m_low) || (frequency > m_high))
complex[i][0] = complex[i][1] = 0.0;
}
diff --git a/intern/audaspace/intern/AUD_Buffer.cpp b/intern/audaspace/intern/AUD_Buffer.cpp
index 71deae0e87e..a8e74a023bf 100644
--- a/intern/audaspace/intern/AUD_Buffer.cpp
+++ b/intern/audaspace/intern/AUD_Buffer.cpp
@@ -27,14 +27,14 @@
#include "AUD_Space.h"
#include <cstring>
-#include <stdlib.h>
+#include <cstdlib>
#define AUD_ALIGN(a) (a + 16 - ((long)a & 15))
AUD_Buffer::AUD_Buffer(int size)
{
m_size = size;
- m_buffer = (sample_t*) malloc(size+16); AUD_NEW("buffer")
+ m_buffer = (data_t*) malloc(size+16); AUD_NEW("buffer")
}
AUD_Buffer::~AUD_Buffer()
@@ -44,7 +44,7 @@ AUD_Buffer::~AUD_Buffer()
sample_t* AUD_Buffer::getBuffer()
{
- return AUD_ALIGN(m_buffer);
+ return (sample_t*) AUD_ALIGN(m_buffer);
}
int AUD_Buffer::getSize()
@@ -54,7 +54,7 @@ int AUD_Buffer::getSize()
void AUD_Buffer::resize(int size, bool keep)
{
- sample_t* buffer = (sample_t*) malloc(size+16); AUD_NEW("buffer")
+ data_t* buffer = (data_t*) malloc(size+16); AUD_NEW("buffer")
// copy old data over if wanted
if(keep)
diff --git a/intern/audaspace/intern/AUD_Buffer.h b/intern/audaspace/intern/AUD_Buffer.h
index 64959b03799..f745ee6154b 100644
--- a/intern/audaspace/intern/AUD_Buffer.h
+++ b/intern/audaspace/intern/AUD_Buffer.h
@@ -39,7 +39,7 @@ private:
int m_size;
/// The pointer to the buffer memory.
- sample_t* m_buffer;
+ data_t* m_buffer;
public:
/**
diff --git a/intern/audaspace/intern/AUD_BufferReader.cpp b/intern/audaspace/intern/AUD_BufferReader.cpp
index 6cea849bdfc..0101de338bd 100644
--- a/intern/audaspace/intern/AUD_BufferReader.cpp
+++ b/intern/audaspace/intern/AUD_BufferReader.cpp
@@ -79,11 +79,11 @@ void AUD_BufferReader::read(int & length, sample_t* & buffer)
{
int sample_size = AUD_SAMPLE_SIZE(m_specs);
- buffer = m_buffer.get()->getBuffer()+m_position*sample_size;
+ buffer = m_buffer.get()->getBuffer() + m_position * m_specs.channels;
// in case the end of the buffer is reached
- if(m_buffer.get()->getSize() < (m_position+length)*sample_size)
- length = m_buffer.get()->getSize()/sample_size-m_position;
+ if(m_buffer.get()->getSize() < (m_position + length) * sample_size)
+ length = m_buffer.get()->getSize() / sample_size - m_position;
if(length < 0)
length = 0;
diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp
index cd6b95b1d9e..b7d0183cb5e 100644
--- a/intern/audaspace/intern/AUD_C-API.cpp
+++ b/intern/audaspace/intern/AUD_C-API.cpp
@@ -23,6 +23,9 @@
* ***** END LGPL LICENSE BLOCK *****
*/
+#include <cstdlib>
+#include <cstring>
+
#include "AUD_NULLDevice.h"
#include "AUD_I3DDevice.h"
#include "AUD_FileFactory.h"
@@ -32,13 +35,21 @@
#include "AUD_PingPongFactory.h"
#include "AUD_LoopFactory.h"
#include "AUD_RectifyFactory.h"
+#include "AUD_EnvelopeFactory.h"
+#include "AUD_LinearResampleFactory.h"
+#include "AUD_LowpassFactory.h"
+#include "AUD_HighpassFactory.h"
+#include "AUD_AccumulatorFactory.h"
+#include "AUD_SumFactory.h"
+#include "AUD_SquareFactory.h"
+#include "AUD_ChannelMapperFactory.h"
+#include "AUD_Buffer.h"
#include "AUD_ReadDevice.h"
#include "AUD_SourceCaps.h"
#include "AUD_IReader.h"
#ifdef WITH_SDL
#include "AUD_SDLDevice.h"
-#include "AUD_FloatMixer.h"
#endif
#ifdef WITH_OPENAL
@@ -55,7 +66,7 @@ extern "C" {
}
#endif
-#include <assert.h>
+#include <cassert>
typedef AUD_IFactory AUD_Sound;
typedef AUD_ReadDevice AUD_Device;
@@ -71,7 +82,7 @@ static AUD_IDevice* AUD_device = NULL;
static int AUD_available_devices[4];
static AUD_I3DDevice* AUD_3ddevice = NULL;
-int AUD_init(AUD_DeviceType device, AUD_Specs specs, int buffersize)
+int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
{
#ifdef WITH_FFMPEG
av_register_all();
@@ -90,12 +101,8 @@ int AUD_init(AUD_DeviceType device, AUD_Specs specs, int buffersize)
break;
#ifdef WITH_SDL
case AUD_SDL_DEVICE:
- {
- dev = new AUD_SDLDevice(specs, buffersize);
- AUD_FloatMixer* mixer = new AUD_FloatMixer();
- ((AUD_SDLDevice*)dev)->setMixer(mixer);
- break;
- }
+ dev = new AUD_SDLDevice(specs, buffersize);
+ break;
#endif
#ifdef WITH_OPENAL
case AUD_OPENAL_DEVICE:
@@ -177,9 +184,8 @@ AUD_SoundInfo AUD_getInfo(AUD_Sound* sound)
else
{
info.specs.channels = AUD_CHANNELS_INVALID;
- info.specs.format = AUD_FORMAT_INVALID;
info.specs.rate = AUD_RATE_INVALID;
- info.length = 0.0;
+ info.length = 0.0f;
}
return info;
@@ -424,7 +430,7 @@ float AUD_get3DSetting(AUD_3DSetting setting)
catch(AUD_Exception)
{
}
- return 0.0;
+ return 0.0f;
}
int AUD_update3DSource(AUD_Handle* handle, AUD_3DData* data)
@@ -480,7 +486,7 @@ float AUD_get3DSourceSetting(AUD_Handle* handle, AUD_3DSourceSetting setting)
{
}
}
- return 0.0;
+ return 0.0f;
}
int AUD_setSoundVolume(AUD_Handle* handle, float volume)
@@ -519,7 +525,7 @@ int AUD_setSoundPitch(AUD_Handle* handle, float pitch)
return false;
}
-AUD_Device* AUD_openReadDevice(AUD_Specs specs)
+AUD_Device* AUD_openReadDevice(AUD_DeviceSpecs specs)
{
try
{
@@ -578,7 +584,7 @@ int AUD_setDeviceSoundVolume(AUD_Device* device, AUD_Handle* handle,
return false;
}
-int AUD_readDevice(AUD_Device* device, sample_t* buffer, int length)
+int AUD_readDevice(AUD_Device* device, data_t* buffer, int length)
{
assert(device);
assert(buffer);
@@ -605,3 +611,55 @@ void AUD_closeReadDevice(AUD_Device* device)
{
}
}
+
+float* AUD_readSoundBuffer(const char* filename, float low, float high,
+ float attack, float release, float threshold,
+ int accumulate, int additive, int square,
+ float sthreshold, int samplerate, int* length)
+{
+ AUD_Buffer buffer;
+ AUD_DeviceSpecs specs;
+ specs.channels = AUD_CHANNELS_MONO;
+ specs.rate = (AUD_SampleRate)samplerate;
+ AUD_Sound* sound;
+
+ AUD_FileFactory file(filename);
+ AUD_ChannelMapperFactory mapper(&file, specs);
+ AUD_LowpassFactory lowpass(&mapper, high);
+ AUD_HighpassFactory highpass(&lowpass, low);
+ AUD_EnvelopeFactory envelope(&highpass, attack, release, threshold, 0.1f);
+ AUD_LinearResampleFactory resampler(&envelope, specs);
+ sound = &resampler;
+ AUD_SquareFactory squaref(sound, sthreshold);
+ if(square)
+ sound = &squaref;
+ AUD_AccumulatorFactory accumulator(sound, additive);
+ AUD_SumFactory sum(sound);
+ if(accumulate)
+ sound = &accumulator;
+ else if(additive)
+ sound = &sum;
+
+ AUD_IReader* reader = sound->createReader();
+
+ if(reader == NULL)
+ return NULL;
+
+ int len;
+ int position = 0;
+ sample_t* readbuffer;
+ do
+ {
+ len = samplerate;
+ buffer.resize((position + len) * sizeof(float), true);
+ reader->read(len, readbuffer);
+ memcpy(buffer.getBuffer() + position, readbuffer, len * sizeof(float));
+ position += len;
+ } while(len != 0);
+ delete reader;
+
+ float* result = (float*)malloc(position * sizeof(float));
+ memcpy(result, buffer.getBuffer(), position * sizeof(float));
+ *length = position;
+ return result;
+}
diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h
index 866f0248cb2..c3439f89ade 100644
--- a/intern/audaspace/intern/AUD_C-API.h
+++ b/intern/audaspace/intern/AUD_C-API.h
@@ -59,7 +59,7 @@ typedef struct
* \param buffersize The buffersize for the device.
* \return Whether the device has been initialized.
*/
-extern int AUD_init(AUD_DeviceType device, AUD_Specs specs, int buffersize);
+extern int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize);
/**
* Returns a integer list with available sound devices. The last one is always
@@ -304,7 +304,7 @@ extern int AUD_setSoundPitch(AUD_Handle* handle, float pitch);
* \param specs The specification of the audio data.
* \return A device handle.
*/
-extern AUD_Device* AUD_openReadDevice(AUD_Specs specs);
+extern AUD_Device* AUD_openReadDevice(AUD_DeviceSpecs specs);
/**
* Sets the main volume of a device.
@@ -342,7 +342,7 @@ extern int AUD_setDeviceSoundVolume(AUD_Device* device,
* played back currently, in that case the buffer is filled with
* silence.
*/
-extern int AUD_readDevice(AUD_Device* device, sample_t* buffer, int length);
+extern int AUD_readDevice(AUD_Device* device, data_t* buffer, int length);
/**
* Closes a read device.
@@ -350,6 +350,16 @@ extern int AUD_readDevice(AUD_Device* device, sample_t* buffer, int length);
*/
extern void AUD_closeReadDevice(AUD_Device* device);
+/**
+ * Reads a sound file into a newly created float buffer.
+ * The sound is therefore bandpassed, rectified and resampled.
+ */
+extern float* AUD_readSoundBuffer(const char* filename, float low, float high,
+ float attack, float release, float threshold,
+ int accumulate, int additive, int square,
+ float sthreshold, int samplerate,
+ int* length);
+
#ifdef __cplusplus
}
#endif
diff --git a/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp b/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp
index 66205a58015..3420ed16649 100644
--- a/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp
+++ b/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp
@@ -29,20 +29,20 @@
#include <cstring>
AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_IReader* reader,
- AUD_Specs specs) :
+ AUD_DeviceSpecs specs) :
AUD_MixerFactory(reader, specs)
{
memset(m_mapping, 0, sizeof(m_mapping));
}
AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_IFactory* factory,
- AUD_Specs specs) :
+ AUD_DeviceSpecs specs) :
AUD_MixerFactory(factory, specs)
{
memset(m_mapping, 0, sizeof(m_mapping));
}
-AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_Specs specs) :
+AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_DeviceSpecs specs) :
AUD_MixerFactory(specs)
{
memset(m_mapping, 0, sizeof(m_mapping));
diff --git a/intern/audaspace/intern/AUD_ChannelMapperFactory.h b/intern/audaspace/intern/AUD_ChannelMapperFactory.h
index c2c39f4bdf6..a67bfa12123 100644
--- a/intern/audaspace/intern/AUD_ChannelMapperFactory.h
+++ b/intern/audaspace/intern/AUD_ChannelMapperFactory.h
@@ -41,9 +41,9 @@ private:
float **m_mapping[9];
public:
- AUD_ChannelMapperFactory(AUD_IReader* reader, AUD_Specs specs);
- AUD_ChannelMapperFactory(AUD_IFactory* factory, AUD_Specs specs);
- AUD_ChannelMapperFactory(AUD_Specs specs);
+ AUD_ChannelMapperFactory(AUD_IReader* reader, AUD_DeviceSpecs specs);
+ AUD_ChannelMapperFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
+ AUD_ChannelMapperFactory(AUD_DeviceSpecs specs);
virtual ~AUD_ChannelMapperFactory();
diff --git a/intern/audaspace/intern/AUD_ChannelMapperReader.cpp b/intern/audaspace/intern/AUD_ChannelMapperReader.cpp
index 61f97c08a8e..d78278219e8 100644
--- a/intern/audaspace/intern/AUD_ChannelMapperReader.cpp
+++ b/intern/audaspace/intern/AUD_ChannelMapperReader.cpp
@@ -32,12 +32,6 @@ AUD_ChannelMapperReader::AUD_ChannelMapperReader(AUD_IReader* reader,
{
m_specs = reader->getSpecs();
- if(m_specs.format != AUD_FORMAT_FLOAT32)
- {
- delete m_reader; AUD_DELETE("reader")
- AUD_THROW(AUD_ERROR_READER);
- }
-
int channels = -1;
m_rch = m_specs.channels;
while(mapping[++channels] != 0);
@@ -55,7 +49,8 @@ AUD_ChannelMapperReader::AUD_ChannelMapperReader(AUD_IReader* reader,
for(i=0; i < m_rch; i++)
sum += mapping[channels][i];
for(i=0; i < m_rch; i++)
- m_mapping[channels][i] = sum > 0.0 ? mapping[channels][i]/sum : 0.0;
+ m_mapping[channels][i] = sum > 0.0f ?
+ mapping[channels][i]/sum : 0.0f;
}
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
@@ -89,9 +84,9 @@ void AUD_ChannelMapperReader::read(int & length, sample_t* & buffer)
if(m_buffer->getSize() < length * 4 * channels)
m_buffer->resize(length * 4 * channels);
- float* in = (float*)buffer;
- float* out = (float*)m_buffer->getBuffer();
- float sum;
+ sample_t* in = buffer;
+ sample_t* out = m_buffer->getBuffer();
+ sample_t sum;
for(int i = 0; i < length; i++)
{
diff --git a/intern/audaspace/intern/AUD_ConverterFactory.cpp b/intern/audaspace/intern/AUD_ConverterFactory.cpp
index a1a86662072..1c6d5468251 100644
--- a/intern/audaspace/intern/AUD_ConverterFactory.cpp
+++ b/intern/audaspace/intern/AUD_ConverterFactory.cpp
@@ -27,14 +27,14 @@
#include "AUD_ConverterReader.h"
AUD_ConverterFactory::AUD_ConverterFactory(AUD_IReader* reader,
- AUD_Specs specs) :
+ AUD_DeviceSpecs specs) :
AUD_MixerFactory(reader, specs) {}
AUD_ConverterFactory::AUD_ConverterFactory(AUD_IFactory* factory,
- AUD_Specs specs) :
+ AUD_DeviceSpecs specs) :
AUD_MixerFactory(factory, specs) {}
-AUD_ConverterFactory::AUD_ConverterFactory(AUD_Specs specs) :
+AUD_ConverterFactory::AUD_ConverterFactory(AUD_DeviceSpecs specs) :
AUD_MixerFactory(specs) {}
AUD_IReader* AUD_ConverterFactory::createReader()
@@ -43,7 +43,7 @@ AUD_IReader* AUD_ConverterFactory::createReader()
if(reader != 0)
{
- if(reader->getSpecs().format != m_specs.format)
+ if(m_specs.format != AUD_FORMAT_FLOAT32)
{
reader = new AUD_ConverterReader(reader, m_specs);
AUD_NEW("reader")
diff --git a/intern/audaspace/intern/AUD_ConverterFactory.h b/intern/audaspace/intern/AUD_ConverterFactory.h
index 3778e8d8f03..11ca6c9f0a8 100644
--- a/intern/audaspace/intern/AUD_ConverterFactory.h
+++ b/intern/audaspace/intern/AUD_ConverterFactory.h
@@ -35,9 +35,9 @@
class AUD_ConverterFactory : public AUD_MixerFactory
{
public:
- AUD_ConverterFactory(AUD_IReader* reader, AUD_Specs specs);
- AUD_ConverterFactory(AUD_IFactory* factory, AUD_Specs specs);
- AUD_ConverterFactory(AUD_Specs specs);
+ AUD_ConverterFactory(AUD_IReader* reader, AUD_DeviceSpecs specs);
+ AUD_ConverterFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
+ AUD_ConverterFactory(AUD_DeviceSpecs specs);
virtual AUD_IReader* createReader();
};
diff --git a/intern/audaspace/intern/AUD_ConverterFunctions.cpp b/intern/audaspace/intern/AUD_ConverterFunctions.cpp
index 1b5d07bcc61..0d48df04a64 100644
--- a/intern/audaspace/intern/AUD_ConverterFunctions.cpp
+++ b/intern/audaspace/intern/AUD_ConverterFunctions.cpp
@@ -29,21 +29,21 @@
#define AUD_U8_0 0x80
#define AUD_S16_MAX 0x7FFF
#define AUD_S16_MIN 0x8000
-#define AUD_S16_FLT 32768.0
+#define AUD_S16_FLT 32768.0f
#define AUD_S32_MAX 0x7FFFFFFF
#define AUD_S32_MIN 0x80000000
-#define AUD_S32_FLT 2147483648.0
-#define AUD_FLT_MAX 1.0
-#define AUD_FLT_MIN -1.0
+#define AUD_S32_FLT 2147483648.0f
+#define AUD_FLT_MAX 1.0f
+#define AUD_FLT_MIN -1.0f
-void AUD_convert_u8_s16(sample_t* target, sample_t* source, int length)
+void AUD_convert_u8_s16(data_t* target, data_t* source, int length)
{
int16_t* t = (int16_t*) target;
for(int i = 0; i < length; i++)
t[i] = (((int16_t)source[i]) - AUD_U8_0) << 8;
}
-void AUD_convert_u8_s24_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_u8_s24_be(data_t* target, data_t* source, int length)
{
for(int i = 0; i < length; i++)
{
@@ -53,7 +53,7 @@ void AUD_convert_u8_s24_be(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_u8_s24_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_u8_s24_le(data_t* target, data_t* source, int length)
{
for(int i = 0; i < length; i++)
{
@@ -63,35 +63,35 @@ void AUD_convert_u8_s24_le(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_u8_s32(sample_t* target, sample_t* source, int length)
+void AUD_convert_u8_s32(data_t* target, data_t* source, int length)
{
int32_t* t = (int32_t*) target;
for(int i = 0; i < length; i++)
t[i] = (((int32_t)source[i]) - AUD_U8_0) << 24;
}
-void AUD_convert_u8_float(sample_t* target, sample_t* source, int length)
+void AUD_convert_u8_float(data_t* target, data_t* source, int length)
{
float* t = (float*) target;
for(int i = 0; i < length; i++)
t[i] = (((int32_t)source[i]) - AUD_U8_0) / ((float)AUD_U8_0);
}
-void AUD_convert_u8_double(sample_t* target, sample_t* source, int length)
+void AUD_convert_u8_double(data_t* target, data_t* source, int length)
{
double* t = (double*) target;
for(int i = 0; i < length; i++)
t[i] = (((int32_t)source[i]) - AUD_U8_0) / ((double)AUD_U8_0);
}
-void AUD_convert_s16_u8(sample_t* target, sample_t* source, int length)
+void AUD_convert_s16_u8(data_t* target, data_t* source, int length)
{
int16_t* s = (int16_t*) source;
for(int i = 0; i < length; i++)
target[i] = (unsigned char)((s[i] >> 8) + AUD_U8_0);
}
-void AUD_convert_s16_s24_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_s16_s24_be(data_t* target, data_t* source, int length)
{
int16_t* s = (int16_t*) source;
for(int i = 0; i < length; i++)
@@ -102,7 +102,7 @@ void AUD_convert_s16_s24_be(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_s16_s24_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_s16_s24_le(data_t* target, data_t* source, int length)
{
int16_t* s = (int16_t*) source;
for(int i = 0; i < length; i++)
@@ -113,7 +113,7 @@ void AUD_convert_s16_s24_le(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_s16_s32(sample_t* target, sample_t* source, int length)
+void AUD_convert_s16_s32(data_t* target, data_t* source, int length)
{
int16_t* s = (int16_t*) source;
int32_t* t = (int32_t*) target;
@@ -121,7 +121,7 @@ void AUD_convert_s16_s32(sample_t* target, sample_t* source, int length)
t[i] = ((int32_t)s[i]) << 16;
}
-void AUD_convert_s16_float(sample_t* target, sample_t* source, int length)
+void AUD_convert_s16_float(data_t* target, data_t* source, int length)
{
int16_t* s = (int16_t*) source;
float* t = (float*) target;
@@ -129,7 +129,7 @@ void AUD_convert_s16_float(sample_t* target, sample_t* source, int length)
t[i] = s[i] / AUD_S16_FLT;
}
-void AUD_convert_s16_double(sample_t* target, sample_t* source, int length)
+void AUD_convert_s16_double(data_t* target, data_t* source, int length)
{
int16_t* s = (int16_t*) source;
double* t = (double*) target;
@@ -137,52 +137,52 @@ void AUD_convert_s16_double(sample_t* target, sample_t* source, int length)
t[i] = s[i] / AUD_S16_FLT;
}
-void AUD_convert_s24_u8_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_u8_be(data_t* target, data_t* source, int length)
{
for(int i = 0; i < length; i++)
target[i] = source[i*3] ^ AUD_U8_0;
}
-void AUD_convert_s24_u8_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_u8_le(data_t* target, data_t* source, int length)
{
for(int i = 0; i < length; i++)
target[i] = source[i*3+2] ^ AUD_U8_0;
}
-void AUD_convert_s24_s16_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_s16_be(data_t* target, data_t* source, int length)
{
int16_t* t = (int16_t*) target;
for(int i = 0; i < length; i++)
t[i] = source[i*3] << 8 | source[i*3+1];
}
-void AUD_convert_s24_s16_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_s16_le(data_t* target, data_t* source, int length)
{
int16_t* t = (int16_t*) target;
for(int i = 0; i < length; i++)
t[i] = source[i*3+2] << 8 | source[i*3+1];
}
-void AUD_convert_s24_s24(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_s24(data_t* target, data_t* source, int length)
{
memcpy(target, source, length * 3);
}
-void AUD_convert_s24_s32_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_s32_be(data_t* target, data_t* source, int length)
{
int32_t* t = (int32_t*) target;
for(int i = 0; i < length; i++)
t[i] = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
}
-void AUD_convert_s24_s32_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_s32_le(data_t* target, data_t* source, int length)
{
int32_t* t = (int32_t*) target;
for(int i = 0; i < length; i++)
t[i] = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
}
-void AUD_convert_s24_float_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_float_be(data_t* target, data_t* source, int length)
{
float* t = (float*) target;
int32_t s;
@@ -193,7 +193,7 @@ void AUD_convert_s24_float_be(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_s24_float_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_float_le(data_t* target, data_t* source, int length)
{
float* t = (float*) target;
int32_t s;
@@ -204,7 +204,7 @@ void AUD_convert_s24_float_le(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_s24_double_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_double_be(data_t* target, data_t* source, int length)
{
double* t = (double*) target;
int32_t s;
@@ -215,7 +215,7 @@ void AUD_convert_s24_double_be(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_s24_double_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_double_le(data_t* target, data_t* source, int length)
{
double* t = (double*) target;
int32_t s;
@@ -226,14 +226,14 @@ void AUD_convert_s24_double_le(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_s32_u8(sample_t* target, sample_t* source, int length)
+void AUD_convert_s32_u8(data_t* target, data_t* source, int length)
{
int16_t* s = (int16_t*) source;
for(int i = 0; i < length; i++)
target[i] = (unsigned char)((s[i] >> 24) + AUD_U8_0);
}
-void AUD_convert_s32_s16(sample_t* target, sample_t* source, int length)
+void AUD_convert_s32_s16(data_t* target, data_t* source, int length)
{
int16_t* t = (int16_t*) target;
int32_t* s = (int32_t*) source;
@@ -241,7 +241,7 @@ void AUD_convert_s32_s16(sample_t* target, sample_t* source, int length)
t[i] = s[i] >> 16;
}
-void AUD_convert_s32_s24_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_s32_s24_be(data_t* target, data_t* source, int length)
{
int32_t* s = (int32_t*) source;
for(int i = 0; i < length; i++)
@@ -252,7 +252,7 @@ void AUD_convert_s32_s24_be(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_s32_s24_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_s32_s24_le(data_t* target, data_t* source, int length)
{
int16_t* s = (int16_t*) source;
for(int i = 0; i < length; i++)
@@ -263,7 +263,7 @@ void AUD_convert_s32_s24_le(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_s32_float(sample_t* target, sample_t* source, int length)
+void AUD_convert_s32_float(data_t* target, data_t* source, int length)
{
int32_t* s = (int32_t*) source;
float* t = (float*) target;
@@ -271,7 +271,7 @@ void AUD_convert_s32_float(sample_t* target, sample_t* source, int length)
t[i] = s[i] / AUD_S32_FLT;
}
-void AUD_convert_s32_double(sample_t* target, sample_t* source, int length)
+void AUD_convert_s32_double(data_t* target, data_t* source, int length)
{
int32_t* s = (int32_t*) source;
double* t = (double*) target;
@@ -279,7 +279,7 @@ void AUD_convert_s32_double(sample_t* target, sample_t* source, int length)
t[i] = s[i] / AUD_S32_FLT;
}
-void AUD_convert_float_u8(sample_t* target, sample_t* source, int length)
+void AUD_convert_float_u8(data_t* target, data_t* source, int length)
{
float* s = (float*) source;
float t;
@@ -295,7 +295,7 @@ void AUD_convert_float_u8(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_float_s16(sample_t* target, sample_t* source, int length)
+void AUD_convert_float_s16(data_t* target, data_t* source, int length)
{
int16_t* t = (int16_t*) target;
float* s = (float*) source;
@@ -310,7 +310,7 @@ void AUD_convert_float_s16(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_float_s24_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_float_s24_be(data_t* target, data_t* source, int length)
{
int32_t t;
float* s = (float*) source;
@@ -328,7 +328,7 @@ void AUD_convert_float_s24_be(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_float_s24_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_float_s24_le(data_t* target, data_t* source, int length)
{
int32_t t;
float* s = (float*) source;
@@ -346,7 +346,7 @@ void AUD_convert_float_s24_le(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_float_s32(sample_t* target, sample_t* source, int length)
+void AUD_convert_float_s32(data_t* target, data_t* source, int length)
{
int32_t* t = (int32_t*) target;
float* s = (float*) source;
@@ -361,7 +361,7 @@ void AUD_convert_float_s32(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_float_double(sample_t* target, sample_t* source, int length)
+void AUD_convert_float_double(data_t* target, data_t* source, int length)
{
float* s = (float*) source;
double* t = (double*) target;
@@ -369,7 +369,7 @@ void AUD_convert_float_double(sample_t* target, sample_t* source, int length)
t[i] = s[i];
}
-void AUD_convert_double_u8(sample_t* target, sample_t* source, int length)
+void AUD_convert_double_u8(data_t* target, data_t* source, int length)
{
double* s = (double*) source;
double t;
@@ -385,7 +385,7 @@ void AUD_convert_double_u8(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_double_s16(sample_t* target, sample_t* source, int length)
+void AUD_convert_double_s16(data_t* target, data_t* source, int length)
{
int16_t* t = (int16_t*) target;
double* s = (double*) source;
@@ -400,7 +400,7 @@ void AUD_convert_double_s16(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_double_s24_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_double_s24_be(data_t* target, data_t* source, int length)
{
int32_t t;
double* s = (double*) source;
@@ -418,7 +418,7 @@ void AUD_convert_double_s24_be(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_double_s24_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_double_s24_le(data_t* target, data_t* source, int length)
{
int32_t t;
double* s = (double*) source;
@@ -436,7 +436,7 @@ void AUD_convert_double_s24_le(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_double_s32(sample_t* target, sample_t* source, int length)
+void AUD_convert_double_s32(data_t* target, data_t* source, int length)
{
int32_t* t = (int32_t*) target;
double* s = (double*) source;
@@ -451,92 +451,10 @@ void AUD_convert_double_s32(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_double_float(sample_t* target, sample_t* source, int length)
+void AUD_convert_double_float(data_t* target, data_t* source, int length)
{
double* s = (double*) source;
float* t = (float*) target;
for(int i = 0; i < length; i++)
t[i] = s[i];
}
-
-void AUD_volume_adjust_u8(sample_t* target, sample_t* source,
- int count, float volume)
-{
- for(int i=0; i<count; i++)
- target[i] = (unsigned char)((source[i]-0x0080) * volume + 0x80);
-}
-
-void AUD_volume_adjust_s24_le(sample_t* target, sample_t* source,
- int count, float volume)
-{
- count *= 3;
- int value;
-
- for(int i=0; i<count; i+=3)
- {
- value = source[i+2] << 16 | source[i+1] << 8 | source[i];
- value |= (((value & 0x800000) >> 23) * 255) << 24;
- value *= volume;
- target[i+2] = value >> 16;
- target[i+1] = value >> 8;
- target[i] = value;
- }
-}
-
-void AUD_volume_adjust_s24_be(sample_t* target, sample_t* source,
- int count, float volume)
-{
- count *= 3;
- int value;
-
- for(int i=0; i < count; i+=3)
- {
- value = source[i] << 16 | source[i+1] << 8 | source[i+2];
- value |= (((value & 0x800000) >> 23) * 255) << 24;
- value *= volume;
- target[i] = value >> 16;
- target[i+1] = value >> 8;
- target[i+2] = value;
- }
-}
-
-void AUD_rectify_u8(sample_t* target, sample_t* source, int count)
-{
- for(int i=0; i<count; i++)
- target[i] = source[i] < 0x80 ? 0x0100 - source[i] : source[i];
-}
-
-void AUD_rectify_s24_le(sample_t* target, sample_t* source, int count)
-{
- count *= 3;
- int value;
-
- for(int i=0; i<count; i+=3)
- {
- value = source[i+2] << 16 | source[i+1] << 8 | source[i];
- value |= (((value & 0x800000) >> 23) * 255) << 24;
- if(value < 0)
- value = -value;
- target[i+2] = value >> 16;
- target[i+1] = value >> 8;
- target[i] = value;
- }
-}
-
-void AUD_rectify_s24_be(sample_t* target, sample_t* source, int count)
-{
- count *= 3;
- int value;
-
- for(int i=0; i < count; i+=3)
- {
- value = source[i] << 16 | source[i+1] << 8 | source[i+2];
- value |= (((value & 0x800000) >> 23) * 255) << 24;
- if(value < 0)
- value = -value;
- target[i] = value >> 16;
- target[i+1] = value >> 8;
- target[i+2] = value;
- }
-}
-
diff --git a/intern/audaspace/intern/AUD_ConverterFunctions.h b/intern/audaspace/intern/AUD_ConverterFunctions.h
index 686e58704b7..a925f138aa2 100644
--- a/intern/audaspace/intern/AUD_ConverterFunctions.h
+++ b/intern/audaspace/intern/AUD_ConverterFunctions.h
@@ -41,133 +41,94 @@
#include <stdint.h>
#endif
-typedef void (*AUD_convert_f)(sample_t* target, sample_t* source, int length);
-
-typedef void (*AUD_volume_adjust_f)(sample_t* target, sample_t* source,
- int count, float volume);
-
-typedef void (*AUD_rectify_f)(sample_t* target, sample_t* source, int count);
+typedef void (*AUD_convert_f)(data_t* target, data_t* source, int length);
template <class T>
-void AUD_convert_copy(sample_t* target, sample_t* source, int length)
+void AUD_convert_copy(data_t* target, data_t* source, int length)
{
memcpy(target, source, length*sizeof(T));
}
-void AUD_convert_u8_s16(sample_t* target, sample_t* source, int length);
-
-void AUD_convert_u8_s24_be(sample_t* target, sample_t* source, int length);
-
-void AUD_convert_u8_s24_le(sample_t* target, sample_t* source, int length);
-
-void AUD_convert_u8_s32(sample_t* target, sample_t* source, int length);
-
-void AUD_convert_u8_float(sample_t* target, sample_t* source, int length);
-
-void AUD_convert_u8_double(sample_t* target, sample_t* source, int length);
-
-void AUD_convert_s16_u8(sample_t* target, sample_t* source, int length);
+void AUD_convert_u8_s16(data_t* target, data_t* source, int length);
-void AUD_convert_s16_s24_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_u8_s24_be(data_t* target, data_t* source, int length);
-void AUD_convert_s16_s24_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_u8_s24_le(data_t* target, data_t* source, int length);
-void AUD_convert_s16_s32(sample_t* target, sample_t* source, int length);
+void AUD_convert_u8_s32(data_t* target, data_t* source, int length);
-void AUD_convert_s16_float(sample_t* target, sample_t* source, int length);
+void AUD_convert_u8_float(data_t* target, data_t* source, int length);
-void AUD_convert_s16_double(sample_t* target, sample_t* source, int length);
+void AUD_convert_u8_double(data_t* target, data_t* source, int length);
-void AUD_convert_s24_u8_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_s16_u8(data_t* target, data_t* source, int length);
-void AUD_convert_s24_u8_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_s16_s24_be(data_t* target, data_t* source, int length);
-void AUD_convert_s24_s16_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_s16_s24_le(data_t* target, data_t* source, int length);
-void AUD_convert_s24_s16_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_s16_s32(data_t* target, data_t* source, int length);
-void AUD_convert_s24_s24(sample_t* target, sample_t* source, int length);
+void AUD_convert_s16_float(data_t* target, data_t* source, int length);
-void AUD_convert_s24_s32_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_s16_double(data_t* target, data_t* source, int length);
-void AUD_convert_s24_s32_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_u8_be(data_t* target, data_t* source, int length);
-void AUD_convert_s24_float_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_u8_le(data_t* target, data_t* source, int length);
-void AUD_convert_s24_float_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_s16_be(data_t* target, data_t* source, int length);
-void AUD_convert_s24_double_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_s16_le(data_t* target, data_t* source, int length);
-void AUD_convert_s24_double_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_s24(data_t* target, data_t* source, int length);
-void AUD_convert_s32_u8(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_s32_be(data_t* target, data_t* source, int length);
-void AUD_convert_s32_s16(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_s32_le(data_t* target, data_t* source, int length);
-void AUD_convert_s32_s24_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_float_be(data_t* target, data_t* source, int length);
-void AUD_convert_s32_s24_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_float_le(data_t* target, data_t* source, int length);
-void AUD_convert_s32_float(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_double_be(data_t* target, data_t* source, int length);
-void AUD_convert_s32_double(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_double_le(data_t* target, data_t* source, int length);
-void AUD_convert_float_u8(sample_t* target, sample_t* source, int length);
+void AUD_convert_s32_u8(data_t* target, data_t* source, int length);
-void AUD_convert_float_s16(sample_t* target, sample_t* source, int length);
+void AUD_convert_s32_s16(data_t* target, data_t* source, int length);
-void AUD_convert_float_s24_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_s32_s24_be(data_t* target, data_t* source, int length);
-void AUD_convert_float_s24_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_s32_s24_le(data_t* target, data_t* source, int length);
-void AUD_convert_float_s32(sample_t* target, sample_t* source, int length);
+void AUD_convert_s32_float(data_t* target, data_t* source, int length);
-void AUD_convert_float_double(sample_t* target, sample_t* source, int length);
+void AUD_convert_s32_double(data_t* target, data_t* source, int length);
-void AUD_convert_double_u8(sample_t* target, sample_t* source, int length);
+void AUD_convert_float_u8(data_t* target, data_t* source, int length);
-void AUD_convert_double_s16(sample_t* target, sample_t* source, int length);
+void AUD_convert_float_s16(data_t* target, data_t* source, int length);
-void AUD_convert_double_s24_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_float_s24_be(data_t* target, data_t* source, int length);
-void AUD_convert_double_s24_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_float_s24_le(data_t* target, data_t* source, int length);
-void AUD_convert_double_s32(sample_t* target, sample_t* source, int length);
+void AUD_convert_float_s32(data_t* target, data_t* source, int length);
-void AUD_convert_double_float(sample_t* target, sample_t* source, int length);
+void AUD_convert_float_double(data_t* target, data_t* source, int length);
-template <class T>
-void AUD_volume_adjust(sample_t* target, sample_t* source,
- int count, float volume)
-{
- T* t = (T*)target;
- T* s = (T*)source;
- for(int i=0; i < count; i++)
- t[i] = (T)(s[i] * volume);
-}
-
-void AUD_volume_adjust_u8(sample_t* target, sample_t* source,
- int count, float volume);
+void AUD_convert_double_u8(data_t* target, data_t* source, int length);
-void AUD_volume_adjust_s24_le(sample_t* target, sample_t* source,
- int count, float volume);
+void AUD_convert_double_s16(data_t* target, data_t* source, int length);
-void AUD_volume_adjust_s24_be(sample_t* target, sample_t* source,
- int count, float volume);
-
-template <class T>
-void AUD_rectify(sample_t* target, sample_t* source, int count)
-{
- T* t = (T*)target;
- T* s = (T*)source;
- for(int i=0; i < count; i++)
- t[i] = s[i] < 0 ? -s[i] : s[i];
-}
+void AUD_convert_double_s24_be(data_t* target, data_t* source, int length);
-void AUD_rectify_u8(sample_t* target, sample_t* source, int count);
+void AUD_convert_double_s24_le(data_t* target, data_t* source, int length);
-void AUD_rectify_s24_le(sample_t* target, sample_t* source, int count);
+void AUD_convert_double_s32(data_t* target, data_t* source, int length);
-void AUD_rectify_s24_be(sample_t* target, sample_t* source, int count);
+void AUD_convert_double_float(data_t* target, data_t* source, int length);
#endif //AUD_CONVERTERFUNCTIONS
diff --git a/intern/audaspace/intern/AUD_ConverterReader.cpp b/intern/audaspace/intern/AUD_ConverterReader.cpp
index da25a2b7460..808144085bb 100644
--- a/intern/audaspace/intern/AUD_ConverterReader.cpp
+++ b/intern/audaspace/intern/AUD_ConverterReader.cpp
@@ -26,205 +26,37 @@
#include "AUD_ConverterReader.h"
#include "AUD_Buffer.h"
-AUD_ConverterReader::AUD_ConverterReader(AUD_IReader* reader, AUD_Specs specs) :
+AUD_ConverterReader::AUD_ConverterReader(AUD_IReader* reader,
+ AUD_DeviceSpecs specs) :
AUD_EffectReader(reader)
{
- m_specs = reader->getSpecs();
+ m_specs.specs = reader->getSpecs();
int bigendian = 1;
bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
- switch(m_specs.format)
+ switch(specs.format)
{
case AUD_FORMAT_U8:
- switch(specs.format)
- {
- case AUD_FORMAT_U8:
- m_convert = AUD_convert_copy<unsigned char>;
- break;
- case AUD_FORMAT_S16:
- m_convert = AUD_convert_u8_s16;
- break;
- case AUD_FORMAT_S24:
- if(bigendian)
- m_convert = AUD_convert_u8_s24_be;
- else
- m_convert = AUD_convert_u8_s24_le;
- break;
- case AUD_FORMAT_S32:
- m_convert = AUD_convert_u8_s32;
- break;
- case AUD_FORMAT_FLOAT32:
- m_convert = AUD_convert_u8_float;
- break;
- case AUD_FORMAT_FLOAT64:
- m_convert = AUD_convert_u8_double;
- break;
- default:
- break;
- }
+ m_convert = AUD_convert_float_u8;
break;
case AUD_FORMAT_S16:
- switch(specs.format)
- {
- case AUD_FORMAT_U8:
- m_convert = AUD_convert_s16_u8;
- break;
- case AUD_FORMAT_S16:
- m_convert = AUD_convert_copy<int16_t>;
- break;
- case AUD_FORMAT_S24:
- if(bigendian)
- m_convert = AUD_convert_s16_s24_be;
- else
- m_convert = AUD_convert_s16_s24_le;
- break;
- case AUD_FORMAT_S32:
- m_convert = AUD_convert_s16_s32;
- break;
- case AUD_FORMAT_FLOAT32:
- m_convert = AUD_convert_s16_float;
- break;
- case AUD_FORMAT_FLOAT64:
- m_convert = AUD_convert_s16_double;
- break;
- default:
- break;
- }
+ m_convert = AUD_convert_float_s16;
break;
case AUD_FORMAT_S24:
if(bigendian)
- switch(specs.format)
- {
- case AUD_FORMAT_U8:
- m_convert = AUD_convert_u8_s24_be;
- break;
- case AUD_FORMAT_S16:
- m_convert = AUD_convert_s16_s24_be;
- break;
- case AUD_FORMAT_S24:
- m_convert = AUD_convert_s24_s24;
- break;
- case AUD_FORMAT_S32:
- m_convert = AUD_convert_s32_s24_be;
- break;
- case AUD_FORMAT_FLOAT32:
- m_convert = AUD_convert_float_s24_be;
- break;
- case AUD_FORMAT_FLOAT64:
- m_convert = AUD_convert_double_s24_be;
- break;
- default:
- break;
- }
+ m_convert = AUD_convert_float_s24_be;
else
- switch(specs.format)
- {
- case AUD_FORMAT_U8:
- m_convert = AUD_convert_u8_s24_le;
- break;
- case AUD_FORMAT_S16:
- m_convert = AUD_convert_s16_s24_le;
- break;
- case AUD_FORMAT_S24:
- m_convert = AUD_convert_s24_s24;
- break;
- case AUD_FORMAT_S32:
- m_convert = AUD_convert_s32_s24_le;
- break;
- case AUD_FORMAT_FLOAT32:
- m_convert = AUD_convert_float_s24_le;
- break;
- case AUD_FORMAT_FLOAT64:
- m_convert = AUD_convert_double_s24_le;
- break;
- default:
- break;
- }
+ m_convert = AUD_convert_float_s24_le;
break;
case AUD_FORMAT_S32:
- switch(specs.format)
- {
- case AUD_FORMAT_U8:
- m_convert = AUD_convert_s32_u8;
- break;
- case AUD_FORMAT_S16:
- m_convert = AUD_convert_s32_s16;
- break;
- case AUD_FORMAT_S24:
- if(bigendian)
- m_convert = AUD_convert_s32_s24_be;
- else
- m_convert = AUD_convert_s32_s24_le;
- break;
- case AUD_FORMAT_S32:
- m_convert = AUD_convert_copy<int32_t>;
- break;
- case AUD_FORMAT_FLOAT32:
- m_convert = AUD_convert_s32_float;
- break;
- case AUD_FORMAT_FLOAT64:
- m_convert = AUD_convert_s32_double;
- break;
- default:
- break;
- }
+ m_convert = AUD_convert_float_s32;
break;
case AUD_FORMAT_FLOAT32:
- switch(specs.format)
- {
- case AUD_FORMAT_U8:
- m_convert = AUD_convert_float_u8;
- break;
- case AUD_FORMAT_S16:
- m_convert = AUD_convert_float_s16;
- break;
- case AUD_FORMAT_S24:
- if(bigendian)
- m_convert = AUD_convert_float_s24_be;
- else
- m_convert = AUD_convert_float_s24_le;
- break;
- case AUD_FORMAT_S32:
- m_convert = AUD_convert_float_s32;
- break;
- case AUD_FORMAT_FLOAT32:
- m_convert = AUD_convert_copy<float>;
- break;
- case AUD_FORMAT_FLOAT64:
- m_convert = AUD_convert_float_double;
- break;
- default:
- break;
- }
+ m_convert = AUD_convert_copy<float>;
break;
case AUD_FORMAT_FLOAT64:
- switch(specs.format)
- {
- case AUD_FORMAT_U8:
- m_convert = AUD_convert_double_u8;
- break;
- case AUD_FORMAT_S16:
- m_convert = AUD_convert_double_s16;
- break;
- case AUD_FORMAT_S24:
- if(bigendian)
- m_convert = AUD_convert_double_s24_be;
- else
- m_convert = AUD_convert_double_s24_le;
- break;
- case AUD_FORMAT_S32:
- m_convert = AUD_convert_double_s32;
- break;
- case AUD_FORMAT_FLOAT32:
- m_convert = AUD_convert_double_float;
- break;
- case AUD_FORMAT_FLOAT64:
- m_convert = AUD_convert_copy<double>;
- break;
- default:
- break;
- }
+ m_convert = AUD_convert_float_double;
break;
default:
break;
@@ -242,7 +74,7 @@ AUD_ConverterReader::~AUD_ConverterReader()
AUD_Specs AUD_ConverterReader::getSpecs()
{
- return m_specs;
+ return m_specs.specs;
}
void AUD_ConverterReader::read(int & length, sample_t* & buffer)
@@ -254,7 +86,8 @@ void AUD_ConverterReader::read(int & length, sample_t* & buffer)
if(m_buffer->getSize() < length*samplesize)
m_buffer->resize(length*samplesize);
- m_convert(m_buffer->getBuffer(), buffer, length*m_specs.channels);
+ m_convert((data_t*)m_buffer->getBuffer(), (data_t*)buffer,
+ length * m_specs.channels);
buffer = m_buffer->getBuffer();
}
diff --git a/intern/audaspace/intern/AUD_ConverterReader.h b/intern/audaspace/intern/AUD_ConverterReader.h
index f855372b636..ba49bbfd9ba 100644
--- a/intern/audaspace/intern/AUD_ConverterReader.h
+++ b/intern/audaspace/intern/AUD_ConverterReader.h
@@ -44,7 +44,7 @@ private:
/**
* The target specification.
*/
- AUD_Specs m_specs;
+ AUD_DeviceSpecs m_specs;
/**
* Converter function.
@@ -58,7 +58,7 @@ public:
* \param specs The target specification.
* \exception AUD_Exception Thrown if the reader is NULL.
*/
- AUD_ConverterReader(AUD_IReader* reader, AUD_Specs specs);
+ AUD_ConverterReader(AUD_IReader* reader, AUD_DeviceSpecs specs);
/**
* Destroys the reader.
*/
diff --git a/intern/audaspace/intern/AUD_FloatMixer.h b/intern/audaspace/intern/AUD_FloatMixer.h
deleted file mode 100644
index 728a0faf3cb..00000000000
--- a/intern/audaspace/intern/AUD_FloatMixer.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * $Id$
- *
- * ***** BEGIN LGPL LICENSE BLOCK *****
- *
- * Copyright 2009 Jörg Hermann Müller
- *
- * This file is part of AudaSpace.
- *
- * AudaSpace is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * AudaSpace 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
- *
- * ***** END LGPL LICENSE BLOCK *****
- */
-
-#ifndef AUD_FLOATMIXER
-#define AUD_FLOATMIXER
-
-#include "AUD_IMixer.h"
-#include "AUD_ConverterFunctions.h"
-class AUD_ConverterFactory;
-class AUD_SRCResampleFactory;
-class AUD_ChannelMapperFactory;
-class AUD_Buffer;
-#include <list>
-
-struct AUD_FloatMixerBuffer
-{
- sample_t* buffer;
- int length;
- float volume;
-};
-
-/**
- * This class is able to mix two audiosignals with floats.
- */
-class AUD_FloatMixer : public AUD_IMixer
-{
-private:
- /**
- * The converter factory that converts all readers for superposition.
- */
- AUD_ConverterFactory* m_converter;
-
- /**
- * The resampling factory that resamples all readers for superposition.
- */
- AUD_SRCResampleFactory* m_resampler;
-
- /**
- * The channel mapper factory that maps all readers for superposition.
- */
- AUD_ChannelMapperFactory* m_mapper;
-
- /**
- * The list of buffers to superpose.
- */
- std::list<AUD_FloatMixerBuffer> m_buffers;
-
- /**
- * The output specification.
- */
- AUD_Specs m_specs;
-
- /**
- * The temporary mixing buffer.
- */
- AUD_Buffer* m_buffer;
-
- /**
- * Converter function.
- */
- AUD_convert_f m_convert;
-
-public:
- /**
- * Creates the mixer.
- */
- AUD_FloatMixer();
-
- virtual ~AUD_FloatMixer();
-
- virtual AUD_IReader* prepare(AUD_IReader* reader);
- virtual void setSpecs(AUD_Specs specs);
- virtual void add(sample_t* buffer, AUD_Specs specs, int length,
- float volume);
- virtual void superpose(sample_t* buffer, int length, float volume);
-};
-
-#endif //AUD_FLOATMIXER
diff --git a/intern/audaspace/intern/AUD_IDevice.h b/intern/audaspace/intern/AUD_IDevice.h
index af2cae206f3..e924f57cefc 100644
--- a/intern/audaspace/intern/AUD_IDevice.h
+++ b/intern/audaspace/intern/AUD_IDevice.h
@@ -53,7 +53,7 @@ public:
/**
* Returns the specification of the device.
*/
- virtual AUD_Specs getSpecs()=0;
+ virtual AUD_DeviceSpecs getSpecs()=0;
/**
* Plays a sound source.
diff --git a/intern/audaspace/SDL/AUD_SDLMixerFactory.cpp b/intern/audaspace/intern/AUD_LinearResampleFactory.cpp
index e0b0c7d3603..e738fc17693 100644
--- a/intern/audaspace/SDL/AUD_SDLMixerFactory.cpp
+++ b/intern/audaspace/intern/AUD_LinearResampleFactory.cpp
@@ -23,42 +23,30 @@
* ***** END LGPL LICENSE BLOCK *****
*/
-#include "AUD_SDLMixerFactory.h"
-#include "AUD_SDLMixerReader.h"
+#include "AUD_LinearResampleFactory.h"
+#include "AUD_LinearResampleReader.h"
-#include <cstring>
+AUD_LinearResampleFactory::AUD_LinearResampleFactory(AUD_IReader* reader,
+ AUD_DeviceSpecs specs) :
+ AUD_ResampleFactory(reader, specs) {}
-AUD_SDLMixerFactory::AUD_SDLMixerFactory(AUD_IReader* reader, AUD_Specs specs) :
- AUD_MixerFactory(reader, specs) {}
+AUD_LinearResampleFactory::AUD_LinearResampleFactory(AUD_IFactory* factory,
+ AUD_DeviceSpecs specs) :
+ AUD_ResampleFactory(factory, specs) {}
-AUD_SDLMixerFactory::AUD_SDLMixerFactory(AUD_IFactory* factory, AUD_Specs specs) :
- AUD_MixerFactory(factory, specs) {}
+AUD_LinearResampleFactory::AUD_LinearResampleFactory(AUD_DeviceSpecs specs) :
+ AUD_ResampleFactory(specs) {}
-AUD_SDLMixerFactory::AUD_SDLMixerFactory(AUD_Specs specs) :
- AUD_MixerFactory(specs) {}
-
-AUD_IReader* AUD_SDLMixerFactory::createReader()
+AUD_IReader* AUD_LinearResampleFactory::createReader()
{
AUD_IReader* reader = getReader();
if(reader != 0)
{
- AUD_Specs specs = reader->getSpecs();
- if(memcmp(&m_specs, &specs, sizeof(AUD_Specs)) != 0)
+ if(reader->getSpecs().rate != m_specs.rate)
{
- try
- {
- reader = new AUD_SDLMixerReader(reader, m_specs);
- AUD_NEW("reader")
- }
- catch(AUD_Exception e)
- {
- // return 0 in case SDL cannot mix the source
- if(e.error != AUD_ERROR_SDL)
- throw;
- else
- reader = NULL;
- }
+ reader = new AUD_LinearResampleReader(reader, m_specs.specs);
+ AUD_NEW("reader")
}
}
return reader;
diff --git a/intern/audaspace/intern/AUD_LinearResampleFactory.h b/intern/audaspace/intern/AUD_LinearResampleFactory.h
new file mode 100644
index 00000000000..81a9d623815
--- /dev/null
+++ b/intern/audaspace/intern/AUD_LinearResampleFactory.h
@@ -0,0 +1,44 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_LINEARRESAMPLEFACTORY
+#define AUD_LINEARRESAMPLEFACTORY
+
+#include "AUD_ResampleFactory.h"
+
+/**
+ * This factory creates a resampling reader that does simple linear resampling.
+ */
+class AUD_LinearResampleFactory : public AUD_ResampleFactory
+{
+public:
+ AUD_LinearResampleFactory(AUD_IReader* reader, AUD_DeviceSpecs specs);
+ AUD_LinearResampleFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
+ AUD_LinearResampleFactory(AUD_DeviceSpecs specs);
+
+ virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_LINEARRESAMPLEFACTORY
diff --git a/intern/audaspace/intern/AUD_LinearResampleReader.cpp b/intern/audaspace/intern/AUD_LinearResampleReader.cpp
new file mode 100644
index 00000000000..dcd5310575d
--- /dev/null
+++ b/intern/audaspace/intern/AUD_LinearResampleReader.cpp
@@ -0,0 +1,133 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_LinearResampleReader.h"
+#include "AUD_Buffer.h"
+
+#include <cmath>
+#include <cstring>
+
+#define CC channels + channel
+
+AUD_LinearResampleReader::AUD_LinearResampleReader(AUD_IReader* reader,
+ AUD_Specs specs) :
+ AUD_EffectReader(reader)
+{
+ m_sspecs = reader->getSpecs();
+
+ m_tspecs = specs;
+ m_tspecs.channels = m_sspecs.channels;
+ m_factor = (float)m_tspecs.rate / (float)m_sspecs.rate;
+
+ m_position = 0;
+ m_sposition = 0;
+
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+ m_cache = new AUD_Buffer(2 * AUD_SAMPLE_SIZE(specs)); AUD_NEW("buffer")
+}
+
+AUD_LinearResampleReader::~AUD_LinearResampleReader()
+{
+ delete m_buffer; AUD_DELETE("buffer")
+ delete m_cache; AUD_DELETE("buffer")
+}
+
+void AUD_LinearResampleReader::seek(int position)
+{
+ m_position = position;
+ m_sposition = floor(position / m_factor);
+ m_reader->seek(m_sposition);
+}
+
+int AUD_LinearResampleReader::getLength()
+{
+ return m_reader->getLength() * m_factor;
+}
+
+int AUD_LinearResampleReader::getPosition()
+{
+ return m_position;
+}
+
+AUD_Specs AUD_LinearResampleReader::getSpecs()
+{
+ return m_tspecs;
+}
+
+void AUD_LinearResampleReader::read(int & length, sample_t* & buffer)
+{
+ int samplesize = AUD_SAMPLE_SIZE(m_tspecs);
+ int size = length * samplesize;
+
+ if(m_buffer->getSize() < size)
+ m_buffer->resize(size);
+
+ int need = ceil((m_position + length) / m_factor) + 1 - m_sposition;
+ int len = need;
+ sample_t* buf;
+ buffer = m_buffer->getBuffer();
+
+ m_reader->read(len, buf);
+
+ if(len < need)
+ length = floor((m_sposition + len - 1) * m_factor) - m_position;
+
+ float spos;
+ sample_t low, high;
+ int channels = m_sspecs.channels;
+
+ for(int channel = 0; channel < channels; channel++)
+ {
+ for(int i = 0; i < length; i++)
+ {
+ spos = (m_position + i) / m_factor - m_sposition;
+
+ if(floor(spos) < 0)
+ {
+ low = m_cache->getBuffer()[(int)(floor(spos) + 2) * CC];
+ if(ceil(spos) < 0)
+ high = m_cache->getBuffer()[(int)(ceil(spos) + 2) * CC];
+ else
+ high = buf[(int)ceil(spos) * CC];
+ }
+ else
+ {
+ low = buf[(int)floor(spos) * CC];
+ high = buf[(int)ceil(spos) * CC];
+ }
+ buffer[i * CC] = low + (spos - floor(spos)) * (high - low);
+ }
+ }
+
+ if(len > 1)
+ memcpy(m_cache->getBuffer(),
+ buf + (len - 2) * channels,
+ 2 * samplesize);
+ else if(len == 1)
+ memcpy(m_cache->getBuffer() + 1 * channels, buf, samplesize);
+
+ m_sposition += len;
+ m_position += length;
+}
diff --git a/intern/audaspace/intern/AUD_LinearResampleReader.h b/intern/audaspace/intern/AUD_LinearResampleReader.h
new file mode 100644
index 00000000000..c86b8b76c59
--- /dev/null
+++ b/intern/audaspace/intern/AUD_LinearResampleReader.h
@@ -0,0 +1,94 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_LINEARRESAMPLEREADER
+#define AUD_LINEARRESAMPLEREADER
+
+#include "AUD_EffectReader.h"
+class AUD_Buffer;
+
+/**
+ * This resampling reader uses libsamplerate for resampling.
+ */
+class AUD_LinearResampleReader : public AUD_EffectReader
+{
+private:
+ /**
+ * The resampling factor.
+ */
+ float m_factor;
+
+ /**
+ * The current position.
+ */
+ int m_position;
+
+ /**
+ * The current reading source position.
+ */
+ int m_sposition;
+
+ /**
+ * The sound output buffer.
+ */
+ AUD_Buffer *m_buffer;
+
+ /**
+ * The input caching buffer.
+ */
+ AUD_Buffer *m_cache;
+
+ /**
+ * The target specification.
+ */
+ AUD_Specs m_tspecs;
+
+ /**
+ * The sample specification of the source.
+ */
+ AUD_Specs m_sspecs;
+
+public:
+ /**
+ * Creates a resampling reader.
+ * \param reader The reader to mix.
+ * \param specs The target specification.
+ * \exception AUD_Exception Thrown if the reader is NULL.
+ */
+ AUD_LinearResampleReader(AUD_IReader* reader, AUD_Specs specs);
+
+ /**
+ * Destroys the reader.
+ */
+ ~AUD_LinearResampleReader();
+
+ virtual void seek(int position);
+ virtual int getLength();
+ virtual int getPosition();
+ virtual AUD_Specs getSpecs();
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_LINEARRESAMPLEREADER
diff --git a/intern/audaspace/intern/AUD_FloatMixer.cpp b/intern/audaspace/intern/AUD_Mixer.cpp
index f7133b9c30e..bddc719b179 100644
--- a/intern/audaspace/intern/AUD_FloatMixer.cpp
+++ b/intern/audaspace/intern/AUD_Mixer.cpp
@@ -23,8 +23,7 @@
* ***** END LGPL LICENSE BLOCK *****
*/
-#include "AUD_FloatMixer.h"
-#include "AUD_ConverterFactory.h"
+#include "AUD_Mixer.h"
#include "AUD_SRCResampleFactory.h"
#include "AUD_ChannelMapperFactory.h"
#include "AUD_IReader.h"
@@ -32,23 +31,19 @@
#include <cstring>
-AUD_FloatMixer::AUD_FloatMixer()
+AUD_Mixer::AUD_Mixer()
{
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
- m_converter = NULL;
m_resampler = NULL;
m_mapper = NULL;
}
-AUD_FloatMixer::~AUD_FloatMixer()
+AUD_Mixer::~AUD_Mixer()
{
delete m_buffer; AUD_DELETE("buffer")
- if(m_converter)
- {
- delete m_converter; AUD_DELETE("factory")
- }
+
if(m_resampler)
{
delete m_resampler; AUD_DELETE("factory")
@@ -59,11 +54,8 @@ AUD_FloatMixer::~AUD_FloatMixer()
}
}
-AUD_IReader* AUD_FloatMixer::prepare(AUD_IReader* reader)
+AUD_IReader* AUD_Mixer::prepare(AUD_IReader* reader)
{
- m_converter->setReader(reader);
- reader = m_converter->createReader();
-
m_resampler->setReader(reader);
reader = m_resampler->createReader();
@@ -76,14 +68,10 @@ AUD_IReader* AUD_FloatMixer::prepare(AUD_IReader* reader)
return reader;
}
-void AUD_FloatMixer::setSpecs(AUD_Specs specs)
+void AUD_Mixer::setSpecs(AUD_DeviceSpecs specs)
{
m_specs = specs;
- if(m_converter)
- {
- delete m_converter; AUD_DELETE("factory")
- }
if(m_resampler)
{
delete m_resampler; AUD_DELETE("factory")
@@ -93,9 +81,6 @@ void AUD_FloatMixer::setSpecs(AUD_Specs specs)
delete m_mapper; AUD_DELETE("factory")
}
- specs.format = AUD_FORMAT_FLOAT32;
-
- m_converter = new AUD_ConverterFactory(specs); AUD_NEW("factory")
m_resampler = new AUD_SRCResampleFactory(specs); AUD_NEW("factory")
m_mapper = new AUD_ChannelMapperFactory(specs); AUD_NEW("factory")
@@ -130,27 +115,26 @@ void AUD_FloatMixer::setSpecs(AUD_Specs specs)
}
}
-void AUD_FloatMixer::add(sample_t* buffer, AUD_Specs specs, int length,
- float volume)
+void AUD_Mixer::add(sample_t* buffer, int length, float volume)
{
- AUD_FloatMixerBuffer buf;
+ AUD_MixerBuffer buf;
buf.buffer = buffer;
buf.length = length;
buf.volume = volume;
m_buffers.push_back(buf);
}
-void AUD_FloatMixer::superpose(sample_t* buffer, int length, float volume)
+void AUD_Mixer::superpose(data_t* buffer, int length, float volume)
{
- AUD_FloatMixerBuffer buf;
+ AUD_MixerBuffer buf;
int channels = m_specs.channels;
if(m_buffer->getSize() < length * channels * 4)
m_buffer->resize(length * channels * 4);
- float* out = (float*)m_buffer->getBuffer();
- float* in;
+ sample_t* out = m_buffer->getBuffer();
+ sample_t* in;
memset(out, 0, length * channels * 4);
@@ -162,11 +146,11 @@ void AUD_FloatMixer::superpose(sample_t* buffer, int length, float volume)
m_buffers.pop_front();
end = buf.length*channels;
- in = (float*) buf.buffer;
+ in = buf.buffer;
for(int i = 0; i < end; i++)
out[i] += in[i]*buf.volume * volume;
}
- m_convert(buffer, (sample_t*) out, length * channels);
+ m_convert(buffer, (data_t*) out, length * channels);
}
diff --git a/intern/audaspace/intern/AUD_IMixer.h b/intern/audaspace/intern/AUD_Mixer.h
index c65e4c69cf7..5097b9ec2a6 100644
--- a/intern/audaspace/intern/AUD_IMixer.h
+++ b/intern/audaspace/intern/AUD_Mixer.h
@@ -23,47 +23,95 @@
* ***** END LGPL LICENSE BLOCK *****
*/
-#ifndef AUD_IMIXER
-#define AUD_IMIXER
+#ifndef AUD_MIXER
+#define AUD_MIXER
-#include "AUD_Space.h"
+#include "AUD_ConverterFunctions.h"
+class AUD_ConverterFactory;
+class AUD_SRCResampleFactory;
+class AUD_ChannelMapperFactory;
+class AUD_Buffer;
class AUD_IReader;
+#include <list>
+
+struct AUD_MixerBuffer
+{
+ sample_t* buffer;
+ int length;
+ float volume;
+};
/**
- * This class is able to mix audiosignals of different format and channel count.
- * \note This class doesn't do resampling!
+ * This class is able to mix audiosignals of different channel count and sample
+ * rate and convert it to a specific output format.
+ * It uses a default ChannelMapperFactory and a SRCResampleFactory for
+ * the perparation.
*/
-class AUD_IMixer
+class AUD_Mixer
{
+private:
+ /**
+ * The resampling factory that resamples all readers for superposition.
+ */
+ AUD_SRCResampleFactory* m_resampler;
+
+ /**
+ * The channel mapper factory that maps all readers for superposition.
+ */
+ AUD_ChannelMapperFactory* m_mapper;
+
+ /**
+ * The list of buffers to superpose.
+ */
+ std::list<AUD_MixerBuffer> m_buffers;
+
+ /**
+ * The output specification.
+ */
+ AUD_DeviceSpecs m_specs;
+
+ /**
+ * The temporary mixing buffer.
+ */
+ AUD_Buffer* m_buffer;
+
+ /**
+ * Converter function.
+ */
+ AUD_convert_f m_convert;
+
public:
/**
+ * Creates the mixer.
+ */
+ AUD_Mixer();
+
+ /**
* Destroys the mixer.
*/
- virtual ~AUD_IMixer(){}
+ ~AUD_Mixer();
/**
* This funuction prepares a reader for playback.
* \param reader The reader to prepare.
* \return The reader that should be used for playback.
*/
- virtual AUD_IReader* prepare(AUD_IReader* reader)=0;
+ AUD_IReader* prepare(AUD_IReader* reader);
/**
* Sets the target specification for superposing.
* \param specs The target specification.
*/
- virtual void setSpecs(AUD_Specs specs)=0;
+ void setSpecs(AUD_DeviceSpecs specs);
/**
* Adds a buffer for superposition.
* \param buffer The buffer to superpose.
- * \param specs The specification of the buffer.
* \param start The start sample of the buffer.
* \param length The length of the buffer in samples.
* \param volume The mixing volume. Must be a value between 0.0 and 1.0.
*/
- virtual void add(sample_t* buffer, AUD_Specs specs, int length,
- float volume)=0;
+ void add(sample_t* buffer, int length, float volume);
/**
* Superposes all added buffers into an output buffer.
@@ -71,7 +119,7 @@ public:
* \param length The length of the buffer in samples.
* \param volume The mixing volume. Must be a value between 0.0 and 1.0.
*/
- virtual void superpose(sample_t* buffer, int length, float volume)=0;
+ void superpose(data_t* buffer, int length, float volume);
};
-#endif //AUD_IMIXER
+#endif //AUD_MIXER
diff --git a/intern/audaspace/intern/AUD_MixerFactory.cpp b/intern/audaspace/intern/AUD_MixerFactory.cpp
index db38d1004db..e78818301fa 100644
--- a/intern/audaspace/intern/AUD_MixerFactory.cpp
+++ b/intern/audaspace/intern/AUD_MixerFactory.cpp
@@ -49,7 +49,7 @@ AUD_IReader* AUD_MixerFactory::getReader()
}
AUD_MixerFactory::AUD_MixerFactory(AUD_IReader* reader,
- AUD_Specs specs)
+ AUD_DeviceSpecs specs)
{
m_specs = specs;
m_reader = reader;
@@ -57,14 +57,14 @@ AUD_MixerFactory::AUD_MixerFactory(AUD_IReader* reader,
}
AUD_MixerFactory::AUD_MixerFactory(AUD_IFactory* factory,
- AUD_Specs specs)
+ AUD_DeviceSpecs specs)
{
m_specs = specs;
m_reader = 0;
m_factory = factory;
}
-AUD_MixerFactory::AUD_MixerFactory(AUD_Specs specs)
+AUD_MixerFactory::AUD_MixerFactory(AUD_DeviceSpecs specs)
{
m_specs = specs;
m_reader = 0;
@@ -79,12 +79,12 @@ AUD_MixerFactory::~AUD_MixerFactory()
}
}
-AUD_Specs AUD_MixerFactory::getSpecs()
+AUD_DeviceSpecs AUD_MixerFactory::getSpecs()
{
return m_specs;
}
-void AUD_MixerFactory::setSpecs(AUD_Specs specs)
+void AUD_MixerFactory::setSpecs(AUD_DeviceSpecs specs)
{
m_specs = specs;
}
diff --git a/intern/audaspace/intern/AUD_MixerFactory.h b/intern/audaspace/intern/AUD_MixerFactory.h
index c61dd283c67..a2f4aa78d76 100644
--- a/intern/audaspace/intern/AUD_MixerFactory.h
+++ b/intern/audaspace/intern/AUD_MixerFactory.h
@@ -47,7 +47,7 @@ protected:
/**
* The target specification for resampling.
*/
- AUD_Specs m_specs;
+ AUD_DeviceSpecs m_specs;
/**
* Returns the reader created out of the factory or taken from m_reader.
@@ -63,20 +63,20 @@ public:
* \param reader The reader to mix.
* \param specs The target specification.
*/
- AUD_MixerFactory(AUD_IReader* reader, AUD_Specs specs);
+ AUD_MixerFactory(AUD_IReader* reader, AUD_DeviceSpecs specs);
/**
* Creates a new factory.
* \param factory The factory to create the readers to mix out of.
* \param specs The target specification.
*/
- AUD_MixerFactory(AUD_IFactory* factory, AUD_Specs specs);
+ AUD_MixerFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
/**
* Creates a new factory.
* \param specs The target specification.
*/
- AUD_MixerFactory(AUD_Specs specs);
+ AUD_MixerFactory(AUD_DeviceSpecs specs);
/**
* Destroys the resampling factory.
@@ -86,13 +86,13 @@ public:
/**
* Returns the target specification for resampling.
*/
- AUD_Specs getSpecs();
+ AUD_DeviceSpecs getSpecs();
/**
* Sets the target specification for resampling.
* \param specs The specification.
*/
- void setSpecs(AUD_Specs specs);
+ void setSpecs(AUD_DeviceSpecs specs);
/**
* Sets the reader for resampling.
diff --git a/intern/audaspace/intern/AUD_NULLDevice.cpp b/intern/audaspace/intern/AUD_NULLDevice.cpp
index d237b71b67e..3936695c28f 100644
--- a/intern/audaspace/intern/AUD_NULLDevice.cpp
+++ b/intern/audaspace/intern/AUD_NULLDevice.cpp
@@ -34,7 +34,7 @@ AUD_NULLDevice::AUD_NULLDevice()
m_specs.rate = AUD_RATE_INVALID;
}
-AUD_Specs AUD_NULLDevice::getSpecs()
+AUD_DeviceSpecs AUD_NULLDevice::getSpecs()
{
return m_specs;
}
diff --git a/intern/audaspace/intern/AUD_NULLDevice.h b/intern/audaspace/intern/AUD_NULLDevice.h
index 155f24f8837..91ddd23cf71 100644
--- a/intern/audaspace/intern/AUD_NULLDevice.h
+++ b/intern/audaspace/intern/AUD_NULLDevice.h
@@ -37,7 +37,7 @@ private:
/**
* The specs of the device.
*/
- AUD_Specs m_specs;
+ AUD_DeviceSpecs m_specs;
public:
/**
@@ -45,7 +45,7 @@ public:
*/
AUD_NULLDevice();
- virtual AUD_Specs getSpecs();
+ virtual AUD_DeviceSpecs getSpecs();
virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
virtual bool pause(AUD_Handle* handle);
virtual bool resume(AUD_Handle* handle);
diff --git a/intern/audaspace/intern/AUD_ReadDevice.cpp b/intern/audaspace/intern/AUD_ReadDevice.cpp
index e2c1d2fac81..37a7d1ae295 100644
--- a/intern/audaspace/intern/AUD_ReadDevice.cpp
+++ b/intern/audaspace/intern/AUD_ReadDevice.cpp
@@ -23,17 +23,17 @@
* ***** END LGPL LICENSE BLOCK *****
*/
-#include "AUD_FloatMixer.h"
+#include "AUD_Mixer.h"
#include "AUD_ReadDevice.h"
#include "AUD_IReader.h"
#include <cstring>
-AUD_ReadDevice::AUD_ReadDevice(AUD_Specs specs)
+AUD_ReadDevice::AUD_ReadDevice(AUD_DeviceSpecs specs)
{
m_specs = specs;
- m_mixer = new AUD_FloatMixer(); AUD_NEW("mixer")
+ m_mixer = new AUD_Mixer(); AUD_NEW("mixer")
m_mixer->setSpecs(m_specs);
m_playing = false;
@@ -46,15 +46,15 @@ AUD_ReadDevice::~AUD_ReadDevice()
destroy();
}
-bool AUD_ReadDevice::read(sample_t* buffer, int length)
+bool AUD_ReadDevice::read(data_t* buffer, int length)
{
if(m_playing)
mix(buffer, length);
else
if(m_specs.format == AUD_FORMAT_U8)
- memset(buffer, 0x80, length * AUD_SAMPLE_SIZE(m_specs));
+ memset(buffer, 0x80, length * AUD_DEVICE_SAMPLE_SIZE(m_specs));
else
- memset(buffer, 0, length * AUD_SAMPLE_SIZE(m_specs));
+ memset(buffer, 0, length * AUD_DEVICE_SAMPLE_SIZE(m_specs));
return m_playing;
}
diff --git a/intern/audaspace/intern/AUD_ReadDevice.h b/intern/audaspace/intern/AUD_ReadDevice.h
index d69b0c31ea5..3fd90df7755 100644
--- a/intern/audaspace/intern/AUD_ReadDevice.h
+++ b/intern/audaspace/intern/AUD_ReadDevice.h
@@ -47,7 +47,7 @@ public:
* Creates a new read device.
* \param specs The wanted audio specification.
*/
- AUD_ReadDevice(AUD_Specs specs);
+ AUD_ReadDevice(AUD_DeviceSpecs specs);
/**
* Closes the device.
@@ -62,7 +62,7 @@ public:
* played back currently, in that case the buffer is filled with
* silence.
*/
- bool read(sample_t* buffer, int length);
+ bool read(data_t* buffer, int length);
};
#endif //AUD_READDEVICE
diff --git a/intern/audaspace/intern/AUD_SinusReader.cpp b/intern/audaspace/intern/AUD_SinusReader.cpp
index 87e2f789d66..c52513d5d2e 100644
--- a/intern/audaspace/intern/AUD_SinusReader.cpp
+++ b/intern/audaspace/intern/AUD_SinusReader.cpp
@@ -26,7 +26,7 @@
#include "AUD_SinusReader.h"
#include "AUD_Buffer.h"
-#include <math.h>
+#include <cmath>
#ifndef M_PI
#define M_PI 3.14159265358979323846
@@ -69,8 +69,7 @@ AUD_Specs AUD_SinusReader::getSpecs()
{
AUD_Specs specs;
specs.rate = m_sampleRate;
- specs.format = AUD_FORMAT_S16;
- specs.channels = AUD_CHANNELS_STEREO;
+ specs.channels = AUD_CHANNELS_MONO;
return specs;
}
@@ -87,18 +86,16 @@ bool AUD_SinusReader::notify(AUD_Message &message)
void AUD_SinusReader::read(int & length, sample_t* & buffer)
{
// resize if necessary
- if(m_buffer->getSize() < length*4)
- m_buffer->resize(length*4);
+ if(m_buffer->getSize() < length * sizeof(sample_t))
+ m_buffer->resize(length * sizeof(sample_t));
// fill with sine data
- short* buf = (short*) m_buffer->getBuffer();
- for(int i=0; i < length; i++)
+ buffer = m_buffer->getBuffer();
+ for(int i = 0; i < length; i++)
{
- buf[i*2] = sin((m_position + i) * 2.0 * M_PI * m_frequency /
- (float)m_sampleRate) * 32700;
- buf[i*2+1] = buf[i*2];
+ buffer[i] = sin((m_position + i) * 2.0f * M_PI * m_frequency /
+ (float)m_sampleRate);
}
- buffer = (sample_t*)buf;
m_position += length;
}
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.cpp b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
index 42a90a6f15e..a615bcd0245 100644
--- a/intern/audaspace/intern/AUD_SoftwareDevice.cpp
+++ b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
@@ -25,7 +25,7 @@
#include "AUD_SoftwareDevice.h"
#include "AUD_IReader.h"
-#include "AUD_IMixer.h"
+#include "AUD_Mixer.h"
#include "AUD_IFactory.h"
#include "AUD_SourceCaps.h"
@@ -51,7 +51,9 @@ void AUD_SoftwareDevice::create()
m_playingSounds = new std::list<AUD_SoftwareHandle*>(); AUD_NEW("list")
m_pausedSounds = new std::list<AUD_SoftwareHandle*>(); AUD_NEW("list")
m_playback = false;
- m_volume = 1.0;
+ m_volume = 1.0f;
+ m_mixer = new AUD_Mixer(); AUD_NEW("mixer")
+ m_mixer->setSpecs(m_specs);
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
@@ -90,7 +92,7 @@ void AUD_SoftwareDevice::destroy()
pthread_mutex_destroy(&m_mutex);
}
-void AUD_SoftwareDevice::mix(sample_t* buffer, int length)
+void AUD_SoftwareDevice::mix(data_t* buffer, int length)
{
lock();
@@ -98,7 +100,7 @@ void AUD_SoftwareDevice::mix(sample_t* buffer, int length)
AUD_SoftwareHandle* sound;
int len;
sample_t* buf;
- int sample_size = AUD_SAMPLE_SIZE(m_specs);
+ int sample_size = AUD_DEVICE_SAMPLE_SIZE(m_specs);
std::list<AUD_SoftwareHandle*> stopSounds;
// for all sounds
@@ -114,7 +116,7 @@ void AUD_SoftwareDevice::mix(sample_t* buffer, int length)
len = length;
sound->reader->read(len, buf);
- m_mixer->add(buf, sound->reader->getSpecs(), len, sound->volume);
+ m_mixer->add(buf, len, sound->volume);
// in case the end of the sound is reached
if(len < length)
@@ -159,14 +161,7 @@ bool AUD_SoftwareDevice::isValid(AUD_Handle* handle)
return false;
}
-void AUD_SoftwareDevice::setMixer(AUD_IMixer* mixer)
-{
- delete m_mixer; AUD_DELETE("mixer")
- m_mixer = mixer;
- mixer->setSpecs(m_specs);
-}
-
-AUD_Specs AUD_SoftwareDevice::getSpecs()
+AUD_DeviceSpecs AUD_SoftwareDevice::getSpecs()
{
return m_specs;
}
@@ -189,7 +184,7 @@ AUD_Handle* AUD_SoftwareDevice::play(AUD_IFactory* factory, bool keep)
AUD_SoftwareHandle* sound = new AUD_SoftwareHandle; AUD_NEW("handle")
sound->keep = keep;
sound->reader = reader;
- sound->volume = 1.0;
+ sound->volume = 1.0f;
lock();
m_playingSounds->push_back(sound);
@@ -426,10 +421,10 @@ bool AUD_SoftwareDevice::setCapability(int capability, void *value)
case AUD_CAPS_VOLUME:
lock();
m_volume = *((float*)value);
- if(m_volume > 1.0)
- m_volume = 1.0;
- else if(m_volume < 0.0)
- m_volume = 0.0;
+ if(m_volume > 1.0f)
+ m_volume = 1.0f;
+ else if(m_volume < 0.0f)
+ m_volume = 0.0f;
unlock();
return true;
case AUD_CAPS_SOURCE_VOLUME:
@@ -440,10 +435,10 @@ bool AUD_SoftwareDevice::setCapability(int capability, void *value)
{
AUD_SoftwareHandle* handle = (AUD_SoftwareHandle*)caps->handle;
handle->volume = caps->value;
- if(handle->volume > 1.0)
- handle->volume = 1.0;
- else if(handle->volume < 0.0)
- handle->volume = 0.0;
+ if(handle->volume > 1.0f)
+ handle->volume = 1.0f;
+ else if(handle->volume < 0.0f)
+ handle->volume = 0.0f;
result = true;
}
unlock();
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.h b/intern/audaspace/intern/AUD_SoftwareDevice.h
index 3768786fa9c..a12fddb1e00 100644
--- a/intern/audaspace/intern/AUD_SoftwareDevice.h
+++ b/intern/audaspace/intern/AUD_SoftwareDevice.h
@@ -28,7 +28,7 @@
#include "AUD_IDevice.h"
struct AUD_SoftwareHandle;
-class AUD_IMixer;
+class AUD_Mixer;
#include <list>
#include <pthread.h>
@@ -47,12 +47,12 @@ protected:
/**
* The specification of the device.
*/
- AUD_Specs m_specs;
+ AUD_DeviceSpecs m_specs;
/**
- * The mixer. Will be deleted by the destroy function.
+ * The mixer.
*/
- AUD_IMixer* m_mixer;
+ AUD_Mixer* m_mixer;
/**
* Initializes member variables.
@@ -69,7 +69,7 @@ protected:
* \param buffer The target buffer.
* \param length The length in samples to be filled.
*/
- void mix(sample_t* buffer, int length);
+ void mix(data_t* buffer, int length);
/**
* This function tells the device, to start or pause playback.
@@ -111,13 +111,7 @@ private:
bool isValid(AUD_Handle* handle);
public:
- /**
- * Sets a new mixer.
- * \param mixer The new mixer.
- */
- void setMixer(AUD_IMixer* mixer);
-
- virtual AUD_Specs getSpecs();
+ virtual AUD_DeviceSpecs getSpecs();
virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
virtual bool pause(AUD_Handle* handle);
virtual bool resume(AUD_Handle* handle);
diff --git a/intern/audaspace/intern/AUD_Space.h b/intern/audaspace/intern/AUD_Space.h
index 123d9c272a0..1d60be3979b 100644
--- a/intern/audaspace/intern/AUD_Space.h
+++ b/intern/audaspace/intern/AUD_Space.h
@@ -28,8 +28,10 @@
/// The size of a format in bytes.
#define AUD_FORMAT_SIZE(format) (format & 0x0F)
+/// The size of a sample in the specified device format in bytes.
+#define AUD_DEVICE_SAMPLE_SIZE(specs) (specs.channels * (specs.format & 0x0F))
/// The size of a sample in the specified format in bytes.
-#define AUD_SAMPLE_SIZE(specs) (specs.channels * (specs.format & 0x0F))
+#define AUD_SAMPLE_SIZE(specs) (specs.channels * sizeof(sample_t))
/// Throws a AUD_Exception with the provided error code.
#define AUD_THROW(exception) { AUD_Exception e; e.error = exception; throw e; }
@@ -233,22 +235,42 @@ typedef enum
AUD_3DSS_CONE_OUTER_GAIN /// Cone outer gain.
} AUD_3DSourceSetting;
-/// Sample pointer type.
-typedef unsigned char sample_t;
+/// Sample type.(float samples)
+typedef float sample_t;
-/// Specification of a sound source or device.
+/// Sample data type (format samples)
+typedef unsigned char data_t;
+
+/// Specification of a sound source.
typedef struct
{
/// Sample rate in Hz.
AUD_SampleRate rate;
- /// Sample format.
- AUD_SampleFormat format;
-
/// Channel count.
AUD_Channels channels;
} AUD_Specs;
+/// Specification of a sound device.
+typedef struct
+{
+ /// Sample format.
+ AUD_SampleFormat format;
+
+ union
+ {
+ struct
+ {
+ /// Sample rate in Hz.
+ AUD_SampleRate rate;
+
+ /// Channel count.
+ AUD_Channels channels;
+ };
+ AUD_Specs specs;
+ };
+} AUD_DeviceSpecs;
+
/// Exception structure.
typedef struct
{
diff --git a/intern/audaspace/intern/AUD_StreamBufferFactory.cpp b/intern/audaspace/intern/AUD_StreamBufferFactory.cpp
index 11391fa4a08..4d2cd9e2505 100644
--- a/intern/audaspace/intern/AUD_StreamBufferFactory.cpp
+++ b/intern/audaspace/intern/AUD_StreamBufferFactory.cpp
@@ -61,9 +61,9 @@ AUD_StreamBufferFactory::AUD_StreamBufferFactory(AUD_IFactory* factory)
// read more
length = size-index;
reader->read(length, buffer);
- memcpy(m_buffer.get()->getBuffer()+index*sample_size,
+ memcpy(m_buffer.get()->getBuffer() + index * m_specs.channels,
buffer,
- length*sample_size);
+ length * sample_size);
size += AUD_BUFFER_RESIZE_BYTES / sample_size;
index += length;
}
diff --git a/intern/audaspace/jack/AUD_JackDevice.cpp b/intern/audaspace/jack/AUD_JackDevice.cpp
index 4d8ab93d672..acd37de870c 100644
--- a/intern/audaspace/jack/AUD_JackDevice.cpp
+++ b/intern/audaspace/jack/AUD_JackDevice.cpp
@@ -23,7 +23,7 @@
* ***** END LGPL LICENSE BLOCK *****
*/
-#include "AUD_FloatMixer.h"
+#include "AUD_Mixer.h"
#include "AUD_JackDevice.h"
#include "AUD_IReader.h"
#include "AUD_Buffer.h"
@@ -38,7 +38,7 @@ int AUD_JackDevice::jack_mix(jack_nframes_t length, void *data)
unsigned int samplesize = AUD_SAMPLE_SIZE(device->m_specs);
if(device->m_buffer->getSize() < samplesize * length)
device->m_buffer->resize(samplesize * length);
- device->mix(device->m_buffer->getBuffer(), length);
+ device->mix((data_t*)device->m_buffer->getBuffer(), length);
float* in = (float*) device->m_buffer->getBuffer();
float* out;
@@ -60,7 +60,7 @@ void AUD_JackDevice::jack_shutdown(void *data)
device->m_valid = false;
}
-AUD_JackDevice::AUD_JackDevice(AUD_Specs specs)
+AUD_JackDevice::AUD_JackDevice(AUD_DeviceSpecs specs)
{
if(specs.channels == AUD_CHANNELS_INVALID)
specs.channels = AUD_CHANNELS_STEREO;
@@ -123,9 +123,6 @@ AUD_JackDevice::AUD_JackDevice(AUD_Specs specs)
free(ports);
}
- m_mixer = new AUD_FloatMixer(); AUD_NEW("mixer")
- m_mixer->setSpecs(m_specs);
-
m_valid = true;
create();
diff --git a/intern/audaspace/jack/AUD_JackDevice.h b/intern/audaspace/jack/AUD_JackDevice.h
index f0c887a2f43..5a073a69432 100644
--- a/intern/audaspace/jack/AUD_JackDevice.h
+++ b/intern/audaspace/jack/AUD_JackDevice.h
@@ -81,7 +81,7 @@ public:
* \param specs The wanted audio specification, where only the channel count is important.
* \exception AUD_Exception Thrown if the audio device cannot be opened.
*/
- AUD_JackDevice(AUD_Specs specs);
+ AUD_JackDevice(AUD_DeviceSpecs specs);
/**
* Closes the Jack client.
diff --git a/intern/audaspace/make/msvc_9_0/audaspace.vcproj b/intern/audaspace/make/msvc_9_0/audaspace.vcproj
index 37ac98c0cf2..bdf14255391 100644
--- a/intern/audaspace/make/msvc_9_0/audaspace.vcproj
+++ b/intern/audaspace/make/msvc_9_0/audaspace.vcproj
@@ -394,31 +394,43 @@
>
</File>
<File
- RelativePath="..\..\intern\AUD_FloatMixer.cpp"
+ RelativePath="..\..\intern\AUD_I3DDevice.h"
>
</File>
<File
- RelativePath="..\..\intern\AUD_FloatMixer.h"
+ RelativePath="..\..\intern\AUD_IDevice.h"
>
</File>
<File
- RelativePath="..\..\intern\AUD_I3DDevice.h"
+ RelativePath="..\..\intern\AUD_IFactory.h"
>
</File>
<File
- RelativePath="..\..\intern\AUD_IDevice.h"
+ RelativePath="..\..\intern\AUD_IReader.h"
>
</File>
<File
- RelativePath="..\..\intern\AUD_IFactory.h"
+ RelativePath="..\..\intern\AUD_LinearResampleFactory.cpp"
>
</File>
<File
- RelativePath="..\..\intern\AUD_IMixer.h"
+ RelativePath="..\..\intern\AUD_LinearResampleFactory.h"
>
</File>
<File
- RelativePath="..\..\intern\AUD_IReader.h"
+ RelativePath="..\..\intern\AUD_LinearResampleReader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_LinearResampleReader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_Mixer.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_Mixer.h"
>
</File>
<File
@@ -518,6 +530,38 @@
Name="FX"
>
<File
+ RelativePath="..\..\FX\AUD_AccumulatorFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_AccumulatorFactory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_AccumulatorReader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_AccumulatorReader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_ButterworthFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_ButterworthFactory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_ButterworthReader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_ButterworthReader.h"
+ >
+ </File>
+ <File
RelativePath="..\..\FX\AUD_DelayFactory.cpp"
>
</File>
@@ -558,6 +602,22 @@
>
</File>
<File
+ RelativePath="..\..\FX\AUD_EnvelopeFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_EnvelopeFactory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_EnvelopeReader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_EnvelopeReader.h"
+ >
+ </File>
+ <File
RelativePath="..\..\FX\AUD_FaderFactory.cpp"
>
</File>
@@ -574,6 +634,22 @@
>
</File>
<File
+ RelativePath="..\..\FX\AUD_HighpassFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_HighpassFactory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_HighpassReader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_HighpassReader.h"
+ >
+ </File>
+ <File
RelativePath="..\..\FX\AUD_LimiterFactory.cpp"
>
</File>
@@ -606,6 +682,22 @@
>
</File>
<File
+ RelativePath="..\..\FX\AUD_LowpassFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_LowpassFactory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_LowpassReader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_LowpassReader.h"
+ >
+ </File>
+ <File
RelativePath="..\..\FX\AUD_PingPongFactory.cpp"
>
</File>
@@ -662,67 +754,75 @@
>
</File>
<File
- RelativePath="..\..\FX\AUD_VolumeFactory.cpp"
+ RelativePath="..\..\FX\AUD_SquareFactory.cpp"
>
</File>
<File
- RelativePath="..\..\FX\AUD_VolumeFactory.h"
+ RelativePath="..\..\FX\AUD_SquareFactory.h"
>
</File>
<File
- RelativePath="..\..\FX\AUD_VolumeReader.cpp"
+ RelativePath="..\..\FX\AUD_SquareReader.cpp"
>
</File>
<File
- RelativePath="..\..\FX\AUD_VolumeReader.h"
+ RelativePath="..\..\FX\AUD_SquareReader.h"
>
</File>
- </Filter>
- <Filter
- Name="OpenAL"
- >
<File
- RelativePath="..\..\OpenAL\AUD_OpenALDevice.cpp"
+ RelativePath="..\..\FX\AUD_SumFactory.cpp"
>
</File>
<File
- RelativePath="..\..\OpenAL\AUD_OpenALDevice.h"
+ RelativePath="..\..\FX\AUD_SumFactory.h"
>
</File>
- </Filter>
- <Filter
- Name="SDL"
- >
<File
- RelativePath="..\..\SDL\AUD_SDLDevice.cpp"
+ RelativePath="..\..\FX\AUD_SumReader.cpp"
>
</File>
<File
- RelativePath="..\..\SDL\AUD_SDLDevice.h"
+ RelativePath="..\..\FX\AUD_SumReader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_VolumeFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_VolumeFactory.h"
>
</File>
<File
- RelativePath="..\..\SDL\AUD_SDLMixer.cpp"
+ RelativePath="..\..\FX\AUD_VolumeReader.cpp"
>
</File>
<File
- RelativePath="..\..\SDL\AUD_SDLMixer.h"
+ RelativePath="..\..\FX\AUD_VolumeReader.h"
>
</File>
+ </Filter>
+ <Filter
+ Name="OpenAL"
+ >
<File
- RelativePath="..\..\SDL\AUD_SDLMixerFactory.cpp"
+ RelativePath="..\..\OpenAL\AUD_OpenALDevice.cpp"
>
</File>
<File
- RelativePath="..\..\SDL\AUD_SDLMixerFactory.h"
+ RelativePath="..\..\OpenAL\AUD_OpenALDevice.h"
>
</File>
+ </Filter>
+ <Filter
+ Name="SDL"
+ >
<File
- RelativePath="..\..\SDL\AUD_SDLMixerReader.cpp"
+ RelativePath="..\..\SDL\AUD_SDLDevice.cpp"
>
</File>
<File
- RelativePath="..\..\SDL\AUD_SDLMixerReader.h"
+ RelativePath="..\..\SDL\AUD_SDLDevice.h"
>
</File>
</Filter>
diff --git a/intern/audaspace/sndfile/AUD_SndFileReader.cpp b/intern/audaspace/sndfile/AUD_SndFileReader.cpp
index 485818552bb..f9ed8d6388e 100644
--- a/intern/audaspace/sndfile/AUD_SndFileReader.cpp
+++ b/intern/audaspace/sndfile/AUD_SndFileReader.cpp
@@ -28,31 +28,14 @@
#include <cstring>
-// This function transforms a SampleFormat to our own sample format
-static inline AUD_SampleFormat SNDFILE_TO_AUD(int fmt)
-{
- switch(fmt & SF_FORMAT_SUBMASK)
- {
- // only read s16, s32 and double as they are
- case SF_FORMAT_PCM_16:
- return AUD_FORMAT_S16;
- case SF_FORMAT_PCM_32:
- return AUD_FORMAT_S32;
- case SF_FORMAT_DOUBLE:
- return AUD_FORMAT_FLOAT64;
- // read all other formats as floats
- default:
- return AUD_FORMAT_FLOAT32;
- }
-}
-
sf_count_t AUD_SndFileReader::vio_get_filelen(void *user_data)
{
AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
return reader->m_membuffer.get()->getSize();
}
-sf_count_t AUD_SndFileReader::vio_seek(sf_count_t offset, int whence, void *user_data)
+sf_count_t AUD_SndFileReader::vio_seek(sf_count_t offset, int whence,
+ void *user_data)
{
AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
@@ -72,14 +55,16 @@ sf_count_t AUD_SndFileReader::vio_seek(sf_count_t offset, int whence, void *user
return reader->m_memoffset;
}
-sf_count_t AUD_SndFileReader::vio_read(void *ptr, sf_count_t count, void *user_data)
+sf_count_t AUD_SndFileReader::vio_read(void *ptr, sf_count_t count,
+ void *user_data)
{
AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
if(reader->m_memoffset + count > reader->m_membuffer.get()->getSize())
count = reader->m_membuffer.get()->getSize() - reader->m_memoffset;
- memcpy(ptr, reader->m_membuffer.get()->getBuffer() + reader->m_memoffset, count);
+ memcpy(ptr, ((data_t*)reader->m_membuffer.get()->getBuffer()) +
+ reader->m_memoffset, count);
reader->m_memoffset += count;
return count;
@@ -103,27 +88,11 @@ AUD_SndFileReader::AUD_SndFileReader(const char* filename)
AUD_THROW(AUD_ERROR_FILE);
m_specs.channels = (AUD_Channels) sfinfo.channels;
- m_specs.format = SNDFILE_TO_AUD(sfinfo.format);
m_specs.rate = (AUD_SampleRate) sfinfo.samplerate;
m_length = sfinfo.frames;
m_seekable = sfinfo.seekable;
m_position = 0;
- switch(m_specs.format)
- {
- case AUD_FORMAT_S16:
- m_read = (sf_read_f) sf_readf_short;
- break;
- case AUD_FORMAT_S32:
- m_read = (sf_read_f) sf_readf_int;
- break;
- case AUD_FORMAT_FLOAT64:
- m_read = (sf_read_f) sf_readf_double;
- break;
- default:
- m_read = (sf_read_f) sf_readf_float;
- }
-
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
}
@@ -147,27 +116,11 @@ AUD_SndFileReader::AUD_SndFileReader(AUD_Reference<AUD_Buffer> buffer)
AUD_THROW(AUD_ERROR_FILE);
m_specs.channels = (AUD_Channels) sfinfo.channels;
- m_specs.format = SNDFILE_TO_AUD(sfinfo.format);
m_specs.rate = (AUD_SampleRate) sfinfo.samplerate;
m_length = sfinfo.frames;
m_seekable = sfinfo.seekable;
m_position = 0;
- switch(m_specs.format)
- {
- case AUD_FORMAT_S16:
- m_read = (sf_read_f) sf_readf_short;
- break;
- case AUD_FORMAT_S32:
- m_read = (sf_read_f) sf_readf_int;
- break;
- case AUD_FORMAT_FLOAT64:
- m_read = (sf_read_f) sf_readf_double;
- break;
- default:
- m_read = (sf_read_f) sf_readf_float;
- }
-
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
}
@@ -227,7 +180,7 @@ void AUD_SndFileReader::read(int & length, sample_t* & buffer)
buffer = m_buffer->getBuffer();
- length = m_read(m_sndfile, buffer, length);
+ length = sf_readf_float(m_sndfile, buffer, length);
m_position += length;
}
diff --git a/intern/audaspace/sndfile/AUD_SndFileReader.h b/intern/audaspace/sndfile/AUD_SndFileReader.h
index da890ef53ca..8886b6e9efc 100644
--- a/intern/audaspace/sndfile/AUD_SndFileReader.h
+++ b/intern/audaspace/sndfile/AUD_SndFileReader.h
@@ -71,11 +71,6 @@ private:
SNDFILE* m_sndfile;
/**
- * The reading function.
- */
- sf_read_f m_read;
-
- /**
* The virtual IO structure for memory file reading.
*/
SF_VIRTUAL_IO m_vio;
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index d4788ae9e86..7e7b24721eb 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -162,6 +162,8 @@ extern void GHOST_GetMainDisplayDimensions(GHOST_SystemHandle systemhandle,
* @param height The height the window.
* @param state The state of the window when opened.
* @param type The type of drawing context installed in this window.
+ * @param stereoVisual Stereo visual for quad buffered stereo.
+ * @param numOfAASamples Number of samples used for AA (zero if no AA)
* @return A handle to the new window ( == NULL if creation failed).
*/
extern GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
@@ -172,7 +174,8 @@ extern GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
- const int stereoVisual);
+ const int stereoVisual,
+ const GHOST_TUns16 numOfAASamples);
/**
* Returns the window user data.
diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h
index 305caa70ae4..d1449aaef59 100644
--- a/intern/ghost/GHOST_ISystem.h
+++ b/intern/ghost/GHOST_ISystem.h
@@ -216,14 +216,15 @@ public:
* Create a new window.
* The new window is added to the list of windows managed.
* Never explicitly delete the window, use disposeWindow() instead.
- * @param title The name of the window (displayed in the title bar of the window if the OS supports it).
- * @param left The coordinate of the left edge of the window.
- * @param top The coordinate of the top edge of the window.
- * @param width The width the window.
- * @param height The height the window.
- * @param state The state of the window when opened.
- * @param type The type of drawing context installed in this window.
+ * @param title The name of the window (displayed in the title bar of the window if the OS supports it).
+ * @param left The coordinate of the left edge of the window.
+ * @param top The coordinate of the top edge of the window.
+ * @param width The width the window.
+ * @param height The height the window.
+ * @param state The state of the window when opened.
+ * @param type The type of drawing context installed in this window.
* @param stereoVisual Create a stereo visual for quad buffered stereo.
+ * @param numOfAASamples Number of samples used for AA (zero if no AA)
* @param parentWindow Parent (embedder) window
* @return The new window (or 0 if creation failed).
*/
@@ -231,7 +232,8 @@ public:
const STR_String& title,
GHOST_TInt32 left, GHOST_TInt32 top, GHOST_TUns32 width, GHOST_TUns32 height,
GHOST_TWindowState state, GHOST_TDrawingContextType type,
- const bool stereoVisual,
+ const bool stereoVisual = false,
+ const GHOST_TUns16 numOfAASamples = 0,
const GHOST_TEmbedderWindowID parentWindow = 0) = 0;
/**
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index 556176809f4..be726282d80 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -140,7 +140,8 @@ GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
- const int stereoVisual)
+ const int stereoVisual,
+ const GHOST_TUns16 numOfAASamples)
{
GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
bool bstereoVisual;
@@ -151,7 +152,7 @@ GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
bstereoVisual = false;
return (GHOST_WindowHandle) system->createWindow(title, left, top, width, height,
- state, type, bstereoVisual);
+ state, type, bstereoVisual, numOfAASamples);
}
GHOST_TUserDataPtr GHOST_GetWindowUserData(GHOST_WindowHandle windowhandle)
diff --git a/intern/ghost/intern/GHOST_SystemCarbon.cpp b/intern/ghost/intern/GHOST_SystemCarbon.cpp
index 57d6f6c06cc..3813a5ee450 100644
--- a/intern/ghost/intern/GHOST_SystemCarbon.cpp
+++ b/intern/ghost/intern/GHOST_SystemCarbon.cpp
@@ -402,6 +402,7 @@ GHOST_IWindow* GHOST_SystemCarbon::createWindow(
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
bool stereoVisual,
+ const GHOST_TUns16 numOfAASamples,
const GHOST_TEmbedderWindowID parentWindow
)
{
diff --git a/intern/ghost/intern/GHOST_SystemCarbon.h b/intern/ghost/intern/GHOST_SystemCarbon.h
index 5b3b786a5ac..7ebbbd8e97b 100644
--- a/intern/ghost/intern/GHOST_SystemCarbon.h
+++ b/intern/ghost/intern/GHOST_SystemCarbon.h
@@ -115,6 +115,7 @@ public:
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
const bool stereoVisual,
+ const GHOST_TUns16 numOfAASamples = 0,
const GHOST_TEmbedderWindowID parentWindow = 0
);
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h
index 81eb8978588..5b78f9b8fa3 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.h
+++ b/intern/ghost/intern/GHOST_SystemCocoa.h
@@ -93,13 +93,15 @@ public:
* Create a new window.
* The new window is added to the list of windows managed.
* Never explicitly delete the window, use disposeWindow() instead.
- * @param title The name of the window (displayed in the title bar of the window if the OS supports it).
- * @param left The coordinate of the left edge of the window.
- * @param top The coordinate of the top edge of the window.
- * @param width The width the window.
- * @param height The height the window.
- * @param state The state of the window when opened.
- * @param type The type of drawing context installed in this window.
+ * @param title The name of the window (displayed in the title bar of the window if the OS supports it).
+ * @param left The coordinate of the left edge of the window.
+ * @param top The coordinate of the top edge of the window.
+ * @param width The width the window.
+ * @param height The height the window.
+ * @param state The state of the window when opened.
+ * @param type The type of drawing context installed in this window.
+ * @param stereoVisual Stereo visual for quad buffered stereo.
+ * @param numOfAASamples Number of samples used for AA (zero if no AA)
* @param parentWindow Parent (embedder) window
* @return The new window (or 0 if creation failed).
*/
@@ -111,7 +113,8 @@ public:
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
- const bool stereoVisual,
+ const bool stereoVisual = false,
+ const GHOST_TUns16 numOfAASamples = 0,
const GHOST_TEmbedderWindowID parentWindow = 0
);
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm
index 71465822bee..1ba20315512 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.mm
+++ b/intern/ghost/intern/GHOST_SystemCocoa.mm
@@ -374,6 +374,25 @@ static GHOST_TKey convertKey(int rawCode, unichar recvChar)
}
+#pragma mark defines for 10.6 api not documented in 10.5
+#ifndef MAC_OS_X_VERSION_10_6
+
+@interface NSEvent(SnowLeopardEvents)
+/* modifier keys currently down. This returns the state of devices combined
+ with synthesized events at the moment, independent of which events
+ have been delivered via the event stream. */
+#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
++ (unsigned int)modifierFlags; //NSUInteger is defined only from 10.5
+#else
++ (NSUInteger)modifierFlags;
+#endif
+@end
+
+#endif
+
+
+#pragma mark Utility functions
+
#define FIRSTFILEBUFLG 512
static bool g_hasFirstFile = false;
static char g_firstFileBuf[512];
@@ -638,6 +657,7 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow(
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
bool stereoVisual,
+ const GHOST_TUns16 numOfAASamples,
const GHOST_TEmbedderWindowID parentWindow
)
{
@@ -653,7 +673,7 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow(
left = left > contentRect.origin.x ? left : contentRect.origin.x;
top = top > contentRect.origin.y ? top : contentRect.origin.y;
- window = new GHOST_WindowCocoa (this, title, left, top, width, height, state, type);
+ window = new GHOST_WindowCocoa (this, title, left, top, width, height, state, type, stereoVisual, numOfAASamples);
if (window) {
if (window->getValid()) {
@@ -883,11 +903,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleApplicationBecomeActiveEvent()
#else
//If build against an older SDK, check if running on 10.6 to use the correct function
if ([NSEvent respondsToSelector:@selector(modifierFlags)]) {
-#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
- modifiers = (unsigned int)[NSEvent modifierFlags];
-#else
- modifiers = (NSUInteger)[NSEvent modifierFlags];
-#endif
+ modifiers = [NSEvent modifierFlags];
}
else {
//TODO: need to find a better workaround for the missing cocoa "getModifierFlag" function in 10.4/10.5
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 15914a5bf43..d7d657fb496 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -190,7 +190,7 @@ GHOST_IWindow* GHOST_SystemWin32::createWindow(
const STR_String& title,
GHOST_TInt32 left, GHOST_TInt32 top, GHOST_TUns32 width, GHOST_TUns32 height,
GHOST_TWindowState state, GHOST_TDrawingContextType type,
- bool stereoVisual, const GHOST_TEmbedderWindowID parentWindow )
+ bool stereoVisual, const GHOST_TUns16 numOfAASamples, const GHOST_TEmbedderWindowID parentWindow )
{
GHOST_Window* window = 0;
window = new GHOST_WindowWin32 (this, title, left, top, width, height, state, type, stereoVisual);
diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h
index 517f7ddbeea..65d6a57ede3 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.h
+++ b/intern/ghost/intern/GHOST_SystemWin32.h
@@ -110,6 +110,8 @@ public:
* @param height The height the window.
* @param state The state of the window when opened.
* @param type The type of drawing context installed in this window.
+ * @param stereoVisual Stereo visual for quad buffered stereo.
+ * @param numOfAASamples Number of samples used for AA (zero if no AA)
* @param parentWindow Parent (embedder) window
* @return The new window (or 0 if creation failed).
*/
@@ -117,7 +119,9 @@ public:
const STR_String& title,
GHOST_TInt32 left, GHOST_TInt32 top, GHOST_TUns32 width, GHOST_TUns32 height,
GHOST_TWindowState state, GHOST_TDrawingContextType type,
- const bool stereoVisual, const GHOST_TEmbedderWindowID parentWindow = 0 );
+ const bool stereoVisual = false,
+ const GHOST_TUns16 numOfAASamples = 0,
+ const GHOST_TEmbedderWindowID parentWindow = 0 );
/***************************************************************************************
** Event management functionality
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index ad8647d2246..3ee3c1a29f3 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -228,6 +228,8 @@ getMainDisplayDimensions(
* @param height The height the window.
* @param state The state of the window when opened.
* @param type The type of drawing context installed in this window.
+ * @param stereoVisual Stereo visual for quad buffered stereo.
+ * @param numOfAASamples Number of samples used for AA (zero if no AA)
* @param parentWindow Parent (embedder) window
* @return The new window (or 0 if creation failed).
*/
@@ -242,6 +244,7 @@ createWindow(
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
bool stereoVisual,
+ const GHOST_TUns16 numOfAASamples,
const GHOST_TEmbedderWindowID parentWindow
){
GHOST_WindowX11 * window = 0;
diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h
index d76c3991beb..361db783102 100644
--- a/intern/ghost/intern/GHOST_SystemX11.h
+++ b/intern/ghost/intern/GHOST_SystemX11.h
@@ -127,6 +127,7 @@ public:
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
const bool stereoVisual,
+ const GHOST_TUns16 numOfAASamples = 0,
const GHOST_TEmbedderWindowID parentWindow = 0
);
diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp
index 14a255e2e5e..939a911dfac 100644
--- a/intern/ghost/intern/GHOST_Window.cpp
+++ b/intern/ghost/intern/GHOST_Window.cpp
@@ -44,13 +44,15 @@ GHOST_Window::GHOST_Window(
GHOST_TInt32 /*left*/, GHOST_TInt32 /*top*/, GHOST_TUns32 width, GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
- const bool stereoVisual)
+ const bool stereoVisual,
+ const GHOST_TUns16 numOfAASamples)
:
m_drawingContextType(type),
m_cursorVisible(true),
m_cursorGrab(GHOST_kGrabDisable),
m_cursorShape(GHOST_kStandardCursorDefault),
- m_stereoVisual(stereoVisual)
+ m_stereoVisual(stereoVisual),
+ m_numOfAASamples(numOfAASamples)
{
m_isUnsavedChanges = false;
m_canAcceptDragOperation = false;
diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h
index 1b5681dc41c..8aab9125130 100644
--- a/intern/ghost/intern/GHOST_Window.h
+++ b/intern/ghost/intern/GHOST_Window.h
@@ -75,14 +75,15 @@ public:
* Constructor.
* Creates a new window and opens it.
* To check if the window was created properly, use the getValid() method.
- * @param title The text shown in the title bar of the window.
- * @param left The coordinate of the left edge of the window.
- * @param top The coordinate of the top edge of the window.
- * @param width The width the window.
- * @param heigh The height the window.
- * @param state The state the window is initially opened with.
- * @param type The type of drawing context installed in this window.
- * @param stereoVisual Stereo visual for quad buffered stereo.
+ * @param title The text shown in the title bar of the window.
+ * @param left The coordinate of the left edge of the window.
+ * @param top The coordinate of the top edge of the window.
+ * @param width The width the window.
+ * @param heigh The height the window.
+ * @param state The state the window is initially opened with.
+ * @param type The type of drawing context installed in this window.
+ * @param stereoVisual Stereo visual for quad buffered stereo.
+ * @param numOfAASamples Number of samples used for AA (zero if no AA)
*/
GHOST_Window(
const STR_String& title,
@@ -92,7 +93,8 @@ public:
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
- const bool stereoVisual = false);
+ const bool stereoVisual = false,
+ const GHOST_TUns16 numOfAASamples = 0);
/**
* @section Interface inherited from GHOST_IWindow left for derived class
@@ -319,6 +321,9 @@ protected:
* the graphics h/w
*/
bool m_stereoVisual;
+
+ /** Number of samples used in anti-aliasing, set to 0 if no AA **/
+ GHOST_TUns16 m_numOfAASamples;
/** Full-screen width */
GHOST_TUns32 m_fullScreenWidth;
diff --git a/intern/ghost/intern/GHOST_WindowCarbon.cpp b/intern/ghost/intern/GHOST_WindowCarbon.cpp
index 362e949a0a4..3e53a052146 100644
--- a/intern/ghost/intern/GHOST_WindowCarbon.cpp
+++ b/intern/ghost/intern/GHOST_WindowCarbon.cpp
@@ -98,7 +98,8 @@ GHOST_WindowCarbon::GHOST_WindowCarbon(
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
- const bool stereoVisual
+ const bool stereoVisual,
+ const GHOST_TUns16 numOfAASamples
) :
GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone),
m_windowRef(0),
diff --git a/intern/ghost/intern/GHOST_WindowCarbon.h b/intern/ghost/intern/GHOST_WindowCarbon.h
index dd00add7fb1..b91e5410ddd 100644
--- a/intern/ghost/intern/GHOST_WindowCarbon.h
+++ b/intern/ghost/intern/GHOST_WindowCarbon.h
@@ -80,7 +80,8 @@ public:
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
- const bool stereoVisual = false
+ const bool stereoVisual = false,
+ const GHOST_TUns16 numOfAASamples = 0
);
/**
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h
index e59d9c17333..b54634b08d7 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.h
+++ b/intern/ghost/intern/GHOST_WindowCocoa.h
@@ -61,15 +61,16 @@ public:
* Constructor.
* Creates a new window and opens it.
* To check if the window was created properly, use the getValid() method.
- * @param systemCocoa The associated system class to forward events to
- * @param title The text shown in the title bar of the window.
- * @param left The coordinate of the left edge of the window.
- * @param top The coordinate of the top edge of the window.
- * @param width The width the window.
- * @param height The height the window.
- * @param state The state the window is initially opened with.
- * @param type The type of drawing context installed in this window.
- * @param stereoVisual Stereo visual for quad buffered stereo.
+ * @param systemCocoa The associated system class to forward events to
+ * @param title The text shown in the title bar of the window.
+ * @param left The coordinate of the left edge of the window.
+ * @param top The coordinate of the top edge of the window.
+ * @param width The width the window.
+ * @param height The height the window.
+ * @param state The state the window is initially opened with.
+ * @param type The type of drawing context installed in this window.
+ * @param stereoVisual Stereo visual for quad buffered stereo.
+ * @param numOfAASamples Number of samples used for AA (zero if no AA)
*/
GHOST_WindowCocoa(
GHOST_SystemCocoa *systemCocoa,
@@ -80,7 +81,8 @@ public:
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
- const bool stereoVisual = false
+ const bool stereoVisual = false,
+ const GHOST_TUns16 numOfAASamples = 0
);
/**
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm
index 8c9f8a7647d..66c6d75b6d7 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.mm
+++ b/intern/ghost/intern/GHOST_WindowCocoa.mm
@@ -34,9 +34,11 @@
#include <Carbon/Carbon.h>
#endif
+#include <OpenGL/gl.h>
/***** Multithreaded opengl code : uncomment for enabling
#include <OpenGL/OpenGL.h>
*/
+
#include "GHOST_WindowCocoa.h"
#include "GHOST_SystemCocoa.h"
@@ -277,14 +279,15 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
- const bool stereoVisual
+ const bool stereoVisual, const GHOST_TUns16 numOfAASamples
) :
- GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone, stereoVisual),
+ GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone, stereoVisual, numOfAASamples),
m_customCursor(0)
{
NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[40];
+ NSOpenGLPixelFormat *pixelFormat = nil;
int i;
-
+
m_systemCocoa = systemCocoa;
m_fullScreen = false;
@@ -329,13 +332,52 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
if (stereoVisual) pixelFormatAttrsWindow[i++] = NSOpenGLPFAStereo;
+ if (numOfAASamples>0) {
+ // Multisample anti-aliasing
+ pixelFormatAttrsWindow[i++] = NSOpenGLPFAMultisample;
+
+ pixelFormatAttrsWindow[i++] = NSOpenGLPFASampleBuffers;
+ pixelFormatAttrsWindow[i++] = (NSOpenGLPixelFormatAttribute) 1;
+
+ pixelFormatAttrsWindow[i++] = NSOpenGLPFASamples;
+ pixelFormatAttrsWindow[i++] = (NSOpenGLPixelFormatAttribute) numOfAASamples;
+
+ pixelFormatAttrsWindow[i++] = NSOpenGLPFANoRecovery;
+ }
+
pixelFormatAttrsWindow[i] = (NSOpenGLPixelFormatAttribute) 0;
-
- //Creates the OpenGL View inside the window
- NSOpenGLPixelFormat *pixelFormat =
- [[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttrsWindow];
+ pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttrsWindow];
+
+
+ //Fall back to no multisampling if Antialiasing init failed
+ if (pixelFormat == nil) {
+ i=0;
+ pixelFormatAttrsWindow[i++] = NSOpenGLPFADoubleBuffer;
+ pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccelerated;
+ //pixelFormatAttrsWindow[i++] = NSOpenGLPFAAllowOfflineRenderers,; // Removed to allow 10.4 builds, and 2 GPUs rendering is not used anyway
+
+ pixelFormatAttrsWindow[i++] = NSOpenGLPFADepthSize;
+ pixelFormatAttrsWindow[i++] = (NSOpenGLPixelFormatAttribute) 32;
+
+ if (stereoVisual) pixelFormatAttrsWindow[i++] = NSOpenGLPFAStereo;
+
+ pixelFormatAttrsWindow[i] = (NSOpenGLPixelFormatAttribute) 0;
+
+ pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttrsWindow];
+
+ }
+ if (numOfAASamples>0) { //Set m_numOfAASamples to the actual value
+ GLint gli;
+ [pixelFormat getValues:&gli forAttribute:NSOpenGLPFASamples forVirtualScreen:0];
+ if (m_numOfAASamples != (GHOST_TUns16)gli) {
+ m_numOfAASamples = (GHOST_TUns16)gli;
+ printf("GHOST_Window could be created with anti-aliasing of only %i samples\n",m_numOfAASamples);
+ }
+ }
+
+ //Creates the OpenGL View inside the window
m_openGLView = [[CocoaOpenGLView alloc] initWithFrame:rect
pixelFormat:pixelFormat];
@@ -398,14 +440,7 @@ GHOST_WindowCocoa::~GHOST_WindowCocoa()
bool GHOST_WindowCocoa::getValid() const
{
- bool valid;
- if (!m_fullScreen) {
- valid = (m_window != 0); //&& ::IsValidWindowPtr(m_windowRef);
- }
- else {
- valid = true;
- }
- return valid;
+ return (m_window != 0);
}
@@ -842,6 +877,9 @@ GHOST_TSuccess GHOST_WindowCocoa::activateDrawingContext()
if (m_openGLContext != nil) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[m_openGLContext makeCurrentContext];
+
+ // Disable AA by default
+ if (m_numOfAASamples > 0) glDisable(GL_MULTISAMPLE_ARB);
[pool drain];
return GHOST_kSuccess;
}
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index ea14f1dfc1b..e276f216fb7 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -105,10 +105,11 @@ GHOST_WindowWin32::GHOST_WindowWin32(
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
- const bool stereoVisual)
+ const bool stereoVisual,
+ const GHOST_TUns16 numOfAASamples)
:
GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone,
- stereoVisual),
+ stereoVisual,numOfAASamples),
m_system(system),
m_hDC(0),
m_hGlRc(0),
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
index 07a31911a5e..954546f3d82 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -75,6 +75,7 @@ public:
* @param state The state the window is initially opened with.
* @param type The type of drawing context installed in this window.
* @param stereoVisual Stereo visual for quad buffered stereo.
+ * @param numOfAASamples Number of samples used for AA (zero if no AA)
*/
GHOST_WindowWin32(
GHOST_SystemWin32 * system,
@@ -85,7 +86,8 @@ public:
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
- const bool stereoVisual = false
+ const bool stereoVisual = false,
+ const GHOST_TUns16 numOfAASamples = 0
);
/**
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index d9c2654f446..4afaa09b3f1 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -153,9 +153,10 @@ GHOST_WindowX11(
GHOST_TWindowState state,
const GHOST_TEmbedderWindowID parentWindow,
GHOST_TDrawingContextType type,
- const bool stereoVisual
+ const bool stereoVisual,
+ const GHOST_TUns16 numOfAASamples
) :
- GHOST_Window(title,left,top,width,height,state,type,stereoVisual),
+ GHOST_Window(title,left,top,width,height,state,type,stereoVisual,numOfAASamples),
m_context(NULL),
m_display(display),
m_system (system),
@@ -170,8 +171,14 @@ GHOST_WindowX11(
int attributes[40], i = 0;
Atom atoms[2];
- int natom;
-
+ int natom;
+ int glxVersionMajor, glxVersionMinor; // As in GLX major.minor
+
+ if (!glXQueryVersion(m_display, &glxVersionMajor, &glxVersionMinor)) {
+ printf("%s:%d: X11 glXQueryVersion() failed, verify working openGL system!\n", __FILE__, __LINE__);
+ return;
+ }
+
if(m_stereoVisual)
attributes[i++] = GLX_STEREO;
@@ -181,13 +188,18 @@ GHOST_WindowX11(
attributes[i++] = GLX_BLUE_SIZE; attributes[i++] = 1;
attributes[i++] = GLX_GREEN_SIZE; attributes[i++] = 1;
attributes[i++] = GLX_DEPTH_SIZE; attributes[i++] = 1;
+ /* GLX 1.4+, multi-sample */
+ if(m_numOfAASamples && (glxVersionMajor >= 1) && (glxVersionMinor >= 4)) {
+ attributes[i++] = GLX_SAMPLE_BUFFERS; attributes[i++] = 1;
+ attributes[i++] = GLX_SAMPLES; attributes[i++] = m_numOfAASamples;
+ }
attributes[i] = None;
-
+
m_visual = glXChooseVisual(m_display, DefaultScreen(m_display), attributes);
if (m_visual == NULL) {
// barf : no visual meeting these requirements could be found.
- printf("%s:%d: X11 glxChooseVisual() failed for OpenGL, verify working openGL system!\n", __FILE__, __LINE__);
+ printf("%s:%d: X11 glXChooseVisual() failed, verify working openGL system!\n", __FILE__, __LINE__);
return;
}
@@ -1226,10 +1238,7 @@ GHOST_WindowX11::
if(m_xtablet.EraserDevice)
XCloseDevice(m_display, m_xtablet.EraserDevice);
- if (m_context) {
- if (m_context == s_firstContext) {
- s_firstContext = NULL;
- }
+ if (m_context != s_firstContext) {
glXDestroyContext(m_display, m_context);
}
diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h
index 0dba1776553..9a299e16eb4 100644
--- a/intern/ghost/intern/GHOST_WindowX11.h
+++ b/intern/ghost/intern/GHOST_WindowX11.h
@@ -67,6 +67,7 @@ public:
* @param parentWindow Parent (embedder) window
* @param type The type of drawing context installed in this window.
* @param stereoVisual Stereo visual for quad buffered stereo.
+ * @param numOfAASamples Number of samples used for AA (zero if no AA)
*/
GHOST_WindowX11(
GHOST_SystemX11 *system,
@@ -79,7 +80,8 @@ public:
GHOST_TWindowState state,
const GHOST_TEmbedderWindowID parentWindow,
GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
- const bool stereoVisual = false
+ const bool stereoVisual = false,
+ const GHOST_TUns16 numOfAASamples = 0
);
bool
diff --git a/intern/ghost/intern/Makefile b/intern/ghost/intern/Makefile
index a6392662c30..d9f2bfe7cde 100644
--- a/intern/ghost/intern/Makefile
+++ b/intern/ghost/intern/Makefile
@@ -42,7 +42,7 @@ CCSRCS += GHOST_NDOFManager.cpp
ifeq ($(OS),$(findstring $(OS), "darwin"))
ifeq ($(WITH_COCOA), true)
- OCSRCS += $(wildcard *Cocoa.mm)
+ OCCSRCS += $(wildcard *Cocoa.mm)
CPPFLAGS += -DGHOST_COCOA
ifeq ($(WITH_QUICKTIME), true)
CPPFLAGS += -DWITH_QUICKTIME
diff --git a/projectfiles_vc9/blender/editors/ED_editors.vcproj b/projectfiles_vc9/blender/editors/ED_editors.vcproj
index 0602112106d..d8e8f5a9eca 100644
--- a/projectfiles_vc9/blender/editors/ED_editors.vcproj
+++ b/projectfiles_vc9/blender/editors/ED_editors.vcproj
@@ -1072,6 +1072,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\editors\object\object_bake.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\editors\object\object_constraint.c"
>
</File>
diff --git a/release/scripts/io/engine_render_pov.py b/release/scripts/io/engine_render_pov.py
index 3ad75f41709..5275574d903 100644
--- a/release/scripts/io/engine_render_pov.py
+++ b/release/scripts/io/engine_render_pov.py
@@ -537,7 +537,7 @@ def write_pov(filename, scene=None, info_callback=None):
writeMatrix(matrix)
file.write('}\n')
- bpy.data.remove_mesh(me)
+ bpy.data.meshes.remove(me)
def exportWorld(world):
if not world:
diff --git a/release/scripts/io/export_3ds.py b/release/scripts/io/export_3ds.py
index 23fd44acc3f..979c53c581d 100644
--- a/release/scripts/io/export_3ds.py
+++ b/release/scripts/io/export_3ds.py
@@ -1061,7 +1061,7 @@ def save_3ds(filename, context):
kfdata.add_subchunk(make_kf_obj_node(ob, name_to_id))
'''
# if not blender_mesh.users:
- bpy.data.remove_mesh(blender_mesh)
+ bpy.data.meshes.remove(blender_mesh)
# blender_mesh.verts = None
i+=i
diff --git a/release/scripts/io/export_fbx.py b/release/scripts/io/export_fbx.py
index 6407f9b6e49..a7e126446bd 100644
--- a/release/scripts/io/export_fbx.py
+++ b/release/scripts/io/export_fbx.py
@@ -651,7 +651,7 @@ def write(filename, batch_objects = None, \
}''' % (curtime))
file.write('\nCreationTime: "%.4i-%.2i-%.2i %.2i:%.2i:%.2i:000"' % curtime)
- file.write('\nCreator: "Blender3D version %s"' % bpy.version_string)
+ file.write('\nCreator: "Blender3D version %s"' % bpy.app.version_string)
pose_items = [] # list of (fbxName, matrix) to write pose data for, easier to collect allong the way
@@ -2989,7 +2989,7 @@ Takes: {''')
# Clear mesh data Only when writing with modifiers applied
for me in meshes_to_clear:
- bpy.data.remove_mesh(me)
+ bpy.data.meshes.remove(me)
# me.verts = None
# --------------------------- Footer
@@ -3391,8 +3391,7 @@ class ExportFBX(bpy.types.Operator):
def poll(self, context):
- print("Poll")
- return context.active_object != None
+ return context.active_object
def execute(self, context):
if not self.properties.path:
diff --git a/release/scripts/io/export_obj.py b/release/scripts/io/export_obj.py
index 6135375d185..8d1a9a9aced 100644
--- a/release/scripts/io/export_obj.py
+++ b/release/scripts/io/export_obj.py
@@ -361,7 +361,7 @@ def write(filename, objects, scene,
file = open(filename, "w")
# Write Header
- file.write('# Blender3D v%s OBJ File: %s\n' % (bpy.version_string, bpy.data.filename.split('/')[-1].split('\\')[-1] ))
+ file.write('# Blender3D v%s OBJ File: %s\n' % (bpy.app.version_string, bpy.data.filename.split('/')[-1].split('\\')[-1] ))
file.write('# www.blender3d.org\n')
# Tell the obj file what material file to use.
@@ -447,7 +447,7 @@ def write(filename, objects, scene,
break
if has_quads:
- newob = bpy.data.add_object('MESH', 'temp_object')
+ newob = bpy.data.objects.new('temp_object', 'MESH')
newob.data = me
# if we forget to set Object.data - crash
scene.objects.link(newob)
@@ -468,7 +468,7 @@ def write(filename, objects, scene,
if not (len(face_index_pairs)+len(edges)+len(me.verts)): # Make sure there is somthing to write
# clean up
- bpy.data.remove_mesh(me)
+ bpy.data.meshes.remove(me)
continue # dont bother with this mesh.
@@ -510,24 +510,12 @@ def write(filename, objects, scene,
# XXX update
tface = me.active_uv_texture.data
- # exception only raised if Python 2.3 or lower...
- try:
- face_index_pairs.sort(key = lambda a: (a[0].material_index, tface[a[1]].image, a[0].smooth))
- except:
- face_index_pairs.sort(lambda a,b: cmp((a[0].material_index, tface[a[1]].image, a[0].smooth),
- (b[0].material_index, tface[b[1]].image, b[0].smooth)))
+ face_index_pairs.sort(key=lambda a: (a[0].material_index, tface[a[1]].image, a[0].smooth))
elif len(materials) > 1:
- try:
- face_index_pairs.sort(key = lambda a: (a[0].material_index, a[0].smooth))
- except:
- face_index_pairs.sort(lambda a,b: cmp((a[0].material_index, a[0].smooth),
- (b[0].material_index, b[0].smooth)))
+ face_index_pairs.sort(key = lambda a: (a[0].material_index, a[0].smooth))
else:
# no materials
- try:
- face_index_pairs.sort(key = lambda a: a[0].smooth)
- except:
- face_index_pairs.sort(lambda a,b: cmp(a[0].smooth, b[0].smooth))
+ face_index_pairs.sort(key = lambda a: a[0].smooth)
# if EXPORT_KEEP_VERT_ORDER:
# pass
# elif faceuv:
@@ -609,7 +597,8 @@ def write(filename, objects, scene,
if EXPORT_NORMALS:
for f in faces:
if f.smooth:
- for v in f:
+ for vIdx in f.verts:
+ v = me.verts[vIdx]
noKey = veckey3d(v.normal)
if noKey not in globalNormals:
globalNormals[noKey] = totno
@@ -779,7 +768,7 @@ def write(filename, objects, scene,
totuvco += uv_unique_count
# clean up
- bpy.data.remove_mesh(me)
+ bpy.data.meshes.remove(me)
if ob_main.dupli_type != 'NONE':
ob_main.free_dupli_list()
diff --git a/release/scripts/io/export_ply.py b/release/scripts/io/export_ply.py
index 3c9e1f86ee2..58f65e928cf 100644
--- a/release/scripts/io/export_ply.py
+++ b/release/scripts/io/export_ply.py
@@ -205,7 +205,7 @@ def write(filename, scene, ob, \
file.write('ply\n')
file.write('format ascii 1.0\n')
- file.write('comment Created by Blender3D %s - www.blender.org, source file: %s\n' % (bpy.version_string, bpy.data.filename.split('/')[-1].split('\\')[-1]))
+ file.write('comment Created by Blender3D %s - www.blender.org, source file: %s\n' % (bpy.app.version_string, bpy.data.filename.split('/')[-1].split('\\')[-1]))
file.write('element vertex %d\n' % len(ply_verts))
@@ -254,7 +254,7 @@ def write(filename, scene, ob, \
print("writing", filename, "done")
if EXPORT_APPLY_MODIFIERS:
- bpy.data.remove_mesh(mesh)
+ bpy.data.meshes.remove(mesh)
# XXX
"""
diff --git a/release/scripts/io/export_x3d.py b/release/scripts/io/export_x3d.py
index 4c3540a458e..6b94a0cc91a 100644
--- a/release/scripts/io/export_x3d.py
+++ b/release/scripts/io/export_x3d.py
@@ -879,7 +879,7 @@ class x3d_class:
# free mesh created with create_mesh()
if me != ob.data:
- bpy.data.remove_mesh(me)
+ bpy.data.meshes.remove(me)
elif objType == "LAMP":
# elif objType == "Lamp":
diff --git a/release/scripts/io/import_scene_3ds.py b/release/scripts/io/import_scene_3ds.py
index 4420f6ef6f0..5f55b169d27 100644
--- a/release/scripts/io/import_scene_3ds.py
+++ b/release/scripts/io/import_scene_3ds.py
@@ -410,8 +410,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
myVertMapping = dict( [ (ii, i) for i, ii in enumerate(vertsToUse) ] )
tempName= '%s_%s' % (contextObName, matName) # matName may be None.
- bmesh = bpy.data.add_mesh(tempName)
-# bmesh = bpy.data.meshes.new(tempName)
+ bmesh = bpy.data.meshes.new(tempName)
if matName == None:
img = None
@@ -465,7 +464,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
# targetFace.image = img
# bmesh.transform(contextMatrix)
- ob = bpy.data.add_object("MESH", tempName)
+ ob = bpy.data.objects.new(tempName, 'MESH')
ob.data = bmesh
SCN.objects.link(ob)
# ob = SCN_OBJECTS.new(bmesh, tempName)
@@ -766,8 +765,8 @@ 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.add_object("LAMP", "Lamp")
- ob.data = bpy.data.add_lamp("Lamp")
+ ob = bpy.data.objects.new("Lamp", 'LAMP')
+ ob.data = bpy.data.lamps.new("Lamp")
SCN.objects.link(ob)
contextLamp[1]= ob.data
diff --git a/release/scripts/io/import_scene_obj.py b/release/scripts/io/import_scene_obj.py
index 228084561b8..001ed923699 100644
--- a/release/scripts/io/import_scene_obj.py
+++ b/release/scripts/io/import_scene_obj.py
@@ -712,8 +712,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
for name, index in list(material_mapping.items()):
materials[index]= unique_materials[name]
- me= bpy.data.add_mesh(dataname)
-# me= bpy.data.meshes.new(dataname)
+ me= bpy.data.meshes.new(dataname)
# make sure the list isnt too big
for material in materials[0:16]:
@@ -864,7 +863,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
me.update()
# me.calcNormals()
- ob= bpy.data.add_object("MESH", "Mesh")
+ ob= bpy.data.objects.new("Mesh", 'MESH')
ob.data= me
scn.objects.link(ob)
# ob= scn.objects.new(me)
@@ -886,12 +885,12 @@ def create_nurbs(scn, context_nurbs, vert_loc, new_objects):
Add nurbs object to blender, only support one type at the moment
'''
deg = context_nurbs.get('deg', (3,))
- curv_range = context_nurbs.get('curv_range', None)
+ curv_range = context_nurbs.get('curv_range')
curv_idx = context_nurbs.get('curv_idx', [])
parm_u = context_nurbs.get('parm_u', [])
parm_v = context_nurbs.get('parm_v', [])
name = context_nurbs.get('name', 'ObjNurb')
- cstype = context_nurbs.get('cstype', None)
+ cstype = context_nurbs.get('cstype')
if cstype == None:
print('\tWarning, cstype not found')
diff --git a/release/scripts/io/netrender/__init__.py b/release/scripts/io/netrender/__init__.py
index 77ab95535aa..b182ef7f452 100644
--- a/release/scripts/io/netrender/__init__.py
+++ b/release/scripts/io/netrender/__init__.py
@@ -32,3 +32,6 @@ jobs = []
slaves = []
blacklist = []
+init_file = ""
+init_data = True
+init_address = True \ No newline at end of file
diff --git a/release/scripts/io/netrender/balancing.py b/release/scripts/io/netrender/balancing.py
index e09b19f956c..344bacde90a 100644
--- a/release/scripts/io/netrender/balancing.py
+++ b/release/scripts/io/netrender/balancing.py
@@ -22,14 +22,23 @@ from netrender.utils import *
import netrender.model
class RatingRule:
+ def __init__(self):
+ self.enabled = True
+
def rate(self, job):
return 0
class ExclusionRule:
+ def __init__(self):
+ self.enabled = True
+
def test(self, job):
return False
class PriorityRule:
+ def __init__(self):
+ self.enabled = True
+
def test(self, job):
return False
@@ -39,6 +48,19 @@ class Balancer:
self.priorities = []
self.exceptions = []
+ def ruleByID(self, rule_id):
+ for rule in self.rules:
+ if id(rule) == rule_id:
+ return rule
+ for rule in self.priorities:
+ if id(rule) == rule_id:
+ return rule
+ for rule in self.exceptions:
+ if id(rule) == rule_id:
+ return rule
+
+ return None
+
def addRule(self, rule):
self.rules.append(rule)
@@ -49,18 +71,18 @@ class Balancer:
self.exceptions.append(exception)
def applyRules(self, job):
- return sum((rule.rate(job) for rule in self.rules))
+ return sum((rule.rate(job) for rule in self.rules if rule.enabled))
def applyPriorities(self, job):
for priority in self.priorities:
- if priority.test(job):
+ if priority.enabled and priority.test(job):
return True # priorities are first
return False
def applyExceptions(self, job):
for exception in self.exceptions:
- if exception.test(job):
+ if exception.enabled and exception.test(job):
return True # exceptions are last
return False
@@ -82,18 +104,20 @@ class Balancer:
class RatingUsage(RatingRule):
def __str__(self):
- return "Usage rating"
+ return "Usage per job"
def rate(self, job):
# less usage is better
return job.usage / job.priority
class RatingUsageByCategory(RatingRule):
- def __str__(self):
- return "Usage per category rating"
-
def __init__(self, get_jobs):
+ super().__init__()
self.getJobs = get_jobs
+
+ def __str__(self):
+ return "Usage per category"
+
def rate(self, job):
total_category_usage = sum([j.usage for j in self.getJobs() if j.category == job.category])
maximum_priority = max([j.priority for j in self.getJobs() if j.category == job.category])
@@ -102,49 +126,61 @@ class RatingUsageByCategory(RatingRule):
return total_category_usage / maximum_priority
class NewJobPriority(PriorityRule):
+ def __init__(self, limit = 1):
+ super().__init__()
+ self.limit = limit
+
+ def setLimit(self, value):
+ self.limit = int(value)
+
def str_limit(self):
return "less than %i frame%s done" % (self.limit, "s" if self.limit > 1 else "")
def __str__(self):
return "Priority to new jobs"
- def __init__(self, limit = 1):
- self.limit = limit
-
def test(self, job):
return job.countFrames(status = DONE) < self.limit
class MinimumTimeBetweenDispatchPriority(PriorityRule):
+ def __init__(self, limit = 10):
+ super().__init__()
+ self.limit = limit
+
+ def setLimit(self, value):
+ self.limit = int(value)
+
def str_limit(self):
return "more than %i minute%s since last" % (self.limit, "s" if self.limit > 1 else "")
def __str__(self):
return "Priority to jobs that haven't been dispatched recently"
- def __init__(self, limit = 10):
- self.limit = limit
-
def test(self, job):
return job.countFrames(status = DISPATCHED) == 0 and (time.time() - job.last_dispatched) / 60 > self.limit
class ExcludeQueuedEmptyJob(ExclusionRule):
def __str__(self):
- return "Exclude queued and empty jobs"
+ return "Exclude non queued or empty jobs"
def test(self, job):
return job.status != JOB_QUEUED or job.countFrames(status = QUEUED) == 0
class ExcludeSlavesLimit(ExclusionRule):
+ def __init__(self, count_jobs, count_slaves, limit = 0.75):
+ super().__init__()
+ self.count_jobs = count_jobs
+ self.count_slaves = count_slaves
+ self.limit = limit
+
+ def setLimit(self, value):
+ self.limit = float(value)
+
def str_limit(self):
return "more than %.0f%% of all slaves" % (self.limit * 100)
def __str__(self):
return "Exclude jobs that would use too many slaves"
- def __init__(self, count_jobs, count_slaves, limit = 0.75):
- self.count_jobs = count_jobs
- self.count_slaves = count_slaves
- self.limit = limit
-
def test(self, job):
return not ( self.count_jobs() == 1 or self.count_slaves() <= 1 or float(job.countSlaves() + 1) / self.count_slaves() <= self.limit )
diff --git a/release/scripts/io/netrender/client.py b/release/scripts/io/netrender/client.py
index d71d6a072ba..01130907553 100644
--- a/release/scripts/io/netrender/client.py
+++ b/release/scripts/io/netrender/client.py
@@ -197,11 +197,11 @@ class NetworkRenderEngine(bpy.types.RenderEngine):
address = "" if netsettings.server_address == "[default]" else netsettings.server_address
- master.runMaster((address, netsettings.server_port), netsettings.server_broadcast, netsettings.path, self.update_stats, self.test_break)
+ master.runMaster((address, netsettings.server_port), netsettings.master_broadcast, netsettings.master_clear, netsettings.path, self.update_stats, self.test_break)
def render_slave(self, scene):
- slave.render_slave(self, scene.network_render)
+ slave.render_slave(self, scene.network_render, scene.render_data.threads)
def render_client(self, scene):
netsettings = scene.network_render
@@ -276,6 +276,6 @@ def compatible(module):
except: pass
del module
-compatible("properties_render")
+#compatible("properties_render")
compatible("properties_world")
compatible("properties_material")
diff --git a/release/scripts/io/netrender/master.py b/release/scripts/io/netrender/master.py
index a33606d19a0..5056eba750d 100644
--- a/release/scripts/io/netrender/master.py
+++ b/release/scripts/io/netrender/master.py
@@ -19,6 +19,7 @@
import sys, os
import http, http.client, http.server, urllib, socket
import subprocess, shutil, time, hashlib
+import select # for select.error
from netrender.utils import *
import netrender.model
@@ -105,6 +106,17 @@ class MRenderJob(netrender.model.RenderJob):
break
else:
self.status = JOB_FINISHED
+
+ def pause(self, status = None):
+ if self.status not in {JOB_PAUSED, JOB_QUEUED}:
+ return
+
+ if status == None:
+ self.status = JOB_PAUSED if self.status == JOB_QUEUED else JOB_QUEUED
+ elif status:
+ self.status = JOB_QUEUED
+ else:
+ self.status = JOB_PAUSED
def start(self):
self.status = JOB_QUEUED
@@ -163,9 +175,11 @@ class MRenderFrame(netrender.model.RenderFrame):
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
file_pattern = re.compile("/file_([a-zA-Z0-9]+)_([0-9]+)")
render_pattern = re.compile("/render_([a-zA-Z0-9]+)_([0-9]+).exr")
+thumb_pattern = re.compile("/thumb_([a-zA-Z0-9]+)_([0-9]+).jpg")
log_pattern = re.compile("/log_([a-zA-Z0-9]+)_([0-9]+).log")
reset_pattern = re.compile("/reset(all|)_([a-zA-Z0-9]+)_([0-9]+)")
cancel_pattern = re.compile("/cancel_([a-zA-Z0-9]+)")
+pause_pattern = re.compile("/pause_([a-zA-Z0-9]+)")
edit_pattern = re.compile("/edit_([a-zA-Z0-9]+)")
class RenderHandler(http.server.BaseHTTPRequestHandler):
@@ -217,7 +231,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
if match:
job_id = match.groups()[0]
frame_number = int(match.groups()[1])
-
+
job = self.server.getJobID(job_id)
if job:
@@ -228,13 +242,53 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
self.send_head(http.client.ACCEPTED)
elif frame.status == DONE:
self.server.stats("", "Sending result to client")
- f = open(job.save_path + "%04d" % frame_number + ".exr", 'rb')
+
+ filename = job.save_path + "%04d" % frame_number + ".exr"
+
+ f = open(filename, 'rb')
+ self.send_head(content = "image/x-exr")
+ shutil.copyfileobj(f, self.wfile)
+ f.close()
+ elif frame.status == ERROR:
+ self.send_head(http.client.PARTIAL_CONTENT)
+ else:
+ # no such frame
+ self.send_head(http.client.NO_CONTENT)
+ else:
+ # no such job id
+ self.send_head(http.client.NO_CONTENT)
+ else:
+ # invalid url
+ self.send_head(http.client.NO_CONTENT)
+ # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+ elif self.path.startswith("/thumb"):
+ match = thumb_pattern.match(self.path)
- self.send_head()
+ if match:
+ job_id = match.groups()[0]
+ frame_number = int(match.groups()[1])
- shutil.copyfileobj(f, self.wfile)
+ job = self.server.getJobID(job_id)
- f.close()
+ if job:
+ frame = job[frame_number]
+
+ if frame:
+ if frame.status in (QUEUED, DISPATCHED):
+ self.send_head(http.client.ACCEPTED)
+ elif frame.status == DONE:
+ filename = job.save_path + "%04d" % frame_number + ".exr"
+
+ thumbname = thumbnail(filename)
+
+ if thumbname:
+ f = open(thumbname, 'rb')
+ self.send_head(content = "image/jpeg")
+ shutil.copyfileobj(f, self.wfile)
+ f.close()
+ else: # thumbnail couldn't be generated
+ self.send_head(http.client.PARTIAL_CONTENT)
+ return
elif frame.status == ERROR:
self.send_head(http.client.PARTIAL_CONTENT)
else:
@@ -456,17 +510,48 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
# invalid url
self.send_head(http.client.NO_CONTENT)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+ elif self.path == "/balance_limit":
+ length = int(self.headers['content-length'])
+ info_map = eval(str(self.rfile.read(length), encoding='utf8'))
+ for rule_id, limit in info_map.items():
+ try:
+ rule = self.server.balancer.ruleByID(rule_id)
+ if rule:
+ rule.setLimit(limit)
+ except:
+ pass # invalid type
+
+ self.send_head()
+ # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+ elif self.path == "/balance_enable":
+ length = int(self.headers['content-length'])
+ info_map = eval(str(self.rfile.read(length), encoding='utf8'))
+ for rule_id, enabled in info_map.items():
+ rule = self.server.balancer.ruleByID(rule_id)
+ if rule:
+ rule.enabled = enabled
+
+ self.send_head()
+ # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
elif self.path.startswith("/cancel"):
match = cancel_pattern.match(self.path)
if match:
+ length = int(self.headers['content-length'])
+
+ if length > 0:
+ info_map = eval(str(self.rfile.read(length), encoding='utf8'))
+ clear = info_map.get("clear", False)
+ else:
+ clear = False
+
job_id = match.groups()[0]
job = self.server.getJobID(job_id)
if job:
self.server.stats("", "Cancelling job")
- self.server.removeJob(job)
+ self.server.removeJob(job, clear)
self.send_head()
else:
# no such job id
@@ -474,12 +559,46 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
else:
# invalid url
self.send_head(http.client.NO_CONTENT)
+ # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+ elif self.path.startswith("/pause"):
+ match = pause_pattern.match(self.path)
+
+ if match:
+ length = int(self.headers['content-length'])
+
+ if length > 0:
+ info_map = eval(str(self.rfile.read(length), encoding='utf8'))
+ status = info_map.get("status", None)
+ else:
+ status = None
+
+ job_id = match.groups()[0]
+ job = self.server.getJobID(job_id)
+
+ if job:
+ self.server.stats("", "Pausing job")
+ job.pause(status)
+ self.send_head()
+ else:
+ # no such job id
+ self.send_head(http.client.NO_CONTENT)
+ else:
+ # invalid url
+ self.send_head(http.client.NO_CONTENT)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
elif self.path == "/clear":
# cancel all jobs
+ length = int(self.headers['content-length'])
+
+ if length > 0:
+ info_map = eval(str(self.rfile.read(length), encoding='utf8'))
+ clear = info_map.get("clear", False)
+ else:
+ clear = False
+
self.server.stats("", "Clearing jobs")
- self.server.clear()
+ self.server.clear(clear)
self.send_head()
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
@@ -647,8 +766,6 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
if not slave.id in job.blacklist:
job.blacklist.append(slave.id)
- self.server.stats("", "Receiving result")
-
slave.finishedFrame(job_frame)
frame.status = job_result
@@ -664,6 +781,44 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
else: # invalid slave id
self.send_head(http.client.NO_CONTENT)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+ elif self.path == "/thumb":
+ self.server.stats("", "Receiving thumbnail result")
+
+ # need some message content here or the slave doesn't like it
+ self.wfile.write(bytes("foo", encoding='utf8'))
+
+ slave_id = self.headers['slave-id']
+
+ slave = self.server.getSeenSlave(slave_id)
+
+ if slave: # only if slave id is valid
+ job_id = self.headers['job-id']
+
+ job = self.server.getJobID(job_id)
+
+ if job:
+ job_frame = int(self.headers['job-frame'])
+
+ frame = job[job_frame]
+
+ if frame:
+ if job.type == netrender.model.JOB_BLENDER:
+ length = int(self.headers['content-length'])
+ buf = self.rfile.read(length)
+ f = open(job.save_path + "%04d" % job_frame + ".jpg", 'wb')
+ f.write(buf)
+ f.close()
+
+ del buf
+
+ self.send_head()
+ else: # frame not found
+ self.send_head(http.client.NO_CONTENT)
+ else: # job not found
+ self.send_head(http.client.NO_CONTENT)
+ else: # invalid slave id
+ self.send_head(http.client.NO_CONTENT)
+ # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
elif self.path.startswith("/log"):
self.server.stats("", "Receiving log file")
@@ -737,7 +892,7 @@ class RenderMasterServer(http.server.HTTPServer):
self.slaves_map.pop(slave.id)
def getSlave(self, slave_id):
- return self.slaves_map.get(slave_id, None)
+ return self.slaves_map.get(slave_id)
def getSeenSlave(self, slave_id):
slave = self.getSlave(slave_id)
@@ -775,11 +930,11 @@ class RenderMasterServer(http.server.HTTPServer):
slave.job.usage += slave_usage
- def clear(self):
+ def clear(self, clear_files = False):
removed = self.jobs[:]
for job in removed:
- self.removeJob(job)
+ self.removeJob(job, clear_files)
def balance(self):
self.balancer.balance(self.jobs)
@@ -798,10 +953,13 @@ class RenderMasterServer(http.server.HTTPServer):
def countSlaves(self):
return len(self.slaves)
- def removeJob(self, job):
+ def removeJob(self, job, clear_files = False):
self.jobs.remove(job)
self.jobs_map.pop(job.id)
-
+
+ if clear_files:
+ shutil.rmtree(job.save_path)
+
for slave in self.slaves:
if slave.job == job:
slave.job = None
@@ -819,7 +977,7 @@ class RenderMasterServer(http.server.HTTPServer):
job.save()
def getJobID(self, id):
- return self.jobs_map.get(id, None)
+ return self.jobs_map.get(id)
def __iter__(self):
for job in self.jobs:
@@ -833,7 +991,10 @@ class RenderMasterServer(http.server.HTTPServer):
return None, None
-def runMaster(address, broadcast, path, update_stats, test_break):
+def clearMaster(path):
+ shutil.rmtree(path)
+
+def runMaster(address, broadcast, clear, path, update_stats, test_break):
httpd = RenderMasterServer(address, RenderHandler, path)
httpd.timeout = 1
httpd.stats = update_stats
@@ -845,7 +1006,10 @@ def runMaster(address, broadcast, path, update_stats, test_break):
start_time = time.time()
while not test_break():
- httpd.handle_request()
+ try:
+ httpd.handle_request()
+ except select.error:
+ pass
if time.time() - start_time >= 10: # need constant here
httpd.timeoutSlaves()
@@ -858,3 +1022,5 @@ def runMaster(address, broadcast, path, update_stats, test_break):
start_time = time.time()
httpd.server_close()
+ if clear:
+ clearMaster(httpd.path)
diff --git a/release/scripts/io/netrender/master_html.py b/release/scripts/io/netrender/master_html.py
index af4db43ae9d..3fff6d0b88c 100644
--- a/release/scripts/io/netrender/master_html.py
+++ b/release/scripts/io/netrender/master_html.py
@@ -37,8 +37,11 @@ def get(handler):
output("<link rel='stylesheet' href='/html/netrender.css' type='text/css'>")
- def link(text, url):
- return "<a href='%s'>%s</a>" % (url, text)
+ def link(text, url, script=""):
+ return "<a href='%s' %s>%s</a>" % (url, script, text)
+
+ def tag(name, text, attr=""):
+ return "<%s %s>%s</%s>" % (name, attr, text, name)
def startTable(border=1, class_style = None, caption = None):
output("<table border='%i'" % border)
@@ -80,6 +83,9 @@ def get(handler):
def endTable():
output("</table>")
+
+ def checkbox(title, value, script=""):
+ return """<input type="checkbox" title="%s" %s %s>""" % (title, "checked" if value else "", ("onclick=\"%s\"" % script) if script else "")
if handler.path == "/html/netrender.js":
f = open(os.path.join(src_folder, "netrender.js"), 'rb')
@@ -101,20 +107,38 @@ def get(handler):
output("<h2>Master</h2>")
- output("""<button title="remove all jobs" onclick="request('/clear', null);">CLEAR JOB LIST</button>""")
+ output("""<button title="remove all jobs" onclick="clear_jobs();">CLEAR JOB LIST</button>""")
startTable(caption = "Rules", class_style = "rules")
- headerTable("type", "description", "limit")
+ headerTable("type", "enabled", "description", "limit")
for rule in handler.server.balancer.rules:
- rowTable("rating", rule, rule.str_limit() if hasattr(rule, "limit") else "&nbsp;")
+ rowTable(
+ "rating",
+ checkbox("", rule.enabled, "balance_enable('%i', '%s')" % (id(rule), str(not rule.enabled))),
+ rule,
+ rule.str_limit() +
+ """<button title="edit limit" onclick="balance_edit('%i', '%s');">edit</button>""" % (id(rule), str(rule.limit)) if hasattr(rule, "limit") else "&nbsp;"
+ )
for rule in handler.server.balancer.priorities:
- rowTable("priority", rule, rule.str_limit() if hasattr(rule, "limit") else "&nbsp;")
+ rowTable(
+ "priority",
+ checkbox("", rule.enabled, "balance_enable('%i', '%s')" % (id(rule), str(not rule.enabled))),
+ rule,
+ rule.str_limit() +
+ """<button title="edit limit" onclick="balance_edit('%i', '%s');">edit</button>""" % (id(rule), str(rule.limit)) if hasattr(rule, "limit") else "&nbsp;"
+ )
for rule in handler.server.balancer.exceptions:
- rowTable("exception", rule, rule.str_limit() if hasattr(rule, "limit") else "&nbsp;")
+ rowTable(
+ "exception",
+ checkbox("", rule.enabled, "balance_enable('%i', '%s')" % (id(rule), str(not rule.enabled))),
+ rule,
+ rule.str_limit() +
+ """<button title="edit limit" onclick="balance_edit('%i', '%s');">edit</button>""" % (id(rule), str(rule.limit)) if hasattr(rule, "limit") else "&nbsp;"
+ )
endTable()
@@ -132,49 +156,51 @@ def get(handler):
startTable()
headerTable(
- "&nbsp;",
- "id",
- "name",
- "category",
- "chunks",
- "priority",
- "usage",
- "wait",
- "status",
- "length",
- "done",
- "dispatched",
- "error",
- "first",
- "exception"
- )
+ "&nbsp;",
+ "id",
+ "name",
+ "category",
+ "chunks",
+ "priority",
+ "usage",
+ "wait",
+ "status",
+ "length",
+ "done",
+ "dispatched",
+ "error",
+ "priority",
+ "exception"
+ )
handler.server.balance()
for job in handler.server.jobs:
results = job.framesStatus()
rowTable(
- """<button title="cancel job" onclick="request('/cancel_%s', null);">X</button>""" % job.id +
- """<button title="reset all frames" onclick="request('/resetall_%s_0', null);">R</button>""" % job.id,
- job.id,
- link(job.name, "/html/job" + job.id),
- job.category if job.category else "<i>None</i>",
- str(job.chunks) +
- """<button title="increase priority" onclick="request('/edit_%s', &quot;{'chunks': %i}&quot;);">+</button>""" % (job.id, job.chunks + 1) +
- """<button title="decrease priority" onclick="request('/edit_%s', &quot;{'chunks': %i}&quot;);" %s>-</button>""" % (job.id, job.chunks - 1, "disabled=True" if job.chunks == 1 else ""),
- str(job.priority) +
- """<button title="increase chunks size" onclick="request('/edit_%s', &quot;{'priority': %i}&quot;);">+</button>""" % (job.id, job.priority + 1) +
- """<button title="decrease chunks size" onclick="request('/edit_%s', &quot;{'priority': %i}&quot;);" %s>-</button>""" % (job.id, job.priority - 1, "disabled=True" if job.priority == 1 else ""),
- "%0.1f%%" % (job.usage * 100),
- "%is" % int(time.time() - job.last_dispatched),
- job.statusText(),
- len(job),
- results[DONE],
- results[DISPATCHED],
- str(results[ERROR]) +
- """<button title="reset error frames" onclick="request('/reset_%s_0', null);" %s>R</button>""" % (job.id, "disabled=True" if not results[ERROR] else ""),
- handler.server.balancer.applyPriorities(job), handler.server.balancer.applyExceptions(job)
- )
+ """<button title="cancel job" onclick="cancel_job('%s');">X</button>""" % job.id +
+ """<button title="pause job" onclick="request('/pause_%s', null);">P</button>""" % job.id +
+ """<button title="reset all frames" onclick="request('/resetall_%s_0', null);">R</button>""" % job.id,
+ job.id,
+ link(job.name, "/html/job" + job.id),
+ job.category if job.category else "<i>None</i>",
+ str(job.chunks) +
+ """<button title="increase chunks size" onclick="request('/edit_%s', &quot;{'chunks': %i}&quot;);">+</button>""" % (job.id, job.chunks + 1) +
+ """<button title="decrease chunks size" onclick="request('/edit_%s', &quot;{'chunks': %i}&quot;);" %s>-</button>""" % (job.id, job.chunks - 1, "disabled=True" if job.chunks == 1 else ""),
+ str(job.priority) +
+ """<button title="increase priority" onclick="request('/edit_%s', &quot;{'priority': %i}&quot;);">+</button>""" % (job.id, job.priority + 1) +
+ """<button title="decrease priority" onclick="request('/edit_%s', &quot;{'priority': %i}&quot;);" %s>-</button>""" % (job.id, job.priority - 1, "disabled=True" if job.priority == 1 else ""),
+ "%0.1f%%" % (job.usage * 100),
+ "%is" % int(time.time() - job.last_dispatched),
+ job.statusText(),
+ len(job),
+ results[DONE],
+ results[DISPATCHED],
+ str(results[ERROR]) +
+ """<button title="reset error frames" onclick="request('/reset_%s_0', null);" %s>R</button>""" % (job.id, "disabled=True" if not results[ERROR] else ""),
+ "yes" if handler.server.balancer.applyPriorities(job) else "no",
+ "yes" if handler.server.balancer.applyExceptions(job) else "no"
+ )
endTable()
@@ -236,10 +262,19 @@ def get(handler):
output("<h2>Frames</h2>")
startTable()
- headerTable("no", "status", "render time", "slave", "log", "result")
+ headerTable("no", "status", "render time", "slave", "log", "result", "")
for frame in job.frames:
- rowTable(frame.number, frame.statusText(), "%.1fs" % frame.time, frame.slave.name if frame.slave else "&nbsp;", link("view log", logURL(job_id, frame.number)) if frame.log_path else "&nbsp;", link("view result", renderURL(job_id, frame.number)) if frame.status == DONE else "&nbsp;")
+ rowTable(
+ frame.number,
+ frame.statusText(),
+ "%.1fs" % frame.time,
+ frame.slave.name if frame.slave else "&nbsp;",
+ link("view log", logURL(job_id, frame.number)) if frame.log_path else "&nbsp;",
+ link("view result", renderURL(job_id, frame.number)) + " [" +
+ tag("span", "show", attr="class='thumb' onclick='showThumb(%s, %i)'" % (job.id, frame.number)) + "]" if frame.status == DONE else "&nbsp;",
+ "<img name='thumb%i' title='hide thumbnails' src='' class='thumb' onclick='showThumb(%s, %i)'>" % (frame.number, job.id, frame.number)
+ )
endTable()
else:
diff --git a/release/scripts/io/netrender/netrender.css b/release/scripts/io/netrender/netrender.css
index 87de1083315..cc8a93bb9a7 100644
--- a/release/scripts/io/netrender/netrender.css
+++ b/release/scripts/io/netrender/netrender.css
@@ -60,7 +60,6 @@ button {
cursor: pointer;
}
-
.cache {
display: none;
}
@@ -72,4 +71,14 @@ button {
.rules {
width: 60em;
text-align: left;
-} \ No newline at end of file
+}
+
+img.thumb {
+ display: none;
+ cursor: pointer;
+}
+
+span.thumb {
+ text-decoration: underline;
+ cursor: pointer;
+}
diff --git a/release/scripts/io/netrender/netrender.js b/release/scripts/io/netrender/netrender.js
index 23f9f25c763..041a39a3ebc 100644
--- a/release/scripts/io/netrender/netrender.js
+++ b/release/scripts/io/netrender/netrender.js
@@ -1,3 +1,7 @@
+lastFrame = -1
+maxFrame = -1
+minFrame = -1
+
function request(url, data)
{
xmlhttp = new XMLHttpRequest();
@@ -11,6 +15,105 @@ function edit(id, info)
request("/edit_" + id, info)
}
+function clear_jobs()
+{
+ var r=confirm("Also delete files on master?");
+
+ if (r==true) {
+ request('/clear', "{'clear':True}");
+ } else {
+ request('/clear', "{'clear':False}");
+ }
+}
+
+function cancel_job(id)
+{
+ var r=confirm("Also delete files on master?");
+
+ if (r==true) {
+ request('/cancel_' + id, "{'clear':True}");
+ } else {
+ request('/cancel_' + id, "{'clear':False}");
+ }
+}
+
+function balance_edit(id, old_value)
+{
+ var new_value = prompt("New limit", old_value);
+ if (new_value != null && new_value != "") {
+ request("/balance_limit", "{" + id + ":'" + new_value + "'}");
+ }
+}
+
+function balance_enable(id, value)
+{
+ request("/balance_enable", "{" + id + ":" + value + "}");
+}
+
+function showThumb(job, frame)
+{
+ if (lastFrame != -1) {
+ if (maxFrame != -1 && minFrame != -1) {
+ if (frame >= minFrame && frame <= maxFrame) {
+ for(i = minFrame; i <= maxFrame; i=i+1) {
+ toggleThumb(job, i);
+ }
+ minFrame = -1;
+ maxFrame = -1;
+ lastFrame = -1;
+ } else if (frame > maxFrame) {
+ for(i = maxFrame+1; i <= frame; i=i+1) {
+ toggleThumb(job, i);
+ }
+ maxFrame = frame;
+ lastFrame = frame;
+ } else {
+ for(i = frame; i <= minFrame-1; i=i+1) {
+ toggleThumb(job, i);
+ }
+ minFrame = frame;
+ lastFrame = frame;
+ }
+ } else if (frame == lastFrame) {
+ toggleThumb(job, frame);
+ } else if (frame < lastFrame) {
+ minFrame = frame;
+ maxFrame = lastFrame;
+
+ for(i = minFrame; i <= maxFrame-1; i=i+1) {
+ toggleThumb(job, i);
+ }
+ lastFrame = frame;
+ } else {
+ minFrame = lastFrame;
+ maxFrame = frame;
+
+ for(i = minFrame+1; i <= maxFrame; i=i+1) {
+ toggleThumb(job, i);
+ }
+ lastFrame = frame;
+ }
+ } else {
+ toggleThumb(job, frame);
+ }
+}
+
+function toggleThumb(job, frame)
+{
+ img = document.images["thumb" + frame];
+ url = "/thumb_" + job + "_" + frame + ".jpg"
+
+ if (img.style.display == "block") {
+ img.style.display = "none";
+ img.src = "";
+ lastFrame = -1;
+ } else {
+ img.src = url;
+ img.style.display = "block";
+ lastFrame = frame;
+ }
+}
+
function returnObjById( id )
{
if (document.getElementById)
diff --git a/release/scripts/io/netrender/operators.py b/release/scripts/io/netrender/operators.py
index 8052b43e5b6..232d70a25be 100644
--- a/release/scripts/io/netrender/operators.py
+++ b/release/scripts/io/netrender/operators.py
@@ -112,6 +112,23 @@ class RENDER_OT_netclientanim(bpy.types.Operator):
return self.execute(context)
@rnaType
+class RENDER_OT_netclientrun(bpy.types.Operator):
+ '''Start network rendering service'''
+ bl_idname = "render.netclientstart"
+ bl_label = "Start Service"
+
+ def poll(self, context):
+ return True
+
+ def execute(self, context):
+ bpy.ops.screen.render('INVOKE_AREA', animation=True)
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+@rnaType
class RENDER_OT_netclientsend(bpy.types.Operator):
'''Send Render Job to the Network'''
bl_idname = "render.netclientsend"
@@ -390,8 +407,7 @@ class netclientdownload(bpy.types.Operator):
@rnaType
class netclientscan(bpy.types.Operator):
- __slots__ = []
- '''Operator documentation text, will be used for the operator tooltip and python docs.'''
+ '''Listen on network for master server broadcasting its address and port.'''
bl_idname = "render.netclientscan"
bl_label = "Client Scan"
@@ -410,7 +426,6 @@ class netclientscan(bpy.types.Operator):
return {'FINISHED'}
def invoke(self, context, event):
- print(dir(self))
return self.execute(context)
@rnaType
diff --git a/release/scripts/io/netrender/slave.py b/release/scripts/io/netrender/slave.py
index e7cac28ace3..c0848d7874f 100644
--- a/release/scripts/io/netrender/slave.py
+++ b/release/scripts/io/netrender/slave.py
@@ -16,7 +16,7 @@
#
# ##### END GPL LICENSE BLOCK #####
-import sys, os, platform
+import sys, os, platform, shutil
import http, http.client, http.server, urllib
import subprocess, time
@@ -45,6 +45,9 @@ else:
def RestoreErrorMode(val):
pass
+def clearSlave(path):
+ shutil.rmtree(path)
+
def slave_Info():
sysname, nodename, release, version, machine, processor = platform.uname()
slave = netrender.model.RenderSlave()
@@ -85,7 +88,7 @@ def testFile(conn, job_id, slave_id, file_index, JOB_PREFIX, file_path, main_pat
return job_full_path
-def render_slave(engine, netsettings):
+def render_slave(engine, netsettings, threads):
timeout = 1
engine.update_stats("", "Network render node initiation")
@@ -103,7 +106,6 @@ def render_slave(engine, netsettings):
os.mkdir(NODE_PREFIX)
while not engine.test_break():
-
conn.request("GET", "/job", headers={"slave-id":slave_id})
response = conn.getresponse()
@@ -149,7 +151,7 @@ def render_slave(engine, netsettings):
frame_args += ["-f", str(frame.number)]
val = SetErrorMode()
- process = subprocess.Popen([BLENDER_PATH, "-b", "-noaudio", job_full_path, "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ process = subprocess.Popen([BLENDER_PATH, "-b", "-noaudio", job_full_path, "-t", str(threads), "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
RestoreErrorMode(val)
elif job.type == netrender.model.JOB_PROCESS:
command = job.frames[0].command
@@ -162,8 +164,8 @@ def render_slave(engine, netsettings):
cancelled = False
stdout = bytes()
run_t = time.time()
- while process.poll() == None and not cancelled:
- stdout += process.stdout.read(32)
+ while not cancelled and process.poll() == None:
+ stdout += process.stdout.read(1024)
current_t = time.time()
cancelled = engine.test_break()
if current_t - run_t > CANCEL_POLL_SPEED:
@@ -211,14 +213,26 @@ def render_slave(engine, netsettings):
headers["job-result"] = str(DONE)
for frame in job.frames:
headers["job-frame"] = str(frame.number)
-
if job.type == netrender.model.JOB_BLENDER:
# send image back to server
- f = open(JOB_PREFIX + "%06d" % frame.number + ".exr", 'rb')
+
+ filename = JOB_PREFIX + "%06d" % frame.number + ".exr"
+
+ # thumbnail first
+ if netsettings.slave_thumb:
+ thumbname = thumbnail(filename)
+
+ f = open(thumbname, 'rb')
+ conn.request("PUT", "/thumb", f, headers=headers)
+ f.close()
+ conn.getresponse()
+
+ f = open(filename, 'rb')
conn.request("PUT", "/render", f, headers=headers)
f.close()
if conn.getresponse().status == http.client.NO_CONTENT:
continue
+
elif job.type == netrender.model.JOB_PROCESS:
conn.request("PUT", "/render", headers=headers)
if conn.getresponse().status == http.client.NO_CONTENT:
@@ -238,10 +252,12 @@ def render_slave(engine, netsettings):
for i in range(timeout):
time.sleep(1)
if engine.test_break():
- conn.close()
- return
+ break
conn.close()
+
+ if netsettings.slave_clear:
+ clearSlave(NODE_PREFIX)
if __name__ == "__main__":
pass
diff --git a/release/scripts/io/netrender/ui.py b/release/scripts/io/netrender/ui.py
index 86eb4bf5c30..e8b9f2a6ed3 100644
--- a/release/scripts/io/netrender/ui.py
+++ b/release/scripts/io/netrender/ui.py
@@ -36,6 +36,46 @@ DISPATCHED = 1
DONE = 2
ERROR = 3
+def init_file():
+ if netrender.init_file != bpy.data.filename:
+ netrender.init_file = bpy.data.filename
+ netrender.init_data = True
+ netrender.init_address = True
+
+def init_data(netsettings):
+ init_file()
+
+ if netrender.init_data:
+ netrender.init_data = False
+
+ netsettings.active_slave_index = 0
+ while(len(netsettings.slaves) > 0):
+ netsettings.slaves.remove(0)
+
+ netsettings.active_blacklisted_slave_index = 0
+ while(len(netsettings.slaves_blacklist) > 0):
+ netsettings.slaves_blacklist.remove(0)
+
+ netsettings.active_job_index = 0
+ while(len(netsettings.jobs) > 0):
+ netsettings.jobs.remove(0)
+
+def verify_address(netsettings):
+ init_file()
+
+ if netrender.init_address:
+ netrender.init_address = False
+
+ try:
+ conn = clientConnection(netsettings.server_address, netsettings.server_port, scan = False)
+ except:
+ conn = None
+
+ if conn:
+ conn.close()
+ else:
+ netsettings.server_address = "[default]"
+
class RenderButtonsPanel(bpy.types.Panel):
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
@@ -56,30 +96,75 @@ class RENDER_PT_network_settings(RenderButtonsPanel):
layout = self.layout
scene = context.scene
- rd = scene.render_data
+ netsettings = scene.network_render
+
+ verify_address(netsettings)
- layout.active = True
+ layout.prop(netsettings, "mode", expand=True)
- split = layout.split()
+ if netsettings.mode in ("RENDER_MASTER", "RENDER_SLAVE"):
+ layout.operator("render.netclientstart", icon='PLAY')
+ layout.prop(netsettings, "path")
+
+ split = layout.split(percentage=0.7)
+
+ col = split.column()
+ col.label(text="Server Adress:")
+ col.prop(netsettings, "server_address", text="")
+
col = split.column()
+ col.label(text="Port:")
+ col.prop(netsettings, "server_port", text="")
+ if netsettings.mode != "RENDER_MASTER":
+ layout.operator("render.netclientscan", icon='FILE_REFRESH', text="")
- if scene.network_render.mode in ("RENDER_MASTER", "RENDER_SLAVE"):
- col.operator("screen.render", text="Start", icon='PLAY').animation = True
+ layout.operator("render.netclientweb", icon='QUESTION')
- col.prop(scene.network_render, "mode")
- col.prop(scene.network_render, "path")
- col.prop(scene.network_render, "server_address")
- col.prop(scene.network_render, "server_port")
+@rnaType
+class RENDER_PT_network_slave_settings(RenderButtonsPanel):
+ bl_label = "Slave Settings"
+ COMPAT_ENGINES = {'NET_RENDER'}
- if scene.network_render.mode == "RENDER_MASTER":
- col.prop(scene.network_render, "server_broadcast")
- else:
- col.operator("render.netclientscan", icon='FILE_REFRESH', text="")
+ def poll(self, context):
+ scene = context.scene
+ return (super().poll(context)
+ and scene.network_render.mode == "RENDER_SLAVE")
- col.operator("render.netclientweb", icon='QUESTION')
+ def draw(self, context):
+ layout = self.layout
+
+ scene = context.scene
+ rd = scene.render_data
+ netsettings = scene.network_render
+ layout.prop(netsettings, "slave_clear")
+ layout.prop(netsettings, "slave_thumb")
+ layout.label(text="Threads:")
+ layout.prop(rd, "threads_mode", expand=True)
+ sub = layout.column()
+ sub.enabled = rd.threads_mode == 'THREADS_FIXED'
+ sub.prop(rd, "threads")
+@rnaType
+class RENDER_PT_network_master_settings(RenderButtonsPanel):
+ bl_label = "Master Settings"
+ COMPAT_ENGINES = {'NET_RENDER'}
+
+ def poll(self, context):
+ scene = context.scene
+ return (super().poll(context)
+ and scene.network_render.mode == "RENDER_MASTER")
+
+ def draw(self, context):
+ layout = self.layout
+
+ scene = context.scene
+ netsettings = scene.network_render
+
+ layout.prop(netsettings, "master_broadcast")
+ layout.prop(netsettings, "master_clear")
+
@rnaType
class RENDER_PT_network_job(RenderButtonsPanel):
bl_label = "Job Settings"
@@ -94,23 +179,31 @@ class RENDER_PT_network_job(RenderButtonsPanel):
layout = self.layout
scene = context.scene
- rd = scene.render_data
-
- layout.active = True
-
- split = layout.split()
+ netsettings = scene.network_render
+ verify_address(netsettings)
+
+ if netsettings.server_address != "[default]":
+ layout.operator("render.netclientanim", icon='RENDER_ANIMATION')
+ layout.operator("render.netclientsend", icon='FILE_BLEND')
+ if netsettings.job_id:
+ row = layout.row()
+ row.operator("screen.render", text="Get Image", icon='RENDER_STILL')
+ row.operator("screen.render", text="Get Animation", icon='RENDER_ANIMATION').animation = True
+
+ split = layout.split(percentage=0.3)
+
+ col = split.column()
+ col.label(text="Name:")
+ col.label(text="Category:")
+
col = split.column()
- if scene.network_render.server_address != "[default]":
- col.operator("render.netclientanim", icon='RENDER_ANIMATION')
- col.operator("render.netclientsend", icon='FILE_BLEND')
- if scene.network_render.job_id:
- col.operator("screen.render", text="Get Results", icon='RENDER_ANIMATION').animation = True
- col.prop(scene.network_render, "job_name")
- col.prop(scene.network_render, "job_category")
- row = col.row()
- row.prop(scene.network_render, "priority")
- row.prop(scene.network_render, "chunks")
+ col.prop(netsettings, "job_name", text="")
+ col.prop(netsettings, "job_category", text="")
+
+ row = layout.row()
+ row.prop(netsettings, "priority")
+ row.prop(netsettings, "chunks")
@rnaType
class RENDER_PT_network_slaves(RenderButtonsPanel):
@@ -119,9 +212,11 @@ class RENDER_PT_network_slaves(RenderButtonsPanel):
def poll(self, context):
scene = context.scene
+ netsettings = scene.network_render
+ verify_address(netsettings)
return (super().poll(context)
- and scene.network_render.mode == "RENDER_CLIENT"
- and scene.network_render.server_address != "[default]")
+ and netsettings.mode == "RENDER_CLIENT"
+ and netsettings.server_address != "[default]")
def draw(self, context):
layout = self.layout
@@ -136,9 +231,7 @@ class RENDER_PT_network_slaves(RenderButtonsPanel):
sub.operator("render.netclientslaves", icon='FILE_REFRESH', text="")
sub.operator("render.netclientblacklistslave", icon='ZOOMOUT', text="")
- if len(netrender.slaves) == 0 and len(netsettings.slaves) > 0:
- while(len(netsettings.slaves) > 0):
- netsettings.slaves.remove(0)
+ init_data(netsettings)
if netsettings.active_slave_index >= 0 and len(netsettings.slaves) > 0:
layout.separator()
@@ -157,9 +250,11 @@ class RENDER_PT_network_slaves_blacklist(RenderButtonsPanel):
def poll(self, context):
scene = context.scene
+ netsettings = scene.network_render
+ verify_address(netsettings)
return (super().poll(context)
- and scene.network_render.mode == "RENDER_CLIENT"
- and scene.network_render.server_address != "[default]")
+ and netsettings.mode == "RENDER_CLIENT"
+ and netsettings.server_address != "[default]")
def draw(self, context):
layout = self.layout
@@ -173,9 +268,7 @@ class RENDER_PT_network_slaves_blacklist(RenderButtonsPanel):
sub = row.column(align=True)
sub.operator("render.netclientwhitelistslave", icon='ZOOMOUT', text="")
- if len(netrender.blacklist) == 0 and len(netsettings.slaves_blacklist) > 0:
- while(len(netsettings.slaves_blacklist) > 0):
- netsettings.slaves_blacklist.remove(0)
+ init_data(netsettings)
if netsettings.active_blacklisted_slave_index >= 0 and len(netsettings.slaves_blacklist) > 0:
layout.separator()
@@ -194,9 +287,11 @@ class RENDER_PT_network_jobs(RenderButtonsPanel):
def poll(self, context):
scene = context.scene
+ netsettings = scene.network_render
+ verify_address(netsettings)
return (super().poll(context)
- and scene.network_render.mode == "RENDER_CLIENT"
- and scene.network_render.server_address != "[default]")
+ and netsettings.mode == "RENDER_CLIENT"
+ and netsettings.server_address != "[default]")
def draw(self, context):
layout = self.layout
@@ -213,9 +308,7 @@ class RENDER_PT_network_jobs(RenderButtonsPanel):
sub.operator("render.netclientcancelall", icon='PANEL_CLOSE', text="")
sub.operator("render.netclientdownload", icon='RENDER_ANIMATION', text="")
- if len(netrender.jobs) == 0 and len(netsettings.jobs) > 0:
- while(len(netsettings.jobs) > 0):
- netsettings.jobs.remove(0)
+ init_data(netsettings)
if netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0:
layout.separator()
@@ -254,12 +347,27 @@ NetRenderSettings.IntProperty( attr="server_port",
min=1,
max=65535)
-NetRenderSettings.BoolProperty( attr="server_broadcast",
- name="Broadcast server address",
- description="broadcast server address on local network",
+NetRenderSettings.BoolProperty( attr="master_broadcast",
+ name="Broadcast",
+ description="broadcast master server address on local network",
+ default = True)
+
+NetRenderSettings.BoolProperty( attr="slave_clear",
+ name="Clear on exit",
+ description="delete downloaded files on exit",
default = True)
-default_path = os.environ.get("TEMP", None)
+NetRenderSettings.BoolProperty( attr="slave_thumb",
+ name="Generate thumbnails",
+ description="Generate thumbnails on slaves instead of master",
+ default = False)
+
+NetRenderSettings.BoolProperty( attr="master_clear",
+ name="Clear on exit",
+ description="delete saved files on exit",
+ default = False)
+
+default_path = os.environ.get("TEMP")
if not default_path:
if os.name == 'nt':
diff --git a/release/scripts/io/netrender/utils.py b/release/scripts/io/netrender/utils.py
index 84275710391..1871a969f80 100644
--- a/release/scripts/io/netrender/utils.py
+++ b/release/scripts/io/netrender/utils.py
@@ -28,7 +28,7 @@ try:
except:
bpy = None
-VERSION = bytes("0.7", encoding='utf8')
+VERSION = bytes("0.8", encoding='utf8')
# Jobs status
JOB_WAITING = 0 # before all data has been entered
@@ -96,15 +96,18 @@ def clientScan(report = None):
return ("", 8000) # return default values
-def clientConnection(address, port, report = None):
+def clientConnection(address, port, report = None, scan = True):
if address == "[default]":
# calling operator from python is fucked, scene isn't in context
# if bpy:
# bpy.ops.render.netclientscan()
# else:
- address, port = clientScan()
- if address == "":
- return None
+ if not scan:
+ return None
+
+ address, port = clientScan()
+ if address == "":
+ return None
try:
conn = http.client.HTTPConnection(address, port)
@@ -169,3 +172,28 @@ def prefixPath(prefix_directory, file_path, prefix_path):
full_path = prefix_directory + file_path
return full_path
+
+def thumbnail(filename):
+ root = os.path.splitext(filename)[0]
+ imagename = os.path.split(filename)[1]
+ thumbname = root + ".jpg"
+
+ if os.path.exists(thumbname):
+ return thumbname
+
+ if bpy:
+ sce = bpy.data.scenes[0]
+ sce.render_data.file_format = "JPEG"
+ sce.render_data.quality = 90
+ bpy.ops.image.open(path = filename)
+ img = bpy.data.images[imagename]
+ img.save(thumbname, scene = sce)
+
+ try:
+ process = subprocess.Popen(["convert", thumbname, "-resize", "300x300", thumbname])
+ process.wait()
+ return thumbname
+ except:
+ pass
+
+ return None
diff --git a/release/scripts/modules/bpy/__init__.py b/release/scripts/modules/bpy/__init__.py
index 65bf75b43e9..6209cbe4f0e 100644
--- a/release/scripts/modules/bpy/__init__.py
+++ b/release/scripts/modules/bpy/__init__.py
@@ -27,6 +27,7 @@ context = _bpy.context
# python modules
from bpy import utils
+from bpy import app
from bpy import ops as _ops_module
@@ -100,9 +101,4 @@ def _main():
load_scripts()
-# constants
-version = _bpy._VERSION
-version_string = _bpy._VERSION_STR
-home = _bpy._HOME
-
_main()
diff --git a/release/scripts/modules/bpy/app.py b/release/scripts/modules/bpy/app.py
new file mode 100644
index 00000000000..da45ab8eb30
--- /dev/null
+++ b/release/scripts/modules/bpy/app.py
@@ -0,0 +1,26 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+# constants
+import _bpy
+version = _bpy._VERSION
+version_string = _bpy._VERSION_STR
+home = _bpy._HOME
+binary_path = _bpy._BINPATH
diff --git a/release/scripts/modules/bpy/ops.py b/release/scripts/modules/bpy/ops.py
index 268189b2db4..75976ebf9a1 100644
--- a/release/scripts/modules/bpy/ops.py
+++ b/release/scripts/modules/bpy/ops.py
@@ -22,8 +22,6 @@
from _bpy import ops as ops_module
# op_add = ops_module.add
-op_remove = ops_module.remove
-op_add_macro = ops_module.add_macro
op_dir = ops_module.dir
op_call = ops_module.call
op_as_string = ops_module.as_string
@@ -57,15 +55,6 @@ class bpy_ops(object):
raise AttributeError(module)
return bpy_ops_submodule(module)
- def add(self, pyop):
- op_add(pyop)
-
- def add_macro(self, pyop):
- op_add_macro(pyop)
-
- def remove(self, pyop):
- op_remove(pyop)
-
def __dir__(self):
submodules = set()
diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py
index 4af724fa3f6..2a757f83208 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -46,6 +46,19 @@ class Object(bpy_types.ID):
import bpy
return [child for child in bpy.data.objects if child.parent == self]
+ @property
+ def group_users(self):
+ """The groups this object is in"""
+ import bpy
+ name = self.name
+ return [group for group in bpy.data.groups if name in group.objects]
+
+ @property
+ def scene_users(self):
+ """The scenes this object is in"""
+ import bpy
+ name = self.name
+ return [scene for scene in bpy.data.scenes if name in scene.objects]
class _GenericBone:
"""
@@ -97,6 +110,11 @@ class _GenericBone:
return parent_list
@property
+ def center(self):
+ """The midpoint between the head and the tail."""
+ return (self.head + self.tail) * 0.5
+
+ @property
def length(self):
"""The distance from head to tail, when set the head is moved to fit the length."""
return self.vector.length
@@ -193,6 +211,19 @@ class EditBone(StructRNA, _GenericBone):
self.tail = self.head + vec
self.roll = other.roll
+ def transform(self, matrix):
+ """
+ Transform the the bones head, tail, roll and envalope (when the matrix has a scale component).
+ Expects a 4x4 or 3x3 matrix.
+ """
+ from Mathutils import Vector
+ z_vec = self.matrix.rotationPart() * Vector(0.0, 0.0, 1.0)
+ self.tail = matrix * self.tail
+ self.head = matrix * self.head
+ scalar = matrix.median_scale
+ self.head_radius *= scalar
+ self.tail_radius *= scalar
+ self.align_roll(matrix * z_vec)
def ord_ind(i1, i2):
if i1 < i2:
diff --git a/release/scripts/modules/retopo.py b/release/scripts/modules/retopo.py
index 15c4c504b32..6fba34b7b58 100644
--- a/release/scripts/modules/retopo.py
+++ b/release/scripts/modules/retopo.py
@@ -21,7 +21,7 @@
import bpy
EPS_SPLINE_DIV = 15.0 # remove doubles is ~15th the length of the spline
-
+ANGLE_JOIN_LIMIT = 25.0 # limit for joining splines into 1.
def get_hub(co, _hubs, EPS_SPLINE):
@@ -118,13 +118,105 @@ class Hub(object):
return faces
+class BBox(object):
+ __slots__ = "xmin", "ymin", "zmin", "xmax", "ymax", "zmax"
+
+ def __init__(self):
+ self.xmin = self.ymin = self.zmin = 100000000.0
+ self.xmax = self.ymax = self.zmax = -100000000.0
+
+ @property
+ def xdim(self):
+ return self.xmax - self.xmin
+
+ @property
+ def ydim(self):
+ return self.ymax - self.ymin
+
+ @property
+ def zdim(self):
+ return self.zmax - self.zmin
+
+ def calc(self, points):
+ xmin = ymin = zmin = 100000000.0
+ xmax = ymax = zmax = -100000000.0
+
+ for pt in points:
+ x, y, z = pt
+ if x < xmin:
+ xmin = x
+ if y < ymin:
+ ymin = y
+ if z < zmin:
+ zmin = z
+
+ if x > xmax:
+ xmax = x
+ if y > ymax:
+ ymax = y
+ if z > zmax:
+ zmax = z
+
+ self.xmin, self.ymin, self.zmin = xmin, ymin, zmin
+ self.xmax, self.ymax, self.zmax = xmax, ymax, zmax
+
+ def xsect(self, other, margin=0.0):
+ if margin == 0.0:
+ if self.xmax < other.xmin:
+ return False
+ if self.ymax < other.ymin:
+ return False
+ if self.zmax < other.zmin:
+ return False
+
+ if self.xmin > other.xmax:
+ return False
+ if self.ymin > other.ymax:
+ return False
+ if self.zmin > other.zmax:
+ return False
+
+ else:
+ xmargin = ((self.xdim + other.xdim) / 2.0) * margin
+ ymargin = ((self.ydim + other.ydim) / 2.0) * margin
+ zmargin = ((self.zdim + other.zdim) / 2.0) * margin
+
+ if self.xmax < other.xmin - xmargin:
+ return False
+ if self.ymax < other.ymin - ymargin:
+ return False
+ if self.zmax < other.zmin - zmargin:
+ return False
+
+ if self.xmin > other.xmax + xmargin:
+ return False
+ if self.ymin > other.ymax + ymargin:
+ return False
+ if self.zmin > other.zmax + zmargin:
+ return False
+ return True
+
+ def __iadd__(self, other):
+ self.xmin = min(self.xmin, other.xmin)
+ self.ymin = min(self.ymin, other.ymin)
+ self.zmin = min(self.zmin, other.zmin)
+
+ self.xmax = max(self.xmax, other.xmax)
+ self.ymax = max(self.ymax, other.ymax)
+ self.zmax = max(self.zmax, other.zmax)
+ return self
+
class Spline(object):
- __slots__ = "points", "hubs", "length"
+ __slots__ = "points", "hubs", "length", "bb"
def __init__(self, points):
self.points = points
self.hubs = []
+ self.calc_length()
+ self.bb = BBox()
+ self.bb.calc(points)
+ def calc_length(self):
# calc length
f = 0.0
co_prev = self.points[0]
@@ -215,8 +307,120 @@ def xsect_spline(sp_a, sp_b, _hubs):
pt_a_prev = pt_a
+def connect_splines(splines):
+ HASH_PREC = 8
+ from Mathutils import AngleBetweenVecs
+ from math import radians
+ ANG_LIMIT = radians(ANGLE_JOIN_LIMIT)
+ def sort_pair(a, b):
+ if a < b:
+ return a, b
+ else:
+ return b, a
+
+ #def test_join(p1a, p1b, p2a, p2b, length_average):
+ def test_join(s1, s2, dir1, dir2, length_average):
+ if dir1 is False:
+ p1a = s1.points[0]
+ p1b = s1.points[1]
+ else:
+ p1a = s1.points[-1]
+ p1b = s1.points[-2]
+
+ if dir2 is False:
+ p2a = s2.points[0]
+ p2b = s2.points[1]
+ else:
+ p2a = s2.points[-1]
+ p2b = s2.points[-2]
+
+ # compare length between tips
+ if (p1a - p2a).length > (length_average / EPS_SPLINE_DIV):
+ return False
+
+ v1 = p1a - p1b
+ v2 = p2b - p2a
+
+ if AngleBetweenVecs(v1, v2) > ANG_LIMIT:
+ return False
+
+ # print("joining!")
+ return True
+
+ # lazy, hash the points that have been compared.
+ comparisons = set()
+
+ do_join = True
+ while do_join:
+ do_join = False
+ for i, s1 in enumerate(splines):
+ key1a = s1.points[0].toTuple(HASH_PREC)
+ key1b = s1.points[-1].toTuple(HASH_PREC)
+
+ for j, s2 in enumerate(splines):
+ if s1 is s2:
+ continue
+
+ length_average = min(s1.length, s2.length)
+
+ key2a = s2.points[0].toTuple(HASH_PREC)
+ key2b = s2.points[-1].toTuple(HASH_PREC)
+
+ # there are 4 ways this may be joined
+ key_pair = sort_pair(key1a, key2a)
+ if key_pair not in comparisons:
+ comparisons.add(key_pair)
+ if test_join(s1, s2, False, False, length_average):
+ s1.points[:0] = reversed(s2.points)
+ s1.bb += s2.bb
+ s1.calc_length()
+ del splines[j]
+ do_join = True
+ break
+
+ key_pair = sort_pair(key1a, key2b)
+ if key_pair not in comparisons:
+ comparisons.add(key_pair)
+ if test_join(s1, s2, False, True, length_average):
+ s1.points[:0] = s2.points
+ s1.bb += s2.bb
+ s1.calc_length()
+ del splines[j]
+ do_join = True
+ break
+
+ key_pair = sort_pair(key1b, key2b)
+ if key_pair not in comparisons:
+ comparisons.add(key_pair)
+ if test_join(s1, s2, True, True, length_average):
+ s1.points += list(reversed(s2.points))
+ s1.bb += s2.bb
+ s1.calc_length()
+ del splines[j]
+ do_join = True
+ break
+
+ key_pair = sort_pair(key1b, key2a)
+ if key_pair not in comparisons:
+ comparisons.add(key_pair)
+ if test_join(s1, s2, True, False, length_average):
+ s1.points += s2.points
+ s1.bb += s2.bb
+ s1.calc_length()
+ del splines[j]
+ do_join = True
+ break
+
+ if do_join:
+ break
+
+
def calculate(gp):
splines = get_splines(gp)
+
+ # spline endpoints may be co-linear, join these into single splines
+ connect_splines(splines)
+
_hubs = {}
for i, sp in enumerate(splines):
@@ -224,7 +428,8 @@ def calculate(gp):
if j <= i:
continue
- xsect_spline(sp, sp_other, _hubs)
+ if sp.bb.xsect(sp_other.bb, margin=0.1):
+ xsect_spline(sp, sp_other, _hubs)
for sp in splines:
sp.link()
@@ -263,12 +468,12 @@ def calculate(gp):
# remove double faces
faces = dict([(tuple(sorted(f)), f) for f in faces]).values()
- mesh = bpy.data.add_mesh("Retopo")
+ mesh = bpy.data.meshes.new("Retopo")
mesh.from_pydata(verts, [], faces)
scene = bpy.context.scene
mesh.update()
- obj_new = bpy.data.add_object('MESH', "Torus")
+ obj_new = bpy.data.objects.new("Torus", 'MESH')
obj_new.data = mesh
scene.objects.link(obj_new)
diff --git a/release/scripts/modules/rigify/__init__.py b/release/scripts/modules/rigify/__init__.py
index 95ae2fed76c..6857d7e8f6d 100644
--- a/release/scripts/modules/rigify/__init__.py
+++ b/release/scripts/modules/rigify/__init__.py
@@ -26,6 +26,12 @@ from rna_prop_ui import rna_idprop_ui_prop_get
SPECIAL_TYPES = "root",
LAYER_TYPES = "main", "extra", "ik", "fk"
+ORG_LAYERS = [n==31 for n in range(0,32)]
+MCH_LAYERS = [n==30 for n in range(0,32)]
+DEF_LAYERS = [n==29 for n in range(0,32)]
+
+
+
class RigifyError(Exception):
"""Exception raised for errors in the metarig.
@@ -341,10 +347,14 @@ def generate_rig(context, obj_orig, prefix="ORG-", META_DEF=True):
layer_second_last[30] = True
for bone_name, bone in arm.bones.items():
+ bone.deform = False # Non DEF bones shouldn't deform
if bone_name.startswith(prefix):
- bone.layer = layer_last
- elif bone_name.startswith("MCH"): # XXX fixme
- bone.layer = layer_second_last
+ bone.layer = ORG_LAYERS
+ elif bone_name.startswith("MCH-"): # XXX fixme
+ bone.layer = MCH_LAYERS
+ elif bone_name.startswith("DEF-"): # XXX fixme
+ bone.layer = DEF_LAYERS
+ bone.deform = True
layer_tot[:] = [max(lay) for lay in zip(layer_tot, bone.layer)]
@@ -370,8 +380,8 @@ def generate_test(context, metarig_type="", GENERATE_FINAL=True):
scene = context.scene
def create_empty_armature(name):
- obj_new = bpy.data.add_object('ARMATURE', name)
- armature = bpy.data.add_armature(name)
+ obj_new = bpy.data.objects.new(name, 'ARMATURE')
+ armature = bpy.data.armatures.new(name)
obj_new.data = armature
scene.objects.link(obj_new)
scene.objects.active = obj_new
diff --git a/release/scripts/modules/rigify/arm_biped_generic.py b/release/scripts/modules/rigify/arm_biped_generic.py
index 509f1bb7aef..0974b1b8010 100644
--- a/release/scripts/modules/rigify/arm_biped_generic.py
+++ b/release/scripts/modules/rigify/arm_biped_generic.py
@@ -254,11 +254,11 @@ def fk(obj, definitions, base_names, options):
driver = driver_fcurve.driver
driver.type = 'AVERAGE'
- tar = driver.targets.new()
- tar.name = "hinge"
- tar.id_type = 'OBJECT'
- tar.id = obj
- tar.data_path = controller_path + '["hinge"]'
+ var = driver.variables.new()
+ var.name = "hinge"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = controller_path + '["hinge"]'
mod = driver_fcurve.modifiers[0]
mod.poly_order = 1
@@ -283,9 +283,99 @@ def fk(obj, definitions, base_names, options):
return None, fk_chain.arm, fk_chain.forearm, fk_chain.hand
+def deform(obj, definitions, base_names, options):
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ # Create upper arm bones: two bones, each half of the upper arm.
+ uarm1 = copy_bone_simple(obj.data, definitions[1], "DEF-%s.01" % base_names[definitions[1]], parent=True)
+ uarm2 = copy_bone_simple(obj.data, definitions[1], "DEF-%s.02" % base_names[definitions[1]], parent=True)
+ uarm1.connected = False
+ uarm2.connected = False
+ uarm2.parent = uarm1
+ center = uarm1.center
+ uarm1.tail = center
+ uarm2.head = center
+
+ # Create forearm bones: two bones, each half of the forearm.
+ farm1 = copy_bone_simple(obj.data, definitions[2], "DEF-%s.01" % base_names[definitions[2]], parent=True)
+ farm2 = copy_bone_simple(obj.data, definitions[2], "DEF-%s.02" % base_names[definitions[2]], parent=True)
+ farm1.connected = False
+ farm2.connected = False
+ farm2.parent = farm1
+ center = farm1.center
+ farm1.tail = center
+ farm2.head = center
+
+ # Create twist bone
+ twist = copy_bone_simple(obj.data, definitions[2], "MCH-arm_twist")
+ twist.connected = False
+ twist.parent = obj.data.edit_bones[definitions[3]]
+ twist.length /= 2
+
+ # Create hand bone
+ hand = copy_bone_simple(obj.data, definitions[3], "DEF-%s" % base_names[definitions[3]], parent=True)
+
+ # Store names before leaving edit mode
+ uarm1_name = uarm1.name
+ uarm2_name = uarm2.name
+ farm1_name = farm1.name
+ farm2_name = farm2.name
+ twist_name = twist.name
+ hand_name = hand.name
+
+ # Leave edit mode
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ # Get the pose bones
+ uarm1 = obj.pose.bones[uarm1_name]
+ uarm2 = obj.pose.bones[uarm2_name]
+ farm1 = obj.pose.bones[farm1_name]
+ farm2 = obj.pose.bones[farm2_name]
+ twist = obj.pose.bones[twist_name]
+ hand = obj.pose.bones[hand_name]
+
+ # Upper arm constraints
+ con = uarm1.constraints.new('DAMPED_TRACK')
+ con.name = "trackto"
+ con.target = obj
+ con.subtarget = definitions[2]
+
+ con = uarm2.constraints.new('COPY_ROTATION')
+ con.name = "copy_rot"
+ con.target = obj
+ con.subtarget = definitions[1]
+
+ # Forearm constraints
+ con = farm1.constraints.new('COPY_ROTATION')
+ con.name = "copy_rot"
+ con.target = obj
+ con.subtarget = definitions[2]
+
+ con = farm2.constraints.new('COPY_ROTATION')
+ con.name = "copy_rot"
+ con.target = obj
+ con.subtarget = twist.name
+
+ con = farm2.constraints.new('DAMPED_TRACK')
+ con.name = "trackto"
+ con.target = obj
+ con.subtarget = definitions[3]
+
+ # Hand constraint
+ con = hand.constraints.new('COPY_ROTATION')
+ con.name = "copy_rot"
+ con.target = obj
+ con.subtarget = definitions[3]
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ return (uarm1_name, uarm2_name, farm1_name, farm2_name, hand_name)
+
+
def main(obj, bone_definition, base_names, options):
bones_fk = fk(obj, bone_definition, base_names, options)
bones_ik = ik(obj, bone_definition, base_names, options)
+ bones_deform = deform(obj, bone_definition, base_names, options)
bpy.ops.object.mode_set(mode='OBJECT')
- blend_bone_list(obj, bone_definition, bones_fk, bones_ik, target_bone=bones_fk[1], blend_default=1.0)
+ blend_bone_list(obj, bone_definition, bones_fk, bones_ik, target_bone=bones_ik[3], target_prop="ik", blend_default=0.0)
+
diff --git a/release/scripts/modules/rigify/copy.py b/release/scripts/modules/rigify/copy.py
index 11c16d2d197..a84487e8e21 100644
--- a/release/scripts/modules/rigify/copy.py
+++ b/release/scripts/modules/rigify/copy.py
@@ -42,7 +42,31 @@ def metarig_template():
def metarig_definition(obj, orig_bone_name):
- return [orig_bone_name]
+ return (orig_bone_name,)
+
+
+def deform(obj, definitions, base_names, options):
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ # Create deform bone.
+ bone = copy_bone_simple(obj.data, definitions[0], "DEF-%s" % base_names[definitions[0]], parent=True)
+
+ # Store name before leaving edit mode
+ bone_name = bone.name
+
+ # Leave edit mode
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ # Get the pose bone
+ bone = obj.pose.bones[bone_name]
+
+ # Constrain to the original bone
+ con = bone.constraints.new('COPY_TRANSFORMS')
+ con.name = "copy_loc"
+ con.target = obj
+ con.subtarget = definitions[0]
+
+ return (bone_name,)
def main(obj, bone_definition, base_names, options):
@@ -59,18 +83,10 @@ def main(obj, bone_definition, base_names, options):
cp.update()
mt.update()
- if not cp.cpy_b.connected:
- con = mt.cpy_p.constraints.new('COPY_LOCATION')
- con.target = obj
- con.subtarget = cp.cpy
-
- con = mt.cpy_p.constraints.new('COPY_ROTATION')
+ con = mt.cpy_p.constraints.new('COPY_TRANSFORMS')
con.target = obj
con.subtarget = cp.cpy
- con = mt.cpy_p.constraints.new('COPY_SCALE')
- con.target = obj
- con.subtarget = cp.cpy
# Rotation mode and axis locks
cp.cpy_p.rotation_mode = mt.cpy_p.rotation_mode
@@ -79,9 +95,13 @@ def main(obj, bone_definition, base_names, options):
cp.cpy_p.lock_rotation = tuple(mt.cpy_p.lock_rotation)
cp.cpy_p.lock_rotation_w = mt.cpy_p.lock_rotation_w
cp.cpy_p.lock_scale = tuple(mt.cpy_p.lock_scale)
+
+ # Create deform bone
+ deform_bone = deform(obj, bone_definition, base_names, options)[0]
# setup layers last
layers = get_layer_dict(options)
cp.cpy_b.layer = layers["main"]
- return [mt.cpy]
+ return (mt.cpy,)
+
diff --git a/release/scripts/modules/rigify/finger_curl.py b/release/scripts/modules/rigify/finger_curl.py
index a4688ee8b5b..4c00f134e19 100644
--- a/release/scripts/modules/rigify/finger_curl.py
+++ b/release/scripts/modules/rigify/finger_curl.py
@@ -86,6 +86,68 @@ def metarig_definition(obj, orig_bone_name):
return bone_definition
+def deform(obj, definitions, base_names, options):
+ """ Creates the deform rig.
+ """
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ # Create base digit bones: two bones, each half of the base digit.
+ f1a = copy_bone_simple(obj.data, definitions[0], "DEF-%s.01" % base_names[definitions[0]], parent=True)
+ f1b = copy_bone_simple(obj.data, definitions[0], "DEF-%s.02" % base_names[definitions[0]], parent=True)
+ f1a.connected = False
+ f1b.connected = False
+ f1b.parent = f1a
+ center = f1a.center
+ f1a.tail = center
+ f1b.head = center
+
+ # Create the other deform bones.
+ f2 = copy_bone_simple(obj.data, definitions[1], "DEF-%s" % base_names[definitions[1]], parent=True)
+ f3 = copy_bone_simple(obj.data, definitions[2], "DEF-%s" % base_names[definitions[2]], parent=True)
+
+ # Store names before leaving edit mode
+ f1a_name = f1a.name
+ f1b_name = f1b.name
+ f2_name = f2.name
+ f3_name = f3.name
+
+ # Leave edit mode
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ # Get the pose bones
+ f1a = obj.pose.bones[f1a_name]
+ f1b = obj.pose.bones[f1b_name]
+ f2 = obj.pose.bones[f2_name]
+ f3 = obj.pose.bones[f3_name]
+
+ # Constrain the base digit's bones
+ con = f1a.constraints.new('DAMPED_TRACK')
+ con.name = "trackto"
+ con.target = obj
+ con.subtarget = definitions[1]
+
+ con = f1a.constraints.new('COPY_SCALE')
+ con.name = "copy_scale"
+ con.target = obj
+ con.subtarget = definitions[0]
+
+ con = f1b.constraints.new('COPY_ROTATION')
+ con.name = "copy_rot"
+ con.target = obj
+ con.subtarget = definitions[0]
+
+ # Constrain the other digit's bones
+ con = f2.constraints.new('COPY_TRANSFORMS')
+ con.name = "copy_transforms"
+ con.target = obj
+ con.subtarget = definitions[1]
+
+ con = f3.constraints.new('COPY_TRANSFORMS')
+ con.name = "copy_transforms"
+ con.target = obj
+ con.subtarget = definitions[2]
+
+
def main(obj, bone_definition, base_names, options):
# *** EDITMODE
@@ -139,6 +201,7 @@ def main(obj, bone_definition, base_names, options):
del control_ebone
+ deform(obj, bone_definition, base_names, options)
# *** POSEMODE
bpy.ops.object.mode_set(mode='OBJECT')
@@ -188,18 +251,18 @@ def main(obj, bone_definition, base_names, options):
driver = fcurve_driver.driver
# scale target
- tar = driver.targets.new()
- tar.name = "scale"
- tar.id_type = 'OBJECT'
- tar.id = obj
- tar.data_path = controller_path + '.scale[1]'
+ var = driver.variables.new()
+ var.name = "scale"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = controller_path + '.scale[1]'
# bend target
- tar = driver.targets.new()
- tar.name = "br"
- tar.id_type = 'OBJECT'
- tar.id = obj
- tar.data_path = controller_path + '["bend_ratio"]'
+ var = driver.variables.new()
+ var.name = "br"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = controller_path + '["bend_ratio"]'
# XXX - todo, any number
if i == 0:
diff --git a/release/scripts/modules/rigify/leg_biped_generic.py b/release/scripts/modules/rigify/leg_biped_generic.py
index 745ee49cbfe..2bf53ddc1ce 100644
--- a/release/scripts/modules/rigify/leg_biped_generic.py
+++ b/release/scripts/modules/rigify/leg_biped_generic.py
@@ -271,7 +271,7 @@ def ik(obj, bone_definition, base_names, options):
bpy.ops.object.mode_set(mode='EDIT')
- return None, ik_chain.thigh, ik_chain.shin, ik_chain.foot, ik_chain.toe, None
+ return (None, ik_chain.thigh, ik_chain.shin, ik_chain.foot, ik_chain.toe, None, ik.foot)
def fk(obj, bone_definition, base_names, options):
@@ -336,12 +336,12 @@ def fk(obj, bone_definition, base_names, options):
fcurve = con.driver_add("influence", 0)
driver = fcurve.driver
- tar = driver.targets.new()
+ var = driver.variables.new()
driver.type = 'AVERAGE'
- tar.name = "var"
- tar.id_type = 'OBJECT'
- tar.id = obj
- tar.data_path = hinge_driver_path
+ var.name = "var"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = hinge_driver_path
mod = fcurve.modifiers[0]
mod.poly_order = 1
@@ -363,12 +363,112 @@ def fk(obj, bone_definition, base_names, options):
bpy.ops.object.mode_set(mode='EDIT')
# dont blend the hips or heel
- return None, fk_chain.thigh, fk_chain.shin, fk_chain.foot, fk_chain.toe, None
+ return (None, fk_chain.thigh, fk_chain.shin, fk_chain.foot, fk_chain.toe, None, None)
+
+
+def deform(obj, definitions, base_names, options):
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ # Create upper leg bones: two bones, each half of the upper leg.
+ uleg1 = copy_bone_simple(obj.data, definitions[1], "DEF-%s.01" % base_names[definitions[1]], parent=True)
+ uleg2 = copy_bone_simple(obj.data, definitions[1], "DEF-%s.02" % base_names[definitions[1]], parent=True)
+ uleg1.connected = False
+ uleg2.connected = False
+ uleg2.parent = uleg1
+ center = uleg1.center
+ uleg1.tail = center
+ uleg2.head = center
+
+ # Create lower leg bones: two bones, each half of the lower leg.
+ lleg1 = copy_bone_simple(obj.data, definitions[2], "DEF-%s.01" % base_names[definitions[2]], parent=True)
+ lleg2 = copy_bone_simple(obj.data, definitions[2], "DEF-%s.02" % base_names[definitions[2]], parent=True)
+ lleg1.connected = False
+ lleg2.connected = False
+ lleg2.parent = lleg1
+ center = lleg1.center
+ lleg1.tail = center
+ lleg2.head = center
+
+ # Create a bone for the second lower leg deform bone to twist with
+ twist = copy_bone_simple(obj.data, lleg2.name, "MCH-leg_twist")
+ twist.length /= 4
+ twist.connected = False
+ twist.parent = obj.data.edit_bones[definitions[3]]
+
+ # Create foot bone
+ foot = copy_bone_simple(obj.data, definitions[3], "DEF-%s" % base_names[definitions[3]], parent=True)
+
+ # Create toe bone
+ toe = copy_bone_simple(obj.data, definitions[4], "DEF-%s" % base_names[definitions[4]], parent=True)
+
+ # Store names before leaving edit mode
+ uleg1_name = uleg1.name
+ uleg2_name = uleg2.name
+ lleg1_name = lleg1.name
+ lleg2_name = lleg2.name
+ twist_name = twist.name
+ foot_name = foot.name
+ toe_name = toe.name
+
+ # Leave edit mode
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ # Get the pose bones
+ uleg1 = obj.pose.bones[uleg1_name]
+ uleg2 = obj.pose.bones[uleg2_name]
+ lleg1 = obj.pose.bones[lleg1_name]
+ lleg2 = obj.pose.bones[lleg2_name]
+ foot = obj.pose.bones[foot_name]
+ toe = obj.pose.bones[toe_name]
+
+ # Upper leg constraints
+ con = uleg1.constraints.new('DAMPED_TRACK')
+ con.name = "trackto"
+ con.target = obj
+ con.subtarget = definitions[2]
+
+ con = uleg2.constraints.new('COPY_ROTATION')
+ con.name = "copy_rot"
+ con.target = obj
+ con.subtarget = definitions[1]
+
+ # Lower leg constraints
+ con = lleg1.constraints.new('COPY_ROTATION')
+ con.name = "copy_rot"
+ con.target = obj
+ con.subtarget = definitions[2]
+
+ con = lleg2.constraints.new('COPY_ROTATION')
+ con.name = "copy_rot"
+ con.target = obj
+ con.subtarget = twist_name
+
+ con = lleg2.constraints.new('DAMPED_TRACK')
+ con.name = "trackto"
+ con.target = obj
+ con.subtarget = definitions[3]
+
+ # Foot constraint
+ con = foot.constraints.new('COPY_ROTATION')
+ con.name = "copy_rot"
+ con.target = obj
+ con.subtarget = definitions[3]
+
+ # Toe constraint
+ con = toe.constraints.new('COPY_ROTATION')
+ con.name = "copy_rot"
+ con.target = obj
+ con.subtarget = definitions[4]
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ return (uleg1_name, uleg2_name, lleg1_name, lleg2_name, foot_name, toe_name, None)
def main(obj, bone_definition, base_names, options):
bones_fk = fk(obj, bone_definition, base_names, options)
bones_ik = ik(obj, bone_definition, base_names, options)
+ deform(obj, bone_definition, base_names, options)
bpy.ops.object.mode_set(mode='OBJECT')
- blend_bone_list(obj, bone_definition, bones_fk, bones_ik, target_bone=bones_ik[1], blend_default=0.0)
+ blend_bone_list(obj, bone_definition + [None], bones_fk, bones_ik, target_bone=bones_ik[6], target_prop="ik", blend_default=0.0)
+
diff --git a/release/scripts/modules/rigify/leg_quadruped_generic.py b/release/scripts/modules/rigify/leg_quadruped_generic.py
index 5f8f274c963..36481d91676 100644
--- a/release/scripts/modules/rigify/leg_quadruped_generic.py
+++ b/release/scripts/modules/rigify/leg_quadruped_generic.py
@@ -20,7 +20,7 @@
import bpy
from rigify import RigifyError
-from rigify_utils import bone_class_instance, copy_bone_simple, add_pole_target_bone
+from rigify_utils import bone_class_instance, copy_bone_simple, add_pole_target_bone, get_base_name, get_side_name
from Mathutils import Vector
METARIG_NAMES = "hips", "thigh", "shin", "foot", "toe"
@@ -119,7 +119,7 @@ def ik(obj, bone_definition, base_names, options):
ik_chain.thigh_e.parent = mt.hips_e
ik_chain.foot_e.parent = None
- ik_chain.rename("foot", ik_chain.foot + "_ik")
+ ik_chain.rename("foot", get_base_name(ik_chain.foot) + "_ik" + get_side_name(ik_chain.foot))
# keep the foot_ik as the parent
ik_chain.toe_e.connected = False
@@ -130,14 +130,14 @@ def ik(obj, bone_definition, base_names, options):
# children of ik_foot
ik = bone_class_instance(obj, ["foot", "foot_roll", "foot_roll_01", "foot_roll_02", "knee_target", "foot_target"])
- ik.knee_target = add_pole_target_bone(obj, mt_chain.shin, "knee_target") #XXX - pick a better name
+ ik.knee_target = add_pole_target_bone(obj, mt_chain.shin, "knee_target" + get_side_name(base_names[mt_chain.foot])) #XXX - pick a better name
ik.update()
ik.knee_target_e.parent = mt.hips_e
# foot roll is an interesting one!
# plot a vector from the toe bones head, bactwards to the length of the foot
# then align it with the foot but reverse direction.
- ik.foot_roll_e = copy_bone_simple(arm, mt_chain.toe, base_names[mt_chain.foot] + "_roll")
+ ik.foot_roll_e = copy_bone_simple(arm, mt_chain.toe, get_base_name(base_names[mt_chain.foot]) + "_roll" + get_side_name(base_names[mt_chain.foot]))
ik.foot_roll = ik.foot_roll_e.name
ik.foot_roll_e.parent = ik_chain.foot_e
ik.foot_roll_e.translate(- (mt_chain.toe_e.vector.normalize() * mt_chain.foot_e.length))
@@ -174,19 +174,19 @@ def ik(obj, bone_definition, base_names, options):
ik_chain.update()
# simple constraining of orig bones
- con = mt_chain.thigh_p.constraints.new('COPY_ROTATION')
+ con = mt_chain.thigh_p.constraints.new('COPY_TRANSFORMS')
con.target = obj
con.subtarget = ik_chain.thigh
- con = mt_chain.shin_p.constraints.new('COPY_ROTATION')
+ con = mt_chain.shin_p.constraints.new('COPY_TRANSFORMS')
con.target = obj
con.subtarget = ik_chain.shin
- con = mt_chain.foot_p.constraints.new('COPY_ROTATION')
+ con = mt_chain.foot_p.constraints.new('COPY_TRANSFORMS')
con.target = obj
con.subtarget = ik.foot_roll_02
- con = mt_chain.toe_p.constraints.new('COPY_ROTATION')
+ con = mt_chain.toe_p.constraints.new('COPY_TRANSFORMS')
con.target = obj
con.subtarget = ik_chain.toe
diff --git a/release/scripts/modules/rigify/neck_flex.py b/release/scripts/modules/rigify/neck_flex.py
index c52230ed30a..a56c7dcb4e3 100644
--- a/release/scripts/modules/rigify/neck_flex.py
+++ b/release/scripts/modules/rigify/neck_flex.py
@@ -100,6 +100,30 @@ def metarig_definition(obj, orig_bone_name):
return bone_definition
+def deform(obj, definitions, base_names, options):
+ for org_bone_name in definitions[2:]:
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ # Create deform bone.
+ bone = copy_bone_simple(obj.data, org_bone_name, "DEF-%s" % base_names[org_bone_name], parent=True)
+
+ # Store name before leaving edit mode
+ bone_name = bone.name
+
+ # Leave edit mode
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ # Get the pose bone
+ bone = obj.pose.bones[bone_name]
+
+ # Constrain to the original bone
+ # XXX. Todo, is this needed if the bone is connected to its parent?
+ con = bone.constraints.new('COPY_TRANSFORMS')
+ con.name = "copy_loc"
+ con.target = obj
+ con.subtarget = org_bone_name
+
+
def main(obj, bone_definition, base_names, options):
from Mathutils import Vector
@@ -180,6 +204,7 @@ def main(obj, bone_definition, base_names, options):
else:
neck_e_parent.parent = orig_parent
+ deform(obj, bone_definition, base_names, options)
bpy.ops.object.mode_set(mode='OBJECT')
@@ -213,12 +238,12 @@ def main(obj, bone_definition, base_names, options):
fcurve = con.driver_add("influence", 0)
driver = fcurve.driver
- tar = driver.targets.new()
+ var = driver.variables.new()
driver.type = 'AVERAGE'
- tar.name = "var"
- tar.id_type = 'OBJECT'
- tar.id = obj
- tar.data_path = hinge_driver_path
+ var.name = "var"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = hinge_driver_path
#mod = fcurve_driver.modifiers.new('GENERATOR')
mod = fcurve.modifiers[0]
@@ -237,11 +262,11 @@ def main(obj, bone_definition, base_names, options):
fcurve.modifiers.remove(0) # grr dont need a modifier
for i in range(len(neck_chain)):
- tar = driver.targets.new()
- tar.name = target_names[i]
- tar.id_type = 'OBJECT'
- tar.id = obj
- tar.data_path = head_driver_path + ('["bend_%.2d"]' % (i + 1))
+ var = driver.variables.new()
+ var.name = target_names[i]
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = head_driver_path + ('["bend_%.2d"]' % (i + 1))
for i, attr in enumerate(ex_chain.attr_names):
@@ -277,17 +302,17 @@ def main(obj, bone_definition, base_names, options):
# add target
- tar = driver.targets.new()
- tar.name = "bend_tot"
- tar.id_type = 'OBJECT'
- tar.id = obj
- tar.data_path = head_driver_path + ('["bend_tot"]')
-
- tar = driver.targets.new()
- tar.name = "bend"
- tar.id_type = 'OBJECT'
- tar.id = obj
- tar.data_path = head_driver_path + ('["%s"]' % prop_name)
+ var = driver.variables.new()
+ var.name = "bend_tot"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = head_driver_path + ('["bend_tot"]')
+
+ var = driver.variables.new()
+ var.name = "bend"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = head_driver_path + ('["%s"]' % prop_name)
# finally constrain the original bone to this one
diff --git a/release/scripts/modules/rigify/palm_curl.py b/release/scripts/modules/rigify/palm_curl.py
index f2ddcca6d59..548c311f823 100644
--- a/release/scripts/modules/rigify/palm_curl.py
+++ b/release/scripts/modules/rigify/palm_curl.py
@@ -98,6 +98,30 @@ def metarig_definition(obj, orig_bone_name):
return [palm_parent.name] + bone_definition
+def deform(obj, definitions, base_names, options):
+ for org_bone_name in definitions[1:]:
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ # Create deform bone.
+ bone = copy_bone_simple(obj.data, org_bone_name, "DEF-%s" % base_names[org_bone_name], parent=True)
+
+ # Store name before leaving edit mode
+ bone_name = bone.name
+
+ # Leave edit mode
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ # Get the pose bone
+ bone = obj.pose.bones[bone_name]
+
+ # Constrain to the original bone
+ # XXX. Todo, is this needed if the bone is connected to its parent?
+ con = bone.constraints.new('COPY_TRANSFORMS')
+ con.name = "copy_loc"
+ con.target = obj
+ con.subtarget = org_bone_name
+
+
def main(obj, bone_definition, base_names, options):
arm = obj.data
@@ -117,6 +141,8 @@ def main(obj, bone_definition, base_names, options):
offset = (pinky_ebone.head - ring_ebone.head)
control_ebone.translate(offset)
+
+ deform(obj, bone_definition, base_names, options)
bpy.ops.object.mode_set(mode='OBJECT')
@@ -143,22 +169,22 @@ def main(obj, bone_definition, base_names, options):
driver = driver_fcurves[0].driver
driver.type = 'AVERAGE'
- tar = driver.targets.new()
- tar.name = "x"
- tar.id_type = 'OBJECT'
- tar.id = obj
- tar.data_path = controller_path + ".rotation_euler[0]"
+ var = driver.variables.new()
+ var.name = "x"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = controller_path + ".rotation_euler[0]"
# *****
driver = driver_fcurves[1].driver
driver.expression = "-x/4.0"
- tar = driver.targets.new()
- tar.name = "x"
- tar.id_type = 'OBJECT'
- tar.id = obj
- tar.data_path = controller_path + ".rotation_euler[0]"
+ var = driver.variables.new()
+ var.name = "x"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = controller_path + ".rotation_euler[0]"
# *****
@@ -168,17 +194,17 @@ def main(obj, bone_definition, base_names, options):
for fcurve in driver_fcurves:
fcurve.modifiers.remove(0) # grr dont need a modifier
- tar = driver.targets.new()
- tar.name = "x"
- tar.id_type = 'OBJECT'
- tar.id = obj
- tar.data_path = controller_path + ".rotation_euler[0]"
-
- tar = driver.targets.new()
- tar.name = "s"
- tar.id_type = 'OBJECT'
- tar.id = obj
- tar.data_path = controller_path + '["spread"]'
+ var = driver.variables.new()
+ var.name = "x"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = controller_path + ".rotation_euler[0]"
+
+ var = driver.variables.new()
+ var.name = "s"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = controller_path + '["spread"]'
for i, child_name in enumerate(children):
diff --git a/release/scripts/modules/rigify/spine_pivot_flex.py b/release/scripts/modules/rigify/spine_pivot_flex.py
index 895a5d854c0..c6a5fa67390 100644
--- a/release/scripts/modules/rigify/spine_pivot_flex.py
+++ b/release/scripts/modules/rigify/spine_pivot_flex.py
@@ -122,6 +122,30 @@ def fk(*args):
main(*args)
+def deform(obj, definitions, base_names, options):
+ for org_bone_name in definitions[2:]:
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ # Create deform bone.
+ bone = copy_bone_simple(obj.data, org_bone_name, "DEF-%s" % base_names[org_bone_name], parent=True)
+
+ # Store name before leaving edit mode
+ bone_name = bone.name
+
+ # Leave edit mode
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ # Get the pose bone
+ bone = obj.pose.bones[bone_name]
+
+ # Constrain to the original bone
+ # XXX. Todo, is this needed if the bone is connected to its parent?
+ con = bone.constraints.new('COPY_TRANSFORMS')
+ con.name = "copy_loc"
+ con.target = obj
+ con.subtarget = org_bone_name
+
+
def main(obj, bone_definition, base_names, options):
from Mathutils import Vector, RotationMatrix
from math import radians, pi
@@ -269,6 +293,7 @@ def main(obj, bone_definition, base_names, options):
spine_e.roll += pi # 180d roll
del spine_e
+ deform(obj, bone_definition, base_names, options)
bpy.ops.object.mode_set(mode='OBJECT')
@@ -316,12 +341,12 @@ def main(obj, bone_definition, base_names, options):
# add driver
fcurve = con.driver_add("influence", 0)
driver = fcurve.driver
- tar = driver.targets.new()
+ var = driver.variables.new()
driver.type = 'AVERAGE'
- tar.name = "var"
- tar.id_type = 'OBJECT'
- tar.id = obj
- tar.data_path = ex.ribcage_copy_p.path_to_id() + '["hinge"]'
+ var.name = "var"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = ex.ribcage_copy_p.path_to_id() + '["hinge"]'
mod = fcurve.modifiers[0]
mod.poly_order = 1
@@ -401,11 +426,11 @@ def main(obj, bone_definition, base_names, options):
fcurve.modifiers.remove(0) # grr dont need a modifier
for i in range(spine_chain_len - 1):
- tar = driver.targets.new()
- tar.name = target_names[i]
- tar.id_type = 'OBJECT'
- tar.id = obj
- tar.data_path = rib_driver_path + ('["bend_%.2d"]' % (i + 1))
+ var = driver.variables.new()
+ var.name = target_names[i]
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = rib_driver_path + ('["bend_%.2d"]' % (i + 1))
for i in range(1, spine_chain_len):
@@ -436,17 +461,17 @@ def main(obj, bone_definition, base_names, options):
# add target
- tar = driver.targets.new()
- tar.name = "bend_tot"
- tar.id_type = 'OBJECT'
- tar.id = obj
- tar.data_path = rib_driver_path + ('["bend_tot"]')
+ var = driver.variables.new()
+ var.name = "bend_tot"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = rib_driver_path + ('["bend_tot"]')
- tar = driver.targets.new()
- tar.name = "bend"
- tar.id_type = 'OBJECT'
- tar.id = obj
- tar.data_path = rib_driver_path + ('["%s"]' % prop_name)
+ var = driver.variables.new()
+ var.name = "bend"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = rib_driver_path + ('["%s"]' % prop_name)
@@ -484,12 +509,12 @@ def main(obj, bone_definition, base_names, options):
fcurve = con.driver_add("influence", 0)
driver = fcurve.driver
- tar = driver.targets.new()
+ var = driver.variables.new()
driver.type = 'AVERAGE'
- tar.name = "var"
- tar.id_type = 'OBJECT'
- tar.id = obj
- tar.data_path = rib_driver_path + '["pivot_slide"]'
+ var.name = "var"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = rib_driver_path + '["pivot_slide"]'
mod = fcurve.modifiers[0]
mod.poly_order = 1
diff --git a/release/scripts/modules/rigify_utils.py b/release/scripts/modules/rigify_utils.py
index 371792a3633..b453ef77d4f 100644
--- a/release/scripts/modules/rigify_utils.py
+++ b/release/scripts/modules/rigify_utils.py
@@ -129,7 +129,7 @@ def blend_bone_list(obj, apply_bones, from_bones, to_bones, target_bone=None, ta
target_bone = apply_bones[-1] # default to the last bone
prop_pbone = obj.pose.bones[target_bone]
- if prop_pbone.get(target_bone, None) is None:
+ if prop_pbone.get(target_bone) is None:
prop = rna_idprop_ui_prop_get(prop_pbone, target_prop, create=True)
prop_pbone[target_prop] = blend_default
prop["soft_min"] = 0.0
@@ -138,11 +138,11 @@ def blend_bone_list(obj, apply_bones, from_bones, to_bones, target_bone=None, ta
driver_path = prop_pbone.path_to_id() + ('["%s"]' % target_prop)
def blend_target(driver):
- tar = driver.targets.new()
- tar.name = target_bone
- tar.id_type = 'OBJECT'
- tar.id = obj
- tar.data_path = driver_path
+ var = driver.variables.new()
+ var.name = target_bone
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = driver_path
def blend_location(new_pbone, from_bone_name, to_bone_name):
con = new_pbone.constraints.new('COPY_LOCATION')
@@ -402,9 +402,9 @@ def _bone_class_instance_update(self):
for member in self.attr_names:
name = getattr(self, member, None)
if name is not None:
- setattr(self, member + "_b", bbones.get(name, None))
- setattr(self, member + "_p", pbones.get(name, None))
- setattr(self, member + "_e", ebones.get(name, None))
+ setattr(self, member + "_b", bbones.get(name))
+ setattr(self, member + "_p", pbones.get(name))
+ setattr(self, member + "_e", ebones.get(name))
def _bone_class_instance_rename(self, attr, new_name):
diff --git a/release/scripts/modules/rna_info.py b/release/scripts/modules/rna_info.py
index 86da0b56943..5d7bd5af70a 100644
--- a/release/scripts/modules/rna_info.py
+++ b/release/scripts/modules/rna_info.py
@@ -252,19 +252,22 @@ class InfoFunctionRNA:
self.description = rna_func.description.strip()
self.args = []
- self.return_value = None
+ self.return_values = ()
def build(self):
rna_func = self.bl_func
parent_id = rna_func
+ self.return_values = []
for rna_prop in rna_func.parameters.values():
prop = GetInfoPropertyRNA(rna_prop, parent_id)
if rna_prop.use_return:
- self.return_value = prop
+ self.return_values.append(prop)
else:
self.args.append(prop)
+ self.return_values = tuple(self.return_values)
+
def __repr__(self):
txt = ''
txt += ' * ' + self.identifier + '('
@@ -566,8 +569,8 @@ def BuildRNAInfo():
func.build()
for prop in func.args:
prop.build()
- if func.return_value:
- func.return_value.build()
+ for prop in func.return_values:
+ prop.build()
# now for operators
op_mods = dir(bpy.ops)
diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py
index 543a10e47e9..f5b9e518c8f 100644
--- a/release/scripts/modules/rna_prop_ui.py
+++ b/release/scripts/modules/rna_prop_ui.py
@@ -124,6 +124,18 @@ def draw(layout, context, context_member, use_edit=True):
assign_props(prop, val_draw, key)
+class PropertyPanel(bpy.types.Panel):
+ """
+ The subclass should have its own poll function
+ and the variable '_context_path' MUST be set.
+ """
+ bl_label = "Custom Properties"
+ bl_default_closed = True
+
+ def draw(self, context):
+ draw(self.layout, context, self._context_path)
+
+
from bpy.props import *
@@ -257,3 +269,4 @@ class WM_OT_properties_remove(bpy.types.Operator):
item = eval("context.%s" % self.properties.path)
del item[self.properties.property]
return {'FINISHED'}
+
diff --git a/release/scripts/op/add_mesh_torus.py b/release/scripts/op/add_mesh_torus.py
index 372afb3654f..865b1d57daf 100644
--- a/release/scripts/op/add_mesh_torus.py
+++ b/release/scripts/op/add_mesh_torus.py
@@ -101,7 +101,7 @@ class AddTorus(bpy.types.Operator):
self.properties.major_segments,
self.properties.minor_segments)
- mesh = bpy.data.add_mesh("Torus")
+ mesh = bpy.data.meshes.new("Torus")
mesh.add_geometry(int(len(verts_loc) / 3), 0, int(len(faces) / 4))
mesh.verts.foreach_set("co", verts_loc)
@@ -114,7 +114,7 @@ class AddTorus(bpy.types.Operator):
ob.selected = False
mesh.update()
- ob_new = bpy.data.add_object('MESH', "Torus")
+ ob_new = bpy.data.objects.new("Torus", 'MESH')
ob_new.data = mesh
scene.objects.link(ob_new)
scene.objects.active = ob_new
diff --git a/release/scripts/op/object.py b/release/scripts/op/object.py
index 5e261c18c23..dd95c6f51a6 100644
--- a/release/scripts/op/object.py
+++ b/release/scripts/op/object.py
@@ -145,6 +145,7 @@ class Retopo(bpy.types.Operator):
def execute(self, context):
import retopo
+ reload(retopo)
retopo.main()
return {'FINISHED'}
@@ -176,11 +177,12 @@ class ShapeTransfer(bpy.types.Operator):
def me_cos(verts):
return [v.co.copy() for v in verts]
- def ob_add_shape(ob):
+ def ob_add_shape(ob, name):
me = ob.data
- ob.add_shape_key(from_mix=False)
+ key = ob.add_shape_key(from_mix=False)
if len(me.shape_keys.keys) == 1:
- ob.add_shape_key(from_mix=False) # we need a rest
+ key = ob.add_shape_key(from_mix=False) # we need a rest
+ key.name = name
ob.active_shape_key_index = len(me.shape_keys.keys) - 1
ob.shape_key_lock = True
@@ -191,6 +193,7 @@ class ShapeTransfer(bpy.types.Operator):
use_clamp = False
me = ob_act.data
+ orig_key_name = ob_act.active_shape_key.name
orig_shape_coords = me_cos(ob_act.active_shape_key.data)
@@ -206,7 +209,7 @@ class ShapeTransfer(bpy.types.Operator):
target_normals = me_nos(me_other.verts)
target_coords = me_cos(me_other.verts)
- ob_add_shape(ob_other)
+ ob_add_shape(ob_other, orig_key_name)
# editing the final coords, only list that stores wrapped coords
target_shape_coords = [v.co for v in ob_other.active_shape_key.data]
@@ -310,6 +313,9 @@ class ShapeTransfer(bpy.types.Operator):
def execute(self, context):
C = bpy.context
ob_act = C.active_object
+ if ob_act.active_shape_key is None:
+ self.report({'ERROR'}, "Active object has no shape key")
+ return {'CANCELLED'}
objects = [ob for ob in C.selected_editable_objects if ob != ob_act]
return self._main(ob_act, objects, self.properties.mode, self.properties.use_clamp)
diff --git a/release/scripts/op/screen_play_rendered_anim.py b/release/scripts/op/screen_play_rendered_anim.py
index a8c97010cce..b52bdf46ebd 100644
--- a/release/scripts/op/screen_play_rendered_anim.py
+++ b/release/scripts/op/screen_play_rendered_anim.py
@@ -29,39 +29,6 @@ import subprocess
import os
import platform
-# from BKE_add_image_extension()
-img_format_exts = {
- 'IRIS': '.rgb',
- 'RADHDR': '.hdr',
- 'PNG': 'png',
- 'TARGA': 'tga',
- 'RAWTARGA': 'tga',
- 'BMP': 'bmp',
- 'TIFF': 'tif',
- 'OPENEXR': 'exr',
- 'MULTILAYER': 'exr',
- 'CINEON': 'cin',
- 'DPX': 'dpx',
- 'JPEG': 'jpg',
- 'JPEG2000': 'jp2',
- 'QUICKTIME_QTKIT': 'mov',
- 'QUICKTIME_CARBON': 'mov',
- 'AVIRAW': 'avi',
- 'AVIJPEG': 'avi',
- 'AVICODEC': 'avi',
- 'XVID': 'avi',
- 'THEORA': 'ogg',
- }
-
-movie_formats = ('QUICKTIME_QTKIT',
- 'QUICKTIME_CARBONTKIT',
- 'AVIRAW',
- 'AVIJPEG',
- 'AVICODEC',
- 'XVID',
- 'THEORA')
-
-
def guess_player_path(preset):
if preset == 'BLENDER24':
player_path = 'blender'
@@ -112,16 +79,13 @@ class PlayRenderedAnim(bpy.types.Operator):
if player_path == '':
player_path = guess_player_path(preset)
- # doesn't support ### frame notation yet
- if rd.file_format in movie_formats:
- file = "%s%04d_%04d" % (file_path, sce.start_frame, sce.end_frame)
- elif preset in ('BLENDER24', 'DJV', 'CUSTOM'):
- file = "%s%04d" % (file_path, sce.start_frame)
- elif preset in ('FRAMECYCLER', 'RV'):
- file = "%s#" % file_path
-
- if rd.file_extensions:
- file += '.' + img_format_exts[rd.file_format]
+ if preset in ('FRAMECYCLER', 'RV'):
+ # replace the number with '#'
+ file_a, file_b = rd.frame_path(frame=0), rd.frame_path(frame=1)
+ 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)
cmd = [player_path]
# extra options, fps controls etc.
diff --git a/release/scripts/op/wm.py b/release/scripts/op/wm.py
index ef7386049c3..4796ec8c97c 100644
--- a/release/scripts/op/wm.py
+++ b/release/scripts/op/wm.py
@@ -42,6 +42,8 @@ rna_path_prop = StringProperty(name="Context Attributes",
rna_reverse_prop = BoolProperty(name="Reverse",
description="Cycle backwards", default=False)
+rna_relative_prop = BoolProperty(name="Relative",
+ description="Apply relative to the current value (delta)", default=False)
def context_path_validate(context, path):
import sys
@@ -61,7 +63,12 @@ def context_path_validate(context, path):
def execute_context_assign(self, context):
if context_path_validate(context, self.properties.path) is Ellipsis:
return {'PASS_THROUGH'}
- exec("context.%s=self.properties.value" % self.properties.path)
+
+ if getattr(self.properties, "relative", False):
+ exec("context.%s+=self.properties.value" % self.properties.path)
+ else:
+ exec("context.%s=self.properties.value" % self.properties.path)
+
return {'FINISHED'}
@@ -86,6 +93,7 @@ class WM_OT_context_set_int(bpy.types.Operator): # same as enum
path = rna_path_prop
value = IntProperty(name="Value", description="Assign value", default=0)
+ relative = rna_relative_prop
execute = execute_context_assign
@@ -97,8 +105,8 @@ class WM_OT_context_set_float(bpy.types.Operator): # same as enum
bl_undo = True
path = rna_path_prop
- value = FloatProperty(name="Value",
- description="Assignment value", default=0.0)
+ value = FloatProperty(name="Value", description="Assignment value", default=0.0)
+ relative = rna_relative_prop
execute = execute_context_assign
@@ -204,25 +212,26 @@ class WM_OT_context_cycle_int(bpy.types.Operator):
reverse = rna_reverse_prop
def execute(self, context):
-
- value = context_path_validate(context, self.properties.path)
+ path = self.properties.path
+ value = context_path_validate(context, path)
if value is Ellipsis:
return {'PASS_THROUGH'}
- self.properties.value = value
if self.properties.reverse:
- self.properties.value -= 1
+ value -= 1
else:
- self.properties.value += 1
- execute_context_assign(self, context)
+ value += 1
+
+ exec("context.%s=value" % path)
- if self.properties.value != eval("context.%s" % self.properties.path):
+ if value != eval("context.%s" % path):
# relies on rna clamping int's out of the range
if self.properties.reverse:
- self.properties.value = (1 << 32)
+ value = (1 << 32)
else:
- self.properties.value = - (1 << 32)
- execute_context_assign(self, context)
+ value = - (1 << 32)
+
+ exec("context.%s=value" % path)
return {'FINISHED'}
diff --git a/release/scripts/ui/properties_data_armature.py b/release/scripts/ui/properties_data_armature.py
index 28cf215fa62..bded38ee3cc 100644
--- a/release/scripts/ui/properties_data_armature.py
+++ b/release/scripts/ui/properties_data_armature.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from rna_prop_ui import PropertyPanel
narrowui = 180
@@ -55,6 +56,10 @@ class DATA_PT_context_arm(DataButtonsPanel):
layout.template_ID(ob, "data")
+class DATA_PT_custom_props_arm(DataButtonsPanel, PropertyPanel):
+ _context_path = "object.data"
+
+
class DATA_PT_skeleton(DataButtonsPanel):
bl_label = "Skeleton"
@@ -89,6 +94,7 @@ class DATA_PT_display(DataButtonsPanel):
def draw(self, context):
layout = self.layout
+ ob = context.object
arm = context.armature
wide_ui = context.region.width > narrowui
@@ -108,6 +114,7 @@ class DATA_PT_display(DataButtonsPanel):
col = split.column()
col.prop(arm, "draw_group_colors", text="Colors")
col.prop(arm, "delay_deform", text="Delay Refresh")
+ col.prop(ob, "x_ray", text="X-Ray (Object)")
class DATA_PT_bone_groups(DataButtonsPanel):
@@ -290,6 +297,7 @@ class DATA_PT_iksolver_itasc(DataButtonsPanel):
row.prop(itasc, "dampmax", text="Damp", slider=True)
row.prop(itasc, "dampeps", text="Eps", slider=True)
+
bpy.types.register(DATA_PT_context_arm)
bpy.types.register(DATA_PT_skeleton)
bpy.types.register(DATA_PT_display)
@@ -297,3 +305,5 @@ bpy.types.register(DATA_PT_bone_groups)
bpy.types.register(DATA_PT_paths)
bpy.types.register(DATA_PT_ghost)
bpy.types.register(DATA_PT_iksolver_itasc)
+
+bpy.types.register(DATA_PT_custom_props_arm)
diff --git a/release/scripts/ui/properties_data_bone.py b/release/scripts/ui/properties_data_bone.py
index 3369adab5a8..96cf400d738 100644
--- a/release/scripts/ui/properties_data_bone.py
+++ b/release/scripts/ui/properties_data_bone.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from rna_prop_ui import PropertyPanel
narrowui = 180
@@ -47,6 +48,17 @@ class BONE_PT_context_bone(BoneButtonsPanel):
row.prop(bone, "name", text="")
+class BONE_PT_custom_props(BoneButtonsPanel, PropertyPanel):
+
+ @property
+ def _context_path(self):
+ obj = bpy.context.object
+ if obj and obj.mode == 'POSE':
+ return "active_pose_bone"
+ else:
+ return "active_bone"
+
+
class BONE_PT_transform(BoneButtonsPanel):
bl_label = "Transform"
@@ -223,8 +235,11 @@ class BONE_PT_display(BoneButtonsPanel):
if wide_ui:
col = split.column()
+
col.label(text="Custom Shape:")
col.prop(pchan, "custom_shape", text="")
+ if pchan.custom_shape:
+ col.prop_object(pchan, "custom_shape_transform", ob.pose, "bones", text="At")
class BONE_PT_inverse_kinematics(BoneButtonsPanel):
@@ -373,21 +388,6 @@ class BONE_PT_deform(BoneButtonsPanel):
col.prop(bone, "cyclic_offset")
-class BONE_PT_properties(BoneButtonsPanel):
- bl_label = "Properties"
- bl_default_closed = True
-
- def draw(self, context):
- import rna_prop_ui
- # reload(rna_prop_ui)
- obj = context.object
- if obj and obj.mode == 'POSE':
- item = "active_pose_bone"
- else:
- item = "active_bone"
-
- rna_prop_ui.draw(self.layout, context, item)
-
bpy.types.register(BONE_PT_context_bone)
bpy.types.register(BONE_PT_transform)
bpy.types.register(BONE_PT_transform_locks)
@@ -395,4 +395,5 @@ bpy.types.register(BONE_PT_relations)
bpy.types.register(BONE_PT_display)
bpy.types.register(BONE_PT_inverse_kinematics)
bpy.types.register(BONE_PT_deform)
-bpy.types.register(BONE_PT_properties)
+
+bpy.types.register(BONE_PT_custom_props)
diff --git a/release/scripts/ui/properties_data_camera.py b/release/scripts/ui/properties_data_camera.py
index e8cba6be7df..d2889b6629e 100644
--- a/release/scripts/ui/properties_data_camera.py
+++ b/release/scripts/ui/properties_data_camera.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from rna_prop_ui import PropertyPanel
narrowui = 180
@@ -58,6 +59,10 @@ class DATA_PT_context_camera(DataButtonsPanel):
layout.template_ID(space, "pin_id")
+class DATA_PT_custom_props_camera(DataButtonsPanel, PropertyPanel):
+ _context_path = "object.data"
+
+
class DATA_PT_camera(DataButtonsPanel):
bl_label = "Lens"
@@ -140,6 +145,9 @@ class DATA_PT_camera_display(DataButtonsPanel):
sub.active = cam.show_passepartout
sub.prop(cam, "passepartout_alpha", text="Alpha", slider=True)
+
bpy.types.register(DATA_PT_context_camera)
bpy.types.register(DATA_PT_camera)
bpy.types.register(DATA_PT_camera_display)
+
+bpy.types.register(DATA_PT_custom_props_camera)
diff --git a/release/scripts/ui/properties_data_curve.py b/release/scripts/ui/properties_data_curve.py
index 3ee16ad9585..442590b8946 100644
--- a/release/scripts/ui/properties_data_curve.py
+++ b/release/scripts/ui/properties_data_curve.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from rna_prop_ui import PropertyPanel
narrowui = 180
@@ -72,6 +73,10 @@ class DATA_PT_context_curve(DataButtonsPanel):
layout.template_ID(ob, "data")
+class DATA_PT_custom_props_curve(DataButtonsPanel, PropertyPanel):
+ _context_path = "object.data"
+
+
class DATA_PT_shape_curve(DataButtonsPanel):
bl_label = "Shape"
@@ -377,6 +382,7 @@ class DATA_PT_textboxes(DataButtonsPanel):
col.prop(box, "x", text="X")
col.prop(box, "y", text="Y")
+
bpy.types.register(DATA_PT_context_curve)
bpy.types.register(DATA_PT_shape_curve)
bpy.types.register(DATA_PT_geometry_curve)
@@ -385,3 +391,5 @@ bpy.types.register(DATA_PT_active_spline)
bpy.types.register(DATA_PT_font)
bpy.types.register(DATA_PT_paragraph)
bpy.types.register(DATA_PT_textboxes)
+
+bpy.types.register(DATA_PT_custom_props_curve)
diff --git a/release/scripts/ui/properties_data_lamp.py b/release/scripts/ui/properties_data_lamp.py
index d5025983ff3..24f6486cdf6 100644
--- a/release/scripts/ui/properties_data_lamp.py
+++ b/release/scripts/ui/properties_data_lamp.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from rna_prop_ui import PropertyPanel
narrowui = 180
@@ -65,6 +66,10 @@ class DATA_PT_context_lamp(DataButtonsPanel):
layout.template_ID(space, "pin_id")
+class DATA_PT_custom_props_lamp(DataButtonsPanel, PropertyPanel):
+ _context_path = "object.data"
+
+
class DATA_PT_lamp(DataButtonsPanel):
bl_label = "Lamp"
@@ -374,6 +379,7 @@ class DATA_PT_falloff_curve(DataButtonsPanel):
self.layout.template_curve_mapping(lamp, "falloff_curve")
+
bpy.types.register(DATA_PT_context_lamp)
bpy.types.register(DATA_PT_preview)
bpy.types.register(DATA_PT_lamp)
@@ -382,3 +388,5 @@ bpy.types.register(DATA_PT_area)
bpy.types.register(DATA_PT_spot)
bpy.types.register(DATA_PT_shadow)
bpy.types.register(DATA_PT_sunsky)
+
+bpy.types.register(DATA_PT_custom_props_lamp)
diff --git a/release/scripts/ui/properties_data_lattice.py b/release/scripts/ui/properties_data_lattice.py
index 640f625a7de..a6221fa5e63 100644
--- a/release/scripts/ui/properties_data_lattice.py
+++ b/release/scripts/ui/properties_data_lattice.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from rna_prop_ui import PropertyPanel
narrowui = 180
@@ -58,6 +59,10 @@ class DATA_PT_context_lattice(DataButtonsPanel):
layout.template_ID(space, "pin_id")
+class DATA_PT_custom_props_lattice(DataButtonsPanel, PropertyPanel):
+ _context_path = "object.data"
+
+
class DATA_PT_lattice(DataButtonsPanel):
bl_label = "Lattice"
@@ -90,5 +95,8 @@ class DATA_PT_lattice(DataButtonsPanel):
layout.prop(lat, "outside")
+
bpy.types.register(DATA_PT_context_lattice)
bpy.types.register(DATA_PT_lattice)
+
+bpy.types.register(DATA_PT_custom_props_lattice)
diff --git a/release/scripts/ui/properties_data_mesh.py b/release/scripts/ui/properties_data_mesh.py
index d6cdcfc2de9..a03d8d55005 100644
--- a/release/scripts/ui/properties_data_mesh.py
+++ b/release/scripts/ui/properties_data_mesh.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from rna_prop_ui import PropertyPanel
narrowui = 180
@@ -58,6 +59,10 @@ class DATA_PT_context_mesh(DataButtonsPanel):
layout.template_ID(space, "pin_id")
+class DATA_PT_custom_props_mesh(DataButtonsPanel, PropertyPanel):
+ _context_path = "object.data"
+
+
class DATA_PT_normals(DataButtonsPanel):
bl_label = "Normals"
@@ -150,7 +155,12 @@ class DATA_PT_shape_keys(DataButtonsPanel):
ob = context.object
key = ob.data.shape_keys
- kb = ob.active_shape_key
+ if key and len(key.keys):
+ # this is so that we get the active shapekey from the
+ # shapekeys block, not from object data
+ kb = key.keys[ob.active_shape_key.name]
+ else:
+ kb = None
wide_ui = context.region.width > narrowui
enable_edit = ob.mode != 'EDIT'
@@ -197,17 +207,12 @@ class DATA_PT_shape_keys(DataButtonsPanel):
sub = row.row(align=True)
subsub = sub.row(align=True)
subsub.active = enable_edit_value
- if ob.shape_key_lock:
- subsub.prop(ob, "shape_key_lock", icon='PINNED', text="")
- else:
- subsub.prop(ob, "shape_key_lock", icon='UNPINNED', text="")
- if kb.mute:
- subsub.prop(kb, "mute", icon='MUTE_IPO_ON', text="")
- else:
- subsub.prop(kb, "mute", icon='MUTE_IPO_OFF', text="")
+ subsub.prop(ob, "shape_key_lock", icon='PINNED' if ob.shape_key_lock else 'UNPINNED', text="")
+ subsub.prop(kb, "mute", icon='MUTE_IPO_ON' if kb.mute else 'MUTE_IPO_OFF', text="")
sub.prop(ob, "shape_key_edit_mode", text="")
sub = row.row(align=True)
+ sub.operator("object.shape_key_transfer", icon='COPY_ID', text="") # icon is not ideal
sub.operator("object.shape_key_mirror", icon='ARROW_LEFTRIGHT', text="")
sub.operator("object.shape_key_clear", icon='X', text="")
@@ -292,3 +297,6 @@ bpy.types.register(DATA_PT_vertex_groups)
bpy.types.register(DATA_PT_shape_keys)
bpy.types.register(DATA_PT_uv_texture)
bpy.types.register(DATA_PT_vertex_colors)
+
+bpy.types.register(DATA_PT_custom_props_mesh)
+
diff --git a/release/scripts/ui/properties_data_metaball.py b/release/scripts/ui/properties_data_metaball.py
index e36bdc991e1..8951693aaac 100644
--- a/release/scripts/ui/properties_data_metaball.py
+++ b/release/scripts/ui/properties_data_metaball.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from rna_prop_ui import PropertyPanel
narrowui = 180
@@ -58,6 +59,10 @@ class DATA_PT_context_metaball(DataButtonsPanel):
layout.template_ID(space, "pin_id")
+class DATA_PT_custom_props_metaball(DataButtonsPanel, PropertyPanel):
+ _context_path = "object.data"
+
+
class DATA_PT_metaball(DataButtonsPanel):
bl_label = "Metaball"
@@ -133,3 +138,7 @@ class DATA_PT_metaball_element(DataButtonsPanel):
bpy.types.register(DATA_PT_context_metaball)
bpy.types.register(DATA_PT_metaball)
bpy.types.register(DATA_PT_metaball_element)
+
+bpy.types.register(DATA_PT_custom_props_metaball)
+
+
diff --git a/release/scripts/ui/properties_material.py b/release/scripts/ui/properties_material.py
index a48b3b1a30a..dfd4270e97b 100644
--- a/release/scripts/ui/properties_material.py
+++ b/release/scripts/ui/properties_material.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from rna_prop_ui import PropertyPanel
narrowui = 180
@@ -125,6 +126,11 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel):
layout.prop(mat, "type", text="")
+class MATERIAL_PT_custom_props(MaterialButtonsPanel, PropertyPanel):
+ COMPAT_ENGINES = {'BLENDER_RENDER'}
+ _context_path = "material"
+
+
class MATERIAL_PT_shading(MaterialButtonsPanel):
bl_label = "Shading"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -880,3 +886,5 @@ bpy.types.register(MATERIAL_PT_volume_shading)
bpy.types.register(MATERIAL_PT_volume_lighting)
bpy.types.register(MATERIAL_PT_volume_transp)
bpy.types.register(MATERIAL_PT_volume_integration)
+
+bpy.types.register(MATERIAL_PT_custom_props)
diff --git a/release/scripts/ui/properties_object.py b/release/scripts/ui/properties_object.py
index ff7e15cde58..3b539506552 100644
--- a/release/scripts/ui/properties_object.py
+++ b/release/scripts/ui/properties_object.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from rna_prop_ui import PropertyPanel
narrowui = 180
@@ -42,6 +43,10 @@ class OBJECT_PT_context_object(ObjectButtonsPanel):
row.prop(ob, "name", text="")
+class OBJECT_PT_custom_props(ObjectButtonsPanel, PropertyPanel):
+ _context_path = "object"
+
+
class OBJECT_PT_transform(ObjectButtonsPanel):
bl_label = "Transform"
@@ -149,11 +154,13 @@ class OBJECT_PT_groups(ObjectButtonsPanel):
if wide_ui:
split = layout.split()
- split.operator_menu_enum("object.group_add", "group", text="Add to Group")
+ split.operator_menu_enum("object.group_add", "group")
split.label()
else:
- layout.operator_menu_enum("object.group_add", "group", text="Add to Group")
+ layout.operator_menu_enum("object.group_add", "group")
+ index = 0
+ value = str(tuple(context.scene.cursor_location))
for group in bpy.data.groups:
if ob.name in group.objects:
col = layout.column(align=True)
@@ -172,6 +179,11 @@ class OBJECT_PT_groups(ObjectButtonsPanel):
if wide_ui:
col = split.column()
col.prop(group, "dupli_offset", text="")
+
+ prop = col.operator("wm.context_set_value", text="From Cursor")
+ prop.path = "object.group_users[%d].dupli_offset" % index
+ prop.value = value
+ index += 1
class OBJECT_PT_display(ObjectButtonsPanel):
@@ -235,20 +247,20 @@ class OBJECT_PT_duplication(ObjectButtonsPanel):
col.prop(ob, "dupli_frames_on", text="On")
col.prop(ob, "dupli_frames_off", text="Off")
- layout.prop(ob, "dupli_frames_no_speed", text="No Speed")
+ layout.prop(ob, "use_dupli_frames_speed", text="Speed")
elif ob.dupli_type == 'VERTS':
- layout.prop(ob, "dupli_verts_rotation", text="Rotation")
+ layout.prop(ob, "use_dupli_verts_rotation", text="Rotation")
elif ob.dupli_type == 'FACES':
split = layout.split()
col = split.column()
- col.prop(ob, "dupli_faces_scale", text="Scale")
+ col.prop(ob, "use_dupli_faces_scale", text="Scale")
if wide_ui:
col = split.column()
- col.prop(ob, "dupli_faces_inherit_scale", text="Inherit Scale")
+ col.prop(ob, "dupli_faces_scale", text="Inherit Scale")
elif ob.dupli_type == 'GROUP':
if wide_ui:
@@ -293,16 +305,6 @@ class OBJECT_PT_animation(ObjectButtonsPanel):
row.active = (ob.parent is not None)
-class OBJECT_PT_properties(ObjectButtonsPanel):
- bl_label = "Properties"
- bl_default_closed = True
-
- def draw(self, context):
- import rna_prop_ui
- # reload(rna_prop_ui)
-
- rna_prop_ui.draw(self.layout, context, "object")
-
bpy.types.register(OBJECT_PT_context_object)
bpy.types.register(OBJECT_PT_transform)
bpy.types.register(OBJECT_PT_transform_locks)
@@ -311,4 +313,5 @@ bpy.types.register(OBJECT_PT_groups)
bpy.types.register(OBJECT_PT_display)
bpy.types.register(OBJECT_PT_duplication)
bpy.types.register(OBJECT_PT_animation)
-bpy.types.register(OBJECT_PT_properties)
+
+bpy.types.register(OBJECT_PT_custom_props)
diff --git a/release/scripts/ui/properties_object_constraint.py b/release/scripts/ui/properties_object_constraint.py
index 12a12ff40dc..cb6f8cd71a2 100644
--- a/release/scripts/ui/properties_object_constraint.py
+++ b/release/scripts/ui/properties_object_constraint.py
@@ -37,8 +37,6 @@ class ConstraintButtonsPanel(bpy.types.Panel):
# match enum type to our functions, avoids a lookup table.
getattr(self, con.type)(context, box, con, wide_ui)
- # show/key buttons here are most likely obsolete now, with
- # keyframing functionality being part of every button
if con.type not in ('RIGID_BODY_JOINT', 'SPLINE_IK', 'NULL'):
box.prop(con, "influence")
@@ -462,6 +460,12 @@ class ConstraintButtonsPanel(bpy.types.Panel):
layout.prop(con, "use_offset")
self.space_template(layout, con, wide_ui)
+
+ def COPY_TRANSFORMS(self, context, layout, con, wide_ui):
+ self.target_template(layout, con, wide_ui)
+
+ self.space_template(layout, con, wide_ui)
+
#def SCRIPT(self, context, layout, con):
@@ -562,6 +566,8 @@ class ConstraintButtonsPanel(bpy.types.Panel):
if wide_ui:
row.label(text="Min/Max:")
row.prop(con, "floor_location", expand=True)
+
+ self.space_template(layout, con, wide_ui)
def RIGID_BODY_JOINT(self, context, layout, con, wide_ui):
self.target_template(layout, con, wide_ui)
diff --git a/release/scripts/ui/properties_particle.py b/release/scripts/ui/properties_particle.py
index a33a1a12f1b..14278ea197c 100644
--- a/release/scripts/ui/properties_particle.py
+++ b/release/scripts/ui/properties_particle.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from rna_prop_ui import PropertyPanel
from properties_physics_common import point_cache_ui
from properties_physics_common import effector_weights_ui
@@ -47,7 +48,7 @@ class ParticleButtonsPanel(bpy.types.Panel):
return particle_panel_poll(context)
-class PARTICLE_PT_particles(ParticleButtonsPanel):
+class PARTICLE_PT_context_particles(ParticleButtonsPanel):
bl_label = ""
bl_show_header = False
@@ -130,6 +131,10 @@ class PARTICLE_PT_particles(ParticleButtonsPanel):
split.prop(psys, "reactor_target_particle_system", text="Particle System")
+class PARTICLE_PT_custom_props(ParticleButtonsPanel, PropertyPanel):
+ _context_path = "particle_system.settings"
+
+
class PARTICLE_PT_emission(ParticleButtonsPanel):
bl_label = "Emission"
@@ -992,7 +997,7 @@ class PARTICLE_PT_vertexgroups(ParticleButtonsPanel):
row.prop_object(psys, "vertex_group_field", ob, "vertex_groups", text="Field")
row.prop(psys, "vertex_group_field_negate", text="")
-bpy.types.register(PARTICLE_PT_particles)
+bpy.types.register(PARTICLE_PT_context_particles)
bpy.types.register(PARTICLE_PT_hair_dynamics)
bpy.types.register(PARTICLE_PT_cache)
bpy.types.register(PARTICLE_PT_emission)
@@ -1006,3 +1011,5 @@ bpy.types.register(PARTICLE_PT_children)
bpy.types.register(PARTICLE_PT_field_weights)
bpy.types.register(PARTICLE_PT_force_fields)
bpy.types.register(PARTICLE_PT_vertexgroups)
+
+bpy.types.register(PARTICLE_PT_custom_props)
diff --git a/release/scripts/ui/properties_physics_field.py b/release/scripts/ui/properties_physics_field.py
index c2f1703a912..90e0912896d 100644
--- a/release/scripts/ui/properties_physics_field.py
+++ b/release/scripts/ui/properties_physics_field.py
@@ -217,6 +217,7 @@ class PHYSICS_PT_collision(PhysicButtonsPanel):
col = split.column()
col.label(text="Particle:")
col.prop(settings, "permeability", slider=True)
+ col.prop(settings, "stickness")
col.prop(settings, "kill_particles")
col.label(text="Particle Damping:")
sub = col.column(align=True)
diff --git a/release/scripts/ui/properties_render.py b/release/scripts/ui/properties_render.py
index 5fb9662ba81..14396bb4c51 100644
--- a/release/scripts/ui/properties_render.py
+++ b/release/scripts/ui/properties_render.py
@@ -326,7 +326,7 @@ class RENDER_PT_output(RenderButtonsPanel):
if wide_ui:
col = split.column()
- col.prop(rd, "file_extensions")
+ col.prop(rd, "use_file_extension")
col.prop(rd, "use_overwrite")
col.prop(rd, "use_placeholder")
@@ -592,30 +592,42 @@ class RENDER_PT_bake(RenderButtonsPanel):
rd = context.scene.render_data
wide_ui = context.region.width > narrowui
- row = layout.row()
- row.operator("object.bake_image", icon='RENDER_STILL')
- row.prop(rd, "bake_type", text="")
-
- col = layout.column()
- col.active = (rd.bake_type == 'NORMALS')
- col.prop(rd, "bake_normal_space")
+ layout.operator("object.bake_image", icon='RENDER_STILL')
+
+ if wide_ui:
+ layout.prop(rd, "bake_type")
+ else:
+ layout.prop(rd, "bake_type", text="")
+
+ if rd.bake_type == 'NORMALS':
+ if wide_ui:
+ layout.prop(rd, "bake_normal_space")
+ else:
+ layout.prop(rd, "bake_normal_space", text="")
+ elif rd.bake_type in ('DISPLACEMENT', 'AO'):
+ layout.prop(rd, "bake_normalized")
+
# col.prop(rd, "bake_aa_mode")
# col.prop(rd, "bake_enable_aa")
+
+ layout.separator()
+
+ split = layout.split()
- col = layout.column()
- row = col.row(align=True)
- row.prop(rd, "bake_active")
- row.prop(rd, "bake_normalized")
-
- row = col.row(align=True)
- row.prop(rd, "bake_clear")
- row.prop(rd, "bake_margin")
-
- row = col.row(align=True)
- row.prop(rd, "bake_distance")
- row.prop(rd, "bake_bias")
-
+ col = split.column()
+ col.prop(rd, "bake_clear")
+ col.prop(rd, "bake_margin")
+ col.prop(rd, "bake_quad_split", text="Split")
+
+ if wide_ui:
+ col = split.column()
+ col.prop(rd, "bake_active")
+ sub = col.column()
+ sub.active = rd.bake_active
+ sub.prop(rd, "bake_distance")
+ sub.prop(rd, "bake_bias")
+
bpy.types.register(RENDER_MT_presets)
bpy.types.register(RENDER_PT_render)
bpy.types.register(RENDER_PT_layers)
diff --git a/release/scripts/ui/properties_scene.py b/release/scripts/ui/properties_scene.py
index c059339c14e..68936a45759 100644
--- a/release/scripts/ui/properties_scene.py
+++ b/release/scripts/ui/properties_scene.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from rna_prop_ui import PropertyPanel
narrowui = 180
@@ -48,6 +49,10 @@ class SCENE_PT_scene(SceneButtonsPanel):
layout.prop(scene, "set", text="")
+class SCENE_PT_custom_props(SceneButtonsPanel, PropertyPanel):
+ _context_path = "scene"
+
+
class SCENE_PT_unit(SceneButtonsPanel):
bl_label = "Units"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -178,3 +183,6 @@ bpy.types.register(SCENE_PT_unit)
bpy.types.register(SCENE_PT_keying_sets)
bpy.types.register(SCENE_PT_keying_set_paths)
bpy.types.register(SCENE_PT_physics)
+
+bpy.types.register(SCENE_PT_custom_props)
+
diff --git a/release/scripts/ui/properties_texture.py b/release/scripts/ui/properties_texture.py
index 4471f6f9644..7b70b355731 100644
--- a/release/scripts/ui/properties_texture.py
+++ b/release/scripts/ui/properties_texture.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from rna_prop_ui import PropertyPanel
narrowui = 180
@@ -87,13 +88,15 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel):
def draw(self, context):
layout = self.layout
+ space = context.space_data
tex = context.texture
wide_ui = context.region.width > narrowui
idblock = context_tex_datablock(context)
+ tex_collection = space.pin_id == None and type(idblock) != bpy.types.Brush
- space = context.space_data
+
- if idblock:
+ if tex_collection:
row = layout.row()
row.template_list(idblock, "textures", idblock, "active_texture_index", rows=2)
@@ -101,24 +104,31 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel):
col = row.column(align=True)
col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP'
col.operator("texture.slot_move", text="", icon='TRIA_DOWN').type = 'DOWN'
-
-
+
if wide_ui:
split = layout.split(percentage=0.65)
- if idblock:
- split.template_ID(idblock, "active_texture", new="texture.new")
- elif tex:
- split.template_ID(space, "pin_id")
+ col = split.column()
else:
- layout.template_ID(idblock, "active_texture", new="texture.new")
-
+ col = layout.column()
+
+ if tex_collection:
+ col.template_ID(idblock, "active_texture", new="texture.new")
+ elif idblock:
+ col.template_ID(idblock, "texture", new="texture.new")
+
+ if space.pin_id:
+ col.template_ID(space, "pin_id")
+
+ if wide_ui:
+ col = split.column()
+
if (not space.pin_id) and (
context.sculpt_object or
context.vertex_paint_object or
context.weight_paint_object or
context.texture_paint_object):
- split.prop(space, "brush_texture", text="Brush", toggle=True)
+ col.prop(space, "brush_texture", text="Brush", toggle=True)
if tex:
layout.prop(tex, "use_nodes")
@@ -140,6 +150,13 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel):
layout.prop(tex, "type", text="")
+class TEXTURE_PT_custom_props(TextureButtonsPanel, PropertyPanel):
+ _context_path = "texture"
+
+ def poll(self, context): # use alternate poll since NONE texture type is ok
+ return context.texture
+
+
class TEXTURE_PT_colors(TextureButtonsPanel):
bl_label = "Colors"
bl_default_closed = True
@@ -268,6 +285,10 @@ class TEXTURE_PT_influence(TextureSlotPanel):
bl_label = "Influence"
def poll(self, context):
+ idblock = context_tex_datablock(context)
+ if type(idblock) == bpy.types.Brush:
+ return False
+
return context.texture_slot
def draw(self, context):
@@ -963,3 +984,5 @@ bpy.types.register(TEXTURE_PT_pointdensity_turbulence)
bpy.types.register(TEXTURE_PT_colors)
bpy.types.register(TEXTURE_PT_mapping)
bpy.types.register(TEXTURE_PT_influence)
+
+bpy.types.register(TEXTURE_PT_custom_props)
diff --git a/release/scripts/ui/properties_world.py b/release/scripts/ui/properties_world.py
index b23a0dffbad..c4eaa049ce6 100644
--- a/release/scripts/ui/properties_world.py
+++ b/release/scripts/ui/properties_world.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from rna_prop_ui import PropertyPanel
narrowui = 180
@@ -69,6 +70,11 @@ class WORLD_PT_context_world(WorldButtonsPanel):
layout.template_ID(scene, "world", new="world.new")
+class WORLD_PT_custom_props(WorldButtonsPanel, PropertyPanel):
+ COMPAT_ENGINES = {'BLENDER_RENDER'}
+ _context_path = "world"
+
+
class WORLD_PT_world(WorldButtonsPanel):
bl_label = "World"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -232,3 +238,5 @@ bpy.types.register(WORLD_PT_world)
bpy.types.register(WORLD_PT_ambient_occlusion)
bpy.types.register(WORLD_PT_mist)
bpy.types.register(WORLD_PT_stars)
+
+bpy.types.register(WORLD_PT_custom_props) \ No newline at end of file
diff --git a/release/scripts/ui/space_dopesheet.py b/release/scripts/ui/space_dopesheet.py
index 4710d9de3aa..d53443a3fb5 100644
--- a/release/scripts/ui/space_dopesheet.py
+++ b/release/scripts/ui/space_dopesheet.py
@@ -151,8 +151,7 @@ class DOPESHEET_MT_key(bpy.types.Menu):
layout.operator_menu_enum("action.mirror", property="type", text="Mirror")
layout.separator()
- # Inconsistent naming? act/action
- layout.operator("act.keyframe_insert")
+ layout.operator("action.keyframe_insert")
layout.separator()
layout.operator("action.duplicate")
diff --git a/release/scripts/ui/space_image.py b/release/scripts/ui/space_image.py
index 27d0aa91349..5d6bc70dd35 100644
--- a/release/scripts/ui/space_image.py
+++ b/release/scripts/ui/space_image.py
@@ -475,6 +475,7 @@ class IMAGE_PT_paint(bpy.types.Panel):
if brush:
col = layout.column()
+ col.template_color_wheel(brush, "color", value_slider=True)
col.prop(brush, "color", text="")
row = col.row(align=True)
diff --git a/release/scripts/ui/space_info.py b/release/scripts/ui/space_info.py
index 4f6a85156d0..b15315b8668 100644
--- a/release/scripts/ui/space_info.py
+++ b/release/scripts/ui/space_info.py
@@ -121,7 +121,7 @@ class INFO_MT_file_open_recent(bpy.types.Menu):
import os
layout = self.layout
layout.operator_context = 'EXEC_AREA'
- file = open(os.path.join(bpy.home, ".Blog"), "rU")
+ file = open(os.path.join(bpy.app.home, ".Blog"), "rU")
for line in file:
line = line.rstrip()
layout.operator("wm.open_mainfile", text=line, icon='FILE_BLEND').path = line
diff --git a/release/scripts/ui/space_nla.py b/release/scripts/ui/space_nla.py
index 285ada5f46e..0060941b476 100644
--- a/release/scripts/ui/space_nla.py
+++ b/release/scripts/ui/space_nla.py
@@ -60,10 +60,7 @@ class NLA_MT_view(bpy.types.Menu):
layout.separator()
layout.prop(st, "show_cframe_indicator")
- if st.show_seconds:
- layout.operator("anim.time_toggle", text="Show Frames")
- else:
- layout.operator("anim.time_toggle", text="Show Seconds")
+ layout.operator("anim.time_toggle", text="Show Frames" if st.show_seconds else "Show Seconds")
layout.prop(st, "show_strip_curves")
diff --git a/release/scripts/ui/space_node.py b/release/scripts/ui/space_node.py
index 9cf0a0c5ef3..3dc26f49a6f 100644
--- a/release/scripts/ui/space_node.py
+++ b/release/scripts/ui/space_node.py
@@ -120,6 +120,7 @@ class NODE_MT_node(bpy.types.Menu):
layout.separator()
layout.operator("node.link_make")
+ layout.operator("node.link_make", text="Make and Replace Links").replace=True
layout.separator()
layout.operator("node.group_edit")
diff --git a/release/scripts/ui/space_sequencer.py b/release/scripts/ui/space_sequencer.py
index 8edadb96de3..99298cc3988 100644
--- a/release/scripts/ui/space_sequencer.py
+++ b/release/scripts/ui/space_sequencer.py
@@ -606,13 +606,16 @@ class SEQUENCER_PT_filter(SequencerButtonsPanel):
row = layout.row()
row.active = strip.use_color_balance
col = row.column()
- col.prop(strip.color_balance, "lift")
+ col.template_color_wheel(strip.color_balance, "lift", value_slider=False)
+ col.row().prop(strip.color_balance, "lift")
col.prop(strip.color_balance, "inverse_lift", text="Inverse")
col = row.column()
- col.prop(strip.color_balance, "gamma")
+ col.template_color_wheel(strip.color_balance, "gamma", value_slider=False)
+ col.row().prop(strip.color_balance, "gamma")
col.prop(strip.color_balance, "inverse_gamma", text="Inverse")
col = row.column()
- col.prop(strip.color_balance, "gain")
+ col.template_color_wheel(strip.color_balance, "gain", value_slider=False)
+ col.row().prop(strip.color_balance, "gain")
col.prop(strip.color_balance, "inverse_gain", text="Inverse")
diff --git a/release/scripts/ui/space_userpref.py b/release/scripts/ui/space_userpref.py
index 4c807fd9bd2..534735bfc24 100644
--- a/release/scripts/ui/space_userpref.py
+++ b/release/scripts/ui/space_userpref.py
@@ -19,6 +19,48 @@
# <pep8 compliant>
import bpy
+# General UI Theme Settings (User Interface)
+def ui_items_general(col, context):
+ row = col.row()
+ sub = row.column()
+ sub.prop(context, "outline")
+ sub.prop(context, "item", slider=True)
+ sub = row.column()
+ sub.prop(context, "inner", slider=True)
+ sub.prop(context, "inner_sel", slider=True)
+ sub = row.column()
+ sub.prop(context, "text")
+ sub.prop(context, "text_sel")
+ sub = row.column()
+ sub.prop(context, "shaded")
+ subsub = sub.column(align=True)
+ subsub.active = context.shaded
+ subsub.prop(context, "shadetop")
+ subsub.prop(context, "shadedown")
+
+ col.separator()
+
+def opengl_lamp_buttons(column, lamp):
+ split = column.split(percentage=0.1)
+
+ if lamp.enabled == True:
+ split.prop(lamp, "enabled", text="", icon='OUTLINER_OB_LAMP')
+ else:
+ split.prop(lamp, "enabled", text="", icon='LAMP_DATA')
+
+ col = split.column()
+ col.active = lamp.enabled
+ row = col.row()
+ row.label(text="Diffuse:")
+ row.prop(lamp, "diffuse_color", text="")
+ row = col.row()
+ row.label(text="Specular:")
+ row.prop(lamp, "specular_color", text="")
+
+ col = split.column()
+ col.active = lamp.enabled
+ col.prop(lamp, "direction", text="")
+
KM_HIERARCHY = [
('Window', 'EMPTY', 'WINDOW', []), # file save, window change, exit
('Screen', 'EMPTY', 'WINDOW', [ # full screen, undo, screenshot
@@ -154,7 +196,6 @@ class USERPREF_PT_interface(bpy.types.Panel):
row = layout.row()
-
col = row.column()
col.label(text="Display:")
col.prop(view, "tooltips")
@@ -176,16 +217,15 @@ class USERPREF_PT_interface(bpy.types.Panel):
sub.prop(view, "mini_axis_size", text="Size")
sub.prop(view, "mini_axis_brightness", text="Brightness")
-
row.separator()
row.separator()
col = row.column()
col.label(text="View Manipulation:")
col.prop(view, "auto_depth")
- col.prop(view, "global_pivot")
col.prop(view, "zoom_to_mouse")
col.prop(view, "rotate_around_selection")
+ col.prop(view, "global_pivot")
col.separator()
@@ -237,13 +277,11 @@ class USERPREF_PT_edit(bpy.types.Panel):
userpref = context.user_preferences
edit = userpref.edit
-
row = layout.row()
-
col = row.column()
col.label(text="Link Materials To:")
- col.row().prop(edit, "material_link", expand=True)
+ col.prop(edit, "material_link", text="")
col.separator()
col.separator()
@@ -252,7 +290,7 @@ class USERPREF_PT_edit(bpy.types.Panel):
col.label(text="New Objects:")
col.prop(edit, "enter_edit_mode")
col.label(text="Align To:")
- col.row().prop(edit, "object_align", expand=True)
+ col.prop(edit, "object_align", text="")
col.separator()
col.separator()
@@ -263,11 +301,9 @@ class USERPREF_PT_edit(bpy.types.Panel):
col.prop(edit, "undo_steps", text="Steps")
col.prop(edit, "undo_memory_limit", text="Memory Limit")
-
row.separator()
row.separator()
-
col = row.column()
col.label(text="Snap:")
col.prop(edit, "snap_translate", text="Translate")
@@ -283,11 +319,9 @@ class USERPREF_PT_edit(bpy.types.Panel):
col.prop(edit, "grease_pencil_eraser_radius", text="Eraser Radius")
col.prop(edit, "grease_pencil_smooth_stroke", text="Smooth Stroke")
-
row.separator()
row.separator()
-
col = row.column()
col.label(text="Keyframing:")
col.prop(edit, "use_visual_keying")
@@ -316,11 +350,9 @@ class USERPREF_PT_edit(bpy.types.Panel):
col.label(text="Transform:")
col.prop(edit, "drag_immediately")
-
row.separator()
row.separator()
-
col = row.column()
col.label(text="Duplicate Data:")
col.prop(edit, "duplicate_mesh", text="Mesh")
@@ -352,12 +384,11 @@ class USERPREF_PT_system(bpy.types.Panel):
userpref = context.user_preferences
system = userpref.system
- lamp0 = system.solid_lights[0]
- lamp1 = system.solid_lights[1]
- lamp2 = system.solid_lights[2]
split = layout.split()
+
+ # 1. Column
column = split.column()
colsplit = column.split(percentage=0.85)
@@ -377,7 +408,6 @@ class USERPREF_PT_system(bpy.types.Panel):
sub = col.column()
sub.active = system.audio_device != 'NONE'
#sub.prop(system, "enable_all_codecs")
- sub.prop(system, "game_sound")
sub.prop(system, "audio_channels", text="Channels")
sub.prop(system, "audio_mixing_buffer", text="Mixing Buffer")
sub.prop(system, "audio_sample_rate", text="Sample Rate")
@@ -387,8 +417,6 @@ class USERPREF_PT_system(bpy.types.Panel):
col.separator()
col.separator()
-
-
#column = split.column()
#colsplit = column.split(percentage=0.85)
@@ -402,7 +430,9 @@ class USERPREF_PT_system(bpy.types.Panel):
#col.separator()
#col.prop(system, "use_textured_fonts")
+
+ # 2. Column
column = split.column()
colsplit = column.split(percentage=0.85)
@@ -411,6 +441,8 @@ class USERPREF_PT_system(bpy.types.Panel):
col.prop(system, "clip_alpha", slider=True)
col.prop(system, "use_mipmaps")
col.prop(system, "use_vbos")
+ #Anti-aliasing is disabled as it breaks broder/lasso select
+ #col.prop(system, "use_antialiasing")
col.label(text="Window Draw Method:")
col.row().prop(system, "window_draw_method", expand=True)
col.label(text="Textures:")
@@ -425,7 +457,9 @@ class USERPREF_PT_system(bpy.types.Panel):
col.label(text="Sequencer:")
col.prop(system, "prefetch_frames")
col.prop(system, "memory_cache_limit")
+
+ # 3. Column
column = split.column()
column.label(text="Solid OpenGL lights:")
@@ -434,79 +468,29 @@ class USERPREF_PT_system(bpy.types.Panel):
split.label()
split.label(text="Colors:")
split.label(text="Direction:")
-
-
- split = column.split(percentage=0.1)
-
- if lamp0.enabled == True:
- split.prop(lamp0, "enabled", text="", icon='OUTLINER_OB_LAMP')
- else:
- split.prop(lamp0, "enabled", text="", icon='LAMP_DATA')
-
- col = split.column()
- col.active = lamp0.enabled
- row = col.row()
- row.label(text="Diffuse:")
- row.prop(lamp0, "diffuse_color", text="")
- row = col.row()
- row.label(text="Specular:")
- row.prop(lamp0, "specular_color", text="")
-
- col = split.column()
- col.active = lamp0.enabled
- col.prop(lamp0, "direction", text="")
-
-
- split = column.split(percentage=0.1)
-
- if lamp1.enabled == True:
- split.prop(lamp1, "enabled", text="", icon='OUTLINER_OB_LAMP')
- else:
- split.prop(lamp1, "enabled", text="", icon='LAMP_DATA')
-
- col = split.column()
- col.active = lamp1.enabled
- row = col.row()
- row.label(text="Diffuse:")
- row.prop(lamp1, "diffuse_color", text="")
- row = col.row()
- row.label(text="Specular:")
- row.prop(lamp1, "specular_color", text="")
-
- col = split.column()
- col.active = lamp1.enabled
- col.prop(lamp1, "direction", text="")
-
-
- split = column.split(percentage=0.1)
-
- if lamp2.enabled == True:
- split.prop(lamp2, "enabled", text="", icon='OUTLINER_OB_LAMP')
- else:
- split.prop(lamp2, "enabled", text="", icon='LAMP_DATA')
-
- col = split.column()
- col.active = lamp2.enabled
- row = col.row()
- row.label(text="Diffuse:")
- row.prop(lamp2, "diffuse_color", text="")
- row = col.row()
- row.label(text="Specular:")
- row.prop(lamp2, "specular_color", text="")
-
- col = split.column()
- col.active = lamp2.enabled
- col.prop(lamp2, "direction", text="")
-
+
+ lamp = system.solid_lights[0]
+ opengl_lamp_buttons(column, lamp)
+
+ lamp = system.solid_lights[1]
+ opengl_lamp_buttons(column, lamp)
+
+ lamp = system.solid_lights[2]
+ opengl_lamp_buttons(column, lamp)
column.separator()
column.separator()
column.separator()
-
- col = column.column()
-
- col.prop(system, "use_weight_color_range", text="Custom Weight Paint Range")
- sub = col.column()
+
+ column.label(text="Color Picker Type:")
+ column.row().prop(system, "color_picker_type", text="")
+
+ column.separator()
+ column.separator()
+ column.separator()
+
+ column.prop(system, "use_weight_color_range", text="Custom Weight Paint Range")
+ sub = column.column()
sub.active = system.use_weight_color_range
sub.template_color_ramp(system, "weight_color_range", expand=True)
@@ -526,351 +510,78 @@ class USERPREF_PT_theme(bpy.types.Panel):
theme = context.user_preferences.themes[0]
- split = layout.split(percentage=0.33)
- split.prop(theme, "active_theme", text="")
-
- layout.separator()
-
- split = layout.split()
-
- if theme.active_theme == 'VIEW_3D':
- v3d = theme.view_3d
-
- col = split.column()
- col.prop(v3d, "back")
- col.prop(v3d, "button")
- col.prop(v3d, "button_title")
- col.prop(v3d, "button_text")
- col.prop(v3d, "header")
+ split_themes = layout.split(percentage=0.2)
+ split_themes.prop(theme, "theme_area", expand=True)
+ split = split_themes.split()
+
+ if theme.theme_area == 'USER_INTERFACE':
col = split.column()
- col.prop(v3d, "grid")
- col.prop(v3d, "wire")
- col.prop(v3d, "lamp", slider=True)
- col.prop(v3d, "editmesh_active", slider=True)
- col = split.column()
- col.prop(v3d, "object_selected")
- col.prop(v3d, "object_active")
- col.prop(v3d, "object_grouped")
- col.prop(v3d, "object_grouped_active")
- col.prop(v3d, "transform")
-
- col = split.column()
- col.prop(v3d, "vertex")
- col.prop(v3d, "face", slider=True)
- col.prop(v3d, "normal")
- col.prop(v3d, "bone_solid")
- col.prop(v3d, "bone_pose")
- #col.prop(v3d, "edge") Doesn't seem to work
-
- elif theme.active_theme == 'USER_INTERFACE':
ui = theme.user_interface.wcol_regular
- layout.label(text="Regular:")
-
- row = layout.row()
- sub = row.column()
- sub.prop(ui, "outline")
- sub.prop(ui, "item", slider=True)
- sub = row.column()
- sub.prop(ui, "inner", slider=True)
- sub.prop(ui, "inner_sel", slider=True)
- sub = row.column()
- sub.prop(ui, "text")
- sub.prop(ui, "text_sel")
- sub = row.column()
- sub.prop(ui, "shaded")
- subsub = sub.column(align=True)
- subsub.active = ui.shaded
- subsub.prop(ui, "shadetop")
- subsub.prop(ui, "shadedown")
-
- layout.separator()
+ col.label(text="Regular:")
+ ui_items_general(col, ui)
ui = theme.user_interface.wcol_tool
- layout.label(text="Tool:")
-
- row = layout.row()
- sub = row.column()
- sub.prop(ui, "outline")
- sub.prop(ui, "item", slider=True)
- sub = row.column()
- sub.prop(ui, "inner", slider=True)
- sub.prop(ui, "inner_sel", slider=True)
- sub = row.column()
- sub.prop(ui, "text")
- sub.prop(ui, "text_sel")
- sub = row.column()
- sub.prop(ui, "shaded")
- subsub = sub.column(align=True)
- subsub.active = ui.shaded
- subsub.prop(ui, "shadetop")
- subsub.prop(ui, "shadedown")
+ col.label(text="Tool:")
+ ui_items_general(col, ui)
ui = theme.user_interface.wcol_radio
- layout.label(text="Radio Buttons:")
-
- row = layout.row()
- sub = row.column()
- sub.prop(ui, "outline")
- sub.prop(ui, "item", slider=True)
- sub = row.column()
- sub.prop(ui, "inner", slider=True)
- sub.prop(ui, "inner_sel", slider=True)
- sub = row.column()
- sub.prop(ui, "text")
- sub.prop(ui, "text_sel")
- sub = row.column()
- sub.prop(ui, "shaded")
- subsub = sub.column(align=True)
- subsub.active = ui.shaded
- subsub.prop(ui, "shadetop")
- subsub.prop(ui, "shadedown")
+ col.label(text="Radio Buttons:")
+ ui_items_general(col, ui)
ui = theme.user_interface.wcol_text
- layout.label(text="Text:")
-
- row = layout.row()
- sub = row.column()
- sub.prop(ui, "outline")
- sub.prop(ui, "item", slider=True)
- sub = row.column()
- sub.prop(ui, "inner", slider=True)
- sub.prop(ui, "inner_sel", slider=True)
- sub = row.column()
- sub.prop(ui, "text")
- sub.prop(ui, "text_sel")
- sub = row.column()
- sub.prop(ui, "shaded")
- subsub = sub.column(align=True)
- subsub.active = ui.shaded
- subsub.prop(ui, "shadetop")
- subsub.prop(ui, "shadedown")
+ col.label(text="Text:")
+ ui_items_general(col, ui)
ui = theme.user_interface.wcol_option
- layout.label(text="Option:")
-
- row = layout.row()
- sub = row.column()
- sub.prop(ui, "outline")
- sub.prop(ui, "item", slider=True)
- sub = row.column()
- sub.prop(ui, "inner", slider=True)
- sub.prop(ui, "inner_sel", slider=True)
- sub = row.column()
- sub.prop(ui, "text")
- sub.prop(ui, "text_sel")
- sub = row.column()
- sub.prop(ui, "shaded")
- subsub = sub.column(align=True)
- subsub.active = ui.shaded
- subsub.prop(ui, "shadetop")
- subsub.prop(ui, "shadedown")
+ col.label(text="Option:")
+ ui_items_general(col, ui)
ui = theme.user_interface.wcol_toggle
- layout.label(text="Toggle:")
-
- row = layout.row()
- sub = row.column()
- sub.prop(ui, "outline")
- sub.prop(ui, "item", slider=True)
- sub = row.column()
- sub.prop(ui, "inner", slider=True)
- sub.prop(ui, "inner_sel", slider=True)
- sub = row.column()
- sub.prop(ui, "text")
- sub.prop(ui, "text_sel")
- sub = row.column()
- sub.prop(ui, "shaded")
- subsub = sub.column(align=True)
- subsub.active = ui.shaded
- subsub.prop(ui, "shadetop")
- subsub.prop(ui, "shadedown")
+ col.label(text="Toggle:")
+ ui_items_general(col, ui)
ui = theme.user_interface.wcol_num
- layout.label(text="Number Field:")
-
- row = layout.row()
- sub = row.column()
- sub.prop(ui, "outline")
- sub.prop(ui, "item", slider=True)
- sub = row.column()
- sub.prop(ui, "inner", slider=True)
- sub.prop(ui, "inner_sel", slider=True)
- sub = row.column()
- sub.prop(ui, "text")
- sub.prop(ui, "text_sel")
- sub = row.column()
- sub.prop(ui, "shaded")
- subsub = sub.column(align=True)
- subsub.active = ui.shaded
- subsub.prop(ui, "shadetop")
- subsub.prop(ui, "shadedown")
+ col.label(text="Number Field:")
+ ui_items_general(col, ui)
ui = theme.user_interface.wcol_numslider
- layout.label(text="Value Slider:")
-
- row = layout.row()
- sub = row.column()
- sub.prop(ui, "outline")
- sub.prop(ui, "item", slider=True)
- sub = row.column()
- sub.prop(ui, "inner", slider=True)
- sub.prop(ui, "inner_sel", slider=True)
- sub = row.column()
- sub.prop(ui, "text")
- sub.prop(ui, "text_sel")
- sub = row.column()
- sub.prop(ui, "shaded")
- subsub = sub.column(align=True)
- subsub.active = ui.shaded
- subsub.prop(ui, "shadetop")
- subsub.prop(ui, "shadedown")
+ col.label(text="Value Slider:")
+ ui_items_general(col, ui)
ui = theme.user_interface.wcol_box
- layout.label(text="Box:")
-
- row = layout.row()
- sub = row.column()
- sub.prop(ui, "outline")
- sub.prop(ui, "item", slider=True)
- sub = row.column()
- sub.prop(ui, "inner", slider=True)
- sub.prop(ui, "inner_sel", slider=True)
- sub = row.column()
- sub.prop(ui, "text")
- sub.prop(ui, "text_sel")
- sub = row.column()
- sub.prop(ui, "shaded")
- subsub = sub.column(align=True)
- subsub.active = ui.shaded
- subsub.prop(ui, "shadetop")
- subsub.prop(ui, "shadedown")
+ col.label(text="Box:")
+ ui_items_general(col, ui)
ui = theme.user_interface.wcol_menu
- layout.label(text="Menu:")
-
- row = layout.row()
- sub = row.column()
- sub.prop(ui, "outline")
- sub.prop(ui, "item", slider=True)
- sub = row.column()
- sub.prop(ui, "inner", slider=True)
- sub.prop(ui, "inner_sel", slider=True)
- sub = row.column()
- sub.prop(ui, "text")
- sub.prop(ui, "text_sel")
- sub = row.column()
- sub.prop(ui, "shaded")
- subsub = sub.column(align=True)
- subsub.active = ui.shaded
- subsub.prop(ui, "shadetop")
- subsub.prop(ui, "shadedown")
+ col.label(text="Menu:")
+ ui_items_general(col, ui)
ui = theme.user_interface.wcol_pulldown
- layout.label(text="Pulldown:")
-
- row = layout.row()
- sub = row.column()
- sub.prop(ui, "outline")
- sub.prop(ui, "item", slider=True)
- sub = row.column()
- sub.prop(ui, "inner", slider=True)
- sub.prop(ui, "inner_sel", slider=True)
- sub = row.column()
- sub.prop(ui, "text")
- sub.prop(ui, "text_sel")
- sub = row.column()
- sub.prop(ui, "shaded")
- subsub = sub.column(align=True)
- subsub.active = ui.shaded
- subsub.prop(ui, "shadetop")
- subsub.prop(ui, "shadedown")
+ col.label(text="Pulldown:")
+ ui_items_general(col, ui)
ui = theme.user_interface.wcol_menu_back
- layout.label(text="Menu Back:")
-
- row = layout.row()
- sub = row.column()
- sub.prop(ui, "outline")
- sub.prop(ui, "item", slider=True)
- sub = row.column()
- sub.prop(ui, "inner", slider=True)
- sub.prop(ui, "inner_sel", slider=True)
- sub = row.column()
- sub.prop(ui, "text")
- sub.prop(ui, "text_sel")
- sub = row.column()
- sub.prop(ui, "shaded")
- subsub = sub.column(align=True)
- subsub.active = ui.shaded
- subsub.prop(ui, "shadetop")
- subsub.prop(ui, "shadedown")
+ col.label(text="Menu Back:")
+ ui_items_general(col, ui)
ui = theme.user_interface.wcol_menu_item
- layout.label(text="Menu Item:")
-
- row = layout.row()
- sub = row.column()
- sub.prop(ui, "outline")
- sub.prop(ui, "item", slider=True)
- sub = row.column()
- sub.prop(ui, "inner", slider=True)
- sub.prop(ui, "inner_sel", slider=True)
- sub = row.column()
- sub.prop(ui, "text")
- sub.prop(ui, "text_sel")
- sub = row.column()
- sub.prop(ui, "shaded")
- subsub = sub.column(align=True)
- subsub.active = ui.shaded
- subsub.prop(ui, "shadetop")
- subsub.prop(ui, "shadedown")
+ col.label(text="Menu Item:")
+ ui_items_general(col, ui)
ui = theme.user_interface.wcol_scroll
- layout.label(text="Scroll Bar:")
-
- row = layout.row()
- sub = row.column()
- sub.prop(ui, "outline")
- sub.prop(ui, "item", slider=True)
- sub = row.column()
- sub.prop(ui, "inner", slider=True)
- sub.prop(ui, "inner_sel", slider=True)
- sub = row.column()
- sub.prop(ui, "text")
- sub.prop(ui, "text_sel")
- sub = row.column()
- sub.prop(ui, "shaded")
- subsub = sub.column(align=True)
- subsub.active = ui.shaded
- subsub.prop(ui, "shadetop")
- subsub.prop(ui, "shadedown")
+ col.label(text="Scroll Bar:")
+ ui_items_general(col, ui)
ui = theme.user_interface.wcol_list_item
- layout.label(text="List Item:")
-
- row = layout.row()
- sub = row.column()
- sub.prop(ui, "outline")
- sub.prop(ui, "item", slider=True)
- sub = row.column()
- sub.prop(ui, "inner", slider=True)
- sub.prop(ui, "inner_sel", slider=True)
- sub = row.column()
- sub.prop(ui, "text")
- sub.prop(ui, "text_sel")
- sub = row.column()
- sub.prop(ui, "shaded")
- subsub = sub.column(align=True)
- subsub.active = ui.shaded
- subsub.prop(ui, "shadetop")
- subsub.prop(ui, "shadedown")
+ col.label(text="List Item:")
+ ui_items_general(col, ui)
ui = theme.user_interface.wcol_state
- layout.label(text="State:")
+ col.label(text="State:")
- row = layout.row()
+ row = col.row()
sub = row.column()
sub.prop(ui, "inner_anim")
sub.prop(ui, "inner_anim_sel")
@@ -884,16 +595,46 @@ class USERPREF_PT_theme(bpy.types.Panel):
sub.prop(ui, "blend")
ui = theme.user_interface
- layout.separator()
-
- sub = layout.row()
- sub.prop(ui, "icon_file")
+ col.separator()
+ col.separator()
+ col.prop(ui, "icon_file")
layout.separator()
layout.separator()
- elif theme.active_theme == 'GRAPH_EDITOR':
+ elif theme.theme_area == 'VIEW_3D':
+ v3d = theme.view_3d
+
+ col = split.column()
+ col.prop(v3d, "back")
+ col.prop(v3d, "button")
+ col.prop(v3d, "button_title")
+ col.prop(v3d, "button_text")
+ col.prop(v3d, "header")
+
+ col = split.column()
+ col.prop(v3d, "grid")
+ col.prop(v3d, "wire")
+ col.prop(v3d, "lamp", slider=True)
+ col.prop(v3d, "editmesh_active", slider=True)
+
+ col = split.column()
+ col.prop(v3d, "object_selected")
+ col.prop(v3d, "object_active")
+ col.prop(v3d, "object_grouped")
+ col.prop(v3d, "object_grouped_active")
+ col.prop(v3d, "transform")
+
+ col = split.column()
+ col.prop(v3d, "vertex")
+ col.prop(v3d, "face", slider=True)
+ col.prop(v3d, "normal")
+ col.prop(v3d, "bone_solid")
+ col.prop(v3d, "bone_pose")
+ #col.prop(v3d, "edge") Doesn't seem to work
+
+ elif theme.theme_area == 'GRAPH_EDITOR':
graph = theme.graph_editor
col = split.column()
@@ -921,7 +662,7 @@ class USERPREF_PT_theme(bpy.types.Panel):
col.separator()
col.prop(graph, "handle_vertex_size")
- elif theme.active_theme == 'FILE_BROWSER':
+ elif theme.theme_area == 'FILE_BROWSER':
file_browse = theme.file_browser
col = split.column()
@@ -941,7 +682,7 @@ class USERPREF_PT_theme(bpy.types.Panel):
col.prop(file_browse, "active_file")
col.prop(file_browse, "active_file_text")
- elif theme.active_theme == 'NLA_EDITOR':
+ elif theme.theme_area == 'NLA_EDITOR':
nla = theme.nla_editor
col = split.column()
@@ -964,7 +705,7 @@ class USERPREF_PT_theme(bpy.types.Panel):
col.prop(nla, "strips_selected")
col.prop(nla, "current_frame")
- elif theme.active_theme == 'DOPESHEET_EDITOR':
+ elif theme.theme_area == 'DOPESHEET_EDITOR':
dope = theme.dopesheet_editor
col = split.column()
@@ -989,7 +730,7 @@ class USERPREF_PT_theme(bpy.types.Panel):
col.prop(dope, "dopesheet_channel")
col.prop(dope, "dopesheet_subchannel")
- elif theme.active_theme == 'IMAGE_EDITOR':
+ elif theme.theme_area == 'IMAGE_EDITOR':
image = theme.image_editor
col = split.column()
@@ -1006,7 +747,7 @@ class USERPREF_PT_theme(bpy.types.Panel):
col = split.column()
col.prop(image, "editmesh_active", slider=True)
- elif theme.active_theme == 'SEQUENCE_EDITOR':
+ elif theme.theme_area == 'SEQUENCE_EDITOR':
seq = theme.sequence_editor
col = split.column()
@@ -1035,7 +776,7 @@ class USERPREF_PT_theme(bpy.types.Panel):
col.prop(seq, "keyframe")
col.prop(seq, "draw_action")
- elif theme.active_theme == 'PROPERTIES':
+ elif theme.theme_area == 'PROPERTIES':
prop = theme.properties
col = split.column()
@@ -1050,7 +791,7 @@ class USERPREF_PT_theme(bpy.types.Panel):
col = split.column()
col.prop(prop, "header")
- elif theme.active_theme == 'TEXT_EDITOR':
+ elif theme.theme_area == 'TEXT_EDITOR':
text = theme.text_editor
col = split.column()
@@ -1076,7 +817,7 @@ class USERPREF_PT_theme(bpy.types.Panel):
col.prop(text, "syntax_string")
col.prop(text, "syntax_numbers")
- elif theme.active_theme == 'TIMELINE':
+ elif theme.theme_area == 'TIMELINE':
time = theme.timeline
col = split.column()
@@ -1092,7 +833,7 @@ class USERPREF_PT_theme(bpy.types.Panel):
col = split.column()
col.prop(time, "current_frame")
- elif theme.active_theme == 'NODE_EDITOR':
+ elif theme.theme_area == 'NODE_EDITOR':
node = theme.node_editor
col = split.column()
@@ -1118,7 +859,7 @@ class USERPREF_PT_theme(bpy.types.Panel):
col.prop(node, "operator_node")
col.prop(node, "group_node")
- elif theme.active_theme == 'LOGIC_EDITOR':
+ elif theme.theme_area == 'LOGIC_EDITOR':
logic = theme.logic_editor
col = split.column()
@@ -1136,7 +877,7 @@ class USERPREF_PT_theme(bpy.types.Panel):
col = split.column()
col.prop(logic, "panel")
- elif theme.active_theme == 'OUTLINER':
+ elif theme.theme_area == 'OUTLINER':
out = theme.outliner
col = split.column()
@@ -1151,7 +892,7 @@ class USERPREF_PT_theme(bpy.types.Panel):
col = split.column()
col.prop(out, "header")
- elif theme.active_theme == 'INFO':
+ elif theme.theme_area == 'INFO':
info = theme.info
col = split.column()
@@ -1165,7 +906,7 @@ class USERPREF_PT_theme(bpy.types.Panel):
col = split.column()
- elif theme.active_theme == 'USER_PREFERENCES':
+ elif theme.theme_area == 'USER_PREFERENCES':
prefs = theme.user_preferences
col = split.column()
@@ -1475,11 +1216,11 @@ class USERPREF_PT_input(bpy.types.Panel):
filter = kc.filter.lower()
for km in kc.keymaps:
+ km = km.active()
+
filtered_items = [kmi for kmi in km.items if filter in kmi.name.lower()]
if len(filtered_items) != 0:
- km = km.active()
-
layout.set_context_pointer("keymap", km)
col = layout.column()
diff --git a/release/scripts/ui/space_view3d.py b/release/scripts/ui/space_view3d.py
index 5563b727487..8c430d39aa3 100644
--- a/release/scripts/ui/space_view3d.py
+++ b/release/scripts/ui/space_view3d.py
@@ -1217,7 +1217,8 @@ class VIEW3D_MT_edit_mesh_edges(bpy.types.Menu):
layout.separator()
- layout.operator("TRANSFORM_OT_edge_slide", text="Edge Slide")
+ layout.operator("TRANSFORM_OT_edge_slide")
+ layout.operator("TRANSFORM_OT_edge_crease")
layout.operator("mesh.loop_multi_select", text="Edge Loop")
# uiItemO(layout, "Loopcut", 0, "mesh.loop_cut"); // CutEdgeloop(em, 1);
diff --git a/release/scripts/ui/space_view3d_toolbar.py b/release/scripts/ui/space_view3d_toolbar.py
index b2c8c39cb3a..a7a8968fb05 100644
--- a/release/scripts/ui/space_view3d_toolbar.py
+++ b/release/scripts/ui/space_view3d_toolbar.py
@@ -542,9 +542,10 @@ class VIEW3D_PT_tools_brush(PaintPanel):
row = col.row(align=True)
row.prop(brush, "size", slider=True)
- row.prop(brush, "use_size_pressure", toggle=True, text="")
if brush.sculpt_tool != 'GRAB':
+ row.prop(brush, "use_size_pressure", toggle=True, text="")
+
row = col.row(align=True)
row.prop(brush, "strength", slider=True)
row.prop(brush, "use_strength_pressure", text="")
@@ -570,6 +571,7 @@ class VIEW3D_PT_tools_brush(PaintPanel):
elif context.texture_paint_object and brush:
col = layout.column()
+ col.template_color_wheel(brush, "color", value_slider=True)
col.prop(brush, "color", text="")
row = col.row(align=True)
@@ -609,6 +611,7 @@ class VIEW3D_PT_tools_brush(PaintPanel):
elif context.vertex_paint_object and brush:
col = layout.column()
+ col.template_color_wheel(brush, "color", value_slider=True)
col.prop(brush, "color", text="")
row = col.row(align=True)
@@ -624,6 +627,29 @@ class VIEW3D_PT_tools_brush(PaintPanel):
#row.prop(brush, "jitter", slider=True)
#row.prop(brush, "use_jitter_pressure", toggle=True, text="")
+
+class VIEW3D_PT_tools_brush_texture(PaintPanel):
+ bl_label = "Texture"
+ bl_default_closed = True
+
+ def poll(self, context):
+ settings = self.paint_settings(context)
+ return (settings and settings.brush and (context.sculpt_object or
+ context.texture_paint_object))
+
+ def draw(self, context):
+ layout = self.layout
+
+ settings = self.paint_settings(context)
+ brush = settings.brush
+ tex_slot = brush.texture_slot
+
+ col = layout.column()
+
+ col.template_ID_preview(brush, "texture", new="texture.new", rows=2, cols=4)
+
+ col.row().prop(tex_slot, "map_mode", expand=True)
+
class VIEW3D_PT_tools_brush_tool(PaintPanel):
bl_label = "Tool"
bl_default_closed = True
@@ -709,7 +735,7 @@ class VIEW3D_PT_tools_brush_curve(PaintPanel):
settings = self.paint_settings(context)
brush = settings.brush
- layout.template_curve_mapping(brush, "curve")
+ layout.template_curve_mapping(brush, "curve", brush=True)
layout.operator_menu_enum("brush.curve_preset", property="shape")
@@ -777,9 +803,9 @@ class VIEW3D_PT_tools_weightpaint_options(View3DPanel):
col.prop(wpaint, "normals")
col.prop(wpaint, "spray")
- data = context.weight_paint_object.data
- if type(data) == bpy.types.Mesh:
- col.prop(data, "use_mirror_x")
+ obj = context.weight_paint_object
+ if obj.type == 'MESH':
+ col.prop(obj.data, "use_mirror_x")
# Commented out because the Apply button isn't an operator yet, making these settings useless
# col.label(text="Gamma:")
@@ -948,6 +974,7 @@ class VIEW3D_PT_tools_particlemode(View3DPanel):
if not pe.hair:
col.label(text="Correct:")
col.prop(pe, "auto_velocity", text="Velocity")
+ col.prop(ob.data, "use_mirror_x")
col = layout.column(align=True)
col.active = pe.editable
@@ -960,7 +987,6 @@ class VIEW3D_PT_tools_particlemode(View3DPanel):
sub.active = pe.fade_time
sub.prop(pe, "fade_frames", slider=True)
-
bpy.types.register(VIEW3D_PT_tools_weightpaint)
bpy.types.register(VIEW3D_PT_tools_objectmode)
bpy.types.register(VIEW3D_PT_tools_meshedit)
@@ -975,6 +1001,7 @@ bpy.types.register(VIEW3D_PT_tools_latticeedit)
bpy.types.register(VIEW3D_PT_tools_posemode)
bpy.types.register(VIEW3D_PT_tools_posemode_options)
bpy.types.register(VIEW3D_PT_tools_brush)
+bpy.types.register(VIEW3D_PT_tools_brush_texture)
bpy.types.register(VIEW3D_PT_tools_brush_tool)
bpy.types.register(VIEW3D_PT_tools_brush_stroke)
bpy.types.register(VIEW3D_PT_tools_brush_curve)
diff --git a/source/Makefile b/source/Makefile
index e08def0f9e2..2f935c91095 100644
--- a/source/Makefile
+++ b/source/Makefile
@@ -211,6 +211,11 @@ ifeq ($(WITH_BINRELOC), true)
COMLIB += $(OCGDIR)/extern/binreloc/$(DEBUG_DIR)libbinreloc.a
endif
+ifeq ($(WITH_OPENCOLLADA), true)
+ COMLIB += $(OCGDIR)/blender/bf_collada/$(DEBUG_DIR)/libbf_collada.a
+ COMLIB += $(BF_PCRE_LIBS)
+endif
+
ifeq ($(OS), windows)
ifeq ($(FREE_WINDOWS), true)
COMLIB += $(NAN_FREETYPE)/lib/libfreetype.a
@@ -519,7 +524,7 @@ endif
$(DIR)/$(DEBUG_DIR)bin/blenderstatic: $(OBJS) $(GRPLIB) $(PULIB) $(COMLIB)
@echo "****> Link $@"
ifdef NAN_BUILDINFO
- $(CCC) $(REL_CFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_REV='"$(BUILD_REV)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"static"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
+ $(CCC) $(CCFLAGS) $(REL_CCFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_REV='"$(BUILD_REV)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"static"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
endif
mkdir -p $(DIR)/$(DEBUG_DIR)bin
$(CCC) $(CCFLAGS) $(LDFLAGS) -o $(DIR)/$(DEBUG_DIR)bin/blenderstatic $(BUILDINFO_O) $(OBJS) $(GRPLIB) $(PULIB) $(COMLIB) $(LLIBS) $(SADD) $(LOPTS)
@@ -533,7 +538,7 @@ endif
$(DIR)/$(DEBUG_DIR)bin/blender$(EXT): $(OBJS) $(GRPLIB) $(PULIB) $(COMLIB)
@echo "****> Link $@"
ifdef NAN_BUILDINFO
- $(CCC) $(REL_CFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_REV='"$(BUILD_REV)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
+ $(CCC) $(CCFLAGS) $(REL_CCFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_REV='"$(BUILD_REV)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
endif
mkdir -p $(DIR)/$(DEBUG_DIR)bin
$(CCC) $(CCFLAGS) $(LDFLAGS) -o $(DIR)/$(DEBUG_DIR)bin/blender$(EXT) $(BUILDINFO_O) $(OBJS) $(GRPLIB) $(PULIB) $(COMLIB) $(LLIBS) $(DADD) $(LOPTS)
@@ -547,7 +552,7 @@ endif
$(DIR)/$(DEBUG_DIR)bin/blenderplayer$(EXT): $(OBJS) $(SPLIB1) $(COMLIB) $(SPLIB)
@echo "****> Link $@"
ifdef NAN_BUILDINFO
- $(CCC) $(REL_CFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_REV='"$(BUILD_REV)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
+ $(CCC) $(CCFLAGS) $(REL_CCFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_REV='"$(BUILD_REV)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
endif
mkdir -p $(DIR)/$(DEBUG_DIR)bin
$(CCC) $(CCFLAGS) $(LDFLAGS) -o $(DIR)/$(DEBUG_DIR)bin/blenderplayer$(EXT) $(BUILDINFO_O) $(OBJS) $(SPLIB1) $(COMLIB) $(SPLIB) $(LLIBS) $(DADD) $(LOPTS)
@@ -561,7 +566,7 @@ endif
$(DIR)/$(DEBUG_DIR)bin/blenderdynplayer$(EXT): $(OBJS) $(COMLIB) $(SPLIB)
@echo "****> Link $@"
ifdef NAN_BUILDINFO
- $(CCC) $(REL_CFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_REV='"$(BUILD_REV)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
+ $(CCC) $(CCFLAGS) $(REL_CCFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_REV='"$(BUILD_REV)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
endif
mkdir -p $(DIR)/$(DEBUG_DIR)bin
$(CCC) $(CCFLAGS) $(LDFLAGS) -o $(DIR)/$(DEBUG_DIR)bin/blenderdynplayer$(EXT) $(BUILDINFO_O) $(OBJS) $(SPLIB1) $(COMLIB) $(SPLIB) $(LLIBS) $(DADD) $(LOPTS)
@@ -575,7 +580,7 @@ endif
$(DIR)/$(DEBUG_DIR)bin/Blender3DPlugin$(SOEXT): $(PLUGAPPLIB_XPLINK)
@echo "****> Link $@"
ifdef NAN_BUILDINFO
- $(CCC) $(REL_CFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_REV='"$(BUILD_REV)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
+ $(CCC) $(CCFLAGS) $(REL_CCFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_REV='"$(BUILD_REV)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
endif
mkdir -p $(DIR)/$(DEBUG_DIR)bin
$(CCC) $(CCFLAGS) $(DYNLDFLAGS) -o $@ $(PLUGAPPLIB_XPLINK) $(LOPTS)
@@ -591,7 +596,7 @@ DEFFILE = ./gameengine/GamePlayer/netscape/src/npB3DPlg.def
$(DIR)/$(DEBUG_DIR)npB3DPlg$(SOEXT): $(NSPLUGLIB) $(PLUGAPPLIB) $(COMLIB) $(SPLIB)
@echo "****> Link $@"
ifdef NAN_BUILDINFO
- $(CCC) $(REL_CFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_REV='"$(BUILD_REV)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
+ $(CCC) $(CCFLAGS) $(REL_CCFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_REV='"$(BUILD_REV)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
endif
# $(CCC) $(DYNLDFLAGS) -o $@ $(NSPLUGLIB) $(PLUGAPPLIB) $(COMLIB) $(SPLIB) $(PLUGREMLIB) $(LLIBS) $(DADD) $(LOPTS)
$(CCC) $(DYNLDFLAGS) -o $@ $(NSPLUGLIB) $(PLUGAPPLIB) $(COMLIB) $(SPLIB) $(PLUGREMLIB) $(LLIBS) $(DADD) $(LOPTS) /def:$(DEFFILE)
@@ -602,7 +607,7 @@ endif
$(DIR)/$(DEBUG_DIR)bin/npBlender3DPlugin$(SOEXT): $(NSPLUGLIB) $(PLUGAPPLIB) $(COMLIB) $(SPLIB)
@echo "****> Link $@"
ifdef NAN_BUILDINFO
- $(CCC) $(REL_CFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_REV='"$(BUILD_REV)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
+ $(CCC) $(CCFLAGS) $(REL_CCFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_REV='"$(BUILD_REV)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
endif
mkdir -p $(DIR)/$(DEBUG_DIR)bin
$(CCC) $(DYNLDFLAGS) -o $@ $(NSPLUGLIB) $(PLUGAPPLIB) $(COMLIB) $(SPLIB) $(PLUGREMLIB) $(LLIBS) $(DADD) $(LOPTS)
@@ -613,7 +618,7 @@ endif
$(DIR)/$(DEBUG_DIR)bin/npTestPlugin$(SOEXT): $(NSPLUGLIB)
@echo "****> Link $@"
ifdef NAN_BUILDINFO
- $(CCC) $(REL_CFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_REV='"$(BUILD_REV)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
+ $(CCC) $(CCFLAGS) $(REL_CCFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_REV='"$(BUILD_REV)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
endif
mkdir -p $(DIR)/$(DEBUG_DIR)bin
$(CCC) $(DYNLDFLAGS) -o $@ $(NSPLUGLIB) $(PLUGTESTLIB) $(LLIBS) $(DADD) $(LOPTS)
diff --git a/source/blender/Makefile b/source/blender/Makefile
index 6bc874c3c93..1c4ff6935b9 100644
--- a/source/blender/Makefile
+++ b/source/blender/Makefile
@@ -37,13 +37,17 @@ DIRS += python nodes gpu
DIRS += blenfont ikplugin
ifeq ($(WITH_QUICKTIME), true)
- DIRS += quicktime
+ DIRS += quicktime
endif
ifeq ($(WITH_OPENJPEG), true)
CFLAGS += -DWITH_OPENJPEG -I../../../../extern/libopenjpeg
endif
+ifeq ($(WITH_OPENCOLLADA), true)
+ DIRS += collada
+endif
+
DIR = $(OCGDIR)/blender
SOURCEDIR = source/blender
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index a3a1ead3924..01f863a4c2e 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -78,6 +78,12 @@ typedef struct DMGridAdjacency {
int rotation[4];
} DMGridAdjacency;
+typedef enum DerivedMeshType {
+ DM_TYPE_CDDM,
+ DM_TYPE_EDITMESH,
+ DM_TYPE_CCGDM
+} DerivedMeshType;
+
typedef struct DerivedMesh DerivedMesh;
struct DerivedMesh {
/* Private DerivedMesh data, only for internal DerivedMesh use */
@@ -87,6 +93,7 @@ struct DerivedMesh {
int deformedOnly; /* set by modifier stack if only deformed from original */
BVHCache bvhCache;
struct GPUDrawObject *drawObject;
+ DerivedMeshType type;
/* Misc. Queries */
@@ -202,7 +209,7 @@ struct DerivedMesh {
/* Get a map of vertices to faces
*/
- struct ListBase *(*getFaceMap)(DerivedMesh *dm);
+ struct ListBase *(*getFaceMap)(struct Object *ob, DerivedMesh *dm);
/* Get the BVH used for paint modes
*/
@@ -329,12 +336,14 @@ void DM_init_funcs(DerivedMesh *dm);
* of vertices, edges and faces (doesn't allocate memory for them, just
* sets up the custom data layers)
*/
-void DM_init(DerivedMesh *dm, int numVerts, int numEdges, int numFaces);
+void DM_init(DerivedMesh *dm, DerivedMeshType type,
+ int numVerts, int numEdges, int numFaces);
/* utility function to initialise a DerivedMesh for the desired number
* of vertices, edges and faces, with a layer setup copied from source
*/
void DM_from_template(DerivedMesh *dm, DerivedMesh *source,
+ DerivedMeshType type,
int numVerts, int numEdges, int numFaces);
/* utility function to release a DerivedMesh's layers
diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h
index 32c5ff81740..4862f4e5c46 100644
--- a/source/blender/blenkernel/BKE_anim.h
+++ b/source/blender/blenkernel/BKE_anim.h
@@ -38,14 +38,34 @@ struct Object;
struct PartEff;
struct Scene;
struct ListBase;
+struct bAnimVizSettings;
+struct bMotionPath;
+struct bPoseChannel;
#include "DNA_object_types.h"
+/* ---------------------------------------------------- */
+/* Animation Visualisation */
+
+void animviz_settings_init(struct bAnimVizSettings *avs);
+
+void animviz_free_motionpath_cache(struct bMotionPath *mpath);
+void animviz_free_motionpath(struct bMotionPath *mpath);
+
+struct bMotionPath *animviz_verify_motionpaths(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan);
+void animviz_calc_motionpaths(struct Scene *scene, struct Object *ob);
+
+/* ---------------------------------------------------- */
+/* Curve Paths */
+
void free_path(struct Path *path);
void calc_curvepath(struct Object *ob);
int interval_test(int min, int max, int p1, int cycl);
int where_on_path(struct Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius);
+/* ---------------------------------------------------- */
+/* Dupli-Geometry */
+
struct ListBase *object_duplilist(struct Scene *sce, struct Object *ob);
void free_object_duplilist(struct ListBase *lb);
int count_duplilist(struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h
index f302618e60d..cf8af56a5a9 100644
--- a/source/blender/blenkernel/BKE_brush.h
+++ b/source/blender/blenkernel/BKE_brush.h
@@ -36,6 +36,7 @@ struct Brush;
struct ImBuf;
struct Scene;
struct wmOperator;
+enum CurveMappingPreset;
/* datablock functions */
struct Brush *add_brush(const char *name);
@@ -54,12 +55,7 @@ int brush_clone_image_set_nr(struct Brush *brush, int nr);
int brush_clone_image_delete(struct Brush *brush);
/* brush curve */
-typedef enum {
- BRUSH_PRESET_SHARP,
- BRUSH_PRESET_SMOOTH,
- BRUSH_PRESET_MAX
-} BrushCurvePreset;
-void brush_curve_preset(struct Brush *b, BrushCurvePreset preset);
+void brush_curve_preset(struct Brush *b, /*enum CurveMappingPreset*/int preset);
float brush_curve_strength_clamp(struct Brush *br, float p, const float len);
float brush_curve_strength(struct Brush *br, float p, const float len); /* used for sculpt */
diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h
index c571688737a..85215592ff0 100644
--- a/source/blender/blenkernel/BKE_colortools.h
+++ b/source/blender/blenkernel/BKE_colortools.h
@@ -34,6 +34,13 @@ struct CurveMap;
struct ImBuf;
struct rctf;
+typedef enum CurveMappingPreset {
+ CURVE_PRESET_LINE,
+ CURVE_PRESET_SHARP,
+ CURVE_PRESET_SMOOTH,
+ CURVE_PRESET_MAX
+} CurveMappingPreset;
+
void floatbuf_to_srgb_byte(float *rectf, unsigned char *rectc, int x1, int x2, int y1, int y2, int w);
void floatbuf_to_byte(float *rectf, unsigned char *rectc, int x1, int x2, int y1, int y2, int w);
@@ -44,7 +51,7 @@ void curvemapping_set_black_white(struct CurveMapping *cumap, float *black, f
void curvemap_remove(struct CurveMap *cuma, int flag);
void curvemap_insert(struct CurveMap *cuma, float x, float y);
-void curvemap_reset(struct CurveMap *cuma, struct rctf *clipr);
+void curvemap_reset(struct CurveMap *cuma, struct rctf *clipr, CurveMappingPreset preset);
void curvemap_sethandle(struct CurveMap *cuma, int type);
void curvemapping_changed(struct CurveMapping *cumap, int rem_doubles);
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index fa6b8969edb..d3457a5f5ae 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -31,6 +31,7 @@
struct FCurve;
struct FModifier;
struct ChannelDriver;
+struct DriverVar;
struct DriverTarget;
struct BezTriple;
@@ -40,7 +41,6 @@ struct StructRNA;
/* ************** Keyframe Tools ***************** */
-// XXX this stuff is defined in BKE_ipo.h too, so maybe skip for now?
typedef struct CfraElem {
struct CfraElem *next, *prev;
float cfra;
@@ -51,13 +51,39 @@ void bezt_add_to_cfra_elem(ListBase *lb, struct BezTriple *bezt);
/* ************** F-Curve Drivers ***************** */
+/* With these iterators for convenience, the variables "tarIndex" and "dtar" can be
+ * accessed directly from the code using them, but it is not recommended that their
+ * values be changed to point at other slots...
+ */
+
+/* convenience looper over ALL driver targets for a given variable (even the unused ones) */
+#define DRIVER_TARGETS_LOOPER(dvar) \
+ { \
+ DriverTarget *dtar= &dvar->targets[0]; \
+ int tarIndex= 0; \
+ for (; tarIndex < MAX_DRIVER_TARGETS; tarIndex++, dtar++)
+
+/* convenience looper over USED driver targets only */
+#define DRIVER_TARGETS_USED_LOOPER(dvar) \
+ { \
+ DriverTarget *dtar= &dvar->targets[0]; \
+ int tarIndex= 0; \
+ for (; tarIndex < dvar->num_targets; tarIndex++, dtar++)
+
+/* tidy up for driver targets loopers */
+#define DRIVER_TARGETS_LOOPER_END \
+ }
+
+/* ---------------------- */
+
void fcurve_free_driver(struct FCurve *fcu);
struct ChannelDriver *fcurve_copy_driver(struct ChannelDriver *driver);
-void driver_free_target(struct ChannelDriver *driver, struct DriverTarget *dtar);
-struct DriverTarget *driver_add_new_target(struct ChannelDriver *driver);
+void driver_free_variable(struct ChannelDriver *driver, struct DriverVar *dvar);
+void driver_change_variable_type(struct DriverVar *dvar, int type);
+struct DriverVar *driver_add_new_variable(struct ChannelDriver *driver);
-float driver_get_target_value(struct ChannelDriver *driver, struct DriverTarget *dtar);
+float driver_get_variable_value (struct ChannelDriver *driver, struct DriverVar *dvar);
/* ************** F-Curve Modifiers *************** */
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index 2e9ac2f65f0..9684aa1c602 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -146,6 +146,7 @@ typedef struct Global {
#define G_FILE_GLSL_NO_EXTRA_TEX (1 << 21) /* deprecated */
#define G_FILE_IGNORE_DEPRECATION_WARNINGS (1 << 22) /* deprecated */
#define G_FILE_RECOVER (1 << 23)
+#define G_FILE_RELATIVE_REMAP (1 << 24)
/* G.windowstate */
#define G_WINDOWSTATE_USERDEF 0
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h
index 9c7460851cb..7981fadccb6 100644
--- a/source/blender/blenkernel/BKE_idprop.h
+++ b/source/blender/blenkernel/BKE_idprop.h
@@ -82,6 +82,11 @@ void IDP_UnlinkID(struct IDProperty *prop);
/*-------- Group Functions -------*/
+/*
+ replaces all properties with the same name in a destination group from a source group.
+*/
+void IDP_ReplaceGroupInGroup(struct IDProperty *dest, struct IDProperty *src);
+
/*checks if a property with the same name as prop exists, and if so replaces it.
Use this to preserve order!*/
void IDP_ReplaceInGroup(struct IDProperty *group, struct IDProperty *prop);
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 85c3c716b8b..6b8d9d1768e 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -47,8 +47,8 @@ void free_image(struct Image *me);
void BKE_stamp_info(struct Scene *scene, struct ImBuf *ibuf);
void BKE_stamp_buf(struct Scene *scene, unsigned char *rect, float *rectf, int width, int height, int channels);
int BKE_write_ibuf(struct Scene *scene, struct ImBuf *ibuf, char *name, int imtype, int subimtype, int quality);
-void BKE_makepicstring(struct Scene *scene, char *string, char *base, int frame, int imtype);
-void BKE_add_image_extension(struct Scene *scene, char *string, int imtype);
+void BKE_makepicstring(char *string, char *base, int frame, int imtype, int use_ext);
+void BKE_add_image_extension(char *string, int imtype);
int BKE_ftype_to_imtype(int ftype);
int BKE_imtype_to_ftype(int imtype);
int BKE_imtype_is_movie(int imtype);
@@ -143,6 +143,9 @@ struct RenderPass *BKE_image_multilayer_index(struct RenderResult *rr, struct Im
struct RenderResult *BKE_image_acquire_renderresult(struct Scene *scene, struct Image *ima);
void BKE_image_release_renderresult(struct Scene *scene, struct Image *ima);
+/* frees all ibufs used by any image datablocks */
+void BKE_image_free_image_ibufs(void);
+
/* goes over all textures that use images */
void BKE_image_free_all_textures(void);
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 3ed9ab8778e..8da732af2dd 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -174,6 +174,7 @@ struct bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node, int inte
struct bNodeLink *nodeAddLink(struct bNodeTree *ntree, struct bNode *fromnode, struct bNodeSocket *fromsock, struct bNode *tonode, struct bNodeSocket *tosock);
void nodeRemLink(struct bNodeTree *ntree, struct bNodeLink *link);
+void nodeRemSocketLinks(struct bNodeTree *ntree, struct bNodeSocket *sock);
struct bNode *nodeFindNodebyName(struct bNodeTree *ntree, const char *name);
int nodeFindNode(struct bNodeTree *ntree, struct bNodeSocket *sock, struct bNode **nodep, int *sockindex);
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 9e70251c782..d0c2052f0d6 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -62,6 +62,8 @@ void update_base_layer(struct Scene *scene, struct Object *ob);
void free_object(struct Object *ob);
void object_free_display(struct Object *ob);
+
+void object_link_modifiers(struct Object *ob, struct Object *from);
void object_free_modifiers(struct Object *ob);
void object_make_proxy(struct Object *ob, struct Object *target, struct Object *gob);
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index 2199240d77b..32202d9d462 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -203,6 +203,7 @@ int psys_check_enabled(struct Object *ob, struct ParticleSystem *psys);
int psys_check_edited(struct ParticleSystem *psys);
void psys_check_group_weights(struct ParticleSettings *part);
+int psys_uses_gravity(struct ParticleSimulationData *sim);
/* free */
void psys_free_settings(struct ParticleSettings *part);
diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h
index 64ce1983e7d..8722485b97d 100644
--- a/source/blender/blenkernel/BKE_sound.h
+++ b/source/blender/blenkernel/BKE_sound.h
@@ -73,7 +73,7 @@ void sound_update_playing(struct bContext *C);
void sound_scrub(struct bContext *C);
#ifdef AUD_CAPI
-AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int end, float volume);
+AUD_Device* sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, int end, float volume);
#endif
void sound_stop_all(struct bContext *C);
diff --git a/source/blender/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h
index c052af775f2..77015876290 100644
--- a/source/blender/blenkernel/BKE_utildefines.h
+++ b/source/blender/blenkernel/BKE_utildefines.h
@@ -97,7 +97,9 @@
/* some math and copy defines */
+#ifndef SWAP
#define SWAP(type, a, b) { type sw_ap; sw_ap=(a); (a)=(b); (b)=sw_ap; }
+#endif
#define ABS(a) ( (a)<0 ? (-(a)) : (a) )
diff --git a/source/blender/blenkernel/BKE_writeavi.h b/source/blender/blenkernel/BKE_writeavi.h
index a8d38dda103..e2778ebb54c 100644
--- a/source/blender/blenkernel/BKE_writeavi.h
+++ b/source/blender/blenkernel/BKE_writeavi.h
@@ -40,19 +40,16 @@ struct RenderData;
struct ReportList;
struct Scene;
-int start_avi(struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports);
-void end_avi(void);
-int append_avi(struct RenderData *rd, int frame, int *pixels, int rectx, int recty, struct ReportList *reports);
-void makeavistring (struct RenderData *rd, char *string);
-
typedef struct bMovieHandle {
int (*start_movie)(struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports);
int (*append_movie)(struct RenderData *rd, int frame, int *pixels, int rectx, int recty, struct ReportList *reports);
void (*end_movie)(void);
int (*get_next_frame)(struct RenderData *rd, struct ReportList *reports); /* optional */
+ void (*get_movie_path)(char *string, struct RenderData *rd); /* optional */
} bMovieHandle;
bMovieHandle *BKE_get_movie_handle(int imtype);
+void BKE_makeanimstring(char *string, struct RenderData *rd);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/BKE_writeffmpeg.h b/source/blender/blenkernel/BKE_writeffmpeg.h
index 6ec8320f026..98c385ea2e1 100644
--- a/source/blender/blenkernel/BKE_writeffmpeg.h
+++ b/source/blender/blenkernel/BKE_writeffmpeg.h
@@ -63,6 +63,7 @@ struct Scene;
extern int start_ffmpeg(struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports);
extern void end_ffmpeg(void);
extern int append_ffmpeg(struct RenderData *rd, int frame, int *pixels, int rectx, int recty, struct ReportList *reports);
+void filepath_ffmpeg(char* string, struct RenderData* rd);
extern void ffmpeg_set_preset(struct RenderData *rd, int preset);
extern void ffmpeg_verify_image_type(struct RenderData *rd);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index a614404dc5e..3ffa32c700d 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -184,9 +184,10 @@ void DM_init_funcs(DerivedMesh *dm)
bvhcache_init(&dm->bvhCache);
}
-void DM_init(DerivedMesh *dm,
+void DM_init(DerivedMesh *dm, DerivedMeshType type,
int numVerts, int numEdges, int numFaces)
{
+ dm->type = type;
dm->numVertData = numVerts;
dm->numEdgeData = numEdges;
dm->numFaceData = numFaces;
@@ -196,7 +197,7 @@ void DM_init(DerivedMesh *dm,
dm->needsFree = 1;
}
-void DM_from_template(DerivedMesh *dm, DerivedMesh *source,
+void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type,
int numVerts, int numEdges, int numFaces)
{
CustomData_copy(&source->vertData, &dm->vertData, CD_MASK_DERIVEDMESH,
@@ -206,6 +207,7 @@ void DM_from_template(DerivedMesh *dm, DerivedMesh *source,
CustomData_copy(&source->faceData, &dm->faceData, CD_MASK_DERIVEDMESH,
CD_CALLOC, numFaces);
+ dm->type = type;
dm->numVertData = numVerts;
dm->numEdgeData = numEdges;
dm->numFaceData = numFaces;
@@ -336,16 +338,25 @@ void *DM_get_face_data(DerivedMesh *dm, int index, int type)
void *DM_get_vert_data_layer(DerivedMesh *dm, int type)
{
+ if(type == CD_MVERT)
+ return dm->getVertArray(dm);
+
return CustomData_get_layer(&dm->vertData, type);
}
void *DM_get_edge_data_layer(DerivedMesh *dm, int type)
{
+ if(type == CD_MEDGE)
+ return dm->getEdgeArray(dm);
+
return CustomData_get_layer(&dm->edgeData, type);
}
void *DM_get_face_data_layer(DerivedMesh *dm, int type)
{
+ if(type == CD_MFACE)
+ return dm->getFaceArray(dm);
+
return CustomData_get_layer(&dm->faceData, type);
}
@@ -512,56 +523,14 @@ static void emDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *us
}
glEnd();
} else {
- GPUBuffer *buffer = NULL;
- float *varray;
-
- if(GPU_buffer_legacy(dm)==FALSE)
- buffer = GPU_buffer_alloc( sizeof(float)*3*2*emdm->em->totedge, 0 );
-
- if( buffer != 0 && (varray = GPU_buffer_lock_stream( buffer )) ) {
- int prevdraw = 0;
- int numedges = 0;
- int draw = 0;
- int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_END };
- GPU_buffer_unlock( buffer );
- GPU_interleaved_setup( buffer, datatype );
- varray = GPU_buffer_lock_stream( buffer );
- for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
- if(!setDrawOptions || setDrawOptions(userData, i)) {
- draw = 1;
- } else {
- draw = 0;
- }
- if( prevdraw != draw && prevdraw != 0 && numedges > 0) {
- GPU_buffer_unlock( buffer );
- glDrawArrays(GL_LINES,0,numedges*2);
- varray = GPU_buffer_lock_stream( buffer );
- numedges = 0;
- }
- if( draw != 0 ) {
- VECCOPY(&varray[numedges*6],eed->v1->co);
- VECCOPY(&varray[numedges*6+3],eed->v2->co);
- numedges++;
- }
- prevdraw = draw;
- }
- GPU_buffer_unlock( buffer );
- if( prevdraw != 0 && numedges > 0) {
- glDrawArrays(GL_LINES,0,numedges*2);
- }
- GPU_buffer_unbind();
- } else {
- glBegin(GL_LINES);
- for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
- if(!setDrawOptions || setDrawOptions(userData, i)) {
- glVertex3fv(eed->v1->co);
- glVertex3fv(eed->v2->co);
- }
+ glBegin(GL_LINES);
+ for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
+ if(!setDrawOptions || setDrawOptions(userData, i)) {
+ glVertex3fv(eed->v1->co);
+ glVertex3fv(eed->v2->co);
}
- glEnd();
}
- if( buffer != 0 )
- GPU_buffer_free( buffer, 0 );
+ glEnd();
}
}
static void emDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
@@ -722,135 +691,41 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
}
}
} else {
- GPUBuffer *buffer = 0;
- float *varray;
- if( setDrawOptions == 0 ) {
- /* 3 floats for position, 3 for normal and times two because the faces may actually be quads instead of triangles */
- buffer = GPU_buffer_alloc( sizeof(float)*6*emdm->em->totface*3*2, 0 );
- }
- if( buffer != 0 && (varray = GPU_buffer_lock_stream( buffer )) ) {
- int prevdraw = 0;
- int numfaces = 0;
- int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_N3F, GPU_BUFFER_INTER_END };
- GPU_buffer_unlock( buffer );
- GPU_interleaved_setup( buffer, datatype );
- glShadeModel(GL_SMOOTH);
- varray = GPU_buffer_lock_stream( buffer );
- for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
- int drawSmooth = (efa->flag & ME_SMOOTH);
- draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
- if( prevdraw != draw && prevdraw != 0 && numfaces > 0) {
- if( prevdraw==2 ) {
- glEnable(GL_POLYGON_STIPPLE);
- glPolygonStipple(stipple_quarttone);
- }
- GPU_buffer_unlock( buffer );
- glDrawArrays(GL_TRIANGLES,0,numfaces*3);
- if( prevdraw==2 ) {
- glDisable(GL_POLYGON_STIPPLE);
- }
- varray = GPU_buffer_lock_stream( buffer );
- numfaces = 0;
- }
- if( draw != 0 ) {
- if(!drawSmooth) {
- VECCOPY(&varray[numfaces*18],efa->v1->co);
- VECCOPY(&varray[numfaces*18+3],efa->n);
-
- VECCOPY(&varray[numfaces*18+6],efa->v2->co);
- VECCOPY(&varray[numfaces*18+9],efa->n);
-
- VECCOPY(&varray[numfaces*18+12],efa->v3->co);
- VECCOPY(&varray[numfaces*18+15],efa->n);
- numfaces++;
- if( efa->v4 ) {
- VECCOPY(&varray[numfaces*18],efa->v3->co);
- VECCOPY(&varray[numfaces*18+3],efa->n);
-
- VECCOPY(&varray[numfaces*18+6],efa->v4->co);
- VECCOPY(&varray[numfaces*18+9],efa->n);
-
- VECCOPY(&varray[numfaces*18+12],efa->v1->co);
- VECCOPY(&varray[numfaces*18+15],efa->n);
- numfaces++;
- }
- }
- else {
- VECCOPY(&varray[numfaces*18],efa->v1->co);
- VECCOPY(&varray[numfaces*18+3],efa->v1->no);
-
- VECCOPY(&varray[numfaces*18+6],efa->v2->co);
- VECCOPY(&varray[numfaces*18+9],efa->v2->no);
-
- VECCOPY(&varray[numfaces*18+12],efa->v3->co);
- VECCOPY(&varray[numfaces*18+15],efa->v3->no);
- numfaces++;
- if( efa->v4 ) {
- VECCOPY(&varray[numfaces*18],efa->v3->co);
- VECCOPY(&varray[numfaces*18+3],efa->v3->no);
-
- VECCOPY(&varray[numfaces*18+6],efa->v4->co);
- VECCOPY(&varray[numfaces*18+9],efa->v4->no);
-
- VECCOPY(&varray[numfaces*18+12],efa->v1->co);
- VECCOPY(&varray[numfaces*18+15],efa->v1->no);
- numfaces++;
- }
- }
- }
- prevdraw = draw;
- }
- GPU_buffer_unlock( buffer );
- if( prevdraw != 0 && numfaces > 0) {
- if( prevdraw==2 ) {
+ for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
+ int drawSmooth = (efa->flag & ME_SMOOTH);
+ draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
+ if(draw) {
+ if (draw==2) { /* enabled with stipple */
glEnable(GL_POLYGON_STIPPLE);
- glPolygonStipple(stipple_quarttone);
- }
- glDrawArrays(GL_TRIANGLES,0,numfaces*3);
- if( prevdraw==2 ) {
- glDisable(GL_POLYGON_STIPPLE);
+ glPolygonStipple(stipple_quarttone);
}
- }
- GPU_buffer_unbind();
- } else {
- for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
- int drawSmooth = (efa->flag & ME_SMOOTH);
- draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
- if(draw) {
- if (draw==2) { /* enabled with stipple */
- glEnable(GL_POLYGON_STIPPLE);
- glPolygonStipple(stipple_quarttone);
- }
- glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
+ glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
- glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
- if (!drawSmooth) {
- glNormal3fv(efa->n);
- glVertex3fv(efa->v1->co);
- glVertex3fv(efa->v2->co);
- glVertex3fv(efa->v3->co);
- if(efa->v4) glVertex3fv(efa->v4->co);
- } else {
- glNormal3fv(efa->v1->no);
- glVertex3fv(efa->v1->co);
- glNormal3fv(efa->v2->no);
- glVertex3fv(efa->v2->co);
- glNormal3fv(efa->v3->no);
- glVertex3fv(efa->v3->co);
- if(efa->v4) {
- glNormal3fv(efa->v4->no);
- glVertex3fv(efa->v4->co);
- }
+ glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
+ if (!drawSmooth) {
+ glNormal3fv(efa->n);
+ glVertex3fv(efa->v1->co);
+ glVertex3fv(efa->v2->co);
+ glVertex3fv(efa->v3->co);
+ if(efa->v4) glVertex3fv(efa->v4->co);
+ } else {
+ glNormal3fv(efa->v1->no);
+ glVertex3fv(efa->v1->co);
+ glNormal3fv(efa->v2->no);
+ glVertex3fv(efa->v2->co);
+ glNormal3fv(efa->v3->no);
+ glVertex3fv(efa->v3->co);
+ if(efa->v4) {
+ glNormal3fv(efa->v4->no);
+ glVertex3fv(efa->v4->co);
}
- glEnd();
-
- if (draw==2)
- glDisable(GL_POLYGON_STIPPLE);
}
+ glEnd();
+
+ if (draw==2)
+ glDisable(GL_POLYGON_STIPPLE);
}
}
- if( buffer != 0 )
- GPU_buffer_free( buffer, 0 );
}
}
@@ -1450,7 +1325,7 @@ static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, Object *ob,
{
EditMeshDerivedMesh *emdm = MEM_callocN(sizeof(*emdm), "emdm");
- DM_init(&emdm->dm, BLI_countlist(&em->verts),
+ DM_init(&emdm->dm, DM_TYPE_EDITMESH, BLI_countlist(&em->verts),
BLI_countlist(&em->edges), BLI_countlist(&em->faces));
emdm->dm.getMinMax = emDM_getMinMax;
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 9e89ae77caa..a95cc7d1816 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -382,12 +382,12 @@ bPoseChannel *get_pose_channel(const bPose *pose, const char *name)
if (ELEM(NULL, pose, name) || (name[0] == 0))
return NULL;
- return BLI_findstring(&pose->chanbase, name, offsetof(bPoseChannel, name));
+ return BLI_findstring(&((bPose *)pose)->chanbase, name, offsetof(bPoseChannel, name));
}
/* Use with care, not on Armature poses but for temporal ones */
/* (currently used for action constraints and in rebuild_pose) */
-bPoseChannel *verify_pose_channel(bPose* pose, const char* name)
+bPoseChannel *verify_pose_channel(bPose *pose, const char *name)
{
bPoseChannel *chan;
@@ -455,10 +455,10 @@ const char *get_ikparam_name(bPose *pose)
void copy_pose (bPose **dst, bPose *src, int copycon)
{
bPose *outPose;
- bPoseChannel *pchan;
+ bPoseChannel *pchan;
ListBase listb;
- if (!src){
+ if (!src) {
*dst=NULL;
return;
}
@@ -482,7 +482,8 @@ void copy_pose (bPose **dst, bPose *src, int copycon)
if (copycon) {
copy_constraints(&listb, &pchan->constraints); // copy_constraints NULLs listb
pchan->constraints= listb;
- pchan->path= NULL;
+ pchan->path= NULL; // XXX remove this line when the new motionpaths are ready... (depreceated code)
+ pchan->mpath= NULL; /* motion paths should not get copied yet... */
}
if(pchan->prop) {
@@ -491,7 +492,7 @@ void copy_pose (bPose **dst, bPose *src, int copycon)
}
/* for now, duplicate Bone Groups too when doing this */
- if(copycon)
+ if (copycon)
BLI_duplicatelist(&outPose->agroups, &src->agroups);
*dst=outPose;
@@ -532,12 +533,20 @@ void init_pose_ikparam(bPose *pose)
void free_pose_channel(bPoseChannel *pchan)
{
- if (pchan->path)
+ // XXX this case here will need to be removed when the new motionpaths are ready
+ if (pchan->path) {
MEM_freeN(pchan->path);
-
+ pchan->path= NULL;
+ }
+
+ if (pchan->mpath) {
+ animviz_free_motionpath(pchan->mpath);
+ pchan->mpath= NULL;
+ }
+
free_constraints(&pchan->constraints);
-
- if(pchan->prop) {
+
+ if (pchan->prop) {
IDP_FreeProperty(pchan->prop);
MEM_freeN(pchan->prop);
}
@@ -550,7 +559,7 @@ void free_pose_channels(bPose *pose)
if (pose->chanbase.first) {
for (pchan = pose->chanbase.first; pchan; pchan=pchan->next)
free_pose_channel(pchan);
-
+
BLI_freelistN(&pose->chanbase);
}
}
@@ -564,14 +573,14 @@ void free_pose(bPose *pose)
/* free pose-groups */
if (pose->agroups.first)
BLI_freelistN(&pose->agroups);
-
+
/* free IK solver state */
BIK_clear_data(pose);
-
+
/* free IK solver param */
if (pose->ikparam)
MEM_freeN(pose->ikparam);
-
+
/* free pose */
MEM_freeN(pose);
}
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 6b8b604cb94..507fc520a85 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -29,16 +29,22 @@
* ***** END GPL LICENSE BLOCK *****
*/
+#include <stdio.h>
#include <math.h>
#include <string.h>
#include "MEM_guardedalloc.h"
+
#include "BLI_blenlib.h"
#include "BLI_editVert.h"
#include "BLI_math.h"
#include "BLI_rand.h"
+
#include "DNA_listBase.h"
+#include "DNA_anim_types.h"
+#include "DNA_action_types.h"
+#include "DNA_armature_types.h"
#include "DNA_curve_types.h"
#include "DNA_effect_types.h"
#include "DNA_group_types.h"
@@ -53,6 +59,7 @@
#include "DNA_vfont_types.h"
#include "BKE_anim.h"
+#include "BKE_animsys.h"
#include "BKE_curve.h"
#include "BKE_DerivedMesh.h"
#include "BKE_displist.h"
@@ -60,30 +67,313 @@
#include "BKE_font.h"
#include "BKE_group.h"
#include "BKE_global.h"
-#include "BKE_ipo.h"
#include "BKE_key.h"
#include "BKE_lattice.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_particle.h"
+#include "BKE_scene.h"
#include "BKE_utildefines.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+// XXX bad level call...
#include "ED_mesh.h"
+/* --------------------- */
+/* forward declarations */
+
static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level, int animated);
+/* ******************************************************************** */
+/* Animation Visualisation */
+
+/* Initialise the default settings for animation visualisation */
+void animviz_settings_init(bAnimVizSettings *avs)
+{
+ /* sanity check */
+ if (avs == NULL)
+ return;
+
+ /* ghosting settings */
+ avs->ghost_bc= avs->ghost_ac= 10;
+
+ avs->ghost_sf= 1; // xxx - take from scene instead?
+ avs->ghost_ef= 250; // xxx - take from scene instead?
+
+ avs->ghost_step= 1;
+
+
+ /* path settings */
+ avs->path_bc= avs->path_ac= 10;
+
+ avs->path_sf= 1; // xxx - take from scene instead?
+ avs->path_ef= 250; // xxx - take from scene instead?
+
+ avs->path_viewflag= (MOTIONPATH_VIEW_KFRAS|MOTIONPATH_VIEW_KFNOS);
+
+ avs->path_step= 1;
+}
+
+/* ------------------- */
+
+/* Free the given motion path's cache */
+void animviz_free_motionpath_cache(bMotionPath *mpath)
+{
+ /* sanity check */
+ if (mpath == NULL)
+ return;
+
+ /* free the path if necessary */
+ if (mpath->points)
+ MEM_freeN(mpath->points);
+
+ /* reset the relevant parameters */
+ mpath->points= NULL;
+ mpath->length= 0;
+}
+
+/* Free the given motion path instance and its data
+ * NOTE: this frees the motion path given!
+ */
+void animviz_free_motionpath(bMotionPath *mpath)
+{
+ /* sanity check */
+ if (mpath == NULL)
+ return;
+
+ /* free the cache first */
+ animviz_free_motionpath_cache(mpath);
+
+ /* now the instance itself */
+ MEM_freeN(mpath);
+}
+
+/* ------------------- */
+
+/* Setup motion paths for the given data
+ * - scene: current scene (for frame ranges, etc.)
+ * - ob: object to add paths for (must be provided)
+ * - pchan: posechannel to add paths for (optional; if not provided, object-paths are assumed)
+ */
+bMotionPath *animviz_verify_motionpaths(Scene *scene, Object *ob, bPoseChannel *pchan)
+{
+ bAnimVizSettings *avs;
+ bMotionPath *mpath, **dst;
+
+ /* sanity checks */
+ if (ELEM(NULL, scene, ob))
+ return NULL;
+
+ /* get destination data */
+ if (pchan) {
+ /* paths for posechannel - assume that posechannel belongs to the object */
+ avs= &ob->pose->avs;
+ dst= &pchan->mpath;
+ }
+ else {
+ /* paths for object */
+ avs= &ob->avs;
+ dst= &ob->mpath;
+ }
+
+ /* if there is already a motionpath, just return that,
+ * but provided it's settings are ok
+ */
+ if (*dst != NULL) {
+ mpath= *dst;
+
+ /* if range is not invalid, and/or length is set ok, just return */
+ if ((mpath->start_frame != mpath->end_frame) && (mpath->length > 0))
+ return mpath;
+ }
+ else {
+ /* create a new motionpath, and assign it */
+ mpath= MEM_callocN(sizeof(bMotionPath), "bMotionPath");
+ *dst= mpath;
+ }
+
+ /* set settings from the viz settings */
+ mpath->start_frame= avs->path_sf;
+ mpath->end_frame= avs->path_ef;
+
+ mpath->length= mpath->end_frame - mpath->start_frame;
+
+ if (avs->path_bakeflag & MOTIONPATH_BAKE_HEADS)
+ mpath->flag |= MOTIONPATH_FLAG_BHEAD;
+
+ /* allocate a cache */
+ mpath->points= MEM_callocN(sizeof(bMotionPathVert)*mpath->length, "bMotionPathVerts");
+
+ /* return it */
+ return mpath;
+}
+
+/* ------------------- */
+
+/* Motion path needing to be baked (mpt) */
+typedef struct MPathTarget {
+ struct MPathTarget *next, *prev;
+
+ bMotionPath *mpath; /* motion path in question */
+
+ Object *ob; /* source object */
+ bPoseChannel *pchan; /* source posechannel (if applicable) */
+} MPathTarget;
+
+/* ........ */
+
+/* get list of motion paths to be baked (assumes the list is ready to be used) */
+static void motionpaths_get_bake_targets(Object *ob, ListBase *targets)
+{
+ MPathTarget *mpt;
+
+ /* object itself first */
+ if ((ob->avs.recalc & ANIMVIZ_RECALC_PATHS) && (ob->mpath)) {
+ /* new target for object */
+ mpt= MEM_callocN(sizeof(MPathTarget), "MPathTarget Ob");
+ BLI_addtail(targets, mpt);
+
+ mpt->mpath= ob->mpath;
+ mpt->ob= ob;
+ }
+
+ /* bones */
+ if ((ob->pose) && (ob->pose->avs.recalc & ANIMVIZ_RECALC_PATHS)) {
+ bArmature *arm= ob->data;
+ bPoseChannel *pchan;
+
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ if ((pchan->bone) && (arm->layer & pchan->bone->layer) && (pchan->mpath)) {
+ /* new target for bone */
+ mpt= MEM_callocN(sizeof(MPathTarget), "MPathTarget PoseBone");
+ BLI_addtail(targets, mpt);
+
+ mpt->mpath= pchan->mpath;
+ mpt->ob= ob;
+ mpt->pchan= pchan;
+ }
+ }
+ }
+}
+
+/* perform baking for the targets on the current frame */
+static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets)
+{
+ MPathTarget *mpt;
+
+ /* for each target, check if it can be baked on the current frame */
+ for (mpt= targets->first; mpt; mpt= mpt->next) {
+ bMotionPath *mpath= mpt->mpath;
+ bMotionPathVert *mpv;
+
+ /* current frame must be within the range the cache works for */
+ if (IN_RANGE(CFRA, mpath->start_frame, mpath->end_frame) == 0)
+ continue;
+
+ /* get the relevant cache vert to write to */
+ mpv= mpath->points + (CFRA - mpath->start_frame);
+
+ /* pose-channel or object path baking? */
+ if (mpt->pchan) {
+ /* heads or tails */
+ if (mpath->flag & MOTIONPATH_FLAG_BHEAD) {
+ VECCOPY(mpv->co, mpt->pchan->pose_head);
+ }
+ else {
+ VECCOPY(mpv->co, mpt->pchan->pose_tail);
+ }
+
+ /* result must be in worldspace */
+ mul_m4_v3(mpt->ob->obmat, mpv->co);
+ }
+ else {
+ /* worldspace object location */
+ VECCOPY(mpv->co, mpt->ob->obmat[3]);
+ }
+ }
+}
+
+/* ........ */
+
+/* Perform baking of the given object's and/or its bones' transforms to motion paths
+ * - scene: current scene
+ * - ob: object whose flagged motionpaths should get calculated
+ * - recalc: whether we need to
+ */
+// TODO: include reports pointer?
+void animviz_calc_motionpaths(Scene *scene, Object *ob)
+{
+ ListBase targets = {NULL, NULL};
+ MPathTarget *mpt;
+ int sfra, efra;
+ int cfra;
+
+ /* sanity checks */
+ if (ob == NULL)
+ return;
+
+ /* get motion paths to affect */
+ motionpaths_get_bake_targets(ob, &targets);
+
+ if (targets.first == NULL)
+ return;
+
+ /* set frame values */
+ cfra = CFRA;
+ sfra = efra = cfra;
+
+ for (mpt= targets.first; mpt; mpt= mpt->next) {
+ /* try to increase area to do (only as much as needed) */
+ sfra= MIN2(sfra, mpt->mpath->start_frame);
+ efra= MAX2(efra, mpt->mpath->end_frame);
+ }
+ if (efra <= sfra) return;
+
+ /* calculate path over requested range */
+ for (CFRA=sfra; CFRA<=efra; CFRA++) {
+ /* do all updates
+ * - if this is too slow, resort to using a more efficient way
+ * that doesn't force complete update, but for now, this is the
+ * most accurate way!
+ */
+ scene_update_for_newframe(scene, ob->lay); // XXX is the layer flag too restrictive?
+
+ /* perform baking for targets */
+ motionpaths_calc_bake_targets(scene, &targets);
+ }
+
+ /* reset original environment */
+ CFRA= cfra;
+ scene_update_for_newframe(scene, ob->lay); // XXX is the layer flag too restrictive?
+
+ // TODO: make an API call for this too?
+ ob->avs.recalc &= ~ANIMVIZ_RECALC_PATHS;
+ if (ob->pose)
+ ob->pose->avs.recalc &= ~ANIMVIZ_RECALC_PATHS;
+
+ /* free temp data */
+ BLI_freelistN(&targets);
+}
+
+/* ******************************************************************** */
+/* Curve Paths - for curve deforms and/or curve following */
+
+/* free curve path data
+ * NOTE: frees the path itself!
+ */
void free_path(Path *path)
{
if(path->data) MEM_freeN(path->data);
MEM_freeN(path);
}
-
+/* calculate a curve-deform path for a curve
+ * - only called from displist.c -> makeDispListCurveTypes
+ */
void calc_curvepath(Object *ob)
{
BevList *bl;
@@ -96,7 +386,6 @@ void calc_curvepath(Object *ob)
float fac, d=0, fac1, fac2;
int a, tot, cycl=0;
-
/* in a path vertices are with equal differences: path->len = number of verts */
/* NOW WITH BEVELCURVE!!! */
@@ -143,7 +432,7 @@ void calc_curvepath(Object *ob)
}
path->totdist= *fp;
-
+
/* the path verts in path->data */
/* now also with TILT value */
pp= path->data = (PathPoint *)MEM_callocN(sizeof(PathPoint)*4*path->len, "pathdata"); // XXX - why *4? - in 2.4x each element was 4 and the size was 16, so better leave for now - Campbell
@@ -155,7 +444,7 @@ void calc_curvepath(Object *ob)
maxdist= dist+tot;
fac= 1.0f/((float)path->len-1.0f);
fac = fac * path->totdist;
-
+
for(a=0; a<path->len; a++) {
d= ((float)a)*fac;
@@ -175,7 +464,7 @@ void calc_curvepath(Object *ob)
fac2= *(fp)-d;
fac1= fac2/fac1;
fac2= 1.0f-fac1;
-
+
interp_v3_v3v3(pp->vec, bevp->vec, bevpn->vec, fac2);
pp->vec[3]= fac1*bevp->alfa + fac2*bevpn->alfa;
pp->radius= fac1*bevp->radius + fac2*bevpn->radius;
@@ -188,11 +477,12 @@ void calc_curvepath(Object *ob)
MEM_freeN(dist);
}
+
+/* is this only used internally?*/
int interval_test(int min, int max, int p1, int cycl)
{
-
if(cycl) {
- if( p1 < min)
+ if(p1 < min)
p1= ((p1 -min) % (max-min+1)) + max+1;
else if(p1 > max)
p1= ((p1 -min) % (max-min+1)) + min;
@@ -204,8 +494,11 @@ int interval_test(int min, int max, int p1, int cycl)
return p1;
}
-/* warning, *vec needs FOUR items! */
-/* ctime is normalized range <0-1> */
+
+/* calculate the deformation implied by the curve path at a given parametric position, and returns whether this operation succeeded
+ * - *vec needs FOUR items!
+ * - ctime is normalized range <0-1>
+ */
int where_on_path(Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius) /* returns OK */
{
Curve *cu;
@@ -305,7 +598,8 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir, float *quat,
return 1;
}
-/* ****************** DUPLICATOR ************** */
+/* ******************************************************************** */
+/* Dupli-Geometry */
static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int type, int animated)
{
@@ -407,7 +701,7 @@ static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int level,
enable_cu_speed= 1;
}
-struct vertexDupliData {
+typedef struct vertexDupliData {
ID *id; /* scene or group, for recursive loops */
int level;
int animated;
@@ -417,12 +711,14 @@ struct vertexDupliData {
Scene *scene;
Object *ob, *par;
float (*orco)[3];
-};
+} vertexDupliData;
+
+/* ------------- */
static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
{
DupliObject *dob;
- struct vertexDupliData *vdd= userData;
+ vertexDupliData *vdd= userData;
float vec[3], q2[4], mat[3][3], tmat[4][4], obmat[4][4];
VECCOPY(vec, co);
@@ -466,7 +762,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl
Mesh *me= par->data;
Base *base = NULL;
DerivedMesh *dm;
- struct vertexDupliData vdd;
+ vertexDupliData vdd;
Scene *sce = NULL;
Group *group = NULL;
GroupObject * go = NULL;
@@ -1070,7 +1366,8 @@ static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int level, i
MEM_freeN(chartransdata);
}
-/* ***************************** */
+/* ------------- */
+
static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level, int animated)
{
if((ob->transflag & OB_DUPLI)==0)
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 4f96b031daa..8b86f6a5d1f 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -319,16 +319,32 @@ static void fcurves_path_rename_fix (ID *owner_id, char *prefix, char *oldName,
/* we need to check every curve... */
for (fcu= curves->first; fcu; fcu= fcu->next) {
/* firstly, handle the F-Curve's own path */
- fcu->rna_path= rna_path_rename_fix(owner_id, prefix, oldName, newName, fcu->rna_path);
+ if (fcu->rna_path)
+ fcu->rna_path= rna_path_rename_fix(owner_id, prefix, oldName, newName, fcu->rna_path);
/* driver? */
if (fcu->driver) {
ChannelDriver *driver= fcu->driver;
- DriverTarget *dtar;
+ DriverVar *dvar;
- /* driver targets */
- for (dtar= driver->targets.first; dtar; dtar=dtar->next) {
- dtar->rna_path= rna_path_rename_fix(dtar->id, prefix, oldName, newName, dtar->rna_path);
+ /* driver variables */
+ for (dvar= driver->variables.first; dvar; dvar=dvar->next) {
+ /* only change the used targets, since the others will need fixing manually anyway */
+ DRIVER_TARGETS_USED_LOOPER(dvar)
+ {
+ /* rename RNA path */
+ if (dtar->rna_path)
+ dtar->rna_path= rna_path_rename_fix(dtar->id, prefix, oldName, newName, dtar->rna_path);
+
+ /* also fix the bone-name (if applicable) */
+ // XXX this has been disabled because the old/new names have padding which means this check will fail
+ //if ( ((dtar->id) && (GS(dtar->id->name) == ID_OB)) &&
+ // (dtar->pchan_name[0]) && (strcmp(oldName, dtar->pchan_name)==0) )
+ //{
+ // BLI_strncpy(dtar->pchan_name, newName, sizeof(dtar->pchan_name));
+ //}
+ }
+ DRIVER_TARGETS_LOOPER_END
}
}
}
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index e53e4a1155b..9ae871b1dea 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -1480,8 +1480,23 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
bPose *pose= ob->pose, *frompose= from->pose;
bPoseChannel *pchan, *pchanp, pchanw;
bConstraint *con;
+ int error = 0;
if (frompose==NULL) return;
+
+ /* in some cases when rigs change, we cant synchronize
+ * to avoid crashing check for possible errors here */
+ for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
+ if (pchan->bone->layer & layer_protected) {
+ if(get_pose_channel(frompose, pchan->name) == NULL) {
+ printf("failed to sync proxy armature because '%s' is missing pose channel '%s'\n", from->id.name, pchan->name);
+ error = 1;
+ }
+ }
+ }
+
+ if(error)
+ return;
/* exception, armature local layer should be proxied too */
if (pose->proxy_layer)
diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c
index 389009cca76..838e595d83f 100644
--- a/source/blender/blenkernel/intern/boids.c
+++ b/source/blender/blenkernel/intern/boids.c
@@ -557,8 +557,8 @@ static int rule_average_speed(BoidRule *rule, BoidBrainData *bbd, BoidValues *va
add_v3_v3v3(bbd->wanted_co, bbd->wanted_co, vec);
/* leveling */
- if(asbr->level > 0.0f) {
- project_v3_v3v3(vec, bbd->wanted_co, bbd->sim->psys->part->acc);
+ if(asbr->level > 0.0f && psys_uses_gravity(bbd->sim)) {
+ project_v3_v3v3(vec, bbd->wanted_co, bbd->sim->scene->physics_settings.gravity);
mul_v3_fl(vec, asbr->level);
sub_v3_v3v3(bbd->wanted_co, bbd->wanted_co, vec);
}
@@ -574,8 +574,8 @@ static int rule_average_speed(BoidRule *rule, BoidBrainData *bbd, BoidValues *va
}
/* leveling */
- if(asbr->level > 0.0f) {
- project_v3_v3v3(vec, bbd->wanted_co, bbd->sim->psys->part->acc);
+ if(asbr->level > 0.0f && psys_uses_gravity(bbd->sim)) {
+ project_v3_v3v3(vec, bbd->wanted_co, bbd->sim->scene->physics_settings.gravity);
mul_v3_fl(vec, asbr->level);
sub_v3_v3v3(bbd->wanted_co, bbd->wanted_co, vec);
}
@@ -1002,8 +1002,8 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
if(dot_v2v2(cvel, dir) > 0.95f / mul || len <= state->rule_fuzziness) {
/* try to reach goal at highest point of the parabolic path */
cur_v = len_v2(pa->prev_state.vel);
- z_v = sasqrt(-2.0f * bbd->part->acc[2] * bbd->wanted_co[2]);
- ground_v = len_v2(bbd->wanted_co)*sasqrt(-0.5f * bbd->part->acc[2] / bbd->wanted_co[2]);
+ z_v = sasqrt(-2.0f * bbd->sim->scene->physics_settings.gravity[2] * bbd->wanted_co[2]);
+ ground_v = len_v2(bbd->wanted_co)*sasqrt(-0.5f * bbd->sim->scene->physics_settings.gravity[2] / bbd->wanted_co[2]);
len = sasqrt((ground_v-cur_v)*(ground_v-cur_v) + z_v*z_v);
@@ -1061,12 +1061,12 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
pa_mass*=pa->size;
/* if boids can't fly they fall to the ground */
- if((boids->options & BOID_ALLOW_FLIGHT)==0 && ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)==0 && bbd->part->acc[2] != 0.0f)
+ if((boids->options & BOID_ALLOW_FLIGHT)==0 && ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)==0 && psys_uses_gravity(bbd->sim))
bpa->data.mode = eBoidMode_Falling;
if(bpa->data.mode == eBoidMode_Falling) {
/* Falling boids are only effected by gravity. */
- acc[2] = bbd->part->acc[2];
+ acc[2] = bbd->sim->scene->physics_settings.gravity[2];
}
else {
/* figure out acceleration */
@@ -1221,7 +1221,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
switch(bpa->data.mode) {
case eBoidMode_InAir:
{
- float grav[3] = {0.0f, 0.0f, bbd->part->acc[2] < 0.0f ? -1.0f : 0.0f};
+ float grav[3] = {0.0f, 0.0f, bbd->sim->scene->physics_settings.gravity[2] < 0.0f ? -1.0f : 0.0f};
/* don't take forward acceleration into account (better banking) */
if(dot_v3v3(bpa->data.acc, pa->state.vel) > 0.0f) {
@@ -1253,7 +1253,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
}
case eBoidMode_Falling:
{
- float grav[3] = {0.0f, 0.0f, bbd->part->acc[2] < 0.0f ? -1.0f : 0.0f};
+ float grav[3] = {0.0f, 0.0f, bbd->sim->scene->physics_settings.gravity[2] < 0.0f ? -1.0f : 0.0f};
/* gather apparent gravity */
VECADDFAC(bpa->gravity, bpa->gravity, grav, dtime);
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 667b0d50ee9..99cd6975665 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -88,7 +88,7 @@ Brush *add_brush(const char *name)
brush->sculpt_tool = SCULPT_TOOL_DRAW;
brush->flag |= BRUSH_SPACE;
- brush_curve_preset(brush, BRUSH_PRESET_SMOOTH);
+ brush_curve_preset(brush, CURVE_PRESET_SMOOTH);
/* enable fake user by default */
brush->id.flag |= LIB_FAKEUSER;
@@ -100,19 +100,11 @@ Brush *add_brush(const char *name)
Brush *copy_brush(Brush *brush)
{
Brush *brushn;
- MTex *mtex;
- int a;
brushn= copy_libblock(brush);
- for(a=0; a<MAX_MTEX; a++) {
- mtex= brush->mtex[a];
- if(mtex) {
- brushn->mtex[a]= MEM_dupallocN(mtex);
- if(mtex->tex) id_us_plus((ID*)mtex->tex);
- }
- }
-
+ if(brush->mtex.tex) id_us_plus((ID*)brush->mtex.tex);
+
brushn->curve= curvemapping_copy(brush->curve);
/* enable fake user by default */
@@ -127,17 +119,8 @@ Brush *copy_brush(Brush *brush)
/* not brush itself */
void free_brush(Brush *brush)
{
- MTex *mtex;
- int a;
-
- for(a=0; a<MAX_MTEX; a++) {
- mtex= brush->mtex[a];
- if(mtex) {
- if(mtex->tex) mtex->tex->id.us--;
- MEM_freeN(mtex);
- }
- }
-
+ if(brush->mtex.tex) brush->mtex.tex->id.us--;
+
curvemapping_free(brush->curve);
}
@@ -242,7 +225,7 @@ void brush_toggled_fake_user(Brush *brush)
}
}
-void brush_curve_preset(Brush *b, BrushCurvePreset preset)
+void brush_curve_preset(Brush *b, /*CurveMappingPreset*/int preset)
{
CurveMap *cm = NULL;
@@ -250,53 +233,16 @@ void brush_curve_preset(Brush *b, BrushCurvePreset preset)
b->curve = curvemapping_add(1, 0, 0, 1, 1);
cm = b->curve->cm;
-
- if(cm->curve)
- MEM_freeN(cm->curve);
-
- if(preset == BRUSH_PRESET_SHARP)
- cm->totpoint= 3;
- if(preset == BRUSH_PRESET_SMOOTH)
- cm->totpoint= 4;
- if(preset == BRUSH_PRESET_MAX)
- cm->totpoint= 2;
-
-
- cm->curve= MEM_callocN(cm->totpoint*sizeof(CurveMapPoint), "curve points");
cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
- if(preset == BRUSH_PRESET_SHARP) {
- cm->curve[0].x= 0;
- cm->curve[0].y= 1;
- cm->curve[1].x= 0.33;
- cm->curve[1].y= 0.33;
- cm->curve[2].x= 1;
- cm->curve[2].y= 0;
- }
- else if(preset == BRUSH_PRESET_SMOOTH) {
- cm->curve[0].x= 0;
- cm->curve[0].y= 1;
- cm->curve[1].x= 0.25;
- cm->curve[1].y= 0.92;
- cm->curve[2].x= 0.75;
- cm->curve[2].y= 0.08;
- cm->curve[3].x= 1;
- cm->curve[3].y= 0;
- }
- else if(preset == BRUSH_PRESET_MAX) {
- cm->curve[0].x= 0;
- cm->curve[0].y= 1;
- cm->curve[1].x= 1;
- cm->curve[1].y= 1;
- }
-
+ curvemap_reset(cm, &b->curve->clipr, preset);
curvemapping_changed(b->curve, 0);
}
static MTex *brush_active_texture(Brush *brush)
{
- if(brush && brush->texact >= 0)
- return brush->mtex[brush->texact];
+ if(brush)
+ return &brush->mtex;
return NULL;
}
@@ -304,8 +250,7 @@ int brush_texture_set_nr(Brush *brush, int nr)
{
ID *idtest, *id=NULL;
- if(brush->mtex[brush->texact])
- id= (ID *)brush->mtex[brush->texact]->tex;
+ id= (ID *)brush->mtex.tex;
idtest= (ID*)BLI_findlink(&G.main->tex, nr-1);
if(idtest==0) { /* new tex */
@@ -316,13 +261,7 @@ int brush_texture_set_nr(Brush *brush, int nr)
if(idtest!=id) {
brush_texture_delete(brush);
- if(brush->mtex[brush->texact]==NULL) {
- brush->mtex[brush->texact]= add_mtex();
- brush->mtex[brush->texact]->r = 1.0f;
- brush->mtex[brush->texact]->g = 1.0f;
- brush->mtex[brush->texact]->b = 1.0f;
- }
- brush->mtex[brush->texact]->tex= (Tex*)idtest;
+ brush->mtex.tex= (Tex*)idtest;
id_us_plus(idtest);
return 1;
@@ -333,16 +272,10 @@ int brush_texture_set_nr(Brush *brush, int nr)
int brush_texture_delete(Brush *brush)
{
- if(brush->mtex[brush->texact]) {
- if(brush->mtex[brush->texact]->tex)
- brush->mtex[brush->texact]->tex->id.us--;
- MEM_freeN(brush->mtex[brush->texact]);
- brush->mtex[brush->texact]= NULL;
+ if(brush->mtex.tex)
+ brush->mtex.tex->id.us--;
- return 1;
- }
-
- return 0;
+ return 1;
}
int brush_clone_image_set_nr(Brush *brush, int nr)
@@ -383,7 +316,7 @@ void brush_check_exists(Brush **brush, const char *name)
/* Brush Sampling */
void brush_sample_tex(Brush *brush, float *xy, float *rgba)
{
- MTex *mtex= brush->mtex[brush->texact];
+ MTex *mtex= &brush->mtex;
if (mtex && mtex->tex) {
float co[3], tin, tr, tg, tb, ta;
@@ -741,7 +674,7 @@ static void brush_painter_refresh_cache(BrushPainter *painter, float *pos)
{
Brush *brush= painter->brush;
BrushPainterCache *cache= &painter->cache;
- MTex *mtex= brush->mtex[brush->texact];
+ MTex *mtex= &brush->mtex;
int size;
short flt;
@@ -976,7 +909,7 @@ float brush_curve_strength(Brush *br, float p, const float len)
unsigned int *brush_gen_texture_cache(Brush *br, int half_side)
{
unsigned int *texcache = NULL;
- MTex *mtex = br->mtex[br->texact];
+ MTex *mtex = &br->mtex;
TexResult texres;
int hasrgb, ix, iy;
int side = half_side * 2;
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 66c39c6571a..e9a1021a203 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -177,13 +177,15 @@ static void cdDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
no_r[2] = no[2]/32767.f;
}
-static ListBase *cdDM_getFaceMap(DerivedMesh *dm)
+static ListBase *cdDM_getFaceMap(Object *ob, DerivedMesh *dm)
{
CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
- if(!cddm->fmap) {
- create_vert_face_map(&cddm->fmap, &cddm->fmap_mem, cddm->mface,
- dm->getNumVerts(dm), dm->getNumFaces(dm));
+ if(!cddm->fmap && ob->type == OB_MESH) {
+ Mesh *me= ob->data;
+
+ create_vert_face_map(&cddm->fmap, &cddm->fmap_mem, me->mface,
+ me->totvert, me->totface);
}
return cddm->fmap;
@@ -1404,7 +1406,7 @@ DerivedMesh *CDDM_new(int numVerts, int numEdges, int numFaces)
CDDerivedMesh *cddm = cdDM_create("CDDM_new dm");
DerivedMesh *dm = &cddm->dm;
- DM_init(dm, numVerts, numEdges, numFaces);
+ DM_init(dm, DM_TYPE_CDDM, numVerts, numEdges, numFaces);
CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
@@ -1430,7 +1432,7 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *ob)
/* this does a referenced copy, with an exception for fluidsim */
- DM_init(dm, mesh->totvert, mesh->totedge, mesh->totface);
+ DM_init(dm, DM_TYPE_CDDM, mesh->totvert, mesh->totedge, mesh->totface);
dm->deformedOnly = 1;
@@ -1563,7 +1565,7 @@ DerivedMesh *CDDM_copy(DerivedMesh *source)
source->getFaceDataArray(source, CD_ORIGINDEX);
/* this initializes dm, and copies all non mvert/medge/mface layers */
- DM_from_template(dm, source, numVerts, numEdges, numFaces);
+ DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numFaces);
dm->deformedOnly = source->deformedOnly;
CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
@@ -1589,7 +1591,7 @@ DerivedMesh *CDDM_from_template(DerivedMesh *source,
DerivedMesh *dm = &cddm->dm;
/* this does a copy of all non mvert/medge/mface layers */
- DM_from_template(dm, source, numVerts, numEdges, numFaces);
+ DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numFaces);
/* now add mvert/medge/mface layers */
CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index 48e42bc539f..d8975c16cc8 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -236,16 +236,54 @@ void curvemap_insert(CurveMap *cuma, float x, float y)
cuma->curve= cmp;
}
-void curvemap_reset(CurveMap *cuma, rctf *clipr)
+void curvemap_reset(CurveMap *cuma, rctf *clipr, CurveMappingPreset preset)
{
- cuma->totpoint= 2;
-
- cuma->curve[0].x= clipr->xmin;
- cuma->curve[0].y= clipr->ymin;
- cuma->curve[0].flag= 0;
- cuma->curve[1].x= clipr->xmax;
- cuma->curve[1].y= clipr->ymax;
- cuma->curve[1].flag= 0;
+ if(cuma->curve)
+ MEM_freeN(cuma->curve);
+
+ switch(preset) {
+ case CURVE_PRESET_LINE: cuma->totpoint= 2; break;
+ case CURVE_PRESET_SHARP: cuma->totpoint= 3; break;
+ case CURVE_PRESET_SMOOTH: cuma->totpoint= 4; break;
+ case CURVE_PRESET_MAX: cuma->totpoint= 2; break;
+ }
+
+ cuma->curve= MEM_callocN(cuma->totpoint*sizeof(CurveMapPoint), "curve points");
+
+ switch(preset) {
+ case CURVE_PRESET_LINE:
+ cuma->curve[0].x= clipr->xmin;
+ cuma->curve[0].y= clipr->ymin;
+ cuma->curve[0].flag= 0;
+ cuma->curve[1].x= clipr->xmax;
+ cuma->curve[1].y= clipr->ymax;
+ cuma->curve[1].flag= 0;
+ break;
+ case CURVE_PRESET_SHARP:
+ cuma->curve[0].x= 0;
+ cuma->curve[0].y= 1;
+ cuma->curve[1].x= 0.33;
+ cuma->curve[1].y= 0.33;
+ cuma->curve[2].x= 1;
+ cuma->curve[2].y= 0;
+ break;
+ case CURVE_PRESET_SMOOTH:
+ cuma->curve[0].x= 0;
+ cuma->curve[0].y= 1;
+ cuma->curve[1].x= 0.25;
+ cuma->curve[1].y= 0.92;
+ cuma->curve[2].x= 0.75;
+ cuma->curve[2].y= 0.08;
+ cuma->curve[3].x= 1;
+ cuma->curve[3].y= 0;
+ break;
+ case CURVE_PRESET_MAX:
+ cuma->curve[0].x= 0;
+ cuma->curve[0].y= 1;
+ cuma->curve[1].x= 1;
+ cuma->curve[1].y= 1;
+ break;
+ }
if(cuma->table) {
MEM_freeN(cuma->table);
@@ -725,10 +763,16 @@ void colorcorrection_do_ibuf(ImBuf *ibuf, const char *profile)
}
}
-
+/* only used for image editor curves */
void curvemapping_do_ibuf(CurveMapping *cumap, ImBuf *ibuf)
{
+ ImBuf *tmpbuf;
int pixel;
+ char *tmpcbuf;
+ float *pix_in;
+ float col[3];
+ int stride= 4;
+ float *pix_out;
if(ibuf==NULL)
return;
@@ -737,35 +781,45 @@ void curvemapping_do_ibuf(CurveMapping *cumap, ImBuf *ibuf)
else if(ibuf->rect==NULL)
imb_addrectImBuf(ibuf);
+ if (!ibuf->rect || !ibuf->rect_float)
+ return;
+
+ /* work on a temp buffer, so can color manage afterwards.
+ * No worse off memory wise than comp nodes */
+ tmpbuf = IMB_dupImBuf(ibuf);
+
curvemapping_premultiply(cumap, 0);
- if(ibuf->rect_float && ibuf->rect) {
- float *pixf= ibuf->rect_float;
- float col[3];
- int stride= 4;
- char *pixc= (char *)ibuf->rect;
-
- if(ibuf->channels)
- stride= ibuf->channels;
-
- for(pixel= ibuf->x*ibuf->y; pixel>0; pixel--, pixf+=stride, pixc+=4) {
- if(stride<3) {
- col[0]= curvemap_evaluateF(cumap->cm, *pixf);
- pixc[1]= pixc[2]= pixc[3]= pixc[0]= FTOCHAR(col[0]);
- }
- else {
- curvemapping_evaluate_premulRGBF(cumap, col, pixf);
- pixc[0]= FTOCHAR(col[0]);
- pixc[1]= FTOCHAR(col[1]);
- pixc[2]= FTOCHAR(col[2]);
- if(stride>3)
- pixc[3]= FTOCHAR(pixf[3]);
- else
- pixc[3]= 255;
- }
+ pix_in= ibuf->rect_float;
+ pix_out= tmpbuf->rect_float;
+// pixc= (char *)ibuf->rect;
+
+ if(ibuf->channels)
+ stride= ibuf->channels;
+
+ for(pixel= ibuf->x*ibuf->y; pixel>0; pixel--, pix_in+=stride, pix_out+=4) {
+ if(stride<3) {
+ col[0]= curvemap_evaluateF(cumap->cm, *pix_in);
+
+ pix_out[1]= pix_out[2]= pix_out[3]= pix_out[0]= col[0];
+ }
+ else {
+ curvemapping_evaluate_premulRGBF(cumap, col, pix_in);
+ pix_out[0]= col[0];
+ pix_out[1]= col[1];
+ pix_out[2]= col[2];
+ if(stride>3)
+ pix_out[3]= pix_in[3];
+ else
+ pix_out[3]= 1.f;
}
}
+ IMB_rect_from_float(tmpbuf);
+ SWAP(char *, tmpbuf->rect, ibuf->rect);
+ IMB_freeImBuf(tmpbuf);
+
+
curvemapping_premultiply(cumap, 1);
}
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 797fe8f7324..4de148803f8 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -1690,8 +1690,8 @@ static void sizelike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *t
if (VALID_CONS_TARGET(ct)) {
float obsize[3], size[3];
- mat4_to_size( size,ct->matrix);
- mat4_to_size( obsize,cob->matrix);
+ mat4_to_size(size, ct->matrix);
+ mat4_to_size(obsize, cob->matrix);
if ((data->flag & SIZELIKE_X) && (obsize[0] != 0)) {
if (data->flag & SIZELIKE_OFFSET) {
@@ -1735,6 +1735,58 @@ static bConstraintTypeInfo CTI_SIZELIKE = {
sizelike_evaluate /* evaluate */
};
+/* ----------- Copy Transforms ------------- */
+
+static int translike_get_tars (bConstraint *con, ListBase *list)
+{
+ if (con && list) {
+ bTransLikeConstraint *data= con->data;
+ bConstraintTarget *ct;
+
+ /* standard target-getting macro for single-target constraints */
+ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static void translike_flush_tars (bConstraint *con, ListBase *list, short nocopy)
+{
+ if (con && list) {
+ bTransLikeConstraint *data= con->data;
+ bConstraintTarget *ct= list->first;
+
+ /* the following macro is used for all standard single-target constraints */
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
+ }
+}
+
+static void translike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
+{
+ bConstraintTarget *ct= targets->first;
+
+ if (VALID_CONS_TARGET(ct)) {
+ /* just copy the entire transform matrix of the target */
+ copy_m4_m4(cob->matrix, ct->matrix);
+ }
+}
+
+static bConstraintTypeInfo CTI_TRANSLIKE = {
+ CONSTRAINT_TYPE_TRANSLIKE, /* type */
+ sizeof(bTransLikeConstraint), /* size */
+ "Copy Transforms", /* name */
+ "bTransLikeConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ NULL, /* copy data */
+ NULL, /* new data */
+ translike_get_tars, /* get constraint targets */
+ translike_flush_tars, /* flush constraint targets */
+ default_get_tarmat, /* get target matrix */
+ translike_evaluate /* evaluate */
+};
/* ----------- Python Constraint -------------- */
@@ -3565,6 +3617,7 @@ static void constraints_init_typeinfo () {
constraintsTypeInfo[20]= &CTI_SHRINKWRAP; /* Shrinkwrap Constraint */
constraintsTypeInfo[21]= &CTI_DAMPTRACK; /* Damped TrackTo Constraint */
constraintsTypeInfo[22]= &CTI_SPLINEIK; /* Spline IK Constraint */
+ constraintsTypeInfo[23]= &CTI_TRANSLIKE; /* Copy Transforms Constraint */
}
/* This function should be used for getting the appropriate type-info when only
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 2f08abd82b3..e664dd01f4d 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -68,6 +68,7 @@
#include "BKE_animsys.h"
#include "BKE_action.h"
#include "BKE_effect.h"
+#include "BKE_fcurve.h"
#include "BKE_global.h"
#include "BKE_group.h"
#include "BKE_key.h"
@@ -316,28 +317,38 @@ static void dag_add_driver_relation(AnimData *adt, DagForest *dag, DagNode *node
for (fcu= adt->drivers.first; fcu; fcu= fcu->next) {
ChannelDriver *driver= fcu->driver;
- DriverTarget *dtar;
+ DriverVar *dvar;
- /* loop over targets, adding relationships as appropriate */
- for (dtar= driver->targets.first; dtar; dtar= dtar->next) {
- if (dtar->id) {
- if (GS(dtar->id->name)==ID_OB) {
- Object *ob= (Object *)dtar->id;
-
- /* normal channel-drives-channel */
- node1 = dag_get_node(dag, dtar->id);
-
- /* check if bone... */
- if ((ob->type==OB_ARMATURE) && dtar->rna_path && strstr(dtar->rna_path, "pose.bones["))
- dag_add_relation(dag, node1, node, isdata?DAG_RL_DATA_DATA:DAG_RL_DATA_OB, "Driver");
- /* check if ob data */
- else if (dtar->rna_path && strstr(dtar->rna_path, "data."))
- dag_add_relation(dag, node1, node, isdata?DAG_RL_DATA_DATA:DAG_RL_DATA_OB, "Driver");
- /* normal */
- else
- dag_add_relation(dag, node1, node, isdata?DAG_RL_OB_DATA:DAG_RL_OB_OB, "Driver");
+ /* loop over variables to get the target relationships */
+ for (dvar= driver->variables.first; dvar; dvar= dvar->next) {
+ /* only used targets */
+ DRIVER_TARGETS_USED_LOOPER(dvar)
+ {
+ if (dtar->id) {
+ // FIXME: other data types need to be added here so that they can work!
+ if (GS(dtar->id->name)==ID_OB) {
+ Object *ob= (Object *)dtar->id;
+
+ /* normal channel-drives-channel */
+ node1 = dag_get_node(dag, dtar->id);
+
+ /* check if bone... */
+ if ((ob->type==OB_ARMATURE) &&
+ ( ((dtar->rna_path) && strstr(dtar->rna_path, "pose.bones[")) ||
+ ((dtar->flag & DTAR_FLAG_STRUCT_REF) && (dtar->pchan_name[0])) ))
+ {
+ dag_add_relation(dag, node1, node, isdata?DAG_RL_DATA_DATA:DAG_RL_DATA_OB, "Driver");
+ }
+ /* check if ob data */
+ else if (dtar->rna_path && strstr(dtar->rna_path, "data."))
+ dag_add_relation(dag, node1, node, isdata?DAG_RL_DATA_DATA:DAG_RL_DATA_OB, "Driver");
+ /* normal */
+ else
+ dag_add_relation(dag, node1, node, isdata?DAG_RL_OB_DATA:DAG_RL_OB_OB, "Driver");
+ }
}
}
+ DRIVER_TARGETS_LOOPER_END
}
}
}
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index d5e033652a8..3ce77c8cb4f 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -41,6 +41,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_anim_types.h"
+#include "DNA_object_types.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
@@ -48,10 +49,12 @@
#include "BKE_fcurve.h"
#include "BKE_animsys.h"
+#include "BKE_action.h"
#include "BKE_curve.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
+#include "BKE_object.h"
#include "BKE_utildefines.h"
#include "RNA_access.h"
@@ -735,108 +738,31 @@ short test_time_fcurve (FCurve *fcu)
/* ***************************** Drivers ********************************* */
-/* Driver API --------------------------------- */
-
-/* This frees the driver target itself */
-void driver_free_target (ChannelDriver *driver, DriverTarget *dtar)
-{
- /* sanity checks */
- if (dtar == NULL)
- return;
-
- /* free target vars */
- if (dtar->rna_path)
- MEM_freeN(dtar->rna_path);
-
- /* remove the target from the driver */
- if (driver)
- BLI_freelinkN(&driver->targets, dtar);
- else
- MEM_freeN(dtar);
-}
-
-/* Add a new driver target variable */
-DriverTarget *driver_add_new_target (ChannelDriver *driver)
-{
- DriverTarget *dtar;
-
- /* sanity checks */
- if (driver == NULL)
- return NULL;
-
- /* make a new target */
- dtar= MEM_callocN(sizeof(DriverTarget), "DriverTarget");
- BLI_addtail(&driver->targets, dtar);
-
- /* make the default ID-type ID_OB, since most driver targets refer to objects */
- dtar->idtype= ID_OB;
-
- /* give the target a 'unique' name */
- strcpy(dtar->name, "var");
- BLI_uniquename(&driver->targets, dtar, "var", '_', offsetof(DriverTarget, name), 64);
-
- /* return the target */
- return dtar;
-}
+/* Driver Variables --------------------------- */
-/* This frees the driver itself */
-void fcurve_free_driver(FCurve *fcu)
-{
- ChannelDriver *driver;
- DriverTarget *dtar, *dtarn;
+/* TypeInfo for Driver Variables (dvti) */
+typedef struct DriverVarTypeInfo {
+ /* evaluation callback */
+ float (*get_value)(ChannelDriver *driver, DriverVar *dvar);
- /* sanity checks */
- if ELEM(NULL, fcu, fcu->driver)
- return;
- driver= fcu->driver;
-
- /* free driver targets */
- for (dtar= driver->targets.first; dtar; dtar= dtarn) {
- dtarn= dtar->next;
- driver_free_target(driver, dtar);
- }
+ /* allocation of target slots */
+ int num_targets; /* number of target slots required */
+ char *target_names[MAX_DRIVER_TARGETS]; /* UI names that should be given to the slots */
+ int target_flags[MAX_DRIVER_TARGETS]; /* flags defining the requirements for each slot */
+} DriverVarTypeInfo;
-#ifndef DISABLE_PYTHON
- if(driver->expr_comp)
- BPY_DECREF(driver->expr_comp);
-#endif
-
- /* free driver itself, then set F-Curve's point to this to NULL (as the curve may still be used) */
- MEM_freeN(driver);
- fcu->driver= NULL;
-}
-
-/* This makes a copy of the given driver */
-ChannelDriver *fcurve_copy_driver (ChannelDriver *driver)
-{
- ChannelDriver *ndriver;
- DriverTarget *dtar;
-
- /* sanity checks */
- if (driver == NULL)
- return NULL;
-
- /* copy all data */
- ndriver= MEM_dupallocN(driver);
-
- /* copy targets */
- ndriver->targets.first= ndriver->targets.last= NULL;
- BLI_duplicatelist(&ndriver->targets, &driver->targets);
+/* Macro to begin definitions */
+#define BEGIN_DVAR_TYPEDEF(type) \
+ {
- for (dtar= ndriver->targets.first; dtar; dtar= dtar->next) {
- /* make a copy of target's rna path if available */
- if (dtar->rna_path)
- dtar->rna_path = MEM_dupallocN(dtar->rna_path);
+/* Macro to end definitions */
+#define END_DVAR_TYPEDEF \
}
-
- /* return the new driver */
- return ndriver;
-}
-/* Driver Evaluation -------------------------- */
+/* ......... */
/* Helper function to obtain a value using RNA from the specified source (for evaluating drivers) */
-float driver_get_target_value (ChannelDriver *driver, DriverTarget *dtar)
+static float dtar_get_prop_val (ChannelDriver *driver, DriverTarget *dtar)
{
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
@@ -853,22 +779,18 @@ float driver_get_target_value (ChannelDriver *driver, DriverTarget *dtar)
RNA_id_pointer_create(dtar->id, &id_ptr);
id= dtar->id;
path= dtar->rna_path;
- index= dtar->array_index;
/* error check for missing pointer... */
+ // TODO: tag the specific target too as having issues
if (id == NULL) {
- printf("Error: driver doesn't have any valid target to use \n");
- if (G.f & G_DEBUG) printf("\tpath = %s [%d] \n", path, index);
+ printf("Error: driver has an invalid target to use \n");
+ if (G.f & G_DEBUG) printf("\tpath = %s\n", path);
driver->flag |= DRIVER_FLAG_INVALID;
return 0.0f;
}
/* get property to read from, and get value as appropriate */
if (RNA_path_resolve_full(&id_ptr, path, &ptr, &prop, &index)) {
- /* for now, if there is no valid index, fall back to the array-index specified separately */
- if (index == -1)
- index= dtar->array_index;
-
switch (RNA_property_type(prop)) {
case PROP_BOOLEAN:
if (RNA_property_array_length(&ptr, prop))
@@ -906,39 +828,423 @@ float driver_get_target_value (ChannelDriver *driver, DriverTarget *dtar)
return value;
}
-/* Get two PoseChannels from the targets of the given Driver */
-static void driver_get_target_pchans2 (ChannelDriver *driver, bPoseChannel **pchan1, bPoseChannel **pchan2)
+/* Helper function to obtain a pointer to a Pose Channel (for evaluating drivers) */
+static bPoseChannel *dtar_get_pchan_ptr (ChannelDriver *driver, DriverTarget *dtar)
{
- DriverTarget *dtar;
- short i = 0;
+ /* sanity check */
+ if ELEM(NULL, driver, dtar)
+ return NULL;
+
+ /* check if the ID here is a valid object */
+ if ((dtar->id) && GS(dtar->id->name)) {
+ Object *ob= (Object *)dtar->id;
+
+ /* get pose, and subsequently, posechannel */
+ return get_pose_channel(ob->pose, dtar->pchan_name);
+ }
+ else {
+ /* cannot find a posechannel this way */
+ return NULL;
+ }
+}
+
+/* ......... */
+
+/* evaluate 'single prop' driver variable */
+static float dvar_eval_singleProp (ChannelDriver *driver, DriverVar *dvar)
+{
+ /* just evaluate the first target slot */
+ return dtar_get_prop_val(driver, &dvar->targets[0]);
+}
+
+/* evaluate 'rotation difference' driver variable */
+static float dvar_eval_rotDiff (ChannelDriver *driver, DriverVar *dvar)
+{
+ bPoseChannel *pchan, *pchan2;
+ float q1[4], q2[4], quat[4], angle;
- /* before doing anything */
- *pchan1= NULL;
- *pchan2= NULL;
+ /* get pose channels, and check if we've got two */
+ pchan= dtar_get_pchan_ptr(driver, &dvar->targets[0]);
+ pchan2= dtar_get_pchan_ptr(driver, &dvar->targets[1]);
- /* only take the first two targets */
- for (dtar= driver->targets.first; (dtar) && (i < 2); dtar=dtar->next, i++) {
- PointerRNA id_ptr, ptr;
- PropertyRNA *prop;
+ if (ELEM(NULL, pchan, pchan2)) {
+ /* disable this driver, since it doesn't work correctly... */
+ driver->flag |= DRIVER_FLAG_INVALID;
- /* get RNA-pointer for the ID-block given in target */
- if (dtar->id)
- RNA_id_pointer_create(dtar->id, &id_ptr);
- else
- continue;
+ /* check what the error was */
+ if ((pchan == NULL) && (pchan2 == NULL))
+ printf("Driver Evaluation Error: Rotational difference failed - first 2 targets invalid \n");
+ else if (pchan == NULL)
+ printf("Driver Evaluation Error: Rotational difference failed - first target not valid PoseChannel \n");
+ else if (pchan2 == NULL)
+ printf("Driver Evaluation Error: Rotational difference failed - second target not valid PoseChannel \n");
+
+ /* stop here... */
+ return 0.0f;
+ }
+
+ /* use the final posed locations */
+ mat4_to_quat(q1, pchan->pose_mat);
+ mat4_to_quat(q2, pchan2->pose_mat);
+
+ invert_qt(q1);
+ mul_qt_qtqt(quat, q1, q2);
+ angle = 2.0f * (saacos(quat[0]));
+ angle= ABS(angle);
+
+ return (angle > M_PI) ? (float)((2.0f * M_PI) - angle) : (float)(angle);
+}
+
+/* evaluate 'location difference' driver variable */
+// TODO: this needs to take into account space conversions...
+static float dvar_eval_locDiff (ChannelDriver *driver, DriverVar *dvar)
+{
+ float loc1[3] = {0.0f,0.0f,0.0f};
+ float loc2[3] = {0.0f,0.0f,0.0f};
+
+ /* get two location values */
+ // NOTE: for now, these are all just worldspace
+ DRIVER_TARGETS_USED_LOOPER(dvar)
+ {
+ /* get pointer to loc values to store in */
+ Object *ob= (Object *)dtar->id;
+ bPoseChannel *pchan;
+ float tmp_loc[3];
- /* resolve path so that we have pointer to the right posechannel */
- if (RNA_path_resolve(&id_ptr, dtar->rna_path, &ptr, &prop)) {
- /* is pointer valid (i.e. pointing to an actual posechannel */
- if ((ptr.type == &RNA_PoseBone) && (ptr.data)) {
- /* first or second target? */
- if (i)
- *pchan1= ptr.data;
- else
- *pchan2= ptr.data;
+ /* check if this target has valid data */
+ if ((ob == NULL) || (GS(dtar->id->name) != ID_OB)) {
+ /* invalid target, so will not have enough targets */
+ driver->flag |= DRIVER_FLAG_INVALID;
+ return 0.0f;
+ }
+
+ /* try to get posechannel */
+ pchan= get_pose_channel(ob->pose, dtar->pchan_name);
+
+ /* check if object or bone */
+ if (pchan) {
+ /* bone */
+ if ((dtar->flag & DTAR_FLAG_LOCALSPACE) == 0) {
+ /* convert to worldspace */
+ VECCOPY(tmp_loc, pchan->pose_head);
+ mul_m4_v3(ob->obmat, tmp_loc);
+ }
+ else {
+ /* local (use transform values directly) */
+ VECCOPY(tmp_loc, pchan->loc);
+ }
+ }
+ else {
+ /* object */
+ if ((dtar->flag & DTAR_FLAG_LOCALSPACE) == 0) {
+ /* worldspace */
+ VECCOPY(tmp_loc, ob->obmat[3]);
+ }
+ else {
+ /* local (use transform values directly) */
+ VECCOPY(tmp_loc, ob->loc);
}
}
+
+ /* copy the location to the right place */
+ if (tarIndex) {
+ VECCOPY(loc2, tmp_loc);
+ }
+ else {
+ VECCOPY(loc1, tmp_loc);
+ }
}
+ DRIVER_TARGETS_LOOPER_END
+
+
+ /* if we're still here, there should now be two targets to use,
+ * so just take the length of the vector between these points
+ */
+ return len_v3v3(loc1, loc2);
+}
+
+/* evaluate 'transform channel' driver variable */
+static float dvar_eval_transChan (ChannelDriver *driver, DriverVar *dvar)
+{
+ DriverTarget *dtar= &dvar->targets[0];
+ Object *ob= (Object *)dtar->id;
+ bPoseChannel *pchan;
+ float mat[4][4];
+ short rotOrder = 0;
+
+ /* check if this target has valid data */
+ if ((ob == NULL) || (GS(dtar->id->name) != ID_OB)) {
+ /* invalid target, so will not have enough targets */
+ driver->flag |= DRIVER_FLAG_INVALID;
+ return 0.0f;
+ }
+
+ /* try to get posechannel */
+ pchan= get_pose_channel(ob->pose, dtar->pchan_name);
+
+ /* check if object or bone, and get transform matrix accordingly */
+ if (pchan) {
+ /* bone */
+ rotOrder= (pchan->rotmode > 0) ? pchan->rotmode : ROT_MODE_EUL;
+
+ if (dtar->flag & DTAR_FLAG_LOCALSPACE)
+ copy_m4_m4(mat, pchan->chan_mat);
+ else
+ mul_m4_m4m4(mat, pchan->pose_mat, ob->obmat);
+ }
+ else {
+ /* object */
+ rotOrder= (ob->rotmode > 0) ? ob->rotmode : ROT_MODE_EUL;
+
+ if (dtar->flag & DTAR_FLAG_LOCALSPACE)
+ object_to_mat4(ob, mat);
+ else
+ copy_m4_m4(mat, ob->obmat);
+ }
+
+ /* check which transform */
+ if (dtar->transChan >= MAX_DTAR_TRANSCHAN_TYPES) {
+ /* not valid channel */
+ return 0.0f;
+ }
+ else if (dtar->transChan >= DTAR_TRANSCHAN_SCALEX) {
+ /* extract scale, and choose the right axis */
+ float scale[3];
+
+ mat4_to_size(scale, mat);
+ return scale[dtar->transChan - DTAR_TRANSCHAN_SCALEX];
+ }
+ else if (dtar->transChan >= DTAR_TRANSCHAN_ROTX) {
+ /* extract euler rotation, and choose the right axis */
+ float eul[3];
+
+ mat4_to_eulO(eul, rotOrder, mat);
+ return eul[dtar->transChan - DTAR_TRANSCHAN_ROTX];
+ }
+ else {
+ /* extract location and choose right axis */
+ return mat[3][dtar->transChan];
+ }
+}
+
+/* ......... */
+
+/* Table of Driver Varaiable Type Info Data */
+DriverVarTypeInfo dvar_types[MAX_DVAR_TYPES] = {
+ BEGIN_DVAR_TYPEDEF(DVAR_TYPE_SINGLE_PROP)
+ dvar_eval_singleProp, /* eval callback */
+ 1, /* number of targets used */
+ {"Property"}, /* UI names for targets */
+ {0} /* flags */
+ END_DVAR_TYPEDEF,
+
+ BEGIN_DVAR_TYPEDEF(DVAR_TYPE_ROT_DIFF)
+ dvar_eval_rotDiff, /* eval callback */
+ 2, /* number of targets used */
+ {"Bone 1", "Bone 2"}, /* UI names for targets */
+ {DTAR_FLAG_STRUCT_REF|DTAR_FLAG_ID_OB_ONLY, DTAR_FLAG_STRUCT_REF|DTAR_FLAG_ID_OB_ONLY} /* flags */
+ END_DVAR_TYPEDEF,
+
+ BEGIN_DVAR_TYPEDEF(DVAR_TYPE_LOC_DIFF)
+ dvar_eval_locDiff, /* eval callback */
+ 2, /* number of targets used */
+ {"Object/Bone 1", "Object/Bone 2"}, /* UI names for targets */
+ {DTAR_FLAG_STRUCT_REF|DTAR_FLAG_ID_OB_ONLY, DTAR_FLAG_STRUCT_REF|DTAR_FLAG_ID_OB_ONLY} /* flags */
+ END_DVAR_TYPEDEF,
+
+ BEGIN_DVAR_TYPEDEF(DVAR_TYPE_TRANSFORM_CHAN)
+ dvar_eval_transChan, /* eval callback */
+ 1, /* number of targets used */
+ {"Object/Bone"}, /* UI names for targets */
+ {DTAR_FLAG_STRUCT_REF|DTAR_FLAG_ID_OB_ONLY} /* flags */
+ END_DVAR_TYPEDEF,
+};
+
+/* Get driver variable typeinfo */
+DriverVarTypeInfo *get_dvar_typeinfo (int type)
+{
+ /* check if valid type */
+ if ((type >= 0) && (type < MAX_DVAR_TYPES))
+ return &dvar_types[type];
+ else
+ return NULL;
+}
+
+/* Driver API --------------------------------- */
+
+/* This frees the driver variable itself */
+void driver_free_variable (ChannelDriver *driver, DriverVar *dvar)
+{
+ /* sanity checks */
+ if (dvar == NULL)
+ return;
+
+ /* free target vars
+ * - need to go over all of them, not just up to the ones that are used
+ * currently, since there may be some lingering RNA paths from
+ * previous users needing freeing
+ */
+ DRIVER_TARGETS_LOOPER(dvar)
+ {
+ /* free RNA path if applicable */
+ if (dtar->rna_path)
+ MEM_freeN(dtar->rna_path);
+ }
+ DRIVER_TARGETS_LOOPER_END
+
+ /* remove the variable from the driver */
+ if (driver)
+ BLI_freelinkN(&driver->variables, dvar);
+ else
+ MEM_freeN(dvar);
+
+#ifndef DISABLE_PYTHON
+ /* since driver variables are cached, the expression needs re-compiling too */
+ if(driver->type==DRIVER_TYPE_PYTHON)
+ driver->flag |= DRIVER_FLAG_RENAMEVAR;
+#endif
+}
+
+/* Change the type of driver variable */
+void driver_change_variable_type (DriverVar *dvar, int type)
+{
+ DriverVarTypeInfo *dvti= get_dvar_typeinfo(type);
+
+ /* sanity check */
+ if (ELEM(NULL, dvar, dvti))
+ return;
+
+ /* set the new settings */
+ dvar->type= type;
+ dvar->num_targets= dvti->num_targets;
+
+ /* make changes to the targets based on the defines for these types
+ * NOTE: only need to make sure the ones we're using here are valid...
+ */
+ DRIVER_TARGETS_USED_LOOPER(dvar)
+ {
+ int flags = dvti->target_flags[tarIndex];
+
+ /* store the flags */
+ dtar->flag = flags;
+
+ /* object ID types only, or idtype not yet initialised*/
+ if ((flags & DTAR_FLAG_ID_OB_ONLY) || (dtar->idtype == 0))
+ dtar->idtype= ID_OB;
+ }
+ DRIVER_TARGETS_LOOPER_END
+}
+
+/* Add a new driver variable */
+DriverVar *driver_add_new_variable (ChannelDriver *driver)
+{
+ DriverVar *dvar;
+
+ /* sanity checks */
+ if (driver == NULL)
+ return NULL;
+
+ /* make a new variable */
+ dvar= MEM_callocN(sizeof(DriverVar), "DriverVar");
+ BLI_addtail(&driver->variables, dvar);
+
+ /* give the variable a 'unique' name */
+ strcpy(dvar->name, "var");
+ BLI_uniquename(&driver->variables, dvar, "var", '_', offsetof(DriverVar, name), 64);
+
+ /* set the default type to 'single prop' */
+ driver_change_variable_type(dvar, DVAR_TYPE_SINGLE_PROP);
+
+#ifndef DISABLE_PYTHON
+ /* since driver variables are cached, the expression needs re-compiling too */
+ if(driver->type==DRIVER_TYPE_PYTHON)
+ driver->flag |= DRIVER_FLAG_RENAMEVAR;
+#endif
+
+ /* return the target */
+ return dvar;
+}
+
+/* This frees the driver itself */
+void fcurve_free_driver(FCurve *fcu)
+{
+ ChannelDriver *driver;
+ DriverVar *dvar, *dvarn;
+
+ /* sanity checks */
+ if ELEM(NULL, fcu, fcu->driver)
+ return;
+ driver= fcu->driver;
+
+ /* free driver targets */
+ for (dvar= driver->variables.first; dvar; dvar= dvarn) {
+ dvarn= dvar->next;
+ driver_free_variable(driver, dvar);
+ }
+
+#ifndef DISABLE_PYTHON
+ /* free compiled driver expression */
+ if (driver->expr_comp)
+ BPY_DECREF(driver->expr_comp);
+#endif
+
+ /* free driver itself, then set F-Curve's point to this to NULL (as the curve may still be used) */
+ MEM_freeN(driver);
+ fcu->driver= NULL;
+}
+
+/* This makes a copy of the given driver */
+ChannelDriver *fcurve_copy_driver (ChannelDriver *driver)
+{
+ ChannelDriver *ndriver;
+ DriverVar *dvar;
+
+ /* sanity checks */
+ if (driver == NULL)
+ return NULL;
+
+ /* copy all data */
+ ndriver= MEM_dupallocN(driver);
+
+ /* copy variables */
+ ndriver->variables.first= ndriver->variables.last= NULL;
+ BLI_duplicatelist(&ndriver->variables, &driver->variables);
+
+ for (dvar= ndriver->variables.first; dvar; dvar= dvar->next) {
+ /* need to go over all targets so that we don't leave any dangling paths */
+ DRIVER_TARGETS_LOOPER(dvar)
+ {
+ /* make a copy of target's rna path if available */
+ if (dtar->rna_path)
+ dtar->rna_path = MEM_dupallocN(dtar->rna_path);
+ }
+ DRIVER_TARGETS_LOOPER_END
+ }
+
+ /* return the new driver */
+ return ndriver;
+}
+
+/* Driver Evaluation -------------------------- */
+
+/* Evaluate a Driver Variable to get a value that contributes to the final */
+float driver_get_variable_value (ChannelDriver *driver, DriverVar *dvar)
+{
+ DriverVarTypeInfo *dvti;
+
+ /* sanity check */
+ if (ELEM(NULL, driver, dvar))
+ return 0.0f;
+
+ /* call the relevant callbacks to get the variable value
+ * using the variable type info
+ */
+ dvti= get_dvar_typeinfo(dvar->type);
+
+ if (dvti && dvti->get_value)
+ return dvti->get_value(driver, dvar);
+ else
+ return 0.0f;
}
/* Evaluate an Channel-Driver to get a 'time' value to use instead of "evaltime"
@@ -947,22 +1253,21 @@ static void driver_get_target_pchans2 (ChannelDriver *driver, bPoseChannel **pch
*/
static float evaluate_driver (ChannelDriver *driver, float evaltime)
{
- DriverTarget *dtar;
+ DriverVar *dvar;
/* check if driver can be evaluated */
if (driver->flag & DRIVER_FLAG_INVALID)
return 0.0f;
- // TODO: the flags for individual targets need to be used too for more fine-grained support...
switch (driver->type) {
case DRIVER_TYPE_AVERAGE: /* average values of driver targets */
case DRIVER_TYPE_SUM: /* sum values of driver targets */
{
- /* check how many targets there are first (i.e. just one?) */
- if (driver->targets.first == driver->targets.last) {
+ /* check how many variables there are first (i.e. just one?) */
+ if (driver->variables.first == driver->variables.last) {
/* just one target, so just use that */
- dtar= driver->targets.first;
- return driver_get_target_value(driver, dtar);
+ dvar= driver->variables.first;
+ return driver_get_variable_value(driver, dvar);
}
else {
/* more than one target, so average the values of the targets */
@@ -970,12 +1275,12 @@ static float evaluate_driver (ChannelDriver *driver, float evaltime)
float value = 0.0f;
/* loop through targets, adding (hopefully we don't get any overflow!) */
- for (dtar= driver->targets.first; dtar; dtar=dtar->next) {
- value += driver_get_target_value(driver, dtar);
+ for (dvar= driver->variables.first; dvar; dvar=dvar->next) {
+ value += driver_get_variable_value(driver, dvar);
tot++;
}
- /* return the average of these */
+ /* perform operations on the total if appropriate */
if (driver->type == DRIVER_TYPE_AVERAGE)
return (value / (float)tot);
else
@@ -984,6 +1289,39 @@ static float evaluate_driver (ChannelDriver *driver, float evaltime)
}
}
break;
+
+ case DRIVER_TYPE_MIN: /* smallest value */
+ case DRIVER_TYPE_MAX: /* largest value */
+ {
+ float value = 0.0f;
+
+ /* loop through the variables, getting the values and comparing them to existing ones */
+ for (dvar= driver->variables.first; dvar; dvar= dvar->next) {
+ /* get value */
+ float tmp_val= driver_get_variable_value(driver, dvar);
+
+ /* store this value if appropriate */
+ if (dvar->prev) {
+ /* check if greater/smaller than the baseline */
+ if (driver->type == DRIVER_TYPE_MAX) {
+ /* max? */
+ if (tmp_val > value)
+ value= tmp_val;
+ }
+ else {
+ /* min? */
+ if (tmp_val < value)
+ value= tmp_val;
+ }
+ }
+ else {
+ /* first item - make this the baseline for comparisons */
+ value= tmp_val;
+ }
+ }
+ }
+ break;
+
case DRIVER_TYPE_PYTHON: /* expression */
{
#ifndef DISABLE_PYTHON
@@ -1001,43 +1339,6 @@ static float evaluate_driver (ChannelDriver *driver, float evaltime)
#endif /* DISABLE_PYTHON*/
}
break;
-
-
- case DRIVER_TYPE_ROTDIFF: /* difference of rotations of 2 bones (should ideally be in same armature) */
- {
- bPoseChannel *pchan, *pchan2;
- float q1[4], q2[4], quat[4], angle;
-
- /* get pose channels, and check if we've got two */
- driver_get_target_pchans2(driver, &pchan, &pchan2);
- if (ELEM(NULL, pchan, pchan2)) {
- /* disable this driver, since it doesn't work correctly... */
- driver->flag |= DRIVER_FLAG_INVALID;
-
- /* check what the error was */
- if ((pchan == NULL) && (pchan2 == NULL))
- printf("Driver Evaluation Error: Rotational difference failed - first 2 targets invalid \n");
- else if (pchan == NULL)
- printf("Driver Evaluation Error: Rotational difference failed - first target not valid PoseChannel \n");
- else if (pchan2 == NULL)
- printf("Driver Evaluation Error: Rotational difference failed - second target not valid PoseChannel \n");
-
- /* stop here... */
- return 0.0f;
- }
-
- /* use the final posed locations */
- mat4_to_quat(q1, pchan->pose_mat);
- mat4_to_quat(q2, pchan2->pose_mat);
-
- invert_qt(q1);
- mul_qt_qtqt(quat, q1, q2);
- angle = 2.0f * (saacos(quat[0]));
- angle= ABS(angle);
-
- return (angle > M_PI) ? (float)((2.0f * M_PI) - angle) : (float)(angle);
- }
- break;
default:
{
@@ -1433,9 +1734,16 @@ static float fcurve_eval_samples (FCurve *fcu, FPoint *fpts, float evaltime)
cvalue= lastfpt->vec[1];
}
else {
+ float t= (float)abs(evaltime - (int)evaltime);
+
/* find the one on the right frame (assume that these are spaced on 1-frame intervals) */
fpt= prevfpt + (int)(evaltime - prevfpt->vec[0]);
- cvalue= fpt->vec[1];
+
+ /* if not exactly on the frame, perform linear interpolation with the next one */
+ if (t != 0.0f)
+ cvalue= interpf(fpt->vec[1], (fpt+1)->vec[1], t);
+ else
+ cvalue= fpt->vec[1];
}
/* return value */
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 5023d87cef8..8a933ba5289 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -349,8 +349,10 @@ bGPDframe *gpencil_layer_getframe (bGPDlayer *gpl, int cframe, short addnew)
if (gpl->actframe) {
gpf= gpl->actframe;
- /* do not allow any changes to layer's active frame if layer is locked */
- if (gpl->flag & GP_LAYER_LOCKED)
+ /* do not allow any changes to layer's active frame if layer is locked from changes
+ * or if the layer has been set to stay on the current frame
+ */
+ if (gpl->flag & (GP_LAYER_LOCKED|GP_LAYER_FRAMELOCK))
return gpf;
/* do not allow any changes to actframe if frame has painting tag attached to it */
if (gpf->flag & GP_FRAME_PAINT)
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 7e081982f24..ddfb28437a9 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -386,6 +386,31 @@ IDProperty *IDP_CopyGroup(IDProperty *prop)
}
/*
+ replaces all properties with the same name in a destination group from a source group.
+*/
+void IDP_ReplaceGroupInGroup(IDProperty *dest, IDProperty *src)
+{
+ IDProperty *loop, *prop;
+ for (prop=src->data.group.first; prop; prop=prop->next) {
+ IDProperty *copy = IDP_CopyProperty(prop);
+
+ for (loop=dest->data.group.first; loop; loop=loop->next) {
+ if (BSTR_EQ(loop->name, prop->name)) {
+ if (loop->next) BLI_insertlinkbefore(&dest->data.group, loop->next, copy);
+ else BLI_addtail(&dest->data.group, copy);
+
+ BLI_remlink(&dest->data.group, loop);
+ IDP_FreeProperty(loop);
+ MEM_freeN(loop);
+ break;
+ }
+ }
+
+ dest->len++;
+ BLI_addtail(&dest->data.group, copy);
+ }
+}
+/*
replaces a property with the same name in a group, or adds
it if the propery doesn't exist.
*/
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 0452b38a2e5..f7edb2bd146 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -725,6 +725,17 @@ void BKE_image_print_memlist(void)
}
}
+/* frees all ibufs used by any image datablocks */
+void BKE_image_free_image_ibufs(void)
+{
+ Image *ima;
+
+ for(ima= G.main->image.first; ima; ima= ima->id.next) {
+ image_free_buffers(ima);
+ }
+
+}
+
void BKE_image_free_all_textures(void)
{
Tex *tex;
@@ -883,7 +894,7 @@ int BKE_imtype_is_movie(int imtype)
return 0;
}
-void BKE_add_image_extension(Scene *scene, char *string, int imtype)
+void BKE_add_image_extension(char *string, int imtype)
{
char *extension="";
@@ -1397,7 +1408,7 @@ int BKE_write_ibuf(Scene *scene, ImBuf *ibuf, char *name, int imtype, int subimt
BLI_make_existing_file(name);
- if(scene->r.stamp & R_STAMP_ALL)
+ if(scene && scene->r.stamp & R_STAMP_ALL)
BKE_stamp_info(scene, ibuf);
ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
@@ -1409,7 +1420,7 @@ int BKE_write_ibuf(Scene *scene, ImBuf *ibuf, char *name, int imtype, int subimt
}
-void BKE_makepicstring(struct Scene *scene, char *string, char *base, int frame, int imtype)
+void BKE_makepicstring(char *string, char *base, int frame, int imtype, int use_ext)
{
if (string==NULL) return;
@@ -1422,8 +1433,8 @@ void BKE_makepicstring(struct Scene *scene, char *string, char *base, int frame,
BLI_convertstringcode(string, G.sce);
BLI_convertstringframe(string, frame);
- if(scene->r.scemode & R_EXTENSION)
- BKE_add_image_extension(scene, string, imtype);
+ if(use_ext)
+ BKE_add_image_extension(string, imtype);
}
@@ -1898,6 +1909,7 @@ static ImBuf *image_get_ibuf_multilayer(Image *ima, ImageUser *iuser)
ibuf->rect_float= rpass->rect;
ibuf->flags |= IB_rectfloat;
ibuf->channels= rpass->channels;
+ ibuf->profile = IB_PROFILE_LINEAR_RGB;
image_assign_ibuf(ima, ibuf, iuser?iuser->multi_index:IMA_NO_INDEX, 0);
}
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 6fc3fc547df..feb7fc3e382 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -295,10 +295,7 @@ static char *pchan_adrcodes_to_paths (int adrcode, int *array_index)
*array_index= 1; return "rotation_euler";
case AC_EUL_Z:
*array_index= 2; return "rotation_euler";
-
- case -1: /* special case for euler-rotations used by old drivers */
- *array_index= 0; return "rotation_euler";
-
+
case AC_LOC_X:
*array_index= 0; return "location";
case AC_LOC_Y:
@@ -944,14 +941,17 @@ static char *get_rna_access (int blocktype, int adrcode, char actname[], char co
strcpy(buf, ""); /* empty string */
BLI_dynstr_append(path, buf);
- /* append property to path (only if applicable) */
- if (blocktype > 0) {
- /* need to add dot before property if there was anything precceding this */
- if (buf[0])
- BLI_dynstr_append(path, ".");
-
- /* now write name of property */
- BLI_dynstr_append(path, propname);
+ /* need to add dot before property if there was anything precceding this */
+ if (buf[0])
+ BLI_dynstr_append(path, ".");
+
+ /* now write name of property */
+ BLI_dynstr_append(path, propname);
+
+ /* if there was no array index pointer provided, add it to the path */
+ if (array_index == NULL) {
+ sprintf(buf, "[\"%d\"]", dummy_index);
+ BLI_dynstr_append(path, buf);
}
/* convert to normal MEM_malloc'd string */
@@ -965,11 +965,40 @@ static char *get_rna_access (int blocktype, int adrcode, char actname[], char co
/* *************************************************** */
/* Conversion Utilities */
+/* Convert adrcodes to driver target transform channel types */
+static short adrcode_to_dtar_transchan (short adrcode)
+{
+ switch (adrcode) {
+ case OB_LOC_X:
+ return DTAR_TRANSCHAN_LOCX;
+ case OB_LOC_Y:
+ return DTAR_TRANSCHAN_LOCY;
+ case OB_LOC_Z:
+ return DTAR_TRANSCHAN_LOCZ;
+
+ case OB_ROT_X:
+ return DTAR_TRANSCHAN_ROTX;
+ case OB_ROT_Y:
+ return DTAR_TRANSCHAN_ROTY;
+ case OB_ROT_Z:
+ return DTAR_TRANSCHAN_ROTZ;
+
+ case OB_SIZE_X:
+ return DTAR_TRANSCHAN_SCALEX;
+ case OB_SIZE_Y:
+ return DTAR_TRANSCHAN_SCALEX;
+ case OB_SIZE_Z:
+ return DTAR_TRANSCHAN_SCALEX;
+
+ default:
+ return 0;
+ }
+}
+
/* Convert IpoDriver to ChannelDriver - will free the old data (i.e. the old driver) */
static ChannelDriver *idriver_to_cdriver (IpoDriver *idriver)
{
ChannelDriver *cdriver;
- DriverTarget *dtar=NULL, *dtar2=NULL;
/* allocate memory for new driver */
cdriver= MEM_callocN(sizeof(ChannelDriver), "ChannelDriver");
@@ -977,85 +1006,59 @@ static ChannelDriver *idriver_to_cdriver (IpoDriver *idriver)
/* if 'pydriver', just copy data across */
if (idriver->type == IPO_DRIVER_TYPE_PYTHON) {
/* PyDriver only requires the expression to be copied */
- // TODO: but the expression will be useless...
+ // FIXME: expression will be useless due to API changes, but at least not totally lost
cdriver->type = DRIVER_TYPE_PYTHON;
- strcpy(cdriver->expression, idriver->name); // XXX is this safe?
+ if (idriver->name[0])
+ BLI_strncpy(cdriver->expression, idriver->name, sizeof(cdriver->expression));
}
else {
- /* what to store depends on the 'blocktype' (ID_OB or ID_PO - object or posechannel) */
- if (idriver->blocktype == ID_AR) {
- /* ID_PO */
+ DriverVar *dvar = NULL;
+ DriverTarget *dtar = NULL;
+
+ /* this should be ok for all types here... */
+ cdriver->type= DRIVER_TYPE_AVERAGE;
+
+ /* what to store depends on the 'blocktype' - object or posechannel */
+ if (idriver->blocktype == ID_AR) { /* PoseChannel */
if (idriver->adrcode == OB_ROT_DIFF) {
- /* Rotational Difference is a special type of driver now... */
- cdriver->type= DRIVER_TYPE_ROTDIFF;
-
- /* make 2 driver targets */
- dtar= driver_add_new_target(cdriver);
- dtar2= driver_add_new_target(cdriver);
+ /* Rotational Difference requires a special type of variable */
+ dvar= driver_add_new_variable(cdriver);
+ driver_change_variable_type(dvar, DVAR_TYPE_ROT_DIFF);
- /* driver must use bones from same armature... */
- dtar->id= dtar2->id= (ID *)idriver->ob;
+ /* first bone target */
+ dtar= &dvar->targets[0];
+ dtar->id= (ID *)idriver->ob;
+ if (idriver->name[0])
+ BLI_strncpy(dtar->pchan_name, idriver->name, 32);
- /* paths for the two targets get the pointers to the relevant Pose-Channels
- * - return pointers to Pose-Channels not rotation channels, as calculation code is picky
- * - old bone names were stored in same var, in idriver->name
- *
- * - we use several hacks here - blocktype == -1 specifies that no property needs to be found, and
- * providing a name for 'actname' will automatically imply Pose-Channel with name 'actname'
- */
- dtar->rna_path= get_rna_access(-1, -1, idriver->name, NULL, NULL);
- dtar2->rna_path= get_rna_access(-1, -1, idriver->name+DRIVER_NAME_OFFS, NULL, NULL);
+ /* second bone target (name was stored in same var as the first one) */
+ dtar= &dvar->targets[1];
+ dtar->id= (ID *)idriver->ob;
+ if (idriver->name[0]) // xxx... for safety
+ BLI_strncpy(dtar->pchan_name, idriver->name+DRIVER_NAME_OFFS, 32);
}
else {
- /* 'standard' driver */
- cdriver->type= DRIVER_TYPE_AVERAGE;
+ /* only a single variable, of type 'transform channel' */
+ dvar= driver_add_new_variable(cdriver);
+ driver_change_variable_type(dvar, DVAR_TYPE_TRANSFORM_CHAN);
- /* make 1 driver target */
- dtar= driver_add_new_target(cdriver);
+ /* only requires a single target */
+ dtar= &dvar->targets[0];
dtar->id= (ID *)idriver->ob;
-
- switch (idriver->adrcode) {
- case OB_LOC_X: /* x,y,z location are quite straightforward */
- dtar->rna_path= get_rna_access(ID_PO, AC_LOC_X, idriver->name, NULL, &dtar->array_index);
- break;
- case OB_LOC_Y:
- dtar->rna_path= get_rna_access(ID_PO, AC_LOC_Y, idriver->name, NULL, &dtar->array_index);
- break;
- case OB_LOC_Z:
- dtar->rna_path= get_rna_access(ID_PO, AC_LOC_Z, idriver->name, NULL, &dtar->array_index);
- break;
-
- case OB_SIZE_X: /* x,y,z scaling are also quite straightforward */
- dtar->rna_path= get_rna_access(ID_PO, AC_SIZE_X, idriver->name, NULL, &dtar->array_index);
- break;
- case OB_SIZE_Y:
- dtar->rna_path= get_rna_access(ID_PO, AC_SIZE_Y, idriver->name, NULL, &dtar->array_index);
- break;
- case OB_SIZE_Z:
- dtar->rna_path= get_rna_access(ID_PO, AC_SIZE_Z, idriver->name, NULL, &dtar->array_index);
- break;
-
- case OB_ROT_X: /* rotation - we need to be careful with this... */
- case OB_ROT_Y:
- case OB_ROT_Z:
- {
- /* -1 here, not rotation code, since old system didn't have eulers */
- dtar->rna_path= get_rna_access(ID_PO, -1, idriver->name, NULL, NULL);
- dtar->array_index= idriver->adrcode - OB_ROT_X;
- }
- break;
- }
+ if (idriver->name[0])
+ BLI_strncpy(dtar->pchan_name, idriver->name, 32);
+ dtar->transChan= adrcode_to_dtar_transchan(idriver->adrcode);
}
}
- else {
- /* ID_OB */
- cdriver->type= DRIVER_TYPE_AVERAGE;
-
- /* make 1 driver target */
- dtar= driver_add_new_target(cdriver);
+ else { /* Object */
+ /* only a single variable, of type 'transform channel' */
+ dvar= driver_add_new_variable(cdriver);
+ driver_change_variable_type(dvar, DVAR_TYPE_TRANSFORM_CHAN);
+ /* only requires single target */
+ dtar= &dvar->targets[0];
dtar->id= (ID *)idriver->ob;
- dtar->rna_path= get_rna_access(ID_OB, idriver->adrcode, NULL, NULL, &dtar->array_index);
+ dtar->transChan= adrcode_to_dtar_transchan(idriver->adrcode);
}
}
@@ -1288,14 +1291,11 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha
* - need to go from degrees to radians...
* - there's only really 1 target to worry about
*/
- if (fcu->driver && fcu->driver->targets.first) {
- DriverTarget *dtar= fcu->driver->targets.first;
+ if (fcu->driver && fcu->driver->variables.first) {
+ DriverVar *dvar= fcu->driver->variables.first;
+ DriverTarget *dtar= &dvar->targets[0];
- /* since drivers could only be for objects, we should just check for 'rotation' being
- * in the name of the path given
- * - WARNING: this will break if we encounter a bone or object explictly named in that way...
- */
- if ((dtar && dtar->rna_path) && strstr(dtar->rna_path, "rotation")) {
+ if (ELEM3(dtar->transChan, DTAR_TRANSCHAN_ROTX, DTAR_TRANSCHAN_ROTY, DTAR_TRANSCHAN_ROTZ)) {
const float fac= (float)M_PI / 180.0f;
dst->vec[0][0] *= fac;
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index c38cfe4ee27..ae3d201a918 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -1274,13 +1274,13 @@ void all_local(Library *lib, int untagged_only)
id->newid= NULL;
idn= id->next; /* id is possibly being inserted again */
- /* The check on the second line (LIB_APPEND_TAG) is done so its
+ /* The check on the second line (LIB_PRE_EXISTING) is done so its
* possible to tag data you dont want to be made local, used for
* appending data, so any libdata alredy linked wont become local
* (very nasty to discover all your links are lost after appending)
* */
if(id->flag & (LIB_EXTERN|LIB_INDIRECT|LIB_NEW) &&
- (untagged_only==0 || !(id->flag & LIB_APPEND_TAG)))
+ (untagged_only==0 || !(id->flag & LIB_PRE_EXISTING)))
{
if(lib==NULL || id->lib==lib) {
id->flag &= ~(LIB_EXTERN|LIB_INDIRECT|LIB_NEW);
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index a3e0ab04991..3567c061f04 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -184,6 +184,9 @@ void init_material(Material *ma)
ma->vol.shade_type = MA_VOL_SHADE_SHADED;
ma->vol.shadeflag |= MA_VOL_PRECACHESHADING;
ma->vol.precache_resolution = 50;
+ ma->vol.ms_spread = 0.2f;
+ ma->vol.ms_diff = 1.f;
+ ma->vol.ms_intensity = 1.f;
ma->mode= MA_TRACEBLE|MA_SHADBUF|MA_SHADOW|MA_RAYBIAS|MA_TANGENT_STR|MA_ZTRANSP;
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index e0640a76f43..fd152c118ae 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -144,12 +144,15 @@ static int is_last_displist(Object *ob)
return 0;
}
-static DerivedMesh *get_original_dm(Scene *scene, Object *ob, float (*vertexCos)[3], int orco)
+/* returns a derived mesh if dm == NULL, for deforming modifiers that need it */
+static DerivedMesh *get_dm(Scene *scene, Object *ob, EditMesh *em, DerivedMesh *dm, float (*vertexCos)[3], int orco)
{
- DerivedMesh *dm= NULL;
+ if(dm)
+ return dm;
if(ob->type==OB_MESH) {
- dm = CDDM_from_mesh((Mesh*)(ob->data), ob);
+ if(em) dm= CDDM_from_editmesh(em, ob->data);
+ else dm = CDDM_from_mesh((Mesh*)(ob->data), ob);
if(vertexCos) {
CDDM_apply_vert_coords(dm, vertexCos);
@@ -185,6 +188,26 @@ static DerivedMesh *get_original_dm(Scene *scene, Object *ob, float (*vertexCos)
return dm;
}
+/* returns a cdderivedmesh if dm == NULL or is another type of derivedmesh */
+static DerivedMesh *get_cddm(Scene *scene, Object *ob, EditMesh *em, DerivedMesh *dm, float (*vertexCos)[3])
+{
+ if(dm && dm->type == DM_TYPE_CDDM)
+ return dm;
+
+ if(!dm) {
+ dm= get_dm(scene, ob, em, dm, vertexCos, 0);
+ }
+ else {
+ dm= CDDM_copy(dm);
+ CDDM_apply_vert_coords(dm, vertexCos);
+ }
+
+ if(dm)
+ CDDM_calc_normals(dm);
+
+ return dm;
+}
+
/***/
static int noneModifier_isDisabled(ModifierData *md, int userRenderParams)
@@ -3770,37 +3793,26 @@ static void displaceModifier_deformVerts(
ModifierData *md, Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
{
- DerivedMesh *dm;
-
- if(derivedData) dm = CDDM_copy(derivedData);
- else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob);
- else return;
-
- CDDM_apply_vert_coords(dm, vertexCos);
- CDDM_calc_normals(dm);
+ DerivedMesh *dm= get_cddm(md->scene, ob, NULL, derivedData, vertexCos);
displaceModifier_do((DisplaceModifierData *)md, ob, dm,
vertexCos, numVerts);
- dm->release(dm);
+ if(dm != derivedData)
+ dm->release(dm);
}
static void displaceModifier_deformVertsEM(
ModifierData *md, Object *ob, EditMesh *editData,
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
{
- DerivedMesh *dm;
-
- if(derivedData) dm = CDDM_copy(derivedData);
- else dm = CDDM_from_editmesh(editData, ob->data);
-
- CDDM_apply_vert_coords(dm, vertexCos);
- CDDM_calc_normals(dm);
+ DerivedMesh *dm= get_cddm(md->scene, ob, editData, derivedData, vertexCos);
displaceModifier_do((DisplaceModifierData *)md, ob, dm,
vertexCos, numVerts);
- dm->release(dm);
+ if(dm != derivedData)
+ dm->release(dm);
}
/* UVProject */
@@ -4328,7 +4340,7 @@ static void smoothModifier_do(
fac = smd->fac;
facm = 1 - fac;
- medges = CDDM_get_edges(dm);
+ medges = dm->getEdgeArray(dm);
numDMEdges = dm->getNumEdges(dm);
defgrp_index = -1;
@@ -4447,36 +4459,26 @@ static void smoothModifier_deformVerts(
ModifierData *md, Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
{
- DerivedMesh *dm;
-
- if(derivedData) dm = CDDM_copy(derivedData);
- else dm = CDDM_from_mesh(ob->data, ob);
-
- CDDM_apply_vert_coords(dm, vertexCos);
- CDDM_calc_normals(dm);
+ DerivedMesh *dm= get_dm(md->scene, ob, NULL, derivedData, NULL, 0);
smoothModifier_do((SmoothModifierData *)md, ob, dm,
vertexCos, numVerts);
- dm->release(dm);
+ if(dm != derivedData)
+ dm->release(dm);
}
static void smoothModifier_deformVertsEM(
ModifierData *md, Object *ob, EditMesh *editData,
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
{
- DerivedMesh *dm;
-
- if(derivedData) dm = CDDM_copy(derivedData);
- else dm = CDDM_from_editmesh(editData, ob->data);
-
- CDDM_apply_vert_coords(dm, vertexCos);
- CDDM_calc_normals(dm);
+ DerivedMesh *dm= get_dm(md->scene, ob, editData, derivedData, NULL, 0);
smoothModifier_do((SmoothModifierData *)md, ob, dm,
vertexCos, numVerts);
- dm->release(dm);
+ if(dm != derivedData)
+ dm->release(dm);
}
/* Cast */
@@ -5027,38 +5029,34 @@ static void castModifier_deformVerts(
ModifierData *md, Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
{
- DerivedMesh *dm = derivedData;
+ DerivedMesh *dm = get_dm(md->scene, ob, NULL, derivedData, NULL, 0);
CastModifierData *cmd = (CastModifierData *)md;
- if (!dm && ob->type == OB_MESH)
- dm = CDDM_from_mesh(ob->data, ob);
-
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 */
castModifier_sphere_do(cmd, ob, dm, vertexCos, numVerts);
}
- if (!derivedData && dm) dm->release(dm);
+ if(dm != derivedData)
+ dm->release(dm);
}
static void castModifier_deformVertsEM(
ModifierData *md, Object *ob, EditMesh *editData,
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
{
- DerivedMesh *dm = derivedData;
+ DerivedMesh *dm = get_dm(md->scene, ob, editData, derivedData, NULL, 0);
CastModifierData *cmd = (CastModifierData *)md;
- if (!dm && ob->type == OB_MESH)
- dm = CDDM_from_editmesh(editData, ob->data);
-
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 */
castModifier_sphere_do(cmd, ob, dm, vertexCos, numVerts);
}
- if (!derivedData && dm) dm->release(dm);
+ if(dm != derivedData)
+ dm->release(dm);
}
/* Wave */
@@ -5429,45 +5427,36 @@ static void waveModifier_deformVerts(
ModifierData *md, Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
{
- DerivedMesh *dm;
+ DerivedMesh *dm= derivedData;
WaveModifierData *wmd = (WaveModifierData *)md;
- if(!wmd->texture && !wmd->defgrp_name[0] && !(wmd->flag & MOD_WAVE_NORM))
- dm = derivedData;
- else if(derivedData) dm = derivedData;
- else if(ob->type == OB_MESH) dm = CDDM_from_mesh(ob->data, ob);
- else return;
-
- if(wmd->flag & MOD_WAVE_NORM) {
- CDDM_apply_vert_coords(dm, vertexCos);
- CDDM_calc_normals(dm);
- }
+ if(wmd->flag & MOD_WAVE_NORM)
+ dm= get_cddm(md->scene, ob, NULL, dm, vertexCos);
+ else if(wmd->texture || wmd->defgrp_name[0])
+ dm= get_dm(md->scene, ob, NULL, dm, NULL, 0);
waveModifier_do(wmd, md->scene, ob, dm, vertexCos, numVerts);
- if(dm != derivedData) dm->release(dm);
+ if(dm != derivedData)
+ dm->release(dm);
}
static void waveModifier_deformVertsEM(
ModifierData *md, Object *ob, EditMesh *editData,
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
{
- DerivedMesh *dm;
+ DerivedMesh *dm= derivedData;
WaveModifierData *wmd = (WaveModifierData *)md;
- if(!wmd->texture && !wmd->defgrp_name[0] && !(wmd->flag & MOD_WAVE_NORM))
- dm = derivedData;
- else if(derivedData) dm = CDDM_copy(derivedData);
- else dm = CDDM_from_editmesh(editData, ob->data);
-
- if(wmd->flag & MOD_WAVE_NORM) {
- CDDM_apply_vert_coords(dm, vertexCos);
- CDDM_calc_normals(dm);
- }
+ if(wmd->flag & MOD_WAVE_NORM)
+ dm= get_cddm(md->scene, ob, editData, dm, vertexCos);
+ else if(wmd->texture || wmd->defgrp_name[0])
+ dm= get_dm(md->scene, ob, editData, dm, NULL, 0);
waveModifier_do(wmd, md->scene, ob, dm, vertexCos, numVerts);
- if(dm != derivedData) dm->release(dm);
+ if(dm != derivedData)
+ dm->release(dm);
}
/* Armature */
@@ -6289,18 +6278,12 @@ static void smokeModifier_deformVerts(
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
{
SmokeModifierData *smd = (SmokeModifierData*) md;
- DerivedMesh *dm = NULL;
-
- if(derivedData) dm = derivedData;
- else if(ob->type == OB_MESH) dm = CDDM_from_mesh(ob->data, ob);
- else return;
-
- CDDM_apply_vert_coords(dm, vertexCos);
- CDDM_calc_normals(dm);
+ DerivedMesh *dm = dm= get_cddm(md->scene, ob, NULL, derivedData, vertexCos);
smokeModifier_do(smd, md->scene, ob, dm, useRenderParams, isFinalCalc);
- if(dm != derivedData) dm->release(dm);
+ if(dm != derivedData)
+ dm->release(dm);
}
static int smokeModifier_dependsOnTime(ModifierData *md)
@@ -6701,7 +6684,7 @@ static void surfaceModifier_deformVerts(
/* if possible use/create DerivedMesh */
if(derivedData) surmd->dm = CDDM_copy(derivedData);
- else surmd->dm = get_original_dm(md->scene, ob, NULL, 0);
+ else surmd->dm = get_dm(md->scene, ob, NULL, NULL, NULL, 0);
if(!ob->pd)
{
@@ -6866,7 +6849,10 @@ static void particleSystemModifier_freeData(ModifierData *md)
psmd->dm=0;
}
- psmd->psys->flag |= PSYS_DELETE;
+ /* ED_object_modifier_remove may have freed this first before calling
+ * modifier_free (which calls this function) */
+ if(psmd->psys)
+ psmd->psys->flag |= PSYS_DELETE;
}
static void particleSystemModifier_copyData(ModifierData *md, ModifierData *target)
{
@@ -6941,7 +6927,7 @@ static void particleSystemModifier_deformVerts(
return;
if(dm==0) {
- dm= get_original_dm(md->scene, ob, vertexCos, 1);
+ dm= get_dm(md->scene, ob, NULL, NULL, vertexCos, 1);
if(!dm)
return;
@@ -8342,7 +8328,7 @@ static void meshdeformModifier_do(
/* if we don't have one computed, use derivedmesh from data
* without any modifiers */
if(!cagedm) {
- cagedm= get_original_dm(md->scene, mmd->object, NULL, 0);
+ cagedm= get_dm(md->scene, mmd->object, NULL, NULL, NULL, 0);
if(cagedm)
cagedm->needsFree= 1;
}
@@ -8478,14 +8464,10 @@ static void meshdeformModifier_deformVerts(
ModifierData *md, Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
{
- DerivedMesh *dm;
-
- if (!derivedData) {
- dm= get_original_dm(md->scene, ob, NULL, 0);
- if (dm == NULL) return;
- }
- else dm= derivedData;
+ DerivedMesh *dm= get_dm(md->scene, ob, NULL, derivedData, NULL, 0);;
+ if(!dm)
+ return;
modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */
@@ -8622,52 +8604,31 @@ static void shrinkwrapModifier_foreachObjectLink(ModifierData *md, Object *ob, O
static void shrinkwrapModifier_deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
{
- DerivedMesh *dm = NULL;
+ DerivedMesh *dm = derivedData;
CustomDataMask dataMask = shrinkwrapModifier_requiredDataMask(ob, md);
- /* We implement requiredDataMask but thats not really usefull since mesh_calc_modifiers pass a NULL derivedData or without the modified vertexs applied */
+ /* ensure we get a CDDM with applied vertex coords */
if(dataMask)
- {
- if(derivedData) dm = CDDM_copy(derivedData);
- else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob);
- else if(ob->type==OB_LATTICE) dm = NULL;
- else return;
-
- if(dm != NULL && (dataMask & (1<<CD_MVERT)))
- {
- CDDM_apply_vert_coords(dm, vertexCos);
- CDDM_calc_normals(dm);
- }
- }
+ dm= get_cddm(md->scene, ob, NULL, dm, vertexCos);
shrinkwrapModifier_deform((ShrinkwrapModifierData*)md, md->scene, ob, dm, vertexCos, numVerts);
- if(dm)
+ if(dm != derivedData)
dm->release(dm);
}
static void shrinkwrapModifier_deformVertsEM(ModifierData *md, Object *ob, EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
{
- DerivedMesh *dm = NULL;
+ DerivedMesh *dm = derivedData;
CustomDataMask dataMask = shrinkwrapModifier_requiredDataMask(ob, md);
+ /* ensure we get a CDDM with applied vertex coords */
if(dataMask)
- {
- if(derivedData) dm = CDDM_copy(derivedData);
- else if(ob->type==OB_MESH) dm = CDDM_from_editmesh(editData, ob->data);
- else if(ob->type==OB_LATTICE) dm = NULL;
- else return;
-
- if(dm != NULL && (dataMask & (1<<CD_MVERT)))
- {
- CDDM_apply_vert_coords(dm, vertexCos);
- CDDM_calc_normals(dm);
- }
- }
+ dm= get_cddm(md->scene, ob, editData, dm, vertexCos);
shrinkwrapModifier_deform((ShrinkwrapModifierData*)md, md->scene, ob, dm, vertexCos, numVerts);
- if(dm)
+ if(dm != derivedData)
dm->release(dm);
}
@@ -8736,54 +8697,33 @@ static void simpledeformModifier_updateDepgraph(ModifierData *md, DagForest *for
static void simpledeformModifier_deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
{
- DerivedMesh *dm = NULL;
+ DerivedMesh *dm = derivedData;
CustomDataMask dataMask = simpledeformModifier_requiredDataMask(ob, md);
- /* We implement requiredDataMask but thats not really usefull since mesh_calc_modifiers pass a NULL derivedData or without the modified vertexs applied */
+ /* we implement requiredDataMask but thats not really usefull since
+ mesh_calc_modifiers pass a NULL derivedData */
if(dataMask)
- {
- if(derivedData) dm = CDDM_copy(derivedData);
- else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob);
- else if(ob->type==OB_LATTICE) dm = NULL;
- else return;
-
- if(dm != NULL && (dataMask & CD_MVERT))
- {
- CDDM_apply_vert_coords(dm, vertexCos);
- CDDM_calc_normals(dm);
- }
- }
+ dm= get_dm(md->scene, ob, NULL, dm, NULL, 0);
SimpleDeformModifier_do((SimpleDeformModifierData*)md, ob, dm, vertexCos, numVerts);
- if(dm)
+ if(dm != derivedData)
dm->release(dm);
-
}
static void simpledeformModifier_deformVertsEM(ModifierData *md, Object *ob, EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
{
- DerivedMesh *dm = NULL;
+ DerivedMesh *dm = derivedData;
CustomDataMask dataMask = simpledeformModifier_requiredDataMask(ob, md);
- /* We implement requiredDataMask but thats not really usefull since mesh_calc_modifiers pass a NULL derivedData or without the modified vertexs applied */
+ /* we implement requiredDataMask but thats not really usefull since
+ mesh_calc_modifiers pass a NULL derivedData */
if(dataMask)
- {
- if(derivedData) dm = CDDM_copy(derivedData);
- else if(ob->type==OB_MESH) dm = CDDM_from_editmesh(editData, ob->data);
- else if(ob->type==OB_LATTICE) dm = NULL;
- else return;
-
- if(dm != NULL && (dataMask & CD_MVERT))
- {
- CDDM_apply_vert_coords(dm, vertexCos);
- CDDM_calc_normals(dm);
- }
- }
+ dm= get_dm(md->scene, ob, editData, dm, NULL, 0);
SimpleDeformModifier_do((SimpleDeformModifierData*)md, ob, dm, vertexCos, numVerts);
- if(dm)
+ if(dm != derivedData)
dm->release(dm);
}
@@ -9248,7 +9188,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
mti = INIT_TYPE(Solidify);
mti->type = eModifierTypeType_Constructive;
mti->flags = eModifierTypeFlag_AcceptsMesh
- //| eModifierTypeFlag_SupportsMapping
+ | eModifierTypeFlag_SupportsMapping
| eModifierTypeFlag_SupportsEditmode
| eModifierTypeFlag_EnableInEditmode;
mti->initData = solidifyModifier_initData;
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 84ef4fb6d1c..b7991d0c589 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -531,20 +531,6 @@ bNode *nodeMakeGroupFromSelected(bNodeTree *ntree)
node->locx-= 0.5f*(min[0]+max[0]);
node->locy-= 0.5f*(min[1]+max[1]);
- /* set selin and selout of the nodetree */
- for(sock= node->inputs.first; sock; sock= sock->next) {
- if(sock->flag & SOCK_SEL) {
- ngroup->selin= sock;
- break;
- }
- }
- for(sock= node->outputs.first; sock; sock= sock->next) {
- if(sock->flag & SOCK_SEL) {
- ngroup->selout= sock;
- break;
- }
- }
-
/* set socket own_index to zero since it can still have a value
* from being in a group before, otherwise it doesn't get a unique
* index in group_verify_own_indices */
@@ -1063,6 +1049,18 @@ void nodeRemLink(bNodeTree *ntree, bNodeLink *link)
MEM_freeN(link);
}
+void nodeRemSocketLinks(bNodeTree *ntree, bNodeSocket *sock)
+{
+ bNodeLink *link, *next;
+
+ for(link= ntree->links.first; link; link= next) {
+ next= link->next;
+ if(link->fromsock==sock || link->tosock==sock) {
+ nodeRemLink(ntree, link);
+ }
+ }
+}
+
bNodeTree *ntreeAddTree(int type)
{
@@ -1122,28 +1120,6 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree, int internal_select)
node->flag &= ~(NODE_SELECT|NODE_ACTIVE);
nnode->flag |= NODE_SELECT;
}
-
- /* deselect original sockets */
- for(sock= node->inputs.first; sock; sock= sock->next) {
- if(sock->flag & SOCK_SEL) sock->flag&= ~SOCK_SEL;
- }
- for(sock= node->outputs.first; sock; sock= sock->next) {
- if(sock->flag & SOCK_SEL) sock->flag&= ~SOCK_SEL;
- }
-
- /* set tree selin and selout to new sockets */
- for(sock= nnode->inputs.first; sock; sock= sock->next) {
- if(sock->flag & SOCK_SEL) {
- ntree->selin= sock;
- break;
- }
- }
- for(sock= nnode->outputs.first; sock; sock= sock->next) {
- if(sock->flag & SOCK_SEL) {
- ntree->selout= sock;
- break;
- }
- }
}
if(node==last) break;
}
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 24d5b9cd882..762ad2432b0 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -167,9 +167,9 @@ void object_free_particlesystems(Object *ob)
{
while(ob->particlesystem.first){
ParticleSystem *psys = ob->particlesystem.first;
-
+
BLI_remlink(&ob->particlesystem,psys);
-
+
psys_free(ob,psys);
}
}
@@ -194,9 +194,9 @@ void object_free_modifiers(Object *ob)
{
while (ob->modifiers.first) {
ModifierData *md = ob->modifiers.first;
-
+
BLI_remlink(&ob->modifiers, md);
-
+
modifier_free(md);
}
@@ -207,6 +207,27 @@ void object_free_modifiers(Object *ob)
object_free_softbody(ob);
}
+void object_link_modifiers(struct Object *ob, struct Object *from)
+{
+ ModifierData *md;
+ object_free_modifiers(ob);
+
+ for (md=from->modifiers.first; md; md=md->next) {
+ ModifierData *nmd = NULL;
+
+ if(ELEM4(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_ParticleInstance, eModifierType_Collision)) continue;
+
+ nmd = modifier_new(md->type);
+ modifier_copyData(md, nmd);
+ BLI_addtail(&ob->modifiers, nmd);
+ }
+
+ copy_object_particlesystems(from, ob);
+ copy_object_softbody(from, ob);
+
+ // TODO: smoke?, cloth?
+}
+
/* here we will collect all local displist stuff */
/* also (ab)used in depsgraph */
void object_free_display(Object *ob)
@@ -283,6 +304,8 @@ void free_object(Object *ob)
BLI_freelistN(&ob->defbase);
if(ob->pose)
free_pose(ob->pose);
+ if(ob->mpath)
+ animviz_free_motionpath(ob->mpath);
free_properties(&ob->prop);
object_free_modifiers(ob);
@@ -332,6 +355,7 @@ void unlink_object(Scene *scene, Object *ob)
unlink_actuators(&ob->actuators);
/* check all objects: parents en bevels and fields, also from libraries */
+ // FIXME: need to check all animation blocks (drivers)
obt= G.main->object.first;
while(obt) {
if(obt->proxy==ob)
@@ -982,7 +1006,7 @@ Object *add_only_object(int type, char *name)
ob->quat[0]= ob->dquat[0]= 1.0f;
/* rotation locks should be 4D for 4 component rotations by default... */
ob->protectflag = OB_LOCK_ROT4D;
-
+
unit_m4(ob->constinv);
unit_m4(ob->parentinv);
unit_m4(ob->obmat);
@@ -1021,6 +1045,9 @@ Object *add_only_object(int type, char *name)
ob->fluidsimSettings = NULL;
ob->pc_ids.first = ob->pc_ids.last = NULL;
+
+ /* Animation Visualisation defaults */
+ animviz_settings_init(&ob->avs);
return ob;
}
@@ -1473,13 +1500,18 @@ void object_make_proxy(Object *ob, Object *target, Object *gob)
for (fcu= ob->adt->drivers.first; fcu; fcu= fcu->next) {
ChannelDriver *driver= fcu->driver;
- DriverTarget *dtar;
+ DriverVar *dvar;
- for (dtar= driver->targets.first; dtar; dtar= dtar->next) {
- if ((Object *)dtar->id == target)
- dtar->id= (ID *)ob;
- else
- id_lib_extern((ID *)dtar->id);
+ for (dvar= driver->variables.first; dvar; dvar= dvar->next) {
+ /* all drivers */
+ DRIVER_TARGETS_LOOPER(dvar)
+ {
+ if ((Object *)dtar->id == target)
+ dtar->id= (ID *)ob;
+ else
+ id_lib_extern((ID *)dtar->id);
+ }
+ DRIVER_TARGETS_LOOPER_END
}
}
}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 992f63520ab..41ca5e1804a 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -361,6 +361,10 @@ void psys_check_group_weights(ParticleSettings *part)
BLI_freelistN(&part->dupliweights);
}
}
+int psys_uses_gravity(ParticleSimulationData *sim)
+{
+ return sim->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY && sim->psys->part && sim->psys->part->effector_weights->global_gravity != 0.0f;
+}
/************************************************/
/* Freeing stuff */
/************************************************/
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index bf8721fd0b0..27e0c632a81 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -2332,7 +2332,7 @@ static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra
mul_v3_fl(force,1.0f/pa_mass);
/* add global acceleration (gravitation) */
- if(sim->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY
+ if(psys_uses_gravity(sim)
/* normal gravity is too strong for hair so it's disabled by default */
&& (part->type != PART_HAIR || part->effector_weights->flag & EFF_WEIGHT_DO_HAIR)) {
float gravity[3];
@@ -2895,7 +2895,9 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
}
else {
VECCOPY(pa->state.co, col.co2);
- VECCOPY(pa->state.vel, vel);
+ /* Stickness to surface */
+ normalize_v3(nor_vec);
+ VECADDFAC(pa->state.vel, vel, nor_vec, -pd->pdef_stickness);
}
}
deflections++;
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index aa81cea79f5..926f7fde14d 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -1694,7 +1694,19 @@ static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cf
if(seq->flag & SEQ_MAKE_FLOAT) {
if (!se->ibuf->rect_float) {
- IMB_float_from_rect(se->ibuf);
+ if (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) {
+ IMB_float_from_rect(se->ibuf);
+ } else {
+ int profile = IB_PROFILE_NONE;
+
+ /* no color management:
+ * don't disturb the existing profiles */
+ SWAP(int, se->ibuf->profile, profile);
+
+ IMB_float_from_rect(se->ibuf);
+
+ SWAP(int, se->ibuf->profile, profile);
+ }
}
if (se->ibuf->rect) {
imb_freerectImBuf(se->ibuf);
@@ -2094,7 +2106,7 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
doseq= scene->r.scemode & R_DOSEQ;
scene->r.scemode &= ~R_DOSEQ;
- RE_BlenderFrame(re, sce,
+ RE_BlenderFrame(re, sce, NULL,
seq->sfra+se->nr+seq->anim_startofs);
if(rendering)
@@ -3792,7 +3804,7 @@ Sequence *sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo
info = AUD_getInfo(sound->handle);
- if (info.specs.format == AUD_FORMAT_INVALID) {
+ if (info.specs.channels == AUD_CHANNELS_INVALID) {
sound_delete(C, sound);
//if(op)
// BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 74c6afdc018..3232e2677b5 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -40,7 +40,7 @@ void sound_disable()
void sound_init()
{
- AUD_Specs specs;
+ AUD_DeviceSpecs specs;
int device, buffersize;
device = U.audiodevice;
@@ -455,7 +455,7 @@ void sound_scrub(struct bContext *C)
}
}
-AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int end, float volume)
+AUD_Device* sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, int end, float volume)
{
AUD_Device* mixdown = AUD_openReadDevice(specs);
SoundHandle *handle;
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 072a665e0e9..3997f83ed49 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -2227,7 +2227,8 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
MFace *mface = NULL;
FaceVertWeight *qweight, *tweight;
- DM_from_template(&ccgdm->dm, dm, ccgSubSurf_getNumFinalVerts(ss),
+ DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM,
+ ccgSubSurf_getNumFinalVerts(ss),
ccgSubSurf_getNumFinalEdges(ss),
ccgSubSurf_getNumFinalFaces(ss));
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 818e6195049..c60001db314 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -703,11 +703,9 @@ void make_local_texture(Tex *tex)
}
br= G.main->brush.first;
while(br) {
- for(a=0; a<MAX_MTEX; a++) {
- if(br->mtex[a] && br->mtex[a]->tex==tex) {
- if(br->id.lib) lib= 1;
- else local= 1;
- }
+ if(br->mtex.tex==tex) {
+ if(br->id.lib) lib= 1;
+ else local= 1;
}
br= br->id.next;
}
@@ -762,13 +760,11 @@ void make_local_texture(Tex *tex)
}
br= G.main->brush.first;
while(br) {
- for(a=0; a<MAX_MTEX; a++) {
- if(br->mtex[a] && br->mtex[a]->tex==tex) {
- if(br->id.lib==0) {
- br->mtex[a]->tex= texn;
- texn->id.us++;
- tex->id.us--;
- }
+ if(br->mtex.tex==tex) {
+ if(br->id.lib==0) {
+ br->mtex.tex= texn;
+ texn->id.us++;
+ tex->id.us--;
}
}
br= br->id.next;
@@ -904,10 +900,6 @@ int give_active_mtex(ID *id, MTex ***mtex_ar, short *act)
*mtex_ar= ((Lamp *)id)->mtex;
if(act) *act= (((Lamp *)id)->texact);
break;
- case ID_BR:
- *mtex_ar= ((Brush *)id)->mtex;
- if(act) *act= (((Brush *)id)->texact);
- break;
default:
*mtex_ar = NULL;
if(act) *act= 0;
@@ -932,9 +924,6 @@ void set_active_mtex(ID *id, short act)
case ID_LA:
((Lamp *)id)->texact= act;
break;
- case ID_BR:
- ((Brush *)id)->texact= act;
- break;
}
}
@@ -1016,35 +1005,18 @@ void set_current_world_texture(World *wo, Tex *newtex)
Tex *give_current_brush_texture(Brush *br)
{
- MTex *mtex= NULL;
- Tex *tex= NULL;
-
- if(br) {
- mtex= br->mtex[(int)(br->texact)];
- if(mtex) tex= mtex->tex;
- }
-
- return tex;
+ return br->mtex.tex;
}
void set_current_brush_texture(Brush *br, Tex *newtex)
{
- int act= br->texact;
-
- if(br->mtex[act] && br->mtex[act]->tex)
- id_us_min(&br->mtex[act]->tex->id);
+ if(br->mtex.tex)
+ id_us_min(&br->mtex.tex->id);
if(newtex) {
- if(!br->mtex[act])
- br->mtex[act]= add_mtex();
-
- br->mtex[act]->tex= newtex;
+ br->mtex.tex= newtex;
id_us_plus(&newtex->id);
}
- else if(br->mtex[act]) {
- MEM_freeN(br->mtex[act]);
- br->mtex[act]= NULL;
- }
}
/* ------------------------------------------------------------------------- */
diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c
index ec3d1185179..9ff5ee00bfb 100644
--- a/source/blender/blenkernel/intern/writeavi.c
+++ b/source/blender/blenkernel/intern/writeavi.c
@@ -45,6 +45,11 @@
#include "BKE_writeavi.h"
#include "AVI_avi.h"
+/* callbacks */
+static int start_avi(Scene *scene, RenderData *rd, int rectx, int recty, ReportList *reports);
+static void end_avi(void);
+static int append_avi(RenderData *rd, int frame, int *pixels, int rectx, int recty, ReportList *reports);
+static void filepath_avi(char *string, RenderData *rd);
/* ********************** general blender movie support ***************************** */
@@ -67,6 +72,7 @@ bMovieHandle *BKE_get_movie_handle(int imtype)
mh.append_movie= append_avi;
mh.end_movie= end_avi;
mh.get_next_frame = NULL;
+ mh.get_movie_path = filepath_avi;
/* do the platform specific handles */
#ifdef __sgi
@@ -86,6 +92,7 @@ bMovieHandle *BKE_get_movie_handle(int imtype)
mh.start_movie= start_qt;
mh.append_movie= append_qt;
mh.end_movie= end_qt;
+ mh.get_movie_path = filepath_qt;
}
#endif
#ifdef WITH_FFMPEG
@@ -93,6 +100,7 @@ bMovieHandle *BKE_get_movie_handle(int imtype)
mh.start_movie = start_ffmpeg;
mh.append_movie = append_ffmpeg;
mh.end_movie = end_ffmpeg;
+ mh.get_movie_path = filepath_ffmpeg;
}
#endif
if (imtype == R_FRAMESERVER) {
@@ -111,7 +119,7 @@ bMovieHandle *BKE_get_movie_handle(int imtype)
static AviMovie *avi=NULL;
static int sframe;
-void makeavistring (RenderData *rd, char *string)
+static void filepath_avi (char *string, RenderData *rd)
{
char txt[64];
@@ -128,7 +136,7 @@ void makeavistring (RenderData *rd, char *string)
}
}
-int start_avi(Scene *scene, RenderData *rd, int rectx, int recty, ReportList *reports)
+static int start_avi(Scene *scene, RenderData *rd, int rectx, int recty, ReportList *reports)
{
int x, y;
char name[256];
@@ -136,7 +144,7 @@ int start_avi(Scene *scene, RenderData *rd, int rectx, int recty, ReportList *re
int quality;
double framerate;
- makeavistring(rd, name);
+ filepath_avi(name, rd);
sframe = (rd->sfra);
x = rectx;
@@ -174,7 +182,7 @@ int start_avi(Scene *scene, RenderData *rd, int rectx, int recty, ReportList *re
return 1;
}
-int append_avi(RenderData *rd, int frame, int *pixels, int rectx, int recty, ReportList *reports)
+static int append_avi(RenderData *rd, int frame, int *pixels, int rectx, int recty, ReportList *reports)
{
unsigned int *rt1, *rt2, *rectot;
int x, y;
@@ -218,3 +226,12 @@ void end_avi(void)
avi= NULL;
}
+/* similar to BKE_makepicstring() */
+void BKE_makeanimstring(char *string, RenderData *rd)
+{
+ bMovieHandle *mh= BKE_get_movie_handle(rd->imtype);
+ if(mh->get_movie_path)
+ mh->get_movie_path(string, rd);
+ else
+ string[0]= '\0';
+}
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 417679417e4..920ff255bcc 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -75,7 +75,6 @@
#endif
extern void do_init_ffmpeg();
-static void makeffmpegstring(RenderData* rd, char* string);
static int ffmpeg_type = 0;
static int ffmpeg_codec = CODEC_ID_MPEG4;
@@ -638,7 +637,7 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
do_init_ffmpeg();
/* Determine the correct filename */
- makeffmpegstring(rd, name);
+ filepath_ffmpeg(name, rd);
fprintf(stderr, "Starting output to %s(ffmpeg)...\n"
" Using type=%d, codec=%d, audio_codec=%d,\n"
" video_bitrate=%d, audio_bitrate=%d,\n"
@@ -772,7 +771,7 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
********************************************************************** */
/* Get the output filename-- similar to the other output formats */
-static void makeffmpegstring(RenderData* rd, char* string) {
+void filepath_ffmpeg(char* string, RenderData* rd) {
// XXX quick define, solve!
#define FILE_MAXDIR 256
@@ -832,7 +831,7 @@ int start_ffmpeg(struct Scene *scene, RenderData *rd, int rectx, int recty, Repo
if(ffmpeg_multiplex_audio && audio_stream)
{
AVCodecContext* c = get_codec_from_stream(audio_stream);
- AUD_Specs specs;
+ AUD_DeviceSpecs specs;
specs.channels = c->channels;
specs.format = AUD_FORMAT_S16;
specs.rate = rd->ffcodecdata.audio_mixrate;
diff --git a/source/blender/blenlib/BLI_bpath.h b/source/blender/blenlib/BLI_bpath.h
index 874c8c7828c..730e3eda283 100644
--- a/source/blender/blenlib/BLI_bpath.h
+++ b/source/blender/blenlib/BLI_bpath.h
@@ -47,11 +47,13 @@ struct BPathIterator {
void (*setpath_callback)(struct BPathIterator *, char *);
void (*getpath_callback)(struct BPathIterator *, char *);
+ char* base_path; /* base path, the directry the blend file is in - normally G.sce */
+
/* only for seq data */
struct BPathIteratorSeqData seqdata;
};
-void BLI_bpathIterator_init (struct BPathIterator *bpi);
+void BLI_bpathIterator_init (struct BPathIterator *bpi, char *base_path);
void BLI_bpathIterator_free (struct BPathIterator *bpi);
char* BLI_bpathIterator_getLib (struct BPathIterator *bpi);
char* BLI_bpathIterator_getName (struct BPathIterator *bpi);
@@ -66,7 +68,7 @@ void BLI_bpathIterator_setPath (struct BPathIterator *bpi, char *path);
/* high level funcs */
/* creates a text file with missing files if there are any */
-void checkMissingFiles(char *txtname );
-void makeFilesRelative(char *txtname, int *tot, int *changed, int *failed, int *linked);
-void makeFilesAbsolute(char *txtname, int *tot, int *changed, int *failed, int *linked);
-void findMissingFiles(char *str);
+void checkMissingFiles(char *basepath, ReportList *reports);
+void makeFilesRelative(char *basepath, ReportList *reports);
+void makeFilesAbsolute(char *basepath, ReportList *reports);
+void findMissingFiles(char *basepath, char *str);
diff --git a/source/blender/blenlib/BLI_math_color.h b/source/blender/blenlib/BLI_math_color.h
index 7444e01c3a6..2123765643e 100644
--- a/source/blender/blenlib/BLI_math_color.h
+++ b/source/blender/blenlib/BLI_math_color.h
@@ -74,6 +74,9 @@ void linearrgb_to_srgb_v3_v3(float *col_to, float *col_from);
int constrain_rgb(float *r, float *g, float *b);
void minmax_rgb(short c[3]);
+void rgb_byte_to_float(char *in, float *out);
+void rgb_float_to_byte(float *in, char *out);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index e676001fba5..f650a55d8ad 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -111,6 +111,8 @@ int isect_axial_line_tri_v3(int axis, float co1[3], float co2[3],
int isect_aabb_aabb_v3(float min1[3], float max1[3], float min2[3], float max2[3]);
+int clip_line_plane(float clipco[3], float plane[4], float co[3]);
+
/****************************** Interpolation ********************************/
/* tri or quad, d can be NULL */
@@ -121,6 +123,8 @@ void interp_weights_poly_v3(float w[], float v[][3], int n, float p[3]);
void interp_cubic_v3(float x[3], float v[3],
float x1[3], float v1[3], float x2[3], float v2[3], float t);
+int interp_sparse_array(float *array, int list_size, float invalid);
+
void barycentric_transform(float pt_tar[3], float const pt_src[3],
const float tri_tar_p1[3], const float tri_tar_p2[3], const float tri_tar_p3[3],
const float tri_src_p1[3], const float tri_src_p2[3], const float tri_src_p3[3]);
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h
index 4dbef4ef07c..4719a835788 100644
--- a/source/blender/blenlib/BLI_math_vector.h
+++ b/source/blender/blenlib/BLI_math_vector.h
@@ -72,11 +72,13 @@ MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3]);
MINLINE void mul_v2_fl(float r[2], float f);
MINLINE void mul_v3_fl(float r[3], float f);
MINLINE void mul_v3_v3fl(float r[3], float a[3], float f);
+MINLINE void mul_v2_v2(float r[2], const float a[2]);
MINLINE void mul_v3_v3(float r[3], float a[3]);
MINLINE void mul_v3_v3v3(float r[3], float a[3], float b[3]);
MINLINE void madd_v3_v3fl(float r[3], float a[3], float f);
MINLINE void madd_v3_v3v3(float r[3], float a[3], float b[3]);
+MINLINE void madd_v2_v2v2fl(float r[2], const float a[2], const float b[2], const float f);
MINLINE void madd_v3_v3v3fl(float r[3], float a[3], float b[3], float f);
MINLINE void madd_v3_v3v3v3(float r[3], float a[3], float b[3], float c[3]);
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index 3f4b9fbae25..eebff8dfaef 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -302,6 +302,8 @@ static BVHNode *bvh_medianof3(BVHNode **a, int lo, int mid, int hi, int axis) //
return a[mid];
}
}
+
+#if 0
/*
* Quicksort algorithm modified for Introsort
*/
@@ -332,7 +334,7 @@ static void sort(BVHNode **a0, int begin, int end, int axis)
bvh_insertionsort(a, begin, end, axis);
}
}
-#if 0
+
static void sort_along_axis(BVHTree *tree, int start, int end, int axis)
{
sort(tree->nodes, start, end, axis);
diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c
index 0df9d9b8db3..626c6ee8443 100644
--- a/source/blender/blenlib/intern/bpath.c
+++ b/source/blender/blenlib/intern/bpath.c
@@ -52,7 +52,7 @@
#include "DNA_sound_types.h"
#include "DNA_scene_types.h" /* to get the current frame */
#include "DNA_sequence_types.h"
-#include "DNA_text_types.h"
+#include "DNA_windowmanager_types.h"
#include "BLI_blenlib.h"
#include "BLI_bpath.h"
@@ -61,7 +61,6 @@
#include "BKE_image.h" /* so we can check the image's type */
#include "BKE_main.h" /* so we can access G.main->*.first */
#include "BKE_sequencer.h"
-#include "BKE_text.h" /* for writing to a textblock */
#include "BKE_utildefines.h"
//XXX #include "BIF_screen.h" /* only for wait cursor */
@@ -86,19 +85,21 @@ enum BPathTypes {
BPATH_DONE
};
-void BLI_bpathIterator_init( struct BPathIterator *bpi ) {
+void BLI_bpathIterator_init( struct BPathIterator *bpi, char *base_path ) {
bpi->type = BPATH_IMAGE;
bpi->data = NULL;
bpi->getpath_callback = NULL;
bpi->setpath_callback = NULL;
- /* Sequencer spesific */
+ /* Sequencer specific */
bpi->seqdata.totseq = 0;
bpi->seqdata.seq = 0;
bpi->seqdata.seqar = NULL;
bpi->seqdata.scene = NULL;
+ bpi->base_path= base_path ? base_path : G.sce;
+
BLI_bpathIterator_step(bpi);
}
@@ -134,7 +135,7 @@ void BLI_bpathIterator_getPathExpanded( struct BPathIterator *bpi, char *path_ex
if (libpath) { /* check the files location relative to its library path */
BLI_convertstringcode(path_expanded, libpath);
} else { /* local data, use the blend files path */
- BLI_convertstringcode(path_expanded, G.sce);
+ BLI_convertstringcode(path_expanded, bpi->base_path);
}
}
char* BLI_bpathIterator_getLib( struct BPathIterator *bpi) {
@@ -413,186 +414,157 @@ int BLI_bpathIterator_isDone( struct BPathIterator *bpi) {
}
/* include the path argument */
-static void bpathToText(Text *btxt, struct BPathIterator *bpi)
+static void bpath_as_report(struct BPathIterator *bpi, const char *message, ReportList *reports)
{
+ char *prefix;
char *name;
char path_expanded[FILE_MAXDIR*2];
+ if(reports==NULL)
+ return;
+
switch(BLI_bpathIterator_getType(bpi)) {
case BPATH_IMAGE:
- txt_insert_buf( btxt, "Image \"" );
+ prefix= "Image";
break;
case BPATH_SOUND:
- txt_insert_buf( btxt, "Sound \"" );
+ prefix= "Sound";
break;
case BPATH_FONT:
- txt_insert_buf( btxt, "Font \"" );
+ prefix= "Font";
break;
case BPATH_LIB:
- txt_insert_buf( btxt, "Library \"" );
+ prefix= "Library";
break;
case BPATH_SEQ:
- txt_insert_buf( btxt, "Sequence \"" );
+ prefix= "Sequence";
break;
default:
- txt_insert_buf( btxt, "Unknown \"" );
+ prefix= "Unknown";
break;
}
name = BLI_bpathIterator_getName(bpi);
-
- if (name) {
- txt_insert_buf( btxt, name );
- }
- txt_insert_buf( btxt, "\" " );
-
BLI_bpathIterator_getPathExpanded(bpi, path_expanded);
-
- txt_insert_buf( btxt, path_expanded );
- txt_insert_buf( btxt, "\n" );
- txt_move_eof( btxt, 0 );
+
+ if(reports) {
+ if (name) BKE_reportf("%s \"%s\", \"%s\": %s", prefix, name, path_expanded, message);
+ else BKE_reportf("%s \"%s\": %s", prefix, path_expanded, message);
+ }
+
}
/* high level function */
-void checkMissingFiles( char *txtname ) {
- Text *btxt = NULL;
+void checkMissingFiles(char *basepath, ReportList *reports) {
struct BPathIterator bpi;
/* be sure there is low chance of the path being too short */
char filepath_expanded[FILE_MAXDIR*2];
- BLI_bpathIterator_init(&bpi);
+ BLI_bpathIterator_init(&bpi, basepath);
while (!BLI_bpathIterator_isDone(&bpi)) {
BLI_bpathIterator_getPathExpanded( &bpi, filepath_expanded );
- if (!BLI_exists(filepath_expanded)) {
- if (!btxt) {
- btxt = add_empty_text( "missing_files.log" );
- if (txtname) {
- BLI_strncpy(txtname, btxt->id.name+2, 24);
- }
- }
- bpathToText(btxt, &bpi);
- }
+ if (!BLI_exists(filepath_expanded))
+ bpath_as_report(&bpi, "file not found", reports);
+
BLI_bpathIterator_step(&bpi);
}
BLI_bpathIterator_free(&bpi);
}
/* dont log any errors at the moment, should probably do this */
-void makeFilesRelative(char *txtname, int *tot, int *changed, int *failed, int *linked) {
+void makeFilesRelative(char *basepath, ReportList *reports) {
+ int tot= 0, changed= 0, failed= 0, linked= 0;
struct BPathIterator bpi;
char filepath[FILE_MAX], *libpath;
/* be sure there is low chance of the path being too short */
char filepath_relative[(FILE_MAXDIR * 2) + FILE_MAXFILE];
- Text *btxt = NULL;
-
- *tot = *changed = *failed = *linked = 0;
-
- BLI_bpathIterator_init(&bpi);
+ BLI_bpathIterator_init(&bpi, basepath);
while (!BLI_bpathIterator_isDone(&bpi)) {
BLI_bpathIterator_getPath(&bpi, filepath);
libpath = BLI_bpathIterator_getLib(&bpi);
if(strncmp(filepath, "//", 2)) {
if (libpath) { /* cant make relative if we are library - TODO, LOG THIS */
- (*linked)++;
+ linked++;
} else { /* local data, use the blend files path */
BLI_strncpy(filepath_relative, filepath, sizeof(filepath_relative));
/* Important BLI_cleanup_dir runs before the path is made relative
* because it wont work for paths that start with "//../" */
- BLI_cleanup_file(G.sce, filepath_relative); /* fix any /foo/../foo/ */
- BLI_makestringcode(G.sce, filepath_relative);
+ BLI_cleanup_file(bpi.base_path, filepath_relative); /* fix any /foo/../foo/ */
+ BLI_makestringcode(bpi.base_path, filepath_relative);
/* be safe and check the length */
if (BLI_bpathIterator_getPathMaxLen(&bpi) <= strlen(filepath_relative)) {
- if (!btxt) {
- btxt = add_empty_text( "missing_no_rel.log" );
- if (txtname) {
- BLI_strncpy(txtname, btxt->id.name+2, 24);
- }
- }
- bpathToText(btxt, &bpi);
- (*failed)++;
+ bpath_as_report(&bpi, "couldn't make path relative (too long)", reports);
+ failed++;
} else {
if(strncmp(filepath_relative, "//", 2)==0) {
BLI_bpathIterator_setPath(&bpi, filepath_relative);
- (*changed)++;
+ changed++;
} else {
- if (!btxt) {
- btxt = add_empty_text( "missing_no_rel.log" );
- if (txtname) {
- BLI_strncpy(txtname, btxt->id.name+2, 24);
- }
- }
- bpathToText(btxt, &bpi);
- (*failed)++;
+ bpath_as_report(&bpi, "couldn't make path relative", reports);
+ failed++;
}
}
}
}
BLI_bpathIterator_step(&bpi);
- (*tot)++;
+ tot++;
}
BLI_bpathIterator_free(&bpi);
+
+ if(reports)
+ BKE_reportf(reports, failed ? RPT_ERROR : RPT_INFO, "Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked);
}
/* dont log any errors at the moment, should probably do this -
* Verry similar to makeFilesRelative - keep in sync! */
-void makeFilesAbsolute(char *txtname, int *tot, int *changed, int *failed, int *linked) {
+void makeFilesAbsolute(char *basepath, ReportList *reports)
+{
+ int tot= 0, changed= 0, failed= 0, linked= 0;
+
struct BPathIterator bpi;
char filepath[FILE_MAX], *libpath;
/* be sure there is low chance of the path being too short */
char filepath_absolute[(FILE_MAXDIR * 2) + FILE_MAXFILE];
- Text *btxt = NULL;
-
- *tot = *changed = *failed = *linked = 0;
-
- BLI_bpathIterator_init(&bpi);
+ BLI_bpathIterator_init(&bpi, basepath);
while (!BLI_bpathIterator_isDone(&bpi)) {
BLI_bpathIterator_getPath(&bpi, filepath);
libpath = BLI_bpathIterator_getLib(&bpi);
if(strncmp(filepath, "//", 2)==0) {
if (libpath) { /* cant make absolute if we are library - TODO, LOG THIS */
- (*linked)++;
+ linked++;
} else { /* get the expanded path and check it is relative or too long */
BLI_bpathIterator_getPathExpanded( &bpi, filepath_absolute );
- BLI_cleanup_file(G.sce, filepath_absolute); /* fix any /foo/../foo/ */
+ BLI_cleanup_file(bpi.base_path, filepath_absolute); /* fix any /foo/../foo/ */
/* to be safe, check the length */
if (BLI_bpathIterator_getPathMaxLen(&bpi) <= strlen(filepath_absolute)) {
- if (!btxt) {
- btxt = add_empty_text( "missing_no_abs.log" );
- if (txtname) {
- BLI_strncpy(txtname, btxt->id.name+2, 24);
- }
- }
- bpathToText(btxt, &bpi);
- (*failed)++;
+ bpath_as_report(&bpi, "couldn't make absolute (too long)", reports);
+ failed++;
} else {
if(strncmp(filepath_absolute, "//", 2)) {
BLI_bpathIterator_setPath(&bpi, filepath_absolute);
- (*changed)++;
+ changed++;
} else {
- if (!btxt) {
- btxt = add_empty_text( "missing_no_abs.log" );
- if (txtname) {
- BLI_strncpy(txtname, btxt->id.name+2, 24);
- }
- }
- bpathToText(btxt, &bpi);
- (*failed)++;
+ bpath_as_report(&bpi, "couldn't make absolute", reports);
+ failed++;
}
}
}
}
BLI_bpathIterator_step(&bpi);
- (*tot)++;
+ tot++;
}
BLI_bpathIterator_free(&bpi);
+
+ if(reports)
+ BKE_reportf(reports, failed ? RPT_ERROR : RPT_INFO, "Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked);
}
@@ -651,7 +623,7 @@ static int findFileRecursive(char *filename_new, const char *dirname, const char
}
/* high level function - call from fileselector */
-void findMissingFiles(char *str) {
+void findMissingFiles(char *basepath, char *str) {
struct BPathIterator bpi;
/* be sure there is low chance of the path being too short */
@@ -665,7 +637,7 @@ void findMissingFiles(char *str) {
BLI_split_dirfile_basic(str, dirname, NULL);
- BLI_bpathIterator_init(&bpi);
+ BLI_bpathIterator_init(&bpi, basepath);
while (!BLI_bpathIterator_isDone(&bpi)) {
BLI_bpathIterator_getPath(&bpi, filepath);
@@ -699,7 +671,7 @@ void findMissingFiles(char *str) {
} else {
/* copy the found path into the old one */
if (G.relbase_valid)
- BLI_makestringcode(G.sce, filename_new);
+ BLI_makestringcode(bpi.base_path, filename_new);
BLI_bpathIterator_setPath( &bpi, filename_new );
}
diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c
index 6dbd9c1381f..a4bd11a4bc8 100644
--- a/source/blender/blenlib/intern/math_color.c
+++ b/source/blender/blenlib/intern/math_color.c
@@ -274,6 +274,26 @@ void cpack_to_rgb(unsigned int col, float *r, float *g, float *b)
*b /= 255.0f;
}
+void rgb_byte_to_float(char *in, float *out)
+{
+ out[0]= ((float)in[0]) / 255.0f;
+ out[1]= ((float)in[1]) / 255.0f;
+ out[2]= ((float)in[2]) / 255.0f;
+}
+
+void rgb_float_to_byte(float *in, char *out)
+{
+ int r, g, b;
+
+ r= (int)(in[0] * 255.0);
+ g= (int)(in[1] * 255.0);
+ b= (int)(in[2] * 255.0);
+
+ out[0]= (char)((r <= 0)? 0 : (r >= 255)? 255 : r);
+ out[1]= (char)((g <= 0)? 0 : (g >= 255)? 255 : g);
+ out[2]= (char)((b <= 0)? 0 : (b >= 255)? 255 : b);
+}
+
/* ********************************* color transforms ********************************* */
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 470e5d71a45..a80f999cdbb 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -32,6 +32,7 @@
#include "BLI_math.h"
#include "BLI_memarena.h"
+#include "MEM_guardedalloc.h"
/********************************** Polygons *********************************/
@@ -1245,6 +1246,55 @@ int isect_point_tri_prism_v3(float p[3], float v1[3], float v2[3], float v3[3])
return 1;
}
+int clip_line_plane(float p1[3], float p2[3], float plane[4])
+{
+ float dp[3], n[3], div, t, pc[3];
+
+ copy_v3_v3(n, plane);
+ sub_v3_v3v3(dp, p2, p1);
+ div= dot_v3v3(dp, n);
+
+ if(div == 0.0f) /* parallel */
+ return 1;
+
+ t= -(dot_v3v3(p1, n) + plane[3])/div;
+
+ if(div > 0.0f) {
+ /* behind plane, completely clipped */
+ if(t >= 1.0f) {
+ zero_v3(p1);
+ zero_v3(p2);
+ return 0;
+ }
+
+ /* intersect plane */
+ if(t > 0.0f) {
+ madd_v3_v3v3fl(pc, p1, dp, t);
+ copy_v3_v3(p1, pc);
+ return 1;
+ }
+
+ return 1;
+ }
+ else {
+ /* behind plane, completely clipped */
+ if(t <= 0.0f) {
+ zero_v3(p1);
+ zero_v3(p2);
+ return 0;
+ }
+
+ /* intersect plane */
+ if(t < 1.0f) {
+ madd_v3_v3v3fl(pc, p1, dp, t);
+ copy_v3_v3(p2, pc);
+ return 1;
+ }
+
+ return 1;
+ }
+}
+
/****************************** Interpolation ********************************/
static float tri_signed_area(float *v1, float *v2, float *v3, int i, int j)
@@ -1408,6 +1458,85 @@ void barycentric_transform(float pt_tar[3], float const pt_src[3],
madd_v3_v3v3fl(pt_tar, pt_tar, no_tar, (z_ofs_src / area_src) * area_tar);
}
+/* given an array with some invalid values this function interpolates valid values
+ * replacing the invalid ones */
+int interp_sparse_array(float *array, int list_size, float skipval)
+{
+ int found_invalid = 0;
+ int found_valid = 0;
+ int i;
+
+ for (i=0; i < list_size; i++) {
+ if(array[i] == skipval)
+ found_invalid= 1;
+ else
+ found_valid= 1;
+ }
+
+ if(found_valid==0) {
+ return -1;
+ }
+ else if (found_invalid==0) {
+ return 0;
+ }
+ else {
+ /* found invalid depths, interpolate */
+ float valid_last= skipval;
+ int valid_ofs= 0;
+
+ float *array_up= MEM_callocN(sizeof(float) * list_size, "interp_sparse_array up");
+ float *array_down= MEM_callocN(sizeof(float) * list_size, "interp_sparse_array up");
+
+ int *ofs_tot_up= MEM_callocN(sizeof(int) * list_size, "interp_sparse_array tup");
+ int *ofs_tot_down= MEM_callocN(sizeof(int) * list_size, "interp_sparse_array tdown");
+
+ for (i=0; i < list_size; i++) {
+ if(array[i] == skipval) {
+ array_up[i]= valid_last;
+ ofs_tot_up[i]= ++valid_ofs;
+ }
+ else {
+ valid_last= array[i];
+ valid_ofs= 0;
+ }
+ }
+
+ valid_last= skipval;
+ valid_ofs= 0;
+
+ for (i=list_size-1; i >= 0; i--) {
+ if(array[i] == skipval) {
+ array_down[i]= valid_last;
+ ofs_tot_down[i]= ++valid_ofs;
+ }
+ else {
+ valid_last= array[i];
+ valid_ofs= 0;
+ }
+ }
+
+ /* now blend */
+ for (i=0; i < list_size; i++) {
+ if(array[i] == skipval) {
+ if(array_up[i] != skipval && array_down[i] != skipval) {
+ array[i]= ((array_up[i] * ofs_tot_down[i]) + (array_down[i] * ofs_tot_up[i])) / (float)(ofs_tot_down[i] + ofs_tot_up[i]);
+ } else if (array_up[i] != skipval) {
+ array[i]= array_up[i];
+ } else if (array_down[i] != skipval) {
+ array[i]= array_down[i];
+ }
+ }
+ }
+
+ MEM_freeN(array_up);
+ MEM_freeN(array_down);
+
+ MEM_freeN(ofs_tot_up);
+ MEM_freeN(ofs_tot_down);
+ }
+
+ return 1;
+}
/* Mean value weights - smooth interpolation weights for polygons with
* more than 3 vertices */
diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c
index 8b09cb86d3a..86a0d0f49a1 100644
--- a/source/blender/blenlib/intern/math_vector_inline.c
+++ b/source/blender/blenlib/intern/math_vector_inline.c
@@ -145,6 +145,12 @@ MINLINE void mul_v3_v3fl(float r[3], float a[3], float f)
r[2]= a[2]*f;
}
+MINLINE void mul_v2_v2(float r[2], const float a[2])
+{
+ r[0] *= a[0];
+ r[1] *= a[1];
+}
+
MINLINE void mul_v3_v3(float r[3], float a[3])
{
r[0] *= a[0];
@@ -166,6 +172,12 @@ MINLINE void madd_v3_v3v3(float r[3], float a[3], float b[3])
r[2] += a[2]*b[2];
}
+MINLINE void madd_v2_v2v2fl(float r[2], const float a[2], const float b[2], const float f)
+{
+ r[0] = a[0] + b[0]*f;
+ r[1] = a[1] + b[1]*f;
+}
+
MINLINE void madd_v3_v3v3fl(float r[3], float a[3], float b[3], float f)
{
r[0] = a[0] + b[0]*f;
diff --git a/source/blender/blenlib/intern/pbvh.c b/source/blender/blenlib/intern/pbvh.c
index 6f33fab2571..0133017eb4d 100644
--- a/source/blender/blenlib/intern/pbvh.c
+++ b/source/blender/blenlib/intern/pbvh.c
@@ -633,6 +633,12 @@ static PBVHNode *pbvh_iter_next(PBVHIter *iter)
/* pop node */
iter->stacksize--;
node= iter->stack[iter->stacksize].node;
+
+ /* on a mesh with no faces this can happen
+ * can remove this check if we know meshes have at least 1 face */
+ if(node==NULL)
+ return NULL;
+
revisiting= iter->stack[iter->stacksize].revisiting;
/* revisiting node already checked */
@@ -694,6 +700,11 @@ void BLI_pbvh_search_gather(PBVH *bvh,
pbvh_iter_end(&iter);
+ if(tot == 0 && array) {
+ MEM_freeN(array);
+ array= NULL;
+ }
+
*r_array= array;
*r_tot= tot;
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index e3b4908df84..c1138bc1031 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -106,6 +106,7 @@
#include "BLI_storage_types.h" // for relname flags
#include "BKE_animsys.h"
+#include "BKE_anim.h"
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_brush.h"
@@ -1531,22 +1532,13 @@ static void direct_link_curvemapping(FileData *fd, CurveMapping *cumap)
static void lib_link_brush(FileData *fd, Main *main)
{
Brush *brush;
- MTex *mtex;
- int a;
/* only link ID pointers */
for(brush= main->brush.first; brush; brush= brush->id.next) {
if(brush->id.flag & LIB_NEEDLINK) {
brush->id.flag -= LIB_NEEDLINK;
- brush->clone.image= newlibadr_us(fd, brush->id.lib, brush->clone.image);
-
- for(a=0; a<MAX_MTEX; a++) {
- mtex= brush->mtex[a];
- if(mtex)
- mtex->tex= newlibadr_us(fd, brush->id.lib, mtex->tex);
- }
-
+ brush->mtex.tex= newlibadr_us(fd, brush->id.lib, brush->mtex.tex);
brush->clone.image= newlibadr_us(fd, brush->id.lib, brush->clone.image);
}
}
@@ -1555,17 +1547,13 @@ static void lib_link_brush(FileData *fd, Main *main)
static void direct_link_brush(FileData *fd, Brush *brush)
{
/* brush itself has been read */
- int a;
-
- for(a=0; a<MAX_MTEX; a++)
- brush->mtex[a]= newdataadr(fd, brush->mtex[a]);
/* fallof curve */
brush->curve= newdataadr(fd, brush->curve);
if(brush->curve)
direct_link_curvemapping(fd, brush->curve);
else
- brush_curve_preset(brush, BRUSH_PRESET_SHARP);
+ brush_curve_preset(brush, CURVE_PRESET_SHARP);
}
static void direct_link_script(FileData *fd, Script *script)
@@ -1711,10 +1699,19 @@ static void lib_link_fcurves(FileData *fd, ID *id, ListBase *list)
/* driver data */
if (fcu->driver) {
ChannelDriver *driver= fcu->driver;
- DriverTarget *dtar;
+ DriverVar *dvar;
- for (dtar= driver->targets.first; dtar; dtar= dtar->next)
- dtar->id= newlibadr(fd, id->lib, dtar->id);
+ for (dvar= driver->variables.first; dvar; dvar= dvar->next) {
+ DRIVER_TARGETS_LOOPER(dvar)
+ {
+ /* only relink if still used */
+ if (tarIndex < dvar->num_targets)
+ dtar->id= newlibadr(fd, id->lib, dtar->id);
+ else
+ dtar->id= NULL;
+ }
+ DRIVER_TARGETS_LOOPER_END
+ }
}
/* modifiers */
@@ -1782,12 +1779,21 @@ static void direct_link_fcurves(FileData *fd, ListBase *list)
fcu->driver= newdataadr(fd, fcu->driver);
if (fcu->driver) {
ChannelDriver *driver= fcu->driver;
- DriverTarget *dtar;
+ DriverVar *dvar;
- /* relink targets and their paths */
- link_list(fd, &driver->targets);
- for (dtar= driver->targets.first; dtar; dtar= dtar->next)
- dtar->rna_path= newdataadr(fd, dtar->rna_path);
+ /* relink variables, targets and their paths */
+ link_list(fd, &driver->variables);
+ for (dvar= driver->variables.first; dvar; dvar= dvar->next) {
+ DRIVER_TARGETS_LOOPER(dvar)
+ {
+ /* only relink the targets being used */
+ if (tarIndex < dvar->num_targets)
+ dtar->rna_path= newdataadr(fd, dtar->rna_path);
+ else
+ dtar->rna_path= NULL;
+ }
+ DRIVER_TARGETS_LOOPER_END
+ }
}
/* modifiers */
@@ -1981,6 +1987,19 @@ static void direct_link_animdata(FileData *fd, AnimData *adt)
adt->actstrip= NULL;
}
+/* ************ READ MOTION PATHS *************** */
+
+/* direct data for cache */
+static void direct_link_motionpath(FileData *fd, bMotionPath *mpath)
+{
+ /* sanity check */
+ if (mpath == NULL)
+ return;
+
+ /* relink points cache */
+ mpath->points= newdataadr(fd, mpath->points);
+}
+
/* ************ READ NODE TREE *************** */
/* singe node tree (also used for material/scene trees), ntree is not NULL */
@@ -2110,23 +2129,7 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
link->fromsock= newdataadr(fd, link->fromsock);
link->tosock= newdataadr(fd, link->tosock);
}
-
- /* set selin and selout */
- for(node= ntree->nodes.first; node; node= node->next) {
- for(sock= node->inputs.first; sock; sock= sock->next) {
- if(sock->flag & SOCK_SEL) {
- ntree->selin= sock;
- break;
- }
- }
- for(sock= node->outputs.first; sock; sock= sock->next) {
- if(sock->flag & SOCK_SEL) {
- ntree->selout= sock;
- break;
- }
- }
- }
-
+
/* type verification is in lib-link */
}
@@ -2288,6 +2291,13 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
data->tar = newlibadr(fd, id->lib, data->tar);
}
break;
+ case CONSTRAINT_TYPE_TRANSLIKE:
+ {
+ bTransLikeConstraint *data;
+ data= ((bTransLikeConstraint*)con->data);
+ data->tar = newlibadr(fd, id->lib, data->tar);
+ }
+ break;
case CONSTRAINT_TYPE_NULL:
break;
}
@@ -3756,6 +3766,7 @@ static void direct_link_pose(FileData *fd, bPose *pose)
pchan->bone= NULL;
pchan->parent= newdataadr(fd, pchan->parent);
pchan->child= newdataadr(fd, pchan->child);
+ pchan->custom_tx= newdataadr(fd, pchan->custom_tx);
direct_link_constraints(fd, &pchan->constraints);
@@ -3763,6 +3774,10 @@ static void direct_link_pose(FileData *fd, bPose *pose)
if (pchan->prop)
IDP_DirectLinkProperty(pchan->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ pchan->mpath= newdataadr(fd, pchan->mpath);
+ if (pchan->mpath)
+ direct_link_motionpath(fd, pchan->mpath);
+
pchan->iktree.first= pchan->iktree.last= NULL;
pchan->path= NULL;
}
@@ -3975,6 +3990,10 @@ static void direct_link_object(FileData *fd, Object *ob)
ob->pose= newdataadr(fd, ob->pose);
direct_link_pose(fd, ob->pose);
+
+ ob->mpath= newdataadr(fd, ob->mpath);
+ if (ob->mpath)
+ direct_link_motionpath(fd, ob->mpath);
link_list(fd, &ob->defbase);
// XXX depreceated - old animation system <<<
@@ -4165,7 +4184,7 @@ static void composite_patch(bNodeTree *ntree, Scene *scene)
bNode *node;
for(node= ntree->nodes.first; node; node= node->next)
- if(node->id==NULL && ELEM3(node->type, CMP_NODE_R_LAYERS, CMP_NODE_COMPOSITE, CMP_NODE_DEFOCUS))
+ if(node->id==NULL && ELEM4(node->type, CMP_NODE_R_LAYERS, CMP_NODE_COMPOSITE, CMP_NODE_DEFOCUS, CMP_NODE_OUTPUT_FILE))
node->id= &scene->id;
}
@@ -10311,10 +10330,88 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
if (1) {
Scene *sce;
+ Object *ob;
+ Brush *brush;
+ Material *ma;
+ /* game engine changes */
for(sce = main->scene.first; sce; sce = sce->id.next) {
sce->gm.eyeseparation = 0.10;
}
+
+ /* anim viz changes */
+ for (ob= main->object.first; ob; ob= ob->id.next) {
+ /* initialise object defaults */
+ animviz_settings_init(&ob->avs);
+
+ /* if armature, copy settings for pose from armature data
+ * performing initialisation where appropriate
+ */
+ if (ob->pose && ob->data) {
+ bArmature *arm= newlibadr(fd, lib, ob->data);
+ if(arm) { /* XXX - why does this fail in some cases? */
+ bAnimVizSettings *avs= &ob->pose->avs;
+
+ /* ghosting settings ---------------- */
+ /* ranges */
+ avs->ghost_bc= avs->ghost_ac= arm->ghostep;
+
+ avs->ghost_sf= arm->ghostsf;
+ avs->ghost_ef= arm->ghostef;
+
+ /* type */
+ avs->ghost_type= arm->ghosttype;
+
+ /* stepsize */
+ avs->ghost_step= arm->ghostsize;
+ if (avs->ghost_step == 0)
+ avs->ghost_step= 1;
+
+ /* path settings --------------------- */
+ /* ranges */
+ avs->path_bc= arm->pathbc;
+ avs->path_ac= arm->pathac;
+
+ avs->path_sf= arm->pathsf;
+ avs->path_ef= arm->pathef;
+
+ /* flags */
+ if (arm->pathflag & ARM_PATH_FNUMS)
+ avs->path_viewflag |= MOTIONPATH_VIEW_FNUMS;
+ if (arm->pathflag & ARM_PATH_KFRAS)
+ avs->path_viewflag |= MOTIONPATH_VIEW_KFRAS;
+ if (arm->pathflag & ARM_PATH_KFNOS)
+ avs->path_viewflag |= MOTIONPATH_VIEW_KFNOS;
+
+ /* bake flags */
+ if (arm->pathflag & ARM_PATH_HEADS)
+ avs->path_bakeflag |= MOTIONPATH_BAKE_HEADS;
+
+ /* type */
+ if (arm->pathflag & ARM_PATH_ACFRA)
+ avs->path_type = MOTIONPATH_TYPE_ACFRA;
+
+ /* stepsize */
+ avs->path_step= arm->pathsize;
+ if (avs->path_step == 0)
+ avs->path_step= 1;
+ }
+ }
+ }
+
+ /* brush texture changes */
+ for (brush= main->brush.first; brush; brush= brush->id.next) {
+ default_mtex(&brush->mtex);
+ }
+
+ for (ma= main->mat.first; ma; ma= ma->id.next) {
+ if (ma->vol.ms_spread < 0.0001f) {
+ ma->vol.ms_spread = 0.2f;
+ ma->vol.ms_diff = 1.f;
+ ma->vol.ms_intensity = 1.f;
+ }
+ }
+
}
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
@@ -10681,10 +10778,16 @@ static void expand_fcurves(FileData *fd, Main *mainvar, ListBase *list)
/* Driver targets if there is a driver */
if (fcu->driver) {
ChannelDriver *driver= fcu->driver;
- DriverTarget *dtar;
+ DriverVar *dvar;
- for (dtar= driver->targets.first; dtar; dtar= dtar->next)
- expand_doit(fd, mainvar, dtar->id);
+ for (dvar= driver->variables.first; dvar; dvar= dvar->next) {
+ DRIVER_TARGETS_LOOPER(dvar)
+ {
+ // TODO: only expand those that are going to get used?
+ expand_doit(fd, mainvar, dtar->id);
+ }
+ DRIVER_TARGETS_LOOPER_END
+ }
}
/* F-Curve Modifiers */
@@ -10813,11 +10916,7 @@ static void expand_texture(FileData *fd, Main *mainvar, Tex *tex)
static void expand_brush(FileData *fd, Main *mainvar, Brush *brush)
{
- int a;
-
- for(a=0; a<MAX_MTEX; a++)
- if(brush->mtex[a])
- expand_doit(fd, mainvar, brush->mtex[a]->tex);
+ expand_doit(fd, mainvar, brush->mtex.tex);
expand_doit(fd, mainvar, brush->clone.image);
}
@@ -11083,6 +11182,12 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb)
expand_doit(fd, mainvar, data->tar);
}
break;
+ case CONSTRAINT_TYPE_TRANSLIKE:
+ {
+ bTransLikeConstraint *data = (bTransLikeConstraint*)curcon->data;
+ expand_doit(fd, mainvar, data->tar);
+ }
+ break;
default:
break;
}
@@ -11497,8 +11602,8 @@ static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, int is
if we are appending, but this object wasnt just added allong with a group,
then this is alredy used indirectly in the scene somewhere else and we didnt just append it.
- (ob->id.flag & LIB_APPEND_TAG)==0 means that this is a newly appended object - Campbell */
- if (is_group_append==0 || (ob->id.flag & LIB_APPEND_TAG)==0) {
+ (ob->id.flag & LIB_PRE_EXISTING)==0 means that this is a newly appended object - Campbell */
+ if (is_group_append==0 || (ob->id.flag & LIB_PRE_EXISTING)==0) {
int do_it= 0;
@@ -11524,6 +11629,36 @@ static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, int is
}
}
+/* when *lib set, it also does objects that were in the appended group */
+static void give_base_to_groups(Main *mainvar, Scene *scene)
+{
+ Group *group;
+
+ /* give all objects which are LIB_INDIRECT a base, or for a group when *lib has been set */
+ for(group= mainvar->group.first; group; group= group->id.next) {
+ if(((group->id.flag & LIB_INDIRECT)==0 && (group->id.flag & LIB_PRE_EXISTING)==0)) {
+ Base *base;
+
+ /* add_object(...) messes with the selection */
+ Object *ob= add_only_object(OB_EMPTY, group->id.name+2);
+ ob->type= OB_EMPTY;
+ ob->lay= scene->lay;
+
+ /* assign the base */
+ base= scene_add_base(scene, ob);
+ base->flag |= SELECT;
+ base->object->flag= base->flag;
+ ob->recalc |= OB_RECALC;
+ scene->basact= base;
+
+ /* assign the group */
+ ob->dup_group= group;
+ ob->transflag |= OB_DUPLIGROUP;
+ rename_id(&ob->id, group->id.name+2);
+ VECCOPY(ob->loc, scene->cursor);
+ }
+ }
+}
static void append_named_part(const bContext *C, Main *mainl, FileData *fd, char *name, int idcode, short flag)
{
@@ -11725,7 +11860,11 @@ static void library_append_end(const bContext *C, Main *mainl, FileData **fd, in
give_base_to_objects(mainvar, scene, NULL, 0);
} else {
give_base_to_objects(mainvar, scene, mainl->curlib, 1);
- }
+ }
+
+ if (flag & FILE_GROUP_INSTANCE) {
+ give_base_to_groups(mainvar, scene);
+ }
} else {
give_base_to_objects(mainvar, scene, NULL, 0);
}
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index c5365195d06..d8bb140186c 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -145,6 +145,7 @@ Any case: direct data is ALWAYS after the lib block
#include "MEM_guardedalloc.h" // MEM_freeN
#include "BLI_blenlib.h"
#include "BLI_linklist.h"
+#include "BLI_bpath.h"
#include "BKE_action.h"
#include "BKE_blender.h"
@@ -932,22 +933,27 @@ static void write_fcurves(WriteData *wd, ListBase *fcurves)
/* driver data */
if (fcu->driver) {
ChannelDriver *driver= fcu->driver;
- DriverTarget *dtar;
+ DriverVar *dvar;
/* don't save compiled python bytecode */
void *expr_comp= driver->expr_comp;
driver->expr_comp= NULL;
-
+
writestruct(wd, DATA, "ChannelDriver", 1, driver);
driver->expr_comp= expr_comp; /* restore */
-
- /* targets */
- for (dtar= driver->targets.first; dtar; dtar= dtar->next) {
- writestruct(wd, DATA, "DriverTarget", 1, dtar);
+
+
+ /* variables */
+ for (dvar= driver->variables.first; dvar; dvar= dvar->next) {
+ writestruct(wd, DATA, "DriverVar", 1, dvar);
- if (dtar->rna_path)
- writedata(wd, DATA, strlen(dtar->rna_path)+1, dtar->rna_path);
+ DRIVER_TARGETS_USED_LOOPER(dvar)
+ {
+ if (dtar->rna_path)
+ writedata(wd, DATA, strlen(dtar->rna_path)+1, dtar->rna_path);
+ }
+ DRIVER_TARGETS_LOOPER_END
}
}
@@ -1058,6 +1064,19 @@ static void write_animdata(WriteData *wd, AnimData *adt)
write_nladata(wd, &adt->nla_tracks);
}
+static void write_motionpath(WriteData *wd, bMotionPath *mpath)
+{
+ /* sanity checks */
+ if (mpath == NULL)
+ return;
+
+ /* firstly, just write the motionpath struct */
+ writestruct(wd, DATA, "bMotionPath", 1, mpath);
+
+ /* now write the array of data */
+ writestruct(wd, DATA, "bMotionPathVert", mpath->length, mpath->points);
+}
+
static void write_constraints(WriteData *wd, ListBase *conlist)
{
bConstraint *con;
@@ -1120,6 +1139,8 @@ static void write_pose(WriteData *wd, bPose *pose)
write_constraints(wd, &chan->constraints);
+ write_motionpath(wd, chan->mpath);
+
/* prevent crashes with autosave, when a bone duplicated in editmode has not yet been assigned to its posechannel */
if (chan->bone)
chan->selectflag= chan->bone->flag & BONE_SELECTED; /* gets restored on read, for library armatures */
@@ -1252,6 +1273,7 @@ static void write_objects(WriteData *wd, ListBase *idbase)
write_pose(wd, ob->pose);
write_defgroups(wd, &ob->defbase);
write_constraints(wd, &ob->constraints);
+ write_motionpath(wd, ob->mpath);
writestruct(wd, DATA, "PartDeflect", 1, ob->pd);
writestruct(wd, DATA, "SoftBody", 1, ob->soft);
@@ -2308,16 +2330,12 @@ static void write_nodetrees(WriteData *wd, ListBase *idbase)
static void write_brushes(WriteData *wd, ListBase *idbase)
{
Brush *brush;
- int a;
for(brush=idbase->first; brush; brush= brush->id.next) {
if(brush->id.us>0 || wd->current) {
writestruct(wd, ID_BR, "Brush", 1, brush);
if (brush->id.properties) IDP_WriteProperty(brush->id.properties, wd);
- for(a=0; a<MAX_MTEX; a++)
- if(brush->mtex[a])
- writestruct(wd, DATA, "MTex", 1, brush->mtex[a]);
-
+
if(brush->curve)
write_curvemapping(wd, brush->curve);
}
@@ -2448,9 +2466,29 @@ int BLO_write_file(Main *mainvar, char *dir, int write_flags, ReportList *report
return 0;
}
+ if(write_flags & G_FILE_RELATIVE_REMAP) {
+ char dir1[FILE_MAXDIR+FILE_MAXFILE];
+ char dir2[FILE_MAXDIR+FILE_MAXFILE];
+ BLI_split_dirfile_basic(dir, dir1, NULL);
+ BLI_split_dirfile_basic(mainvar->name, dir2, NULL);
+
+ /* just incase there is some subtle difference */
+ BLI_cleanup_dir(mainvar->name, dir1);
+ BLI_cleanup_dir(mainvar->name, dir2);
+
+ if(strcmp(dir1, dir2)==0)
+ write_flags &= ~G_FILE_RELATIVE_REMAP;
+ else
+ makeFilesAbsolute(G.sce, NULL);
+
+ }
+
BLI_make_file_string(G.sce, userfilename, BLI_gethome(), ".B25.blend");
write_user_block= BLI_streq(dir, userfilename);
+ if(write_flags & G_FILE_RELATIVE_REMAP)
+ makeFilesRelative(dir, NULL); /* note, making relative to something OTHER then G.sce */
+
err= write_file_handle(mainvar, file, NULL,NULL, write_user_block, write_flags);
close(file);
diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp
index d2543423097..ef36a2eea9a 100644
--- a/source/blender/collada/DocumentExporter.cpp
+++ b/source/blender/collada/DocumentExporter.cpp
@@ -21,6 +21,7 @@ extern "C"
{
#include "BKE_DerivedMesh.h"
#include "BKE_fcurve.h"
+#include "BKE_animsys.h"
#include "BLI_path_util.h"
#include "BLI_fileops.h"
#include "ED_keyframing.h"
@@ -36,6 +37,7 @@ extern "C"
#include "BKE_armature.h"
#include "BKE_image.h"
#include "BKE_utildefines.h"
+#include "BKE_object.h"
#include "BLI_math.h"
#include "BLI_string.h"
@@ -198,6 +200,12 @@ static std::string get_camera_id(Object *ob)
return translate_id(id_name(ob)) + "-camera";
}
+std::string get_joint_id(Bone *bone, Object *ob_arm)
+{
+ return translate_id(id_name(ob_arm) + "_" + bone->name);
+}
+
+
/*
Utilities to avoid code duplication.
Definition can take some time to understand, but they should be useful.
@@ -851,11 +859,6 @@ private:
return ob_arm;
}
- std::string get_joint_id(Bone *bone, Object *ob_arm)
- {
- return translate_id(id_name(ob_arm) + "_" + bone->name);
- }
-
std::string get_joint_sid(Bone *bone)
{
char name[100];
@@ -1538,9 +1541,23 @@ public:
if (t->mapto & MAP_REF) {
ep.setReflective(createTexture(ima, uvname, sampler));
}
+ // alpha
if (t->mapto & MAP_ALPHA) {
ep.setTransparent(createTexture(ima, uvname, sampler));
}
+ // extension:
+ // Normal map --> Must be stored with <extra> tag as different technique,
+ // since COLLADA doesn't support normal maps, even in current COLLADA 1.5.
+ if (t->mapto & MAP_NORM) {
+ COLLADASW::Texture texture(key);
+ texture.setTexcoord(uvname);
+ texture.setSampler(*sampler);
+ // technique FCOLLADA, with the <bump> tag, is most likely the best understood,
+ // most widespread de-facto standard.
+ texture.setProfileName("FCOLLADA");
+ texture.setChildElementName("bump");
+ ep.setExtraTechniqueColorOrTexture(COLLADASW::ColorOrTexture(texture));
+ }
}
// performs the actual writing
ep.addProfileElements();
@@ -1720,9 +1737,9 @@ public:
class AnimationExporter: COLLADASW::LibraryAnimations
{
Scene *scene;
- std::map<bActionGroup*, std::vector<FCurve*> > fcurves_actionGroup_map;
- std::map<bActionGroup*, std::vector<FCurve*> > rotfcurves_actionGroup_map;
+
public:
+
AnimationExporter(COLLADASW::StreamWriter *sw): COLLADASW::LibraryAnimations(sw) {}
void exportAnimations(Scene *sce)
@@ -1736,17 +1753,278 @@ public:
closeLibrary();
}
- // create <animation> for each transform axis
+ // called for each exported object
+ void operator() (Object *ob)
+ {
+ if (!ob->adt || !ob->adt->action) return;
+
+ FCurve *fcu = (FCurve*)ob->adt->action->curves.first;
+
+ if (ob->type == OB_ARMATURE) {
+ if (!ob->data) return;
+
+ bArmature *arm = (bArmature*)ob->data;
+ for (Bone *bone = (Bone*)arm->bonebase.first; bone; bone = bone->next)
+ write_bone_animation(ob, bone);
+ }
+ else {
+ while (fcu) {
+ // TODO "rotation_quaternion" is also possible for objects (although euler is default)
+ if ((!strcmp(fcu->rna_path, "location") || !strcmp(fcu->rna_path, "scale")) ||
+ (!strcmp(fcu->rna_path, "rotation_euler") && ob->rotmode == ROT_MODE_EUL))
+ dae_animation(fcu, id_name(ob));
+
+ fcu = fcu->next;
+ }
+ }
+ }
+
+protected:
+
+ void dae_animation(FCurve *fcu, std::string ob_name)
+ {
+ const char *axis_names[] = {"X", "Y", "Z"};
+ const char *axis_name = NULL;
+ char anim_id[200];
+ char anim_name[200];
+
+ if (fcu->array_index < 3)
+ axis_name = axis_names[fcu->array_index];
+
+ BLI_snprintf(anim_id, sizeof(anim_id), "%s.%s.%s", (char*)translate_id(ob_name).c_str(),
+ fcu->rna_path, axis_names[fcu->array_index]);
+ BLI_snprintf(anim_name, sizeof(anim_name), "%s.%s.%s",
+ (char*)ob_name.c_str(), fcu->rna_path, axis_names[fcu->array_index]);
+
+ // check rna_path is one of: rotation, scale, location
+
+ openAnimation(anim_id, anim_name);
+
+ // create input source
+ std::string input_id = create_source_from_fcurve(Sampler::INPUT, fcu, anim_id, axis_name);
+
+ // create output source
+ std::string output_id = create_source_from_fcurve(Sampler::OUTPUT, fcu, anim_id, axis_name);
+
+ // create interpolations source
+ std::string interpolation_id = create_interpolation_source(fcu->totvert, anim_id, axis_name);
+
+ std::string sampler_id = std::string(anim_id) + SAMPLER_ID_SUFFIX;
+ COLLADASW::LibraryAnimations::Sampler sampler(sampler_id);
+ std::string empty;
+ sampler.addInput(Sampler::INPUT, COLLADABU::URI(empty, input_id));
+ sampler.addInput(Sampler::OUTPUT, COLLADABU::URI(empty, output_id));
+
+ // this input is required
+ sampler.addInput(Sampler::INTERPOLATION, COLLADABU::URI(empty, interpolation_id));
+
+ addSampler(sampler);
+
+ std::string target = translate_id(ob_name)
+ + "/" + get_transform_sid(fcu->rna_path, -1, axis_name);
+ addChannel(COLLADABU::URI(empty, sampler_id), target);
+
+ closeAnimation();
+ }
+
+ void write_bone_animation(Object *ob_arm, Bone *bone)
+ {
+ if (!ob_arm->adt)
+ return;
+
+ for (int i = 0; i < 3; i++)
+ sample_and_write_bone_animation(ob_arm, bone, i);
+
+ for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next)
+ write_bone_animation(ob_arm, child);
+ }
+
+ void sample_and_write_bone_animation(Object *ob_arm, Bone *bone, int transform_type)
+ {
+ bArmature *arm = (bArmature*)ob_arm->data;
+ int flag = arm->flag;
+ std::vector<float> fra;
+ char prefix[256];
+
+ BLI_snprintf(prefix, sizeof(prefix), "pose.bones[\"%s\"]", bone->name);
+
+ bPoseChannel *pchan = get_pose_channel(ob_arm->pose, bone->name);
+ if (!pchan)
+ return;
+
+ switch (transform_type) {
+ case 0:
+ find_rotation_frames(ob_arm, fra, prefix, pchan->rotmode);
+ break;
+ case 1:
+ find_frames(ob_arm, fra, prefix, "scale");
+ break;
+ case 2:
+ find_frames(ob_arm, fra, prefix, "location");
+ break;
+ default:
+ return;
+ }
- float convert_time(float frame) {
+ // exit rest position
+ if (flag & ARM_RESTPOS) {
+ arm->flag &= ~ARM_RESTPOS;
+ where_is_pose(scene, ob_arm);
+ }
+
+ if (fra.size()) {
+ float *v = (float*)MEM_callocN(sizeof(float) * 3 * fra.size(), "temp. anim frames");
+ sample_animation(v, fra, transform_type, bone, ob_arm);
+
+ if (transform_type == 0) {
+ // write x, y, z curves separately if it is rotation
+ float *c = (float*)MEM_callocN(sizeof(float) * fra.size(), "temp. anim frames");
+ for (int i = 0; i < 3; i++) {
+ for (int j = 0; j < fra.size(); j++)
+ c[j] = v[j * 3 + i];
+
+ dae_bone_animation(fra, c, transform_type, i, id_name(ob_arm), bone->name);
+ }
+ MEM_freeN(c);
+ }
+ else {
+ // write xyz at once if it is location or scale
+ dae_bone_animation(fra, v, transform_type, -1, id_name(ob_arm), bone->name);
+ }
+
+ MEM_freeN(v);
+ }
+
+ // restore restpos
+ if (flag & ARM_RESTPOS)
+ arm->flag = flag;
+ where_is_pose(scene, ob_arm);
+ }
+
+ void sample_animation(float *v, std::vector<float> &frames, int type, Bone *bone, Object *ob_arm)
+ {
+ bPoseChannel *pchan, *parchan = NULL;
+ bPose *pose = ob_arm->pose;
+
+ pchan = get_pose_channel(pose, bone->name);
+
+ if (!pchan)
+ return;
+
+ parchan = pchan->parent;
+
+ enable_fcurves(ob_arm->adt->action, bone->name);
+
+ std::vector<float>::iterator it;
+ for (it = frames.begin(); it != frames.end(); it++) {
+ float mat[4][4], ipar[4][4];
+
+ float ctime = bsystem_time(scene, ob_arm, *it, 0.0f);
+
+ BKE_animsys_evaluate_animdata(&ob_arm->id, ob_arm->adt, *it, ADT_RECALC_ANIM);
+ where_is_pose_bone(scene, ob_arm, pchan, ctime);
+
+ // compute bone local mat
+ if (bone->parent) {
+ invert_m4_m4(ipar, parchan->pose_mat);
+ mul_m4_m4m4(mat, pchan->pose_mat, ipar);
+ }
+ else
+ copy_m4_m4(mat, pchan->pose_mat);
+
+ switch (type) {
+ case 0:
+ mat4_to_eul(v, mat);
+ break;
+ case 1:
+ mat4_to_size(v, mat);
+ break;
+ case 2:
+ copy_v3_v3(v, mat[3]);
+ break;
+ }
+
+ v += 3;
+ }
+
+ enable_fcurves(ob_arm->adt->action, NULL);
+ }
+
+ // dae_bone_animation -> add_bone_animation
+ // (blend this into dae_bone_animation)
+ void dae_bone_animation(std::vector<float> &fra, float *v, int tm_type, int axis, std::string ob_name, std::string bone_name)
+ {
+ const char *axis_names[] = {"X", "Y", "Z"};
+ const char *axis_name = NULL;
+ char anim_id[200];
+ char anim_name[200];
+ bool is_rot = tm_type == 0;
+
+ if (!fra.size())
+ return;
+
+ char rna_path[200];
+ BLI_snprintf(rna_path, sizeof(rna_path), "pose.bones[\"%s\"].%s", bone_name.c_str(),
+ tm_type == 0 ? "rotation_quaternion" : (tm_type == 1 ? "scale" : "location"));
+
+ if (axis > -1)
+ axis_name = axis_names[axis];
+
+ std::string transform_sid = get_transform_sid(NULL, tm_type, axis_name);
+
+ BLI_snprintf(anim_id, sizeof(anim_id), "%s.%s.%s", (char*)translate_id(ob_name).c_str(),
+ (char*)translate_id(bone_name).c_str(), (char*)transform_sid.c_str());
+ BLI_snprintf(anim_name, sizeof(anim_name), "%s.%s.%s",
+ (char*)ob_name.c_str(), (char*)bone_name.c_str(), (char*)transform_sid.c_str());
+
+ // TODO check rna_path is one of: rotation, scale, location
+
+ openAnimation(anim_id, anim_name);
+
+ // create input source
+ std::string input_id = create_source_from_vector(Sampler::INPUT, fra, is_rot, anim_id, axis_name);
+
+ // create output source
+ std::string output_id;
+ if (axis == -1)
+ output_id = create_xyz_source(v, fra.size(), anim_id);
+ else
+ output_id = create_source_from_array(Sampler::OUTPUT, v, fra.size(), is_rot, anim_id, axis_name);
+
+ // create interpolations source
+ std::string interpolation_id = create_interpolation_source(fra.size(), anim_id, axis_name);
+
+ std::string sampler_id = std::string(anim_id) + SAMPLER_ID_SUFFIX;
+ COLLADASW::LibraryAnimations::Sampler sampler(sampler_id);
+ std::string empty;
+ sampler.addInput(Sampler::INPUT, COLLADABU::URI(empty, input_id));
+ sampler.addInput(Sampler::OUTPUT, COLLADABU::URI(empty, output_id));
+
+ // TODO create in/out tangents source
+
+ // this input is required
+ sampler.addInput(Sampler::INTERPOLATION, COLLADABU::URI(empty, interpolation_id));
+
+ addSampler(sampler);
+
+ std::string target = translate_id(ob_name + "_" + bone_name) + "/" + transform_sid;
+ addChannel(COLLADABU::URI(empty, sampler_id), target);
+
+ closeAnimation();
+ }
+
+ float convert_time(float frame)
+ {
return FRA2TIME(frame);
}
- float convert_angle(float angle) {
+ float convert_angle(float angle)
+ {
return COLLADABU::Math::Utils::radToDegF(angle);
}
- std::string get_semantic_suffix(Sampler::Semantic semantic) {
+ std::string get_semantic_suffix(Sampler::Semantic semantic)
+ {
switch(semantic) {
case Sampler::INPUT:
return INPUT_SOURCE_ID_SUFFIX;
@@ -1763,17 +2041,25 @@ public:
}
void add_source_parameters(COLLADASW::SourceBase::ParameterNameList& param,
- Sampler::Semantic semantic, bool rotation, const char *axis) {
+ Sampler::Semantic semantic, bool is_rot, const char *axis)
+ {
switch(semantic) {
case Sampler::INPUT:
param.push_back("TIME");
break;
case Sampler::OUTPUT:
- if (rotation) {
+ if (is_rot) {
param.push_back("ANGLE");
}
else {
- param.push_back(axis);
+ if (axis) {
+ param.push_back(axis);
+ }
+ else {
+ param.push_back("X");
+ param.push_back("Y");
+ param.push_back("Z");
+ }
}
break;
case Sampler::IN_TANGENT:
@@ -1808,7 +2094,7 @@ public:
}
}
- std::string create_source(Sampler::Semantic semantic, FCurve *fcu, std::string& anim_id, const char *axis_name)
+ std::string create_source_from_fcurve(Sampler::Semantic semantic, FCurve *fcu, const std::string& anim_id, const char *axis_name)
{
std::string source_id = anim_id + get_semantic_suffix(semantic);
@@ -1842,26 +2128,28 @@ public:
return source_id;
}
- std::string create_interpolation_source(FCurve *fcu, std::string& anim_id, const char *axis_name)
+ std::string create_source_from_array(Sampler::Semantic semantic, float *v, int tot, bool is_rot, const std::string& anim_id, const char *axis_name)
{
- std::string source_id = anim_id + get_semantic_suffix(Sampler::INTERPOLATION);
-
- //bool is_rotation = !strcmp(fcu->rna_path, "rotation");
+ std::string source_id = anim_id + get_semantic_suffix(semantic);
- COLLADASW::NameSource source(mSW);
+ COLLADASW::FloatSourceF source(mSW);
source.setId(source_id);
source.setArrayId(source_id + ARRAY_ID_SUFFIX);
- source.setAccessorCount(fcu->totvert);
+ source.setAccessorCount(tot);
source.setAccessorStride(1);
COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
- param.push_back("INTERPOLATION");
+ add_source_parameters(param, semantic, is_rot, axis_name);
source.prepareToAppendValues();
- for (int i = 0; i < fcu->totvert; i++) {
- // XXX
- source.appendValues(LINEAR_NAME);
+ for (int i = 0; i < tot; i++) {
+ float val = v[i];
+ if (semantic == Sampler::INPUT)
+ val = convert_time(val);
+ else if (is_rot)
+ val = convert_angle(val);
+ source.appendValues(val);
}
source.finish();
@@ -1869,258 +2157,161 @@ public:
return source_id;
}
- std::string get_transform_sid(char *rna_path, const char *axis_name)
+ std::string create_source_from_vector(Sampler::Semantic semantic, std::vector<float> &fra, bool is_rot, const std::string& anim_id, const char *axis_name)
{
- // if (!strcmp(rna_path, "rotation"))
-// return std::string(rna_path) + axis_name;
-
-// return std::string(rna_path) + "." + axis_name;
- std::string new_rna_path;
-
- if (strstr(rna_path, "rotation")) {
- new_rna_path = "rotation";
- return new_rna_path + axis_name;
- }
- else if (strstr(rna_path, "location")) {
- new_rna_path = strstr(rna_path, "location");
- return new_rna_path + "." + axis_name;
- }
- else if (strstr(rna_path, "scale")) {
- new_rna_path = strstr(rna_path, "scale");
- return new_rna_path + "." + axis_name;
- }
- return NULL;
- }
+ std::string source_id = anim_id + get_semantic_suffix(semantic);
- void add_animation(FCurve *fcu, std::string ob_name)
- {
- const char *axis_names[] = {"X", "Y", "Z"};
- const char *axis_name = NULL;
- char c_anim_id[100]; // careful!
- char c_anim_name[100]; // careful!
+ COLLADASW::FloatSourceF source(mSW);
+ source.setId(source_id);
+ source.setArrayId(source_id + ARRAY_ID_SUFFIX);
+ source.setAccessorCount(fra.size());
+ source.setAccessorStride(1);
- if (fcu->array_index < 3)
- axis_name = axis_names[fcu->array_index];
-
- BLI_snprintf(c_anim_id, sizeof(c_anim_id), "%s.%s.%s", (char*)translate_id(ob_name).c_str(),
- fcu->rna_path, axis_names[fcu->array_index]);
- std::string anim_id(c_anim_id);
- BLI_snprintf(c_anim_name, sizeof(c_anim_name), "%s.%s.%s",
- (char*)ob_name.c_str(), fcu->rna_path, axis_names[fcu->array_index]);
- std::string anim_name = c_anim_name;
+ COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
+ add_source_parameters(param, semantic, is_rot, axis_name);
- // check rna_path is one of: rotation, scale, location
+ source.prepareToAppendValues();
- openAnimation(anim_id, anim_name);
+ std::vector<float>::iterator it;
+ for (it = fra.begin(); it != fra.end(); it++) {
+ float val = *it;
+ if (semantic == Sampler::INPUT)
+ val = convert_time(val);
+ else if (is_rot)
+ val = convert_angle(val);
+ source.appendValues(val);
+ }
- // create input source
- std::string input_id = create_source(Sampler::INPUT, fcu, anim_id, axis_name);
+ source.finish();
- // create output source
- std::string output_id = create_source(Sampler::OUTPUT, fcu, anim_id, axis_name);
+ return source_id;
+ }
- // create interpolations source
- std::string interpolation_id = create_interpolation_source(fcu, anim_id, axis_name);
+ // only used for sources with OUTPUT semantic
+ std::string create_xyz_source(float *v, int tot, const std::string& anim_id)
+ {
+ Sampler::Semantic semantic = Sampler::OUTPUT;
+ std::string source_id = anim_id + get_semantic_suffix(semantic);
- std::string sampler_id = anim_id + SAMPLER_ID_SUFFIX;
- COLLADASW::LibraryAnimations::Sampler sampler(sampler_id);
- std::string empty;
- sampler.addInput(Sampler::INPUT, COLLADABU::URI(empty, input_id));
- sampler.addInput(Sampler::OUTPUT, COLLADABU::URI(empty, output_id));
+ COLLADASW::FloatSourceF source(mSW);
+ source.setId(source_id);
+ source.setArrayId(source_id + ARRAY_ID_SUFFIX);
+ source.setAccessorCount(tot);
+ source.setAccessorStride(3);
+
+ COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
+ add_source_parameters(param, semantic, false, NULL);
- // this input is required
- sampler.addInput(Sampler::INTERPOLATION, COLLADABU::URI(empty, interpolation_id));
+ source.prepareToAppendValues();
- addSampler(sampler);
+ for (int i = 0; i < tot; i++) {
+ source.appendValues(*v, *(v + 1), *(v + 2));
+ v += 3;
+ }
- std::string target = translate_id(ob_name)
- + "/" + get_transform_sid(fcu->rna_path, axis_name);
- addChannel(COLLADABU::URI(empty, sampler_id), target);
+ source.finish();
- closeAnimation();
+ return source_id;
}
-
- void add_bone_animation(FCurve *fcu, std::string ob_name, std::string bone_name)
+
+ std::string create_interpolation_source(int tot, const std::string& anim_id, const char *axis_name)
{
- const char *axis_names[] = {"X", "Y", "Z"};
- const char *axis_name = NULL;
- char c_anim_id[100]; // careful!
- char c_anim_name[100]; // careful!
+ std::string source_id = anim_id + get_semantic_suffix(Sampler::INTERPOLATION);
- if (fcu->array_index < 3)
- axis_name = axis_names[fcu->array_index];
-
- std::string transform_sid = get_transform_sid(fcu->rna_path, axis_name);
+ COLLADASW::NameSource source(mSW);
+ source.setId(source_id);
+ source.setArrayId(source_id + ARRAY_ID_SUFFIX);
+ source.setAccessorCount(tot);
+ source.setAccessorStride(1);
- BLI_snprintf(c_anim_id, sizeof(c_anim_id), "%s.%s.%s", (char*)translate_id(ob_name).c_str(),
- (char*)translate_id(bone_name).c_str(), (char*)transform_sid.c_str());
- std::string anim_id(c_anim_id);
- BLI_snprintf(c_anim_name, sizeof(c_anim_name), "%s.%s.%s",
- (char*)ob_name.c_str(), (char*)bone_name.c_str(), (char*)transform_sid.c_str());
- std::string anim_name(c_anim_name);
-
- // check rna_path is one of: rotation, scale, location
-
- openAnimation(anim_id, anim_name);
-
- // create input source
- std::string input_id = create_source(Sampler::INPUT, fcu, anim_id, axis_name);
+ COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
+ param.push_back("INTERPOLATION");
- // create output source
- std::string output_id = create_source(Sampler::OUTPUT, fcu, anim_id, axis_name);
+ source.prepareToAppendValues();
- // create interpolations source
- std::string interpolation_id = create_interpolation_source(fcu, anim_id, axis_name);
+ for (int i = 0; i < tot; i++) {
+ source.appendValues(LINEAR_NAME);
+ }
- std::string sampler_id = anim_id + SAMPLER_ID_SUFFIX;
- COLLADASW::LibraryAnimations::Sampler sampler(sampler_id);
- std::string empty;
- sampler.addInput(Sampler::INPUT, COLLADABU::URI(empty, input_id));
- sampler.addInput(Sampler::OUTPUT, COLLADABU::URI(empty, output_id));
+ source.finish();
- // this input is required
- sampler.addInput(Sampler::INTERPOLATION, COLLADABU::URI(empty, interpolation_id));
+ return source_id;
+ }
- addSampler(sampler);
+ std::string get_transform_sid(char *rna_path, int tm_type, const char *axis_name)
+ {
+ if (rna_path) {
+ char *name = extract_transform_name(rna_path);
- std::string target = translate_id(ob_name + "_" + bone_name) + "/" + transform_sid;
- addChannel(COLLADABU::URI(empty, sampler_id), target);
+ if (strstr(name, "rotation"))
+ return std::string("rotation") + axis_name;
+ else if (!strcmp(name, "location") || !strcmp(name, "scale"))
+ return std::string(name);
+ }
+ else {
+ if (tm_type == 0)
+ return std::string("rotation") + axis_name;
+ else
+ return tm_type == 1 ? "scale" : "location";
+ }
- closeAnimation();
+ return NULL;
}
-
- FCurve *create_fcurve(int array_index, char *rna_path)
+
+ char *extract_transform_name(char *rna_path)
{
- FCurve *fcu = (FCurve*)MEM_callocN(sizeof(FCurve), "FCurve");
-
- fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED);
- fcu->rna_path = BLI_strdupn(rna_path, strlen(rna_path));
- fcu->array_index = array_index;
- return fcu;
- }
-
- void create_bezt(FCurve *fcu, float frame, float output)
- {
- BezTriple bez;
- memset(&bez, 0, sizeof(BezTriple));
- bez.vec[1][0] = frame;
- bez.vec[1][1] = output;
- bez.ipo = U.ipo_new; /* use default interpolation mode here... */
- bez.f1 = bez.f2 = bez.f3 = SELECT;
- bez.h1 = bez.h2 = HD_AUTO;
- insert_bezt_fcurve(fcu, &bez, 0);
- calchandles_fcurve(fcu);
+ char *dot = strrchr(rna_path, '.');
+ return dot ? (dot + 1) : rna_path;
}
-
- void change_quat_to_eul(Object *ob, bActionGroup *grp, char *grpname)
+
+ void find_frames(Object *ob, std::vector<float> &fra, const char *prefix, const char *tm_name)
{
- std::vector<FCurve*> &rot_fcurves = rotfcurves_actionGroup_map[grp];
-
- FCurve *quatcu[4] = {NULL, NULL, NULL, NULL};
- int i;
-
- for (i = 0; i < rot_fcurves.size(); i++)
- quatcu[rot_fcurves[i]->array_index] = rot_fcurves[i];
-
- char *rna_path = rot_fcurves[0]->rna_path;
-
- FCurve *eulcu[3] = {
- create_fcurve(0, rna_path),
- create_fcurve(1, rna_path),
- create_fcurve(2, rna_path)
- };
-
- for (i = 0; i < 4; i++) {
-
- FCurve *cu = quatcu[i];
-
- if (!cu) continue;
-
- for (int j = 0; j < cu->totvert; j++) {
- float frame = cu->bezt[j].vec[1][0];
-
- float quat[4] = {
- quatcu[0] ? evaluate_fcurve(quatcu[0], frame) : 0.0f,
- quatcu[1] ? evaluate_fcurve(quatcu[1], frame) : 0.0f,
- quatcu[2] ? evaluate_fcurve(quatcu[2], frame) : 0.0f,
- quatcu[3] ? evaluate_fcurve(quatcu[3], frame) : 0.0f
- };
-
- float eul[3];
-
- quat_to_eul( eul,quat);
-
- for (int k = 0; k < 3; k++)
- create_bezt(eulcu[k], frame, eul[k]);
+ FCurve *fcu= (FCurve*)ob->adt->action->curves.first;
+
+ for (; fcu; fcu = fcu->next) {
+ if (prefix && strncmp(prefix, fcu->rna_path, strlen(prefix)))
+ continue;
+
+ char *name = extract_transform_name(fcu->rna_path);
+ if (!strcmp(name, tm_name)) {
+ for (int i = 0; i < fcu->totvert; i++) {
+ float f = fcu->bezt[i].vec[1][0];
+ if (std::find(fra.begin(), fra.end(), f) == fra.end())
+ fra.push_back(f);
+ }
}
}
-
- for (i = 0; i < 3; i++) {
- add_bone_animation(eulcu[i], id_name(ob), std::string(grpname));
- free_fcurve(eulcu[i]);
- }
}
- // called for each exported object
- void operator() (Object *ob)
+ void find_rotation_frames(Object *ob, std::vector<float> &fra, const char *prefix, int rotmode)
{
- if (!ob->adt || !ob->adt->action) return;
-
- FCurve *fcu = (FCurve*)ob->adt->action->curves.first;
-
- if (ob->type == OB_ARMATURE) {
-
- while (fcu) {
-
- if (strstr(fcu->rna_path, ".rotation"))
- rotfcurves_actionGroup_map[fcu->grp].push_back(fcu);
- else fcurves_actionGroup_map[fcu->grp].push_back(fcu);
-
- fcu = fcu->next;
- }
-
- for (bPoseChannel *pchan = (bPoseChannel*)ob->pose->chanbase.first; pchan; pchan = pchan->next) {
- int i;
- char *grpname = pchan->name;
- bActionGroup *grp = action_groups_find_named(ob->adt->action, grpname);
-
- if (!grp) continue;
-
- // write animation for location & scaling
- if (fcurves_actionGroup_map.find(grp) == fcurves_actionGroup_map.end()) continue;
-
- std::vector<FCurve*> &fcurves = fcurves_actionGroup_map[grp];
- for (i = 0; i < fcurves.size(); i++)
- add_bone_animation(fcurves[i], id_name(ob), std::string(grpname));
-
- // ... for rotation
- if (rotfcurves_actionGroup_map.find(grp) == rotfcurves_actionGroup_map.end())
- continue;
-
- // if rotation mode is euler - no need to convert it
- if (pchan->rotmode == ROT_MODE_EUL) {
-
- std::vector<FCurve*> &rotfcurves = rotfcurves_actionGroup_map[grp];
-
- for (i = 0; i < rotfcurves.size(); i++)
- add_bone_animation(rotfcurves[i], id_name(ob), std::string(grpname));
- }
-
- // convert rotation to euler & write animation
- else change_quat_to_eul(ob, grp, grpname);
+ if (rotmode > 0)
+ find_frames(ob, fra, prefix, "rotation_euler");
+ else if (rotmode == ROT_MODE_QUAT)
+ find_frames(ob, fra, prefix, "rotation_quaternion");
+ else if (rotmode == ROT_MODE_AXISANGLE)
+ ;
+ }
+
+ // enable fcurves driving a specific bone, disable all the rest
+ // if bone_name = NULL enable all fcurves
+ void enable_fcurves(bAction *act, char *bone_name)
+ {
+ FCurve *fcu;
+ char prefix[200];
+
+ if (bone_name)
+ BLI_snprintf(prefix, sizeof(prefix), "pose.bones[\"%s\"]", bone_name);
+
+ for (fcu = (FCurve*)act->curves.first; fcu; fcu = fcu->next) {
+ if (bone_name) {
+ if (!strncmp(fcu->rna_path, prefix, strlen(prefix)))
+ fcu->flag &= ~FCURVE_DISABLED;
+ else
+ fcu->flag |= FCURVE_DISABLED;
}
- }
- else {
- while (fcu) {
-
- if (!strcmp(fcu->rna_path, "location") ||
- !strcmp(fcu->rna_path, "scale") ||
- !strcmp(fcu->rna_path, "rotation_euler")) {
-
- add_animation(fcu, id_name(ob));
- }
-
- fcu = fcu->next;
+ else {
+ fcu->flag &= ~FCURVE_DISABLED;
}
}
}
@@ -2192,3 +2383,12 @@ void DocumentExporter::exportCurrentScene(Scene *sce, const char* filename)
void DocumentExporter::exportScenes(const char* filename)
{
}
+
+/*
+
+NOTES:
+
+* AnimationExporter::sample_animation enables all curves on armature, this is undesirable for a user
+
+ */
+
diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp
index 575160ff84e..26e95c378a6 100644
--- a/source/blender/collada/DocumentImporter.cpp
+++ b/source/blender/collada/DocumentImporter.cpp
@@ -43,6 +43,8 @@ extern "C"
#include "ED_armature.h"
#include "ED_mesh.h" // ED_vgroup_vert_add, ...
#include "ED_anim_api.h"
+#include "ED_object.h"
+
#include "WM_types.h"
#include "WM_api.h"
@@ -82,6 +84,7 @@ extern "C"
#include "DNA_mesh_types.h"
#include "DNA_material_types.h"
#include "DNA_scene_types.h"
+#include "DNA_modifier_types.h"
#include "MEM_guardedalloc.h"
@@ -497,20 +500,24 @@ private:
void link_armature(bContext *C, Object *ob, std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& joint_by_uid,
TransformReader *tm)
{
+ Object workob;
+ Scene *scene = CTX_data_scene(C);
+
+ ModifierData *md = ED_object_modifier_add(NULL, scene, ob, NULL, eModifierType_Armature);
+ ((ArmatureModifierData *)md)->object = ob_arm;
+
tm->decompose(bind_shape_matrix, ob->loc, ob->rot, NULL, ob->size);
ob->parent = ob_arm;
- ob->partype = PARSKEL;
+ ob->partype = PAROBJECT;
+
+ what_does_parent(scene, ob, &workob);
+ invert_m4_m4(ob->parentinv, workob.obmat);
+
ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA;
((bArmature*)ob_arm->data)->deformflag = ARM_DEF_VGROUP;
- // we need armature matrix here... where do we get it from I wonder...
- // root node/joint? or node with <instance_controller>?
- float parmat[4][4];
- unit_m4(parmat);
- invert_m4_m4(ob->parentinv, parmat);
-
// create all vertex groups
std::vector<JointData>::iterator it;
int joint_index;
@@ -551,7 +558,7 @@ private:
}
}
- DAG_scene_sort(CTX_data_scene(C));
+ DAG_scene_sort(scene);
DAG_ids_flush_update(0);
WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
}
@@ -624,6 +631,9 @@ private:
if (parent && totchild == 1) {
copy_v3_v3(parent->tail, bone->head);
+ // not setting BONE_CONNECTED because this would lock child bone location with respect to parent
+ // bone->flag |= BONE_CONNECTED;
+
// XXX increase this to prevent "very" small bones?
const float epsilon = 0.000001f;
@@ -2430,7 +2440,7 @@ public:
Bone *bone = get_named_bone((bArmature*)ob->data, bone_name);
if (!bone) {
- fprintf(stderr, "cannot find bone \"%s\"", bone_name);
+ fprintf(stderr, "cannot find bone \"%s\"\n", bone_name);
#ifdef ARMATURE_TEST
return NULL;
#else
@@ -2773,9 +2783,14 @@ public:
// use bind matrix if available or calc "current" world mat
if (!armature_importer->get_joint_bind_mat(m, node)) {
- float temp[4][4];
- get_node_mat(temp, node, NULL, NULL);
- mul_m4_m4m4(m, temp, par);
+ if (par) {
+ float temp[4][4];
+ get_node_mat(temp, node, NULL, NULL);
+ mul_m4_m4m4(m, temp, par);
+ }
+ else {
+ get_node_mat(m, node, NULL, NULL);
+ }
}
COLLADAFW::NodePointerArray& children = node->getChildNodes();
diff --git a/source/blender/collada/Makefile b/source/blender/collada/Makefile
new file mode 100644
index 00000000000..29a731dbcb2
--- /dev/null
+++ b/source/blender/collada/Makefile
@@ -0,0 +1,42 @@
+#
+# $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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2008 Blender Foundation.
+# All rights reserved.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL LICENSE BLOCK *****
+#
+#
+
+LIBNAME = bf_collada
+DIR = $(OCGDIR)/blender/bf_collada
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_C_WARNINGS)
+
+CPPFLAGS += -I../makesdna -I../blenlib -I../blenkernel -I../editors/include
+CPPFLAGS += -I../windowmanager -I../makesrna
+CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
+CPPFLAGS += -I$(BF_OPENCOLLADA)/include/COLLADABaseUtils
+CPPFLAGS += -I$(BF_OPENCOLLADA)/include/COLLADAFrameWork
+CPPFLAGS += -I$(BF_OPENCOLLADA)/include/COLLADAStreamWriter
+CPPFLAGS += -I$(BF_OPENCOLLADA)/include/COLLADASaxFrameworkLoader
diff --git a/source/blender/editors/CMakeLists.txt b/source/blender/editors/CMakeLists.txt
index b9027578482..0572c85ac08 100644
--- a/source/blender/editors/CMakeLists.txt
+++ b/source/blender/editors/CMakeLists.txt
@@ -90,10 +90,9 @@ IF(WIN32)
SET(INC ${INC} ${PTHREADS_INC})
ENDIF(WIN32)
-# TODO buildinfo
-IF(BF_BUILDINFO)
+IF(WITH_BUILDINFO)
ADD_DEFINITIONS(-DNAN_BUILDINFO)
-ENDIF(BF_BUILDINFO)
+ENDIF(WITH_BUILDINFO)
BLENDERLIB_NOLIST(bf_editors "${SRC}" "${INC}")
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index aa0fcab3e36..0f19da0e6bd 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -120,6 +120,13 @@ extern void gl_round_box_shade(int mode, float minx, float miny, float maxx, flo
/* Draw Backdrop ---------------------------------- */
+/* get backdrop color for top-level widgets (Scene and Object only) */
+static void acf_generic_root_color(bAnimContext *ac, bAnimListElem *ale, float *color)
+{
+ /* darker blue for top-level widgets */
+ UI_GetThemeColor3fv(TH_DOPESHEET_CHANNELOB, color);
+}
+
/* backdrop for top-level widgets (Scene and Object only) */
static void acf_generic_root_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
{
@@ -127,38 +134,48 @@ static void acf_generic_root_backdrop(bAnimContext *ac, bAnimListElem *ale, floa
View2D *v2d= &ac->ar->v2d;
short expanded= ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0;
short offset= (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
+ float color[3];
- /* darker blue for top-level widgets */
- UI_ThemeColor(TH_DOPESHEET_CHANNELOB);
+ /* set backdrop drawing color */
+ acf->get_backdrop_color(ac, ale, color);
+ glColor3fv(color);
/* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
uiSetRoundBox((expanded)? (1):(1|8));
gl_round_box(GL_POLYGON, offset, yminc, v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc, 8);
}
+
+/* get backdrop color for data expanders under top-level Scene/Object */
+static void acf_generic_dataexpand_color(bAnimContext *ac, bAnimListElem *ale, float *color)
+{
+ /* lighter color than top-level widget */
+ UI_GetThemeColor3fv(TH_DOPESHEET_CHANNELSUBOB, color);
+}
+
/* backdrop for data expanders under top-level Scene/Object */
static void acf_generic_dataexpand_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
{
bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
View2D *v2d= &ac->ar->v2d;
short offset= (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
+ float color[3];
- /* lighter color than top-level widget */
- UI_ThemeColor(TH_DOPESHEET_CHANNELSUBOB);
+ /* set backdrop drawing color */
+ acf->get_backdrop_color(ac, ale, color);
+ glColor3fv(color);
/* no rounded corner - just rectangular box */
glRectf(offset, yminc, v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc);
}
-/* backdrop for generic channels */
-static void acf_generic_channel_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
+/* get backdrop color for generic channels */
+static void acf_generic_channel_color(bAnimContext *ac, bAnimListElem *ale, float *color)
{
bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
- View2D *v2d= &ac->ar->v2d;
SpaceAction *saction = NULL;
bActionGroup *grp = NULL;
short indent= (acf->get_indent_level) ? acf->get_indent_level(ac, ale) : 0;
- short offset= (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
/* get context info needed... */
if ((ac->sa) && (ac->sa->spacetype == SPACE_ACTION))
@@ -188,10 +205,27 @@ static void acf_generic_channel_backdrop(bAnimContext *ac, bAnimListElem *ale, f
VECCOPY(cp, grp->cs.active);
}
- glColor3ub(cp[0], cp[1], cp[2]);
+ /* copy the colors over, transforming from bytes to floats */
+ rgb_byte_to_float(cp, color);
+ }
+ else {
+ // FIXME: what happens when the indention is 1 greater than what it should be (due to grouping)?
+ int colOfs= 20 - 20*indent;
+ UI_GetThemeColorShade3fv(TH_HEADER, colOfs, color);
}
- else // FIXME: what happens when the indention is 1 greater than what it should be (due to grouping)?
- UI_ThemeColorShade(TH_HEADER, ((indent==0)?20: (indent==1)?-20: -40));
+}
+
+/* backdrop for generic channels */
+static void acf_generic_channel_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
+{
+ bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
+ View2D *v2d= &ac->ar->v2d;
+ short offset= (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
+ float color[3];
+
+ /* set backdrop drawing color */
+ acf->get_backdrop_color(ac, ale, color);
+ glColor3fv(color);
/* no rounded corners - just rectangular box */
glRectf(offset, yminc, v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc);
@@ -348,13 +382,23 @@ static short acf_generic_dataexpand_setting_valid(bAnimContext *ac, bAnimListEle
/* Animation Summary ----------------------------------- */
+/* get backdrop color for summary widget */
+static void acf_summary_color(bAnimContext *ac, bAnimListElem *ale, float *color)
+{
+ // FIXME: hardcoded color - same as the 'action' line in NLA
+ glColor3f(0.8f, 0.2f, 0.0f); // reddish color
+}
+
/* backdrop for summary widget */
static void acf_summary_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
{
+ bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
View2D *v2d= &ac->ar->v2d;
+ float color[3];
- // FIXME: hardcoded color - same as the 'action' line in NLA
- glColor3f(0.8f, 0.2f, 0.0f); // reddish color
+ /* set backdrop drawing color */
+ acf->get_backdrop_color(ac, ale, color);
+ glColor3fv(color);
/* rounded corners on LHS only
* - top and bottom
@@ -424,6 +468,7 @@ static void *acf_summary_setting_ptr(bAnimListElem *ale, int setting, short *typ
/* all animation summary (DopeSheet only) type define */
static bAnimChannelType ACF_SUMMARY =
{
+ acf_summary_color, /* backdrop color */
acf_summary_backdrop, /* backdrop */
acf_generic_indention_0, /* indent level */
NULL, /* offset */
@@ -522,6 +567,7 @@ static void *acf_scene_setting_ptr(bAnimListElem *ale, int setting, short *type)
/* scene type define */
static bAnimChannelType ACF_SCENE =
{
+ acf_generic_root_color, /* backdrop color */
acf_generic_root_backdrop, /* backdrop */
acf_generic_indention_0, /* indent level */
NULL, /* offset */
@@ -641,6 +687,7 @@ static void *acf_object_setting_ptr(bAnimListElem *ale, int setting, short *type
/* object type define */
static bAnimChannelType ACF_OBJECT =
{
+ acf_generic_root_color, /* backdrop color */
acf_generic_root_backdrop, /* backdrop */
acf_generic_indention_0, /* indent level */
NULL, /* offset */
@@ -655,6 +702,16 @@ static bAnimChannelType ACF_OBJECT =
/* Group ------------------------------------------- */
+/* get backdrop color for group widget */
+static void acf_group_color(bAnimContext *ac, bAnimListElem *ale, float *color)
+{
+ /* highlight only for action group channels */
+ if (ale->flag & AGRP_ACTIVE)
+ UI_GetThemeColorShade3fv(TH_GROUP_ACTIVE, 10, color);
+ else
+ UI_GetThemeColorShade3fv(TH_GROUP, 20, color);
+}
+
/* backdrop for group widget */
static void acf_group_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
{
@@ -662,12 +719,11 @@ static void acf_group_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc
View2D *v2d= &ac->ar->v2d;
short expanded= ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0;
short offset= (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
+ float color[3];
- /* only for action group channels */
- if (ale->flag & AGRP_ACTIVE)
- UI_ThemeColorShade(TH_GROUP_ACTIVE, 10);
- else
- UI_ThemeColorShade(TH_GROUP, 20);
+ /* set backdrop drawing color */
+ acf->get_backdrop_color(ac, ale, color);
+ glColor3fv(color);
/* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
uiSetRoundBox((expanded)? (1):(1|8));
@@ -738,6 +794,7 @@ static void *acf_group_setting_ptr(bAnimListElem *ale, int setting, short *type)
/* group type define */
static bAnimChannelType ACF_GROUP =
{
+ acf_group_color, /* backdrop color */
acf_group_backdrop, /* backdrop */
acf_generic_indention_0, /* indent level */
acf_generic_group_offset, /* offset */
@@ -821,6 +878,7 @@ static void *acf_fcurve_setting_ptr(bAnimListElem *ale, int setting, short *type
/* fcurve type define */
static bAnimChannelType ACF_FCURVE =
{
+ acf_generic_channel_color, /* backdrop color */
acf_generic_channel_backdrop, /* backdrop */
acf_generic_indention_flexible, /* indent level */ // xxx rename this to f-curves only?
acf_generic_group_offset, /* offset */
@@ -902,6 +960,7 @@ static void *acf_fillactd_setting_ptr(bAnimListElem *ale, int setting, short *ty
/* object action expander type define */
static bAnimChannelType ACF_FILLACTD =
{
+ acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop,/* backdrop */
acf_generic_indention_1, /* indent level */
acf_generic_basic_offset, /* offset */
@@ -977,6 +1036,7 @@ static void *acf_filldrivers_setting_ptr(bAnimListElem *ale, int setting, short
/* drivers expander type define */
static bAnimChannelType ACF_FILLDRIVERS =
{
+ acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop,/* backdrop */
acf_generic_indention_1, /* indent level */
acf_generic_basic_offset, /* offset */
@@ -1020,6 +1080,7 @@ static int acf_fillmatd_setting_flag(int setting, short *neg)
/* materials expander type define */
static bAnimChannelType ACF_FILLMATD=
{
+ acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop,/* backdrop */
acf_generic_indention_1, /* indent level */
acf_generic_basic_offset, /* offset */
@@ -1063,6 +1124,7 @@ static int acf_fillpartd_setting_flag(int setting, short *neg)
/* particles expander type define */
static bAnimChannelType ACF_FILLPARTD=
{
+ acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop,/* backdrop */
acf_generic_indention_1, /* indent level */
acf_generic_basic_offset, /* offset */
@@ -1142,6 +1204,7 @@ static void *acf_dsmat_setting_ptr(bAnimListElem *ale, int setting, short *type)
/* material expander type define */
static bAnimChannelType ACF_DSMAT=
{
+ acf_generic_channel_color, /* backdrop color */
acf_generic_channel_backdrop, /* backdrop */
acf_generic_indention_0, /* indent level */
acf_dsmat_offset, /* offset */
@@ -1215,6 +1278,7 @@ static void *acf_dslam_setting_ptr(bAnimListElem *ale, int setting, short *type)
/* lamp expander type define */
static bAnimChannelType ACF_DSLAM=
{
+ acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop,/* backdrop */
acf_generic_indention_1, /* indent level */
acf_generic_basic_offset, /* offset */
@@ -1288,6 +1352,7 @@ static void *acf_dscam_setting_ptr(bAnimListElem *ale, int setting, short *type)
/* camera expander type define */
static bAnimChannelType ACF_DSCAM=
{
+ acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop,/* backdrop */
acf_generic_indention_1, /* indent level */
acf_generic_basic_offset, /* offset */
@@ -1371,6 +1436,7 @@ static void *acf_dscur_setting_ptr(bAnimListElem *ale, int setting, short *type)
/* curve expander type define */
static bAnimChannelType ACF_DSCUR=
{
+ acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop,/* backdrop */
acf_generic_indention_1, /* indent level */
acf_generic_basic_offset, /* offset */
@@ -1444,6 +1510,7 @@ static void *acf_dsskey_setting_ptr(bAnimListElem *ale, int setting, short *type
/* shapekey expander type define */
static bAnimChannelType ACF_DSSKEY=
{
+ acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop,/* backdrop */
acf_generic_indention_1, /* indent level */
acf_generic_basic_offset, /* offset */
@@ -1517,6 +1584,7 @@ static void *acf_dswor_setting_ptr(bAnimListElem *ale, int setting, short *type)
/* world expander type define */
static bAnimChannelType ACF_DSWOR=
{
+ acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop,/* backdrop */
acf_generic_indention_1, /* indent level */
acf_generic_basic_offset, /* offset */
@@ -1590,6 +1658,7 @@ static void *acf_dspart_setting_ptr(bAnimListElem *ale, int setting, short *type
/* particle expander type define */
static bAnimChannelType ACF_DSPART=
{
+ acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop,/* backdrop */
acf_generic_indention_1, /* indent level */
acf_generic_basic_offset, /* offset */
@@ -1663,6 +1732,7 @@ static void *acf_dsmball_setting_ptr(bAnimListElem *ale, int setting, short *typ
/* metaball expander type define */
static bAnimChannelType ACF_DSMBALL=
{
+ acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop,/* backdrop */
acf_generic_indention_1, /* indent level */
acf_generic_basic_offset, /* offset */
@@ -1736,6 +1806,7 @@ static void *acf_dsarm_setting_ptr(bAnimListElem *ale, int setting, short *type)
/* metaball expander type define */
static bAnimChannelType ACF_DSARM=
{
+ acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop,/* backdrop */
acf_generic_indention_1, /* indent level */
acf_generic_basic_offset, /* offset */
@@ -1809,6 +1880,7 @@ static void *acf_dsntree_setting_ptr(bAnimListElem *ale, int setting, short *typ
/* node tree expander type define */
static bAnimChannelType ACF_DSNTREE=
{
+ acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop,/* backdrop */
acf_generic_indention_1, /* indent level */ // XXX this only works for compositing
acf_generic_basic_offset, /* offset */
@@ -1882,6 +1954,7 @@ static void *acf_dsmesh_setting_ptr(bAnimListElem *ale, int setting, short *type
/* node tree expander type define */
static bAnimChannelType ACF_DSMESH=
{
+ acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop,/* backdrop */
acf_generic_indention_1, /* indent level */ // XXX this only works for compositing
acf_generic_basic_offset, /* offset */
@@ -1969,6 +2042,7 @@ static void *acf_shapekey_setting_ptr(bAnimListElem *ale, int setting, short *ty
/* shapekey expander type define */
static bAnimChannelType ACF_SHAPEKEY=
{
+ acf_generic_channel_color, /* backdrop color */
acf_generic_channel_backdrop, /* backdrop */
acf_generic_indention_0, /* indent level */
acf_generic_basic_offset, /* offset */
@@ -2314,6 +2388,7 @@ void ANIM_channel_setting_set (bAnimContext *ac, bAnimListElem *ale, int setting
void ANIM_channel_draw (bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
{
bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
+ View2D *v2d= &ac->ar->v2d;
short selected, offset;
float y, ymid, ytext;
@@ -2411,6 +2486,66 @@ void ANIM_channel_draw (bAnimContext *ac, bAnimListElem *ale, float yminc, float
offset += 3;
UI_DrawString(offset, ytext, name);
}
+
+ /* step 6) draw backdrops behidn mute+protection toggles + (sliders) ....................... */
+ /* reset offset - now goes from RHS of panel */
+ offset = 0;
+
+ // TODO: when drawing sliders, make those draw instead of these toggles if not enough space
+
+ if (v2d) {
+ short draw_sliders = 0;
+ float color[3];
+
+ /* get and set backdrop color */
+ acf->get_backdrop_color(ac, ale, color);
+ glColor3fv(color);
+
+ /* check if we need to show the sliders */
+ if ((ac->sa) && ELEM(ac->spacetype, SPACE_ACTION, SPACE_IPO)) {
+ switch (ac->spacetype) {
+ case SPACE_ACTION:
+ {
+ SpaceAction *saction= (SpaceAction *)ac->sa->spacedata.first;
+ draw_sliders= (saction->flag & SACTION_SLIDERS);
+ }
+ break;
+ case SPACE_IPO:
+ {
+ SpaceIpo *sipo= (SpaceIpo *)ac->sa->spacedata.first;
+ draw_sliders= (sipo->flag & SIPO_SLIDERS);
+ }
+ break;
+ }
+ }
+
+ /* check if there's enough space for the toggles if the sliders are drawn too */
+ if ( !(draw_sliders) || ((v2d->mask.xmax-v2d->mask.xmin) > ACHANNEL_BUTTON_WIDTH/2) ) {
+ /* protect... */
+ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PROTECT))
+ offset += ICON_WIDTH;
+ /* mute... */
+ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_MUTE))
+ offset += ICON_WIDTH;
+ }
+
+ /* draw slider
+ * - even if we can draw sliders for this view, we must also check that the channel-type supports them
+ * (only only F-Curves really can support them for now)
+ * - slider should start before the toggles (if they're visible) to keep a clean line down the side
+ */
+ if ((draw_sliders) && ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_SHAPEKEY)) {
+ /* adjust offset */
+ offset += SLIDER_WIDTH;
+ }
+
+
+ /* finally draw a backdrop rect behind these
+ * - starts from the point where the first toggle/slider starts,
+ * - ends past the space that might be reserved for a scroller
+ */
+ glRectf(v2d->cur.xmax-(float)offset, yminc, v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc);
+ }
}
/* ------------------ */
@@ -2421,14 +2556,15 @@ static void achannel_setting_widget_cb(bContext *C, void *poin, void *poin2)
WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN_EDIT, NULL);
}
-/* callback for visiblility-toggle widget settings - perform value flushing (Graph Editor only) */
-static void achannel_setting_visible_widget_cb(bContext *C, void *ale_npoin, void *dummy_poin)
+/* callback for widget settings that need flushing */
+static void achannel_setting_flush_widget_cb(bContext *C, void *ale_npoin, void *setting_wrap)
{
bAnimListElem *ale_setting= (bAnimListElem *)ale_npoin;
bAnimContext ac;
ListBase anim_data = {NULL, NULL};
int filter;
- short vizOn = 0;
+ int setting = GET_INT_FROM_POINTER(setting_wrap);
+ short on = 0;
/* send notifiers before doing anything else... */
WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN_EDIT, NULL);
@@ -2440,10 +2576,10 @@ static void achannel_setting_visible_widget_cb(bContext *C, void *ale_npoin, voi
/* verify that we have a channel to operate on, and that it has all we need */
if (ale_setting) {
/* check if the setting is on... */
- vizOn= ANIM_channel_setting_get(&ac, ale_setting, ACHANNEL_SETTING_VISIBLE);
+ on= ANIM_channel_setting_get(&ac, ale_setting, setting);
- /* vizOn == -1 means setting not found... */
- if (vizOn == -1)
+ /* on == -1 means setting not found... */
+ if (on == -1)
return;
}
else
@@ -2457,7 +2593,7 @@ static void achannel_setting_visible_widget_cb(bContext *C, void *ale_npoin, voi
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
/* call API method to flush the setting */
- ANIM_visibility_flush_anim_channels(&ac, &anim_data, ale_setting, vizOn);
+ ANIM_flush_setting_anim_channels(&ac, &anim_data, ale_setting, setting, on);
/* free temp data */
BLI_freelistN(&anim_data);
@@ -2635,11 +2771,19 @@ static void draw_setting_widget (bAnimContext *ac, bAnimListElem *ale, bAnimChan
/* set call to send relevant notifiers and/or perform type-specific updates */
if (but) {
- /* 'visibility' toggles for Graph Editor need special flushing */
- if (setting == ACHANNEL_SETTING_VISIBLE)
- uiButSetNFunc(but, achannel_setting_visible_widget_cb, MEM_dupallocN(ale), 0);
- else
- uiButSetFunc(but, achannel_setting_widget_cb, NULL, NULL);
+ switch (setting) {
+ /* settings needing flushing up/down hierarchy */
+ case ACHANNEL_SETTING_VISIBLE: /* Graph Editor - 'visibility' toggles */
+ case ACHANNEL_SETTING_PROTECT: /* General - protection flags */
+ case ACHANNEL_SETTING_MUTE: /* General - muting flags */
+ uiButSetNFunc(but, achannel_setting_flush_widget_cb, MEM_dupallocN(ale), SET_INT_IN_POINTER(setting));
+ break;
+
+ /* no flushing */
+ case ACHANNEL_SETTING_EXPAND: /* expanding - cannot flush, otherwise all would open/close at once */
+ default:
+ uiButSetFunc(but, achannel_setting_widget_cb, NULL, NULL);
+ }
}
}
}
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index ebb3136d530..530e9179474 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -364,9 +364,10 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short
* then the channels under closed expanders get ignored...
* - ale_setting: the anim channel (not in the anim_data list directly, though occuring there)
* with the new state of the setting that we want flushed up/down the hierarchy
- * - vizOn: whether the visibility setting has been enabled or disabled
+ * - setting: type of setting to set
+ * - on: whether the visibility setting has been enabled or disabled
*/
-void ANIM_visibility_flush_anim_channels (bAnimContext *ac, ListBase *anim_data, bAnimListElem *ale_setting, short vizOn)
+void ANIM_flush_setting_anim_channels (bAnimContext *ac, ListBase *anim_data, bAnimListElem *ale_setting, int setting, short on)
{
bAnimListElem *ale, *match=NULL;
int prevLevel=0, matchLevel=0;
@@ -394,13 +395,22 @@ void ANIM_visibility_flush_anim_channels (bAnimContext *ac, ListBase *anim_data,
* - we define the level as simply being the offset for the start of the channel
*/
matchLevel= (acf->get_offset)? acf->get_offset(ac, ale_setting) : 0;
+ prevLevel= matchLevel;
}
/* flush up?
- * - only flush up if the current state is now enabled
+ *
+ * For Visibility:
+ * - only flush up if the current state is now enabled (positive 'on' state is default)
* (otherwise, it's too much work to force the parents to be inactive too)
+ *
+ * For everything else:
+ * - only flush up if the current state is now disabled (negative 'off' state is default)
+ * (otherwise, it's too much work to force the parents to be active too)
*/
- if (vizOn) {
+ if ( ((setting == ACHANNEL_SETTING_VISIBLE) && on) ||
+ ((setting != ACHANNEL_SETTING_VISIBLE) && on==0) )
+ {
/* go backwards in the list, until the highest-ranking element (by indention has been covered) */
for (ale= match->prev; ale; ale= ale->prev) {
bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
@@ -416,7 +426,7 @@ void ANIM_visibility_flush_anim_channels (bAnimContext *ac, ListBase *anim_data,
* when toggling visibility of F-Curves, gets flushed), flush the new status...
*/
if (level < prevLevel)
- ANIM_channel_setting_set(ac, ale, ACHANNEL_SETTING_VISIBLE, vizOn);
+ ANIM_channel_setting_set(ac, ale, setting, on);
/* however, if the level is 'greater than' (i.e. less important than the previous channel,
* stop searching, since we've already reached the bottom of another hierarchy
*/
@@ -444,7 +454,7 @@ void ANIM_visibility_flush_anim_channels (bAnimContext *ac, ListBase *anim_data,
* flush the new status...
*/
if (level > matchLevel)
- ANIM_channel_setting_set(ac, ale, ACHANNEL_SETTING_VISIBLE, vizOn);
+ ANIM_channel_setting_set(ac, ale, setting, on);
/* however, if the level is 'less than or equal to' the channel that was changed,
* (i.e. the current channel is as important if not more important than the changed channel)
* then we should stop, since we've found the last one of the children we should flush
@@ -1054,7 +1064,7 @@ static int animchannels_visibility_set_exec(bContext *C, wmOperator *op)
ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_ADD);
/* now, also flush selection status up/down as appropriate */
- ANIM_visibility_flush_anim_channels(&ac, &all_data, ale, 1);
+ ANIM_flush_setting_anim_channels(&ac, &all_data, ale, ACHANNEL_SETTING_VISIBLE, 1);
}
BLI_freelistN(&anim_data);
@@ -1128,7 +1138,7 @@ static int animchannels_visibility_toggle_exec(bContext *C, wmOperator *op)
ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, vis);
/* now, also flush selection status up/down as appropriate */
- ANIM_visibility_flush_anim_channels(&ac, &all_data, ale, (vis == ACHANNEL_SETFLAG_ADD));
+ ANIM_flush_setting_anim_channels(&ac, &all_data, ale, ACHANNEL_SETTING_VISIBLE, (vis == ACHANNEL_SETFLAG_ADD));
}
/* cleanup */
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index 4cc3a8d343f..7d1ddda1c6d 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -120,7 +120,7 @@ void ED_markers_get_minmax (ListBase *markers, short sel, float *first, float *l
int selcount = 0;
/* sanity check */
- printf("markers = %p - %p, %p \n", markers, markers->first, markers->last);
+ //printf("markers = %p - %p, %p \n", markers, markers->first, markers->last);
if (markers == NULL) {
*first = 0.0f;
*last = 0.0f;
@@ -240,9 +240,8 @@ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
/* vertical line - dotted */
- // NOTE: currently only used for sequencer
#ifdef DURIAN_CAMERA_SWITCH
- if (marker->camera || flag & DRAW_MARKERS_LINES) {
+ if ((marker->camera) || (flag & DRAW_MARKERS_LINES)) {
#else
if (flag & DRAW_MARKERS_LINES) {
#endif
@@ -252,10 +251,10 @@ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag)
glColor4ub(255, 255, 255, 96);
else
glColor4ub(0, 0, 0, 96);
-
+
glBegin(GL_LINES);
glVertex2f((xpos*xscale)+0.5f, 12.0f);
- glVertex2f((xpos*xscale)+0.5f, 34.0f*yscale); /* a bit lazy but we know it cant be greater then 34 strips high */
+ glVertex2f((xpos*xscale)+0.5f, (v2d->cur.ymax+12.0f)*yscale);
glEnd();
setlinestyle(0);
@@ -351,7 +350,7 @@ static int ed_marker_add(bContext *C, wmOperator *op)
marker = MEM_callocN(sizeof(TimeMarker), "TimeMarker");
marker->flag= SELECT;
marker->frame= frame;
- sprintf(marker->name, "Frame %d", frame); // XXX - temp code only
+ sprintf(marker->name, "F_%02d", frame); // XXX - temp code only
BLI_addtail(markers, marker);
WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL);
diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c
index 59e52c0d489..b816ffbe905 100644
--- a/source/blender/editors/animation/drivers.c
+++ b/source/blender/editors/animation/drivers.c
@@ -404,8 +404,7 @@ static int add_driver_button_exec (bContext *C, wmOperator *op)
/* send updates */
DAG_ids_flush_update(0);
- /* for now, only send ND_KEYS for KeyingSets */
- WM_event_add_notifier(C, ND_KEYS, NULL); // XXX
+ WM_event_add_notifier(C, NC_ANIMATION|ND_FCURVES_ORDER, NULL); // XXX
}
return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED;
@@ -468,8 +467,7 @@ static int remove_driver_button_exec (bContext *C, wmOperator *op)
/* send updates */
DAG_ids_flush_update(0);
- /* for now, only send ND_KEYS for KeyingSets */
- WM_event_add_notifier(C, ND_KEYS, NULL); // XXX
+ WM_event_add_notifier(C, NC_ANIMATION|ND_FCURVES_ORDER, NULL); // XXX
}
return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED;
diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c
index b3b0d6308a7..828ff9792be 100644
--- a/source/blender/editors/animation/keyframes_edit.c
+++ b/source/blender/editors/animation/keyframes_edit.c
@@ -455,11 +455,11 @@ void ANIM_editkeyframes_refresh(bAnimContext *ac)
filter= ANIMFILTER_CURVESONLY;
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* loop over ipo-curves that are likely to have been edited, and check them */
+ /* loop over F-Curves that are likely to have been edited, and check them */
for (ale= anim_data.first; ale; ale= ale->next) {
FCurve *fcu= ale->key_data;
- /* make sure keyframes in F-curve are all in order, and handles are in valid positions */
+ /* make sure keyframes in F-Curve are all in order, and handles are in valid positions */
sort_time_fcurve(fcu);
testhandles_fcurve(fcu);
}
@@ -936,7 +936,6 @@ static short select_bezier_invert(BeztEditData *bed, BezTriple *bezt)
return 0;
}
-// NULL
BeztEditFunc ANIM_editkeyframes_select(short selectmode)
{
switch (selectmode) {
diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c
index fb9d4d53b0f..a1ff940e8b9 100644
--- a/source/blender/editors/animation/keyframes_general.c
+++ b/source/blender/editors/animation/keyframes_general.c
@@ -67,21 +67,26 @@
/* **************************************************** */
-/* Only delete the nominated keyframe from provided ipo-curve.
+/* Only delete the nominated keyframe from provided F-Curve.
* Not recommended to be used many times successively. For that
- * there is delete_ipo_keys().
+ * there is delete_fcurve_keys().
*/
void delete_fcurve_key(FCurve *fcu, int index, short do_recalc)
{
- /* firstly check that index is valid */
- if (index < 0)
- index *= -1;
+ /* sanity check */
if (fcu == NULL)
return;
- if (index >= fcu->totvert)
+
+ /* verify the index:
+ * 1) cannot be greater than the number of available keyframes
+ * 2) negative indices are for specifying a value from the end of the array
+ */
+ if (abs(index) >= fcu->totvert)
return;
+ else if (index < 0)
+ index += fcu->totvert;
- /* Delete this key */
+ /* Delete this keyframe */
memmove(&fcu->bezt[index], &fcu->bezt[index+1], sizeof(BezTriple)*(fcu->totvert-index-1));
fcu->totvert--;
@@ -250,7 +255,7 @@ void clean_fcurve(FCurve *fcu, float thresh)
/* ---------------- */
-/* temp struct used for smooth_ipo */
+/* temp struct used for smooth_fcurve */
typedef struct tSmooth_Bezt {
float *h1, *h2, *h3; /* bezt->vec[0,1,2][1] */
} tSmooth_Bezt;
diff --git a/source/blender/editors/armature/poseSlide.c b/source/blender/editors/armature/poseSlide.c
index 7ceb50057ce..0e066b112b0 100644
--- a/source/blender/editors/armature/poseSlide.c
+++ b/source/blender/editors/armature/poseSlide.c
@@ -417,7 +417,7 @@ static void pose_slide_apply_quat (tPoseSlideOp *pso, tPChanFCurveLink *pfl)
float cframe;
/* get the path to use - this should be quaternion rotations only (needs care) */
- path= BLI_sprintfN("%s.%s", pfl->pchan_path, "rotation");
+ path= BLI_sprintfN("%s.%s", pfl->pchan_path, "rotation_quaternion");
/* get the current frame number */
cframe= (float)pso->cframe;
@@ -463,6 +463,19 @@ static void pose_slide_apply_quat (tPoseSlideOp *pso, tPChanFCurveLink *pfl)
/* just perform the interpol between quat_prev and quat_next using pso->percentage as a guide */
interp_qt_qtqt(pchan->quat, quat_prev, quat_next, pso->percentage);
}
+ else if (pso->mode == POSESLIDE_PUSH) {
+ float quat_diff[4], quat_orig[4];
+
+ /* calculate the delta transform from the previous to the current */
+ // TODO: investigate ways to favour one transform more?
+ sub_qt_qtqt(quat_diff, pchan->quat, quat_prev);
+
+ /* make a copy of the original rotation */
+ QUATCOPY(quat_orig, pchan->quat);
+
+ /* increase the original by the delta transform, by an amount determined by percentage */
+ add_qt_qtqt(pchan->quat, quat_orig, quat_diff, pso->percentage);
+ }
else {
float quat_interp[4], quat_orig[4];
int iters= (int)ceil(10.0f*pso->percentage); // TODO: maybe a sensitivity ctrl on top of this is needed
@@ -475,11 +488,8 @@ static void pose_slide_apply_quat (tPoseSlideOp *pso, tPChanFCurveLink *pfl)
/* make a copy of the original rotation */
QUATCOPY(quat_orig, pchan->quat);
- /* tricky interpolations - mode-dependent blending between original and new */
- if (pso->mode == POSESLIDE_RELAX) // xxx this was the original code, so should work fine
- interp_qt_qtqt(pchan->quat, quat_orig, quat_interp, 1.0f/6.0f);
- else // I'm just guessing here...
- interp_qt_qtqt(pchan->quat, quat_orig, quat_interp, 6.0f/5.0f);
+ /* tricky interpolations - blending between original and new */
+ interp_qt_qtqt(pchan->quat, quat_orig, quat_interp, 1.0f/6.0f);
}
}
}
@@ -612,22 +622,15 @@ static int pose_slide_invoke_common (bContext *C, wmOperator *op, tPoseSlideOp *
/* cancel if no keyframes found... */
if (pso->keys.root) {
ActKeyColumn *ak;
+ float cframe= (float)pso->cframe;
/* firstly, check if the current frame is a keyframe... */
- ak= (ActKeyColumn *)BLI_dlrbTree_search_exact(&pso->keys, compare_ak_cfraPtr, &pso->cframe);
+ ak= (ActKeyColumn *)BLI_dlrbTree_search_exact(&pso->keys, compare_ak_cfraPtr, &cframe);
if (ak == NULL) {
/* current frame is not a keyframe, so search */
- ActKeyColumn *pk= (ActKeyColumn *)BLI_dlrbTree_search_prev(&pso->keys, compare_ak_cfraPtr, &pso->cframe);
- ActKeyColumn *nk= (ActKeyColumn *)BLI_dlrbTree_search_next(&pso->keys, compare_ak_cfraPtr, &pso->cframe);
-
- /* check if we found good keyframes */
- if ((pk == nk) && (pk != NULL)) {
- if (pk->cfra < pso->cframe)
- nk= nk->next;
- else if (nk->cfra > pso->cframe)
- pk= pk->prev;
- }
+ ActKeyColumn *pk= (ActKeyColumn *)BLI_dlrbTree_search_prev(&pso->keys, compare_ak_cfraPtr, &cframe);
+ ActKeyColumn *nk= (ActKeyColumn *)BLI_dlrbTree_search_next(&pso->keys, compare_ak_cfraPtr, &cframe);
/* new set the frames */
/* prev frame */
diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c
index aeb42142abd..df5f551fb0c 100644
--- a/source/blender/editors/armature/poseobject.c
+++ b/source/blender/editors/armature/poseobject.c
@@ -227,6 +227,7 @@ void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob)
if ((pchan->bone) && (arm->layer & pchan->bone->layer)) {
if (pchan->path) {
/* if the pathsf and pathef aren't initialised, abort! */
+ // XXX can now have negative frames, so this check needs improvement
if (ELEM(0, pchan->pathsf, pchan->pathef))
return;
diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c
index 5deffbabb77..59ad4124a95 100644
--- a/source/blender/editors/gpencil/gpencil_buttons.c
+++ b/source/blender/editors/gpencil/gpencil_buttons.c
@@ -119,13 +119,13 @@ static void gp_drawui_layer (uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl)
box= uiLayoutBox(layout);
row= uiLayoutRow(box, 0);
+ uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_EXPAND);
block= uiLayoutGetBlock(row); // err...
uiBlockSetEmboss(block, UI_EMBOSSN);
/* left-align ............................... */
- subrow= uiLayoutRow(row, 1);
- uiLayoutSetAlignment(subrow, UI_LAYOUT_ALIGN_LEFT);
+ subrow= uiLayoutRow(row, 0);
/* active */
icon= (gpl->flag & GP_LAYER_ACTIVE) ? ICON_RADIOBUT_ON : ICON_RADIOBUT_OFF;
@@ -168,6 +168,11 @@ static void gp_drawui_layer (uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl)
/* visibility button */
uiItemR(subrow, "", ICON_RESTRICT_VIEW_OFF, &ptr, "hide", 0);
+ /* frame locking */
+ // TODO: this needs its own icons...
+ icon= (gpl->flag & GP_LAYER_FRAMELOCK) ? ICON_RENDER_STILL : ICON_RENDER_ANIMATION;
+ uiItemR(subrow, "", icon, &ptr, "frame_lock", 0);
+
uiBlockSetEmboss(block, UI_EMBOSS);
/* name */
@@ -189,7 +194,6 @@ static void gp_drawui_layer (uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl)
box= uiLayoutBox(layout);
split= uiLayoutSplit(box, 0.5f, 0);
-
/* draw settings ---------------------------------- */
/* left column ..................... */
col= uiLayoutColumn(split, 0);
@@ -229,7 +233,7 @@ static void draw_gpencil_panel (bContext *C, uiLayout *layout, bGPdata *gpd, Poi
{
PointerRNA gpd_ptr;
bGPDlayer *gpl;
- uiLayout *col;
+ uiLayout *col, *row;
/* make new PointerRNA for Grease Pencil block */
RNA_id_pointer_create((ID *)gpd, &gpd_ptr);
@@ -254,12 +258,21 @@ static void draw_gpencil_panel (bContext *C, uiLayout *layout, bGPdata *gpd, Poi
}
/* draw gpd drawing settings first ------------------------------------- */
- col= uiLayoutColumn(layout, 0);
+ col= uiLayoutColumn(layout, 1);
/* label */
uiItemL(col, "Drawing Settings:", 0);
/* 'stick to view' option */
- uiItemR(col, NULL, 0, &gpd_ptr, "view_space_draw", 0);
+ row= uiLayoutRow(col, 1);
+ uiItemEnumR_string(row, NULL, 0, &gpd_ptr, "draw_mode", "VIEW");
+ uiItemEnumR_string(row, NULL, 0, &gpd_ptr, "draw_mode", "CURSOR");
+ row= uiLayoutRow(col, 1);
+ uiItemEnumR_string(row, NULL, 0, &gpd_ptr, "draw_mode", "SURFACE");
+ uiItemEnumR_string(row, NULL, 0, &gpd_ptr, "draw_mode", "STROKE");
+
+ row= uiLayoutRow(col, 0);
+ uiLayoutSetActive(row, (gpd->flag & (GP_DATA_DEPTH_STROKE|GP_DATA_DEPTH_VIEW)) ? 1:0);
+ uiItemR(row, NULL, 0, &gpd_ptr, "use_stroke_endpoints", 0);
}
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 3f9e3e04411..371e73cfb9b 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -155,15 +155,7 @@ static int gpencil_draw_poll (bContext *C)
static int gpencil_project_check (tGPsdata *p)
{
bGPdata *gpd= p->gpd;
-
- if( (gpd->sbuffer_sflag & GP_STROKE_3DSPACE) &&
- (p->scene->toolsettings->snap_mode==SCE_SNAP_MODE_FACE) &&
- (p->scene->toolsettings->snap_flag & SCE_SNAP_PROJECT) )
- {
- return 1;
- }
-
- return 0;
+ return ((gpd->sbuffer_sflag & GP_STROKE_3DSPACE) && (p->gpd->flag & (GP_DATA_DEPTH_VIEW | GP_DATA_DEPTH_STROKE))) ? 1:0;
}
/* ******************************************* */
@@ -220,13 +212,13 @@ static short gp_stroke_filtermval (tGPsdata *p, int mval[2], int pmval[2])
/* convert screen-coordinates to buffer-coordinates */
// XXX this method needs a total overhaul!
-static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[])
+static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[], float *depth)
{
bGPdata *gpd= p->gpd;
/* in 3d-space - pt->x/y/z are 3 side-by-side floats */
if (gpd->sbuffer_sflag & GP_STROKE_3DSPACE) {
- if(gpencil_project_check(p) && (view_autodist_simple(p->ar, mval, out))) {
+ if(gpencil_project_check(p) && (view_autodist_simple(p->ar, mval, out, 0, depth))) {
/* projecting onto 3D-Geometry
* - nothing more needs to be done here, since view_autodist_simple() has already done it
*/
@@ -466,6 +458,8 @@ static void gp_stroke_newfrombuffer (tGPsdata *p)
bGPDspoint *pt;
tGPspoint *ptc;
int i, totelem;
+ /* since strokes are so fine, when using their depth we need a margin otherwise they might get missed */
+ int depth_margin = (p->gpd->flag & GP_DATA_DEPTH_STROKE) ? 4 : 0;
/* get total number of points to allocate space for
* - drawing straight-lines only requires the endpoints
@@ -501,7 +495,7 @@ static void gp_stroke_newfrombuffer (tGPsdata *p)
ptc= gpd->sbuffer;
/* convert screen-coordinates to appropriate coordinates (and store them) */
- gp_stroke_convertcoords(p, &ptc->x, &pt->x);
+ gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
/* copy pressure */
pt->pressure= ptc->pressure;
@@ -514,23 +508,79 @@ static void gp_stroke_newfrombuffer (tGPsdata *p)
ptc= ((tGPspoint *)gpd->sbuffer) + (gpd->sbuffer_size - 1);
/* convert screen-coordinates to appropriate coordinates (and store them) */
- gp_stroke_convertcoords(p, &ptc->x, &pt->x);
+ gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
/* copy pressure */
pt->pressure= ptc->pressure;
}
}
else {
+ float *depth_arr= NULL;
+
+ /* get an array of depths, far depths are blended */
+ if(gpencil_project_check(p)) {
+ short mval[2];
+ int interp_depth = 0;
+ int found_depth = 0;
+
+ depth_arr= MEM_mallocN(sizeof(float) * gpd->sbuffer_size, "depth_points");
+
+ for (i=0, ptc=gpd->sbuffer; i < gpd->sbuffer_size; i++, ptc++, pt++) {
+ mval[0]= ptc->x; mval[1]= ptc->y;
+ if(view_autodist_depth(p->ar, mval, depth_margin, depth_arr+i) == 0)
+ interp_depth= TRUE;
+ else
+ found_depth= TRUE;
+ }
+
+ if(found_depth==FALSE) {
+ /* eeh... not much we can do.. :/, ignore depth in this case, use the 3D cursor */
+ for (i=gpd->sbuffer_size-1; i >= 0; i--)
+ depth_arr[i] = 0.9999f;
+ }
+ else {
+ if(p->gpd->flag & GP_DATA_DEPTH_STROKE_ENDPOINTS) {
+ /* remove all info between the valid endpoints */
+ int first_valid = 0;
+ int last_valid = 0;
+
+ for (i=0; i < gpd->sbuffer_size; i++)
+ if(depth_arr[i] != FLT_MAX)
+ break;
+ first_valid= i;
+
+ for (i=gpd->sbuffer_size-1; i >= 0; i--)
+ if(depth_arr[i] != FLT_MAX)
+ break;
+ last_valid= i;
+
+ /* invalidate non-endpoints, so only blend between first and last */
+ for (i=first_valid+1; i < last_valid; i++)
+ depth_arr[i]= FLT_MAX;
+
+ interp_depth= TRUE;
+ }
+
+ if(interp_depth) {
+ interp_sparse_array(depth_arr, gpd->sbuffer_size, FLT_MAX);
+ }
+ }
+ }
+
+
+ pt= gps->points;
+
/* convert all points (normal behaviour) */
- for (i=0, ptc=gpd->sbuffer; i < gpd->sbuffer_size && ptc; i++, ptc++) {
+ for (i=0, ptc=gpd->sbuffer; i < gpd->sbuffer_size && ptc; i++, ptc++, pt++) {
/* convert screen-coordinates to appropriate coordinates (and store them) */
- gp_stroke_convertcoords(p, &ptc->x, &pt->x);
+ gp_stroke_convertcoords(p, &ptc->x, &pt->x, depth_arr ? depth_arr+i:NULL);
/* copy pressure */
pt->pressure= ptc->pressure;
-
- pt++;
}
+
+ if(depth_arr)
+ MEM_freeN(depth_arr);
}
/* add stroke to frame */
@@ -1141,7 +1191,7 @@ static void gpencil_draw_exit (bContext *C, wmOperator *op)
/* need to restore the original projection settings before packing up */
view3d_operator_needs_opengl(C);
- view_autodist_init(p->scene, p->ar, v3d);
+ view_autodist_init(p->scene, p->ar, v3d, (p->gpd->flag & GP_DATA_DEPTH_STROKE) ? 1:0);
}
gp_paint_cleanup(p);
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index c34885fbe6b..531751a609e 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -327,6 +327,8 @@ typedef enum eAnimChannel_Settings {
/* Drawing, mouse handling, and flag setting behaviour... */
typedef struct bAnimChannelType {
/* drawing */
+ /* get RGB color that is used to draw the majority of the backdrop */
+ void (*get_backdrop_color)(bAnimContext *ac, bAnimListElem *ale, float *color);
/* draw backdrop strip for channel */
void (*draw_backdrop)(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc);
/* get depth of indention (relative to the depth channel is nested at) */
@@ -334,7 +336,6 @@ typedef struct bAnimChannelType {
/* get offset in pixels for the start of the channel (in addition to the indent depth) */
short (*get_offset)(bAnimContext *ac, bAnimListElem *ale);
-
/* get name (for channel lists) */
void (*name)(bAnimListElem *ale, char *name);
/* get icon (for channel lists) */
@@ -385,9 +386,10 @@ void ANIM_channel_setting_set(bAnimContext *ac, bAnimListElem *ale, int setting,
* then the channels under closed expanders get ignored...
* - ale_setting: the anim channel (not in the anim_data list directly, though occuring there)
* with the new state of the setting that we want flushed up/down the hierarchy
- * - vizOn: whether the visibility setting has been enabled or disabled
+ * - setting: type of setting to set
+ * - on: whether the visibility setting has been enabled or disabled
*/
-void ANIM_visibility_flush_anim_channels(bAnimContext *ac, ListBase *anim_data, bAnimListElem *ale_setting, short vizOn);
+void ANIM_flush_setting_anim_channels(bAnimContext *ac, ListBase *anim_data, bAnimListElem *ale_setting, int setting, short on);
/* Deselect all animation channels */
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 66c32b06f95..174447c0f9f 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -85,8 +85,6 @@ int *mesh_get_x_mirror_faces(struct Object *ob, struct EditMesh *em);
int join_mesh_exec(struct bContext *C, struct wmOperator *op);
int join_mesh_shapes_exec(struct bContext *C, struct wmOperator *op);
-void objects_bake_render(struct Scene *scene, short event, char **error_msg);
-
/* mesh_ops.c */
void ED_operatortypes_mesh(void);
void ED_operatormacros_mesh(void);
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index de5a9fe4e07..a7879c7b70d 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -127,8 +127,9 @@ unsigned int view3d_sample_backbuf(struct ViewContext *vc, int x, int y);
int view_autodist(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, short *mval, float mouse_worldloc[3]);
/* only draw so view_autodist_simple can be called many times after */
-int view_autodist_init(struct Scene *scene, struct ARegion *ar, struct View3D *v3d);
-int view_autodist_simple(struct ARegion *ar, short *mval, float mouse_worldloc[3]);
+int view_autodist_init(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, int mode);
+int view_autodist_simple(struct ARegion *ar, short *mval, float mouse_worldloc[3], int margin, float *force_depth);
+int view_autodist_depth(struct ARegion *ar, short *mval, int margin, float *depth);
/* select */
#define MAXPICKBUF 10000
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 77a8ea8e912..0b7499b947a 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -126,11 +126,12 @@ typedef struct uiLayout uiLayout;
#define UI_TEXT_LEFT 64
#define UI_ICON_LEFT 128
#define UI_ICON_SUBMENU 256
+#define UI_ICON_PREVIEW 512
/* control for button type block */
-#define UI_MAKE_TOP 512
-#define UI_MAKE_DOWN 1024
-#define UI_MAKE_LEFT 2048
-#define UI_MAKE_RIGHT 4096
+#define UI_MAKE_TOP 1024
+#define UI_MAKE_DOWN 2048
+#define UI_MAKE_LEFT 4096
+#define UI_MAKE_RIGHT 8192
/* button align flag, for drawing groups together */
#define UI_BUT_ALIGN (15<<14)
@@ -427,6 +428,7 @@ struct PointerRNA *uiButGetOperatorPtrRNA(uiBut *but);
#define UI_ID_FAKE_USER 256
#define UI_ID_PIN 512
#define UI_ID_BROWSE_RENDER 1024
+#define UI_ID_PREVIEWS 2048
#define UI_ID_FULL (UI_ID_RENAME|UI_ID_BROWSE|UI_ID_ADD_NEW|UI_ID_OPEN|UI_ID_ALONE|UI_ID_DELETE|UI_ID_LOCAL)
typedef void (*uiIDPoinFuncFP)(struct bContext *C, char *str, struct ID **idpp);
@@ -451,10 +453,9 @@ uiBut *uiDefIconTextBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg,
uiBut *uiDefKeyevtButS(uiBlock *block, int retval, char *str, short x1, short y1, short x2, short y2, short *spoin, char *tip);
uiBut *uiDefHotKeyevtButS(uiBlock *block, int retval, char *str, short x1, short y1, short x2, short y2, short *keypoin, short *modkeypoin, char *tip);
-uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxlen, short x1, short y1, short x2, short y2, char *tip);
+uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxlen, short x1, short y1, short x2, short y2, float a1, float a2, char *tip);
void uiBlockPickerButtons(struct uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval);
-void uiBlockColorbandButtons(struct uiBlock *block, struct ColorBand *coba, struct rctf *butr, int event);
uiBut *uiDefAutoButR(uiBlock *block, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, char *name, int icon, int x1, int y1, int x2, int y2);
void uiDefAutoButsRNA(const struct bContext *C, uiLayout *layout, struct PointerRNA *ptr, int columns);
@@ -641,6 +642,8 @@ void uiTemplateHeader(uiLayout *layout, struct bContext *C, int menus);
void uiTemplateDopeSheetFilter(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr);
void uiTemplateID(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname,
char *newop, char *openop, char *unlinkop);
+void uiTemplateIDPreview(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname,
+ char *newop, char *openop, char *unlinkop, int rows, int cols);
void uiTemplateAnyID(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname,
char *proptypename, char *text);
void uiTemplatePathBuilder(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname,
@@ -649,7 +652,8 @@ uiLayout *uiTemplateModifier(uiLayout *layout, struct PointerRNA *ptr);
uiLayout *uiTemplateConstraint(uiLayout *layout, struct PointerRNA *ptr);
void uiTemplatePreview(uiLayout *layout, struct ID *id, struct ID *parent, struct MTex *slot);
void uiTemplateColorRamp(uiLayout *layout, struct PointerRNA *ptr, char *propname, int expand);
-void uiTemplateCurveMapping(uiLayout *layout, struct PointerRNA *ptr, char *propname, int type, int levels);
+void uiTemplateCurveMapping(uiLayout *layout, struct PointerRNA *ptr, char *propname, int type, int levels, int brush);
+void uiTemplateColorWheel(uiLayout *layout, struct PointerRNA *ptr, char *propname, int value_slider);
void uiTemplateTriColorSet(uiLayout *layout, struct PointerRNA *ptr, char *propname);
void uiTemplateLayers(uiLayout *layout, struct PointerRNA *ptr, char *propname,
PointerRNA *used_ptr, char *used_propname, int active_layer);
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index afe6a2b9dcb..69e75d0e7c4 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -55,7 +55,9 @@ int UI_icon_get_width(int icon_id);
int UI_icon_get_height(int icon_id);
void UI_icon_draw(float x, float y, int icon_id);
-void UI_icon_draw_preview(float x, float y, int icon_id, int nocreate);
+void UI_icon_draw_preview(float x, float y, int icon_id);
+void UI_icon_draw_preview_aspect(float x, float y, int icon_id, float aspect);
+void UI_icon_draw_preview_aspect_size(float x, float y, int icon_id, float aspect, int size);
void UI_icon_draw_aspect(float x, float y, int icon_id, float aspect, float alpha);
void UI_icon_draw_aspect_color(float x, float y, int icon_id, float aspect, float *rgb);
diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h
index 1ae3634c73b..787a39591c7 100644
--- a/source/blender/editors/include/UI_resources.h
+++ b/source/blender/editors/include/UI_resources.h
@@ -236,6 +236,8 @@ int UI_GetThemeValue(int colorid);
// get three color values, scaled to 0.0-1.0 range
void UI_GetThemeColor3fv(int colorid, float *col);
+// get the color, range 0.0-1.0, complete with shading offset
+void UI_GetThemeColorShade3fv(int colorid, int offset, float *col);
// get the 3 or 4 byte values
void UI_GetThemeColor3ubv(int colorid, char *col);
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 88b9c7819fd..5c91a91e447 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1116,7 +1116,6 @@ void ui_get_but_vectorf(uiBut *but, float *vec)
if(but->editvec) {
VECCOPY(vec, but->editvec);
- return;
}
if(but->rnaprop) {
@@ -1152,7 +1151,6 @@ void ui_set_but_vectorf(uiBut *but, float *vec)
if(but->editvec) {
VECCOPY(but->editvec, vec);
- return;
}
if(but->rnaprop) {
@@ -3171,9 +3169,10 @@ uiBut *uiDefHotKeyevtButS(uiBlock *block, int retval, char *str, short x1, short
/* arg is pointer to string/name, use uiButSetSearchFunc() below to make this work */
-uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxlen, short x1, short y1, short x2, short y2, char *tip)
+/* here a1 and a2, if set, control thumbnail preview rows/cols */
+uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxlen, short x1, short y1, short x2, short y2, float a1, float a2, char *tip)
{
- uiBut *but= ui_def_but(block, SEARCH_MENU, retval, "", x1, y1, x2, y2, arg, 0.0, maxlen, 0.0, 0.0, tip);
+ uiBut *but= ui_def_but(block, SEARCH_MENU, retval, "", x1, y1, x2, y2, arg, 0.0, maxlen, a1, a2, tip);
but->icon= (BIFIconID) icon;
but->flag|= UI_HAS_ICON;
diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c
index acfd48e0269..e35ffade342 100644
--- a/source/blender/editors/interface/interface_anim.c
+++ b/source/blender/editors/interface/interface_anim.c
@@ -168,7 +168,7 @@ void uiAnimContextProperty(const bContext *C, struct PointerRNA *ptr, struct Pro
if(ar) {
for(block=ar->uiblocks.first; block; block=block->next) {
for(but=block->buttons.first; but; but= but->next) {
- if(but->active && but->rnapoin.id.data) {
+ if((but->active || but->flag & UI_BUT_LAST_ACTIVE) && but->rnapoin.id.data) {
*ptr= but->rnapoin;
*prop= but->rnaprop;
*index= but->rnaindex;
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index fa5d60a20f6..916a48b7442 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -402,11 +402,7 @@ static void ui_apply_but_BUTM(bContext *C, uiBut *but, uiHandleButtonData *data)
static void ui_apply_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data)
{
- if(but->type == COL) {
- if(but->a1 != -1) // this is not a color picker (weak!)
- ui_set_but_vectorf(but, data->vec);
- }
- else if(ELEM3(but->type, MENU, ICONROW, ICONTEXTROW))
+ if(ELEM3(but->type, MENU, ICONROW, ICONTEXTROW))
ui_set_but_val(but, data->value);
ui_check_but(but);
@@ -2586,6 +2582,7 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, wm
but->hsv[2]= CLAMPIS(but->hsv[2]+0.05f, 0.0f, 1.0f);
hsv_to_rgb(but->hsv[0], but->hsv[1], but->hsv[2], data->vec, data->vec+1, data->vec+2);
+ ui_set_but_vectorf(but, data->vec);
button_activate_state(C, but, BUTTON_STATE_EXIT);
ui_apply_button(C, but->block, but, data, 1);
@@ -2694,6 +2691,7 @@ static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx, int my)
{
+ float rgb[3], hsv[3];
float x, y;
int changed= 1;
int color_profile = but->block->color_profile;
@@ -2702,6 +2700,9 @@ static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx,
if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA)
color_profile = BLI_PR_NONE;
}
+
+ ui_get_but_vectorf(but, rgb);
+ rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
/* relative position within box */
x= ((float)mx-but->x1)/(but->x2-but->x1);
@@ -2710,31 +2711,35 @@ static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx,
CLAMP(y, 0.0, 1.0);
if(but->a1==0) {
- but->hsv[0]= x;
- but->hsv[2]= y;
+ hsv[2]= x;
+ hsv[1]= y;
}
else if(but->a1==1) {
- but->hsv[0]= x;
- but->hsv[1]= y;
+ hsv[0]= x;
+ hsv[2]= y;
}
else if(but->a1==2) {
- but->hsv[2]= x;
- but->hsv[1]= y;
+ hsv[0]= x;
+ hsv[1]= y;
}
else if(but->a1==3) {
- but->hsv[0]= x;
+ hsv[0]= x;
}
- else {
+ else if(but->a1==4) {
+ hsv[1]= x;
+ }
+ else if(but->a1==5) {
+ hsv[2]= x;
+ }
+ else if (but->a1==9){
/* vertical 'value' strip */
- but->hsv[2]= y;
+ hsv[2]= y;
if (color_profile)
- but->hsv[2] = srgb_to_linearrgb(but->hsv[2]);
+ hsv[2] = srgb_to_linearrgb(hsv[2]);
}
- ui_set_but_hsv(but); // converts to rgb
-
- // update button values and strings
- ui_update_block_buts_hsv(but->block, but->hsv);
+ hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2);
+ ui_set_but_vectorf(but, rgb);
data->draglastx= mx;
data->draglasty= my;
@@ -2766,7 +2771,12 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
}
}
else if(data->state == BUTTON_STATE_NUM_EDITING) {
- if(event->type == MOUSEMOVE) {
+ if(event->type == ESCKEY) {
+ data->cancel= 1;
+ data->escapecancel= 1;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ else if(event->type == MOUSEMOVE) {
if(mx!=data->draglastx || my!=data->draglasty) {
if(ui_numedit_but_HSVCUBE(but, data, mx, my))
ui_numedit_apply(C, block, but, data);
@@ -2785,16 +2795,18 @@ static int ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, int mx
{
rcti rect;
int changed= 1;
-
+ float rgb[3], hsv[3];
+
rect.xmin= but->x1; rect.xmax= but->x2;
rect.ymin= but->y1; rect.ymax= but->y2;
- ui_hsvcircle_vals_from_pos(but->hsv, but->hsv+1, &rect, (float)mx, (float)my);
+ ui_get_but_vectorf(but, rgb);
+ rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
- ui_set_but_hsv(but); // converts to rgb
+ ui_hsvcircle_vals_from_pos(hsv, hsv+1, &rect, (float)mx, (float)my);
- // update button values and strings
- // XXX ui_update_block_buts_hsv(but->block, but->hsv);
+ hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2);
+ ui_set_but_vectorf(but, rgb);
data->draglastx= mx;
data->draglasty= my;
@@ -2827,8 +2839,13 @@ static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandle
}
}
else if(data->state == BUTTON_STATE_NUM_EDITING) {
+ if(event->type == ESCKEY) {
+ data->cancel= 1;
+ data->escapecancel= 1;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
/* XXX hardcoded keymap check.... */
- if(event->type == WHEELDOWNMOUSE) {
+ else if(event->type == WHEELDOWNMOUSE) {
but->hsv[2]= CLAMPIS(but->hsv[2]-0.05f, 0.0f, 1.0f);
ui_set_but_hsv(but); // converts to rgb
ui_numedit_apply(C, block, but, data);
@@ -2844,9 +2861,9 @@ static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandle
ui_numedit_apply(C, block, but, data);
}
}
- else if(event->type==LEFTMOUSE && event->val!=KM_PRESS)
+ else if(event->type==LEFTMOUSE && event->val!=KM_PRESS) {
button_activate_state(C, but, BUTTON_STATE_EXIT);
-
+ }
return WM_UI_HANDLER_BREAK;
}
@@ -3780,7 +3797,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
retval= ui_do_but_BUT(C, but, data, event);
break;
case COL:
- if(but->a1 == -1) // signal to prevent calling up color picker
+ if(but->a1 == 9) // signal to prevent calling up color picker
retval= ui_do_but_EXIT(C, but, data, event);
else
retval= ui_do_but_BLOCK(C, but, data, event);
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index e219198da0f..43c8b0b2c74 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -940,7 +940,7 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, float al
}
}
-void ui_id_icon_render(bContext *C, ID *id)
+void ui_id_icon_render(bContext *C, ID *id, int preview)
{
PreviewImage *pi = BKE_previewimg_get(id);
@@ -948,13 +948,17 @@ void ui_id_icon_render(bContext *C, ID *id)
if ((pi->changed[0] ||!pi->rect[0])) /* changed only ever set by dynamic icons */
{
/* create the preview rect if necessary */
- icon_set_image(C, id, pi, 0);
+
+ icon_set_image(C, id, pi, 0); /* icon size */
+ if (preview)
+ icon_set_image(C, id, pi, 1); /* preview size */
+
pi->changed[0] = 0;
}
}
}
-int ui_id_icon_get(bContext *C, ID *id)
+int ui_id_icon_get(bContext *C, ID *id, int preview)
{
int iconid= 0;
@@ -968,7 +972,7 @@ int ui_id_icon_get(bContext *C, ID *id)
case ID_LA: /* fall through */
iconid= BKE_icon_getid(id);
/* checks if not exists, or changed */
- ui_id_icon_render(C, id);
+ ui_id_icon_render(C, id, preview);
break;
default:
break;
@@ -1004,8 +1008,18 @@ void UI_icon_draw_size(float x, float y, int size, int icon_id, float alpha)
icon_draw_size(x, y, icon_id, 1.0f, alpha, NULL, 0, size, 1);
}
-void UI_icon_draw_preview(float x, float y, int icon_id, int nocreate)
+void UI_icon_draw_preview(float x, float y, int icon_id)
+{
+ icon_draw_mipmap(x, y, icon_id, 1.0f, 1.0f, PREVIEW_MIPMAP_LARGE, 0);
+}
+
+void UI_icon_draw_preview_aspect(float x, float y, int icon_id, float aspect)
+{
+ icon_draw_mipmap(x, y, icon_id, aspect, 1.0f, PREVIEW_MIPMAP_LARGE, 0);
+}
+
+void UI_icon_draw_preview_aspect_size(float x, float y, int icon_id, float aspect, int size)
{
- icon_draw_mipmap(x, y, icon_id, 1.0f, 1.0f, PREVIEW_MIPMAP_LARGE, nocreate);
+ icon_draw_size(x, y, icon_id, aspect, 1.0f, NULL, PREVIEW_MIPMAP_LARGE, size, 0);
}
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 02808f9c2e7..aec48b5c7c7 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -348,7 +348,6 @@ extern void ui_set_but_soft_range(uiBut *but, double value);
extern void ui_check_but(uiBut *but);
extern int ui_is_but_float(uiBut *but);
extern int ui_is_but_unit(uiBut *but);
-extern void ui_update_block_buts_hsv(uiBlock *block, float *hsv);
extern void ui_bounds_block(uiBlock *block);
extern void ui_block_translate(uiBlock *block, int x, int y);
@@ -378,7 +377,7 @@ struct uiPopupBlockHandle {
int butretval;
int menuretval;
float retvalue;
- float retvec[3];
+ float retvec[4];
};
uiBlock *ui_block_func_COL(struct bContext *C, uiPopupBlockHandle *handle, void *arg_but);
@@ -450,13 +449,14 @@ struct ThemeUI;
void ui_widget_color_init(struct ThemeUI *tui);
void ui_draw_menu_item(struct uiFontStyle *fstyle, rcti *rect, char *name, int iconid, int state);
+void ui_draw_preview_item(struct uiFontStyle *fstyle, rcti *rect, char *name, int iconid, int state);
/* interface_style.c */
void uiStyleInit(void);
/* interface_icons.c */
-void ui_id_icon_render(struct bContext *C, struct ID *id);
-int ui_id_icon_get(struct bContext *C, struct ID *id);
+void ui_id_icon_render(struct bContext *C, struct ID *id, int preview);
+int ui_id_icon_get(struct bContext *C, struct ID *id, int preview);
/* resources.c */
void init_userdef_do_versions(void);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index e512c1f6bf8..57102f4ad50 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -388,28 +388,28 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, char *name, int icon
}
}
else if(subtype == PROP_MATRIX) {
- /* matrix layout */
+ int totdim, dim_size[3]; /* 3 == RNA_MAX_ARRAY_DIMENSION */
int row, col;
uiBlockSetCurLayout(block, uiLayoutAbsolute(layout, 1));
- len= ceil(sqrt(len));
-
- h /= len;
- w /= len;
+ totdim= RNA_property_array_dimension(ptr, prop, dim_size);
+ if (totdim != 2) return; /* only 2D matrices supported in UI so far */
+
+ w /= dim_size[0];
+ h /= dim_size[1];
- // XXX test
for(a=0; a<len; a++) {
- col= a%len;
- row= a/len;
-
- but= uiDefAutoButR(block, ptr, prop, a, "", 0, x + w*col, y+(row-a-1)*UI_UNIT_Y, w, UI_UNIT_Y);
+ col= a % dim_size[0];
+ row= a / dim_size[0];
+
+ but= uiDefAutoButR(block, ptr, prop, a, "", 0, x + w*col, y+(dim_size[1]*UI_UNIT_Y)-(row*UI_UNIT_Y), w, UI_UNIT_Y);
if(slider && but->type==NUM)
but->type= NUMSLI;
}
}
else {
- if(ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA))
+ if(ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA) && !expand)
uiDefAutoButR(block, ptr, prop, -1, "", 0, 0, 0, w, UI_UNIT_Y);
if(!ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA) || expand) {
@@ -911,7 +911,7 @@ void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, Proper
name= (char*)RNA_property_ui_name(prop);
if(!icon)
icon= RNA_property_ui_icon(prop);
-
+
if(ELEM4(type, PROP_INT, PROP_FLOAT, PROP_STRING, PROP_POINTER))
name= ui_item_name_add_colon(name, namestr);
else if(type == PROP_BOOLEAN && len && index == RNA_NO_INDEX)
@@ -1115,7 +1115,7 @@ static void rna_search_cb(const struct bContext *C, void *arg_but, char *str, ui
continue;
if(RNA_struct_is_ID(itemptr.type))
- iconid= ui_id_icon_get((bContext*)C, itemptr.data);
+ iconid= ui_id_icon_get((bContext*)C, itemptr.data, 0);
name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 25bfaf3d682..268f6d6e648 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -40,6 +40,7 @@
#include "DNA_view2d_types.h"
#include "BLI_blenlib.h"
+#include "BLI_math_color.h"
#include "BKE_context.h"
#include "BKE_utildefines.h"
@@ -59,6 +60,142 @@
/* ********************************************************** */
+typedef struct Eyedropper {
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ int index;
+} Eyedropper;
+
+static int eyedropper_init(bContext *C, wmOperator *op)
+{
+ Eyedropper *eye;
+
+ op->customdata= eye= MEM_callocN(sizeof(Eyedropper), "Eyedropper");
+
+ uiAnimContextProperty(C, &eye->ptr, &eye->prop, &eye->index);
+
+ return (eye->ptr.data && eye->prop && RNA_property_editable(&eye->ptr, eye->prop));
+}
+
+static void eyedropper_exit(bContext *C, wmOperator *op)
+{
+ WM_cursor_restore(CTX_wm_window(C));
+
+ if(op->customdata)
+ MEM_freeN(op->customdata);
+ op->customdata= NULL;
+}
+
+static int eyedropper_cancel(bContext *C, wmOperator *op)
+{
+ eyedropper_exit(C, op);
+ return OPERATOR_CANCELLED;
+}
+
+static void eyedropper_sample(bContext *C, Eyedropper *eye, short mx, short my)
+{
+ float col[3];
+
+ glReadBuffer(GL_FRONT);
+ glReadPixels(mx, my, 1, 1, GL_RGB, GL_FLOAT, col);
+ glReadBuffer(GL_BACK);
+
+ if(RNA_property_type(eye->prop) == PROP_FLOAT) {
+
+ if (RNA_property_array_length(&eye->ptr, eye->prop) < 3) return;
+
+ /* convert from screen (srgb) space to linear rgb space */
+ if (RNA_property_subtype(eye->prop) == PROP_COLOR)
+ srgb_to_linearrgb_v3_v3(col, col);
+
+ RNA_property_float_set_array(&eye->ptr, eye->prop, col);
+
+ RNA_property_update(C, &eye->ptr, eye->prop);
+ }
+}
+
+/* main modal status check */
+static int eyedropper_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ Eyedropper *eye = (Eyedropper *)op->customdata;
+
+ switch(event->type) {
+ case ESCKEY:
+ case RIGHTMOUSE:
+ return eyedropper_cancel(C, op);
+ case LEFTMOUSE:
+ if(event->val==KM_RELEASE) {
+ eyedropper_sample(C, eye, event->x, event->y);
+ eyedropper_exit(C, op);
+ return OPERATOR_FINISHED;
+ }
+ break;
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+/* Modal Operator init */
+static int eyedropper_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ /* init */
+ if (eyedropper_init(C, op)) {
+ WM_cursor_modal(CTX_wm_window(C), BC_EYEDROPPER_CURSOR);
+
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+ } else {
+ eyedropper_exit(C, op);
+ return OPERATOR_CANCELLED;
+ }
+}
+
+/* Repeat operator */
+static int eyedropper_exec (bContext *C, wmOperator *op)
+{
+ /* init */
+ if (eyedropper_init(C, op)) {
+
+ /* do something */
+
+ /* cleanup */
+ eyedropper_exit(C, op);
+
+ return OPERATOR_FINISHED;
+ } else {
+ return OPERATOR_CANCELLED;
+ }
+}
+
+static int eyedropper_poll(bContext *C)
+{
+ if (!CTX_wm_window(C)) return 0;
+ else return 1;
+}
+
+void UI_OT_eyedropper(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Eyedropper";
+ ot->idname= "UI_OT_eyedropper";
+ ot->description= "Sample a color from the Blender Window to store in a property";
+
+ /* api callbacks */
+ ot->invoke= eyedropper_invoke;
+ ot->modal= eyedropper_modal;
+ ot->cancel= eyedropper_cancel;
+ ot->exec= eyedropper_exec;
+ ot->poll= eyedropper_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_BLOCKING;
+
+ /* properties */
+}
+
+
/* Copy Data Path Operator ------------------------ */
static int copy_data_path_button_exec(bContext *C, wmOperator *op)
@@ -140,7 +277,7 @@ void UI_OT_reset_default_button(wmOperatorType *ot)
/* identifiers */
ot->name= "Reset to Default Value";
ot->idname= "UI_OT_reset_default_button";
- ot->description= "Copy the RNA data path for this property to the clipboard.";
+ ot->description= "Reset this property's value to its default value";
/* callbacks */
ot->poll= reset_default_button_poll;
@@ -248,6 +385,7 @@ void UI_OT_copy_to_selected_button(wmOperatorType *ot)
void UI_buttons_operatortypes(void)
{
+ WM_operatortype_append(UI_OT_eyedropper);
WM_operatortype_append(UI_OT_copy_data_path_button);
WM_operatortype_append(UI_OT_reset_default_button);
WM_operatortype_append(UI_OT_copy_to_selected_button);
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 8ebfed21dcc..6bc4e7b0b65 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -547,6 +547,8 @@ typedef struct uiSearchboxData {
uiSearchItems items;
int active; /* index in items array */
int noback; /* when menu opened with enough space for this */
+ int preview; /* draw thumbnail previews, rather than list */
+ int prv_rows, prv_cols;
} uiSearchboxData;
#define SEARCH_ITEMS 10
@@ -628,14 +630,34 @@ static void ui_searchbox_select(bContext *C, ARegion *ar, uiBut *but, int step)
static void ui_searchbox_butrect(rcti *rect, uiSearchboxData *data, int itemnr)
{
- int buth= (data->bbox.ymax-data->bbox.ymin - 2*MENU_TOP)/SEARCH_ITEMS;
-
- *rect= data->bbox;
- rect->xmin= data->bbox.xmin + 3.0f;
- rect->xmax= data->bbox.xmax - 3.0f;
-
- rect->ymax= data->bbox.ymax - MENU_TOP - itemnr*buth;
- rect->ymin= rect->ymax - buth;
+ /* thumbnail preview */
+ if (data->preview) {
+ int buth = (data->bbox.ymax - data->bbox.ymin - 2*MENU_TOP) / data->prv_rows;
+ int butw = (data->bbox.xmax - data->bbox.xmin) / data->prv_cols;
+ int row, col;
+
+ *rect= data->bbox;
+
+ col = itemnr % data->prv_cols;
+ row = itemnr / data->prv_cols;
+
+ rect->xmin += col * butw;
+ rect->xmax = rect->xmin + butw;
+
+ rect->ymax = data->bbox.ymax - (row * buth);
+ rect->ymin = rect->ymax - buth;
+ }
+ /* list view */
+ else {
+ int buth= (data->bbox.ymax-data->bbox.ymin - 2*MENU_TOP)/SEARCH_ITEMS;
+
+ *rect= data->bbox;
+ rect->xmin= data->bbox.xmin + 3.0f;
+ rect->xmax= data->bbox.xmax - 3.0f;
+
+ rect->ymax= data->bbox.ymax - MENU_TOP - itemnr*buth;
+ rect->ymin= rect->ymax - buth;
+ }
}
@@ -799,27 +821,55 @@ static void ui_searchbox_region_draw(const bContext *C, ARegion *ar)
if(data->items.totitem) {
rcti rect;
int a;
+
+ if (data->preview) {
+ /* draw items */
+ for(a=0; a<data->items.totitem; a++) {
+ ui_searchbox_butrect(&rect, data, a);
- /* draw items */
- for(a=0; a<data->items.totitem; a++) {
- ui_searchbox_butrect(&rect, data, a);
+ /* widget itself */
+ if (data->preview)
+ ui_draw_preview_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a+1)==data->active?UI_ACTIVE:0);
+ else
+ ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a+1)==data->active?UI_ACTIVE:0);
+ }
- /* widget itself */
- ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a+1)==data->active?UI_ACTIVE:0);
+ /* indicate more */
+ if(data->items.more) {
+ ui_searchbox_butrect(&rect, data, data->items.maxitem-1);
+ glEnable(GL_BLEND);
+ UI_icon_draw(rect.xmax-18, rect.ymin-7, ICON_TRIA_DOWN);
+ glDisable(GL_BLEND);
+ }
+ if(data->items.offset) {
+ ui_searchbox_butrect(&rect, data, 0);
+ glEnable(GL_BLEND);
+ UI_icon_draw(rect.xmin, rect.ymax-9, ICON_TRIA_UP);
+ glDisable(GL_BLEND);
+ }
- }
- /* indicate more */
- if(data->items.more) {
- ui_searchbox_butrect(&rect, data, data->items.maxitem-1);
- glEnable(GL_BLEND);
- UI_icon_draw((rect.xmax-rect.xmin)/2, rect.ymin-9, ICON_TRIA_DOWN);
- glDisable(GL_BLEND);
- }
- if(data->items.offset) {
- ui_searchbox_butrect(&rect, data, 0);
- glEnable(GL_BLEND);
- UI_icon_draw((rect.xmax-rect.xmin)/2, rect.ymax-7, ICON_TRIA_UP);
- glDisable(GL_BLEND);
+ } else {
+ /* draw items */
+ for(a=0; a<data->items.totitem; a++) {
+ ui_searchbox_butrect(&rect, data, a);
+
+ /* widget itself */
+ ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a+1)==data->active?UI_ACTIVE:0);
+
+ }
+ /* indicate more */
+ if(data->items.more) {
+ ui_searchbox_butrect(&rect, data, data->items.maxitem-1);
+ glEnable(GL_BLEND);
+ UI_icon_draw((rect.xmax-rect.xmin)/2, rect.ymin-9, ICON_TRIA_DOWN);
+ glDisable(GL_BLEND);
+ }
+ if(data->items.offset) {
+ ui_searchbox_butrect(&rect, data, 0);
+ glEnable(GL_BLEND);
+ UI_icon_draw((rect.xmax-rect.xmin)/2, rect.ymax-7, ICON_TRIA_UP);
+ glDisable(GL_BLEND);
+ }
}
}
}
@@ -830,7 +880,7 @@ static void ui_searchbox_region_free(ARegion *ar)
int a;
/* free search data */
- for(a=0; a<SEARCH_ITEMS; a++)
+ for(a=0; a<data->items.maxitem; a++)
MEM_freeN(data->items.names[a]);
MEM_freeN(data->items.names);
MEM_freeN(data->items.pointers);
@@ -876,8 +926,13 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
if(but->block->flag & UI_BLOCK_LOOP)
data->noback= 1;
- /* compute position */
+ if (but->a1 > 0 && but->a2 > 0) {
+ data->preview = 1;
+ data->prv_rows = but->a1;
+ data->prv_cols = but->a2;
+ }
+ /* compute position */
if(but->block->flag & UI_BLOCK_LOOP) {
/* this case is search menu inside other menu */
/* we copy region size */
@@ -972,13 +1027,17 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
ED_region_tag_redraw(ar);
/* prepare search data */
- data->items.maxitem= SEARCH_ITEMS;
+ if (data->preview) {
+ data->items.maxitem= data->prv_rows * data->prv_cols;
+ } else {
+ data->items.maxitem= SEARCH_ITEMS;
+ }
data->items.maxstrlen= but->hardmax;
data->items.totitem= 0;
- data->items.names= MEM_callocN(SEARCH_ITEMS*sizeof(void *), "search names");
- data->items.pointers= MEM_callocN(SEARCH_ITEMS*sizeof(void *), "search pointers");
- data->items.icons= MEM_callocN(SEARCH_ITEMS*sizeof(int), "search icons");
- for(x1=0; x1<SEARCH_ITEMS; x1++)
+ data->items.names= MEM_callocN(data->items.maxitem*sizeof(void *), "search names");
+ data->items.pointers= MEM_callocN(data->items.maxitem*sizeof(void *), "search pointers");
+ data->items.icons= MEM_callocN(data->items.maxitem*sizeof(int), "search icons");
+ for(x1=0; x1<data->items.maxitem; x1++)
data->items.names[x1]= MEM_callocN(but->hardmax+1, "search pointers");
return ar;
@@ -1476,15 +1535,6 @@ static void ui_warp_pointer(short x, short y)
#define DPICK 6.0
#define BPICK 24.0
-#define UI_PALETTE_TOT 16
-/* note; in tot+1 the old color is stored */
-static float palette[UI_PALETTE_TOT+1][3]= {
-{0.93, 0.83, 0.81}, {0.88, 0.89, 0.73}, {0.69, 0.81, 0.57}, {0.51, 0.76, 0.64},
-{0.37, 0.56, 0.61}, {0.33, 0.29, 0.55}, {0.46, 0.21, 0.51}, {0.40, 0.12, 0.18},
-{1.0, 1.0, 1.0}, {0.85, 0.85, 0.85}, {0.7, 0.7, 0.7}, {0.56, 0.56, 0.56},
-{0.42, 0.42, 0.42}, {0.28, 0.28, 0.28}, {0.14, 0.14, 0.14}, {0.0, 0.0, 0.0}
-};
-
/* for picker, while editing hsv */
void ui_set_but_hsv(uiBut *but)
{
@@ -1494,50 +1544,37 @@ void ui_set_but_hsv(uiBut *but)
ui_set_but_vectorf(but, col);
}
-static void update_picker_hex(uiBlock *block, float *rgb)
+/* also used by small picker, be careful with name checks below... */
+void ui_update_block_buts_rgb(uiBlock *block, float *rgb)
{
uiBut *bt;
- char col[16];
+ float hsv[3];
- sprintf(col, "%02X%02X%02X", (unsigned int)(rgb[0]*255.0), (unsigned int)(rgb[1]*255.0), (unsigned int)(rgb[2]*255.0));
+ rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
// this updates button strings, is hackish... but button pointers are on stack of caller function
-
for(bt= block->buttons.first; bt; bt= bt->next) {
- if(strcmp(bt->str, "Hex: ")==0)
+ if (bt->rnaprop) {
+
+ ui_set_but_vectorf(bt, rgb);
+
+ }
+ else if(strcmp(bt->str, "Hex: ")==0) {
+ char col[16];
+
+ sprintf(col, "%02X%02X%02X", (unsigned int)(rgb[0]*255.0), (unsigned int)(rgb[1]*255.0), (unsigned int)(rgb[2]*255.0));
+
strcpy(bt->poin, col);
-
- ui_check_but(bt);
- }
-}
-
-/* also used by small picker, be careful with name checks below... */
-void ui_update_block_buts_hsv(uiBlock *block, float *hsv)
-{
- uiBut *bt;
- float r, g, b;
- float rgb[3];
-
- // this updates button strings, is hackish... but button pointers are on stack of caller function
- hsv_to_rgb(hsv[0], hsv[1], hsv[2], &r, &g, &b);
-
- rgb[0] = r; rgb[1] = g; rgb[2] = b;
- update_picker_hex(block, rgb);
-
- for(bt= block->buttons.first; bt; bt= bt->next) {
- if(ELEM(bt->type, HSVCUBE, HSVCIRCLE)) {
- VECCOPY(bt->hsv, hsv);
- ui_set_but_hsv(bt);
}
else if(bt->str[1]==' ') {
if(bt->str[0]=='R') {
- ui_set_but_val(bt, r);
+ ui_set_but_val(bt, rgb[0]);
}
else if(bt->str[0]=='G') {
- ui_set_but_val(bt, g);
+ ui_set_but_val(bt, rgb[1]);
}
else if(bt->str[0]=='B') {
- ui_set_but_val(bt, b);
+ ui_set_but_val(bt, rgb[2]);
}
else if(bt->str[0]=='H') {
ui_set_but_val(bt, hsv[0]);
@@ -1554,315 +1591,62 @@ void ui_update_block_buts_hsv(uiBlock *block, float *hsv)
}
}
-static void ui_update_block_buts_hex(uiBlock *block, char *hexcol)
-{
- uiBut *bt;
- float r=0, g=0, b=0;
- float h, s, v;
-
-
- // this updates button strings, is hackish... but button pointers are on stack of caller function
- hex_to_rgb(hexcol, &r, &g, &b);
- rgb_to_hsv(r, g, b, &h, &s, &v);
-
- for(bt= block->buttons.first; bt; bt= bt->next) {
- if(bt->type==HSVCUBE) {
- bt->hsv[0] = h;
- bt->hsv[1] = s;
- bt->hsv[2] = v;
- ui_set_but_hsv(bt);
- }
- else if(bt->str[1]==' ') {
- if(bt->str[0]=='R') {
- ui_set_but_val(bt, r);
- }
- else if(bt->str[0]=='G') {
- ui_set_but_val(bt, g);
- }
- else if(bt->str[0]=='B') {
- ui_set_but_val(bt, b);
- }
- else if(bt->str[0]=='H') {
- ui_set_but_val(bt, h);
- }
- else if(bt->str[0]=='S') {
- ui_set_but_val(bt, s);
- }
- else if(bt->str[0]=='V') {
- ui_set_but_val(bt, v);
- }
- }
-
- ui_check_but(bt);
- }
-}
-
-/* bt1 is palette but, col1 is original color */
-/* callback to copy from/to palette */
-static void do_palette_cb(bContext *C, void *bt1, void *col1)
+static void do_picker_rna_cb(bContext *C, void *bt1, void *unused)
{
- wmWindow *win= CTX_wm_window(C);
- uiBut *but1= (uiBut *)bt1;
- uiPopupBlockHandle *popup= but1->block->handle;
- float *col= (float *)col1;
- float *fp, hsv[3];
+ uiBut *but= (uiBut *)bt1;
+ uiPopupBlockHandle *popup= but->block->handle;
+ PropertyRNA *prop = but->rnaprop;
+ PointerRNA ptr = but->rnapoin;
+ float rgb[4];
- fp= (float *)but1->poin;
-
- if(win->eventstate->ctrl) {
- VECCOPY(fp, col);
- }
- else {
- VECCOPY(col, fp);
+ if (prop) {
+ RNA_property_float_get_array(&ptr, prop, rgb);
+ ui_update_block_buts_rgb(but->block, rgb);
}
- rgb_to_hsv(col[0], col[1], col[2], hsv, hsv+1, hsv+2);
- ui_update_block_buts_hsv(but1->block, hsv);
- update_picker_hex(but1->block, col);
-
- if(popup)
- popup->menuretval= UI_RETURN_UPDATE;
-}
-
-static void do_hsv_cb(bContext *C, void *bt1, void *unused)
-{
- uiBut *but1= (uiBut *)bt1;
- uiPopupBlockHandle *popup= but1->block->handle;
-
if(popup)
popup->menuretval= UI_RETURN_UPDATE;
}
-/* bt1 is num but, hsv1 is pointer to original color in hsv space*/
-/* callback to handle changes in num-buts in picker */
-static void do_palette1_cb(bContext *C, void *bt1, void *hsv1)
+static void do_hsv_rna_cb(bContext *C, void *bt1, void *hsv_arg)
{
- uiBut *but1= (uiBut *)bt1;
- uiPopupBlockHandle *popup= but1->block->handle;
- float *hsv= (float *)hsv1;
- float *fp= NULL;
+ uiBut *but= (uiBut *)bt1;
+ uiPopupBlockHandle *popup= but->block->handle;
+ float *hsv = (float *)hsv_arg;
+ float rgb[3];
- if(but1->str[1]==' ') {
- if(but1->str[0]=='R') fp= (float *)but1->poin;
- else if(but1->str[0]=='G') fp= ((float *)but1->poin)-1;
- else if(but1->str[0]=='B') fp= ((float *)but1->poin)-2;
- }
- if(fp) {
- rgb_to_hsv(fp[0], fp[1], fp[2], hsv, hsv+1, hsv+2);
- }
- ui_update_block_buts_hsv(but1->block, hsv);
-
- if(popup)
- popup->menuretval= UI_RETURN_UPDATE;
-}
-
-/* bt1 is num but, col1 is pointer to original color */
-/* callback to handle changes in num-buts in picker */
-static void do_palette2_cb(bContext *C, void *bt1, void *col1)
-{
- uiBut *but1= (uiBut *)bt1;
- uiPopupBlockHandle *popup= but1->block->handle;
- float *rgb= (float *)col1;
- float *fp= NULL;
+ hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2);
- if(but1->str[1]==' ') {
- if(but1->str[0]=='H') fp= (float *)but1->poin;
- else if(but1->str[0]=='S') fp= ((float *)but1->poin)-1;
- else if(but1->str[0]=='V') fp= ((float *)but1->poin)-2;
- }
- if(fp) {
- hsv_to_rgb(fp[0], fp[1], fp[2], rgb, rgb+1, rgb+2);
- }
- ui_update_block_buts_hsv(but1->block, fp);
-
- if(popup)
- popup->menuretval= UI_RETURN_UPDATE;
-}
-
-static void do_palette_hex_cb(bContext *C, void *bt1, void *hexcl)
-{
- uiBut *but1= (uiBut *)bt1;
- uiPopupBlockHandle *popup= but1->block->handle;
- char *hexcol= (char *)hexcl;
+ ui_update_block_buts_rgb(but->block, rgb);
- ui_update_block_buts_hex(but1->block, hexcol);
-
if(popup)
popup->menuretval= UI_RETURN_UPDATE;
}
-/* used for both 3d view and image window */
-static void do_palette_sample_cb(bContext *C, void *bt1, void *col1) /* frontbuf */
-{
- /* XXX 2.50 this should become an operator? */
-#if 0
- uiBut *but1= (uiBut *)bt1;
- uiBut *but;
- float tempcol[4];
- int x=0, y=0;
- short mval[2];
- float hsv[3];
- short capturing;
- int oldcursor;
- Window *win;
- unsigned short dev;
-
- oldcursor=get_cursor();
- win=winlay_get_active_window();
-
- while (get_mbut() & L_MOUSE) UI_wait_for_statechange();
-
- SetBlenderCursor(BC_EYEDROPPER_CURSOR);
-
- /* loop and wait for a mouse click */
- capturing = TRUE;
- while(capturing) {
- char ascii;
- short val;
-
- dev = extern_qread_ext(&val, &ascii);
-
- if(dev==INPUTCHANGE) break;
- if(get_mbut() & R_MOUSE) break;
- else if(get_mbut() & L_MOUSE) {
- uiGetMouse(mywinget(), mval);
- x= mval[0]; y= mval[1];
-
- capturing = FALSE;
- break;
- }
- else if(dev==ESCKEY) break;
- }
- window_set_cursor(win, oldcursor);
-
- if(capturing) return;
-
- if(x<0 || y<0) return;
-
- /* if we've got a glick, use OpenGL to sample the color under the mouse pointer */
- glReadBuffer(GL_FRONT);
- glReadPixels(x, y, 1, 1, GL_RGBA, GL_FLOAT, tempcol);
- glReadBuffer(GL_BACK);
-
- /* and send that color back to the picker */
- rgb_to_hsv(tempcol[0], tempcol[1], tempcol[2], hsv, hsv+1, hsv+2);
- ui_update_block_buts_hsv(but1->block, hsv);
- update_picker_hex(but1->block, tempcol);
-
- for (but= but1->block->buttons.first; but; but= but->next) {
- ui_check_but(but);
- ui_draw_but(but);
- }
-
- but= but1->block->buttons.first;
- ui_block_flush_back(but->block);
-#endif
-}
-
-/* color picker, Gimp version. mode: 'f' = floating panel, 'p' = popup */
-/* col = read/write to, hsv/old/hexcol = memory for temporal use */
-void uiBlockPickerButtons(uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval)
+static void do_hex_rna_cb(bContext *C, void *bt1, void *hexcl)
{
- uiBut *bt;
- float h, offs;
- int a;
-
- VECCOPY(old, col); // old color stored there, for palette_cb to work
-
- // the cube intersection
- bt= uiDefButF(block, HSVCUBE, retval, "", 0,DPICK+BPICK,FPICK,FPICK, col, 0.0, 0.0, 2, 0, "");
- uiButSetFunc(bt, do_hsv_cb, bt, NULL);
-
- bt= uiDefButF(block, HSVCUBE, retval, "", 0,0,FPICK,BPICK, col, 0.0, 0.0, 3, 0, "");
- uiButSetFunc(bt, do_hsv_cb, bt, NULL);
-
- // palette
-
- bt=uiDefButF(block, COL, retval, "", FPICK+DPICK, 0, BPICK,BPICK, old, 0.0, 0.0, -1, 0, "Old color, click to restore");
- uiButSetFunc(bt, do_palette_cb, bt, col);
- uiDefButF(block, COL, retval, "", FPICK+DPICK, BPICK+DPICK, BPICK,60-BPICK-DPICK, col, 0.0, 0.0, -1, 0, "Active color");
-
- h= (DPICK+BPICK+FPICK-64)/(UI_PALETTE_TOT/2.0);
- uiBlockBeginAlign(block);
- for(a= -1+UI_PALETTE_TOT/2; a>=0; a--) {
- bt= uiDefButF(block, COL, retval, "", FPICK+DPICK, 65.0+(float)a*h, BPICK/2, h, palette[a+UI_PALETTE_TOT/2], 0.0, 0.0, -1, 0, "Click to choose, hold CTRL to store in palette");
- uiButSetFunc(bt, do_palette_cb, bt, col);
- bt= uiDefButF(block, COL, retval, "", FPICK+DPICK+BPICK/2, 65.0+(float)a*h, BPICK/2, h, palette[a], 0.0, 0.0, -1, 0, "Click to choose, hold CTRL to store in palette");
- uiButSetFunc(bt, do_palette_cb, bt, col);
- }
- uiBlockEndAlign(block);
-
- // buttons
- rgb_to_hsv(col[0], col[1], col[2], hsv, hsv+1, hsv+2);
- sprintf(hexcol, "%02X%02X%02X", (unsigned int)(col[0]*255.0), (unsigned int)(col[1]*255.0), (unsigned int)(col[2]*255.0));
-
- offs= FPICK+2*DPICK+BPICK;
-
- /* note; made this a TOG now, with NULL pointer. Is because BUT now gets handled with a afterfunc */
- bt= uiDefIconTextBut(block, TOG, UI_RETURN_OK, ICON_EYEDROPPER, "Sample", offs+55, 170, 85, 20, NULL, 0, 0, 0, 0, "Sample the color underneath the following mouse click (ESC or RMB to cancel)");
- uiButSetFunc(bt, do_palette_sample_cb, bt, col);
- uiButSetFlag(bt, UI_TEXT_LEFT);
-
- bt= uiDefBut(block, TEX, retval, "Hex: ", offs, 140, 140, 20, hexcol, 0, 8, 0, 0, "Hex triplet for color (#RRGGBB)");
- uiButSetFunc(bt, do_palette_hex_cb, bt, hexcol);
-
- uiBlockBeginAlign(block);
- bt= uiDefButF(block, NUMSLI, retval, "R ", offs, 110, 140,20, col, 0.0, 1.0, 10, 3, "");
- uiButSetFunc(bt, do_palette1_cb, bt, hsv);
- bt= uiDefButF(block, NUMSLI, retval, "G ", offs, 90, 140,20, col+1, 0.0, 1.0, 10, 3, "");
- uiButSetFunc(bt, do_palette1_cb, bt, hsv);
- bt= uiDefButF(block, NUMSLI, retval, "B ", offs, 70, 140,20, col+2, 0.0, 1.0, 10, 3, "");
- uiButSetFunc(bt, do_palette1_cb, bt, hsv);
+ uiBut *but= (uiBut *)bt1;
+ uiPopupBlockHandle *popup= but->block->handle;
+ char *hexcol= (char *)hexcl;
+ float rgb[3];
- uiBlockBeginAlign(block);
- bt= uiDefButF(block, NUMSLI, retval, "H ", offs, 40, 140,20, hsv, 0.0, 1.0, 10, 3, "");
- uiButSetFunc(bt, do_palette2_cb, bt, col);
- bt= uiDefButF(block, NUMSLI, retval, "S ", offs, 20, 140,20, hsv+1, 0.0, 1.0, 10, 3, "");
- uiButSetFunc(bt, do_palette2_cb, bt, col);
- bt= uiDefButF(block, NUMSLI, retval, "V ", offs, 0, 140,20, hsv+2, 0.0, 1.0, 10, 3, "");
- uiButSetFunc(bt, do_palette2_cb, bt, col);
- uiBlockEndAlign(block);
-}
-
-/* bt1 is num but, hsv1 is pointer to original color in hsv space*/
-/* callback to handle changes */
-static void do_picker_small_cb(bContext *C, void *bt1, void *hsv1)
-{
- uiBut *but1= (uiBut *)bt1;
- uiPopupBlockHandle *popup= but1->block->handle;
- float *hsv= (float *)hsv1;
- float *fp= NULL;
+ hex_to_rgb(hexcol, rgb, rgb+1, rgb+2);
- fp= (float *)but1->poin;
- rgb_to_hsv(fp[0], fp[1], fp[2], hsv, hsv+1, hsv+2);
-
- ui_update_block_buts_hsv(but1->block, hsv);
+ ui_update_block_buts_rgb(but->block, rgb);
if(popup)
popup->menuretval= UI_RETURN_UPDATE;
}
-/* picker sizes S hsize, F full size, D spacer, B button/pallette height */
-#define SPICK1 150.0
-#define DPICK1 6.0
-
-/* only the color, a HS circle and V slider */
-static void uiBlockPickerSmall(uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval)
+static void close_popup_cb(bContext *C, void *bt1, void *arg)
{
- uiBut *bt;
+ uiBut *but= (uiBut *)bt1;
+ uiPopupBlockHandle *popup= but->block->handle;
- VECCOPY(old, col); // old color stored there, for palette_cb to work
-
- /* HS circle */
- bt= uiDefButF(block, HSVCIRCLE, retval, "", 0, 0,SPICK1,SPICK1, col, 0.0, 0.0, 0, 0, "");
- uiButSetFunc(bt, do_picker_small_cb, bt, hsv);
-
- /* value */
- bt= uiDefButF(block, HSVCUBE, retval, "", SPICK1+DPICK1,0,14,SPICK1, col, 0.0, 0.0, 4, 0, "");
- uiButSetFunc(bt, do_picker_small_cb, bt, hsv);
+ if(popup)
+ popup->menuretval= UI_RETURN_OK;
}
-
static void picker_new_hide_reveal(uiBlock *block, short colormode)
{
uiBut *bt;
@@ -1891,20 +1675,62 @@ static void do_picker_new_mode_cb(bContext *C, void *bt1, void *colv)
{
uiBut *bt= bt1;
short colormode= ui_get_but_val(bt);
-
picker_new_hide_reveal(bt->block, colormode);
}
+/* picker sizes S hsize, F full size, D spacer, B button/pallette height */
+#define SPICK1 150.0
+#define DPICK1 6.0
+
+#define PICKER_H 150
+#define PICKER_W 150
+#define PICKER_SPACE 6
+#define PICKER_BAR 14
+
+#define PICKER_TOTAL_W (PICKER_W+PICKER_SPACE+PICKER_BAR)
+
+static void circle_picker(uiBlock *block, PointerRNA *ptr, const char *propname)
+{
+ uiBut *bt;
+
+ /* HS circle */
+ bt= uiDefButR(block, HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W, ptr, propname, -1, 0.0, 0.0, 0, 0, "");
+ uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
+
+ /* value */
+ uiDefButR(block, HSVCUBE, 0, "", PICKER_W+PICKER_SPACE,0,PICKER_BAR,PICKER_H, ptr, propname, -1, 0.0, 0.0, 9, 0, "");
+ uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
+}
+
+
+static void square_picker(uiBlock *block, PointerRNA *ptr, const char *propname, int type)
+{
+ uiBut *bt;
+ int bartype = type + 3;
+
+ /* HS square */
+ bt= uiDefButR(block, HSVCUBE, 0, "", 0, PICKER_BAR+PICKER_SPACE, PICKER_TOTAL_W, PICKER_H, ptr, propname, -1, 0.0, 0.0, type, 0, "");
+ uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
+
+ /* value */
+ uiDefButR(block, HSVCUBE, 0, "", 0, 0, PICKER_TOTAL_W, PICKER_BAR, ptr, propname, -1, 0.0, 0.0, bartype, 0, "");
+ uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
+}
+
/* a HS circle, V slider, rgb/hsv/hex sliders */
-static void uiBlockPickerNew(uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval)
+static void uiBlockPicker(uiBlock *block, float *rgb, PointerRNA *ptr, PropertyRNA *prop)
{
static short colormode= 0; /* temp? 0=rgb, 1=hsv, 2=hex */
uiBut *bt;
- int width;
+ int width, butwidth;
static char tip[50];
+ static float hsv[3];
+ static char hexcol[128];
+ const char *propname = RNA_property_identifier(prop);
- VECCOPY(old, col); // old color stored there, for palette_cb to work
+ width= PICKER_TOTAL_W;
+ butwidth = width - UI_UNIT_X - 10;
/* existence of profile means storage is in linear colour space, with display correction */
if (block->color_profile == BLI_PR_NONE)
@@ -1912,50 +1738,63 @@ static void uiBlockPickerNew(uiBlock *block, float *col, float *hsv, float *old,
else
sprintf(tip, "Value in Linear RGB Color Space");
- /* HS circle */
- bt= uiDefButF(block, HSVCIRCLE, retval, "", 0, 0,SPICK1,SPICK1, col, 0.0, 0.0, 0, 0, "");
- uiButSetFunc(bt, do_picker_small_cb, bt, hsv);
-
- /* value */
- bt= uiDefButF(block, HSVCUBE, retval, "", SPICK1+DPICK1,0,14,SPICK1, col, 0.0, 0.0, 4, 0, "");
- uiButSetFunc(bt, do_picker_small_cb, bt, hsv);
+ RNA_property_float_get_array(ptr, prop, rgb);
+ rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
+
+ switch (U.color_picker_type) {
+ case USER_CP_CIRCLE:
+ circle_picker(block, ptr, propname);
+ break;
+ case USER_CP_SQUARE_SV:
+ square_picker(block, ptr, propname, 0);
+ break;
+ case USER_CP_SQUARE_HS:
+ square_picker(block, ptr, propname, 1);
+ break;
+ case USER_CP_SQUARE_HV:
+ square_picker(block, ptr, propname, 2);
+ break;
+ }
/* mode */
- width= (SPICK1+DPICK1+14)/3;
uiBlockBeginAlign(block);
- bt= uiDefButS(block, ROW, retval, "RGB", 0, -30, width, 19, &colormode, 0.0, 0.0, 0, 0, "");
- uiButSetFunc(bt, do_picker_new_mode_cb, bt, col);
- bt= uiDefButS(block, ROW, retval, "HSV", width, -30, width, 19, &colormode, 0.0, 1.0, 0, 0, "");
+ bt= uiDefButS(block, ROW, 0, "RGB", 0, -30, width/3, UI_UNIT_Y, &colormode, 0.0, 0.0, 0, 0, "");
+ uiButSetFunc(bt, do_picker_new_mode_cb, bt, rgb);
+ bt= uiDefButS(block, ROW, 0, "HSV", width/3, -30, width/3, UI_UNIT_Y, &colormode, 0.0, 1.0, 0, 0, "");
uiButSetFunc(bt, do_picker_new_mode_cb, bt, hsv);
- bt= uiDefButS(block, ROW, retval, "Hex", 2*width, -30, width, 19, &colormode, 0.0, 2.0, 0, 0, "");
+ bt= uiDefButS(block, ROW, 0, "Hex", 2*width/3, -30, width/3, UI_UNIT_Y, &colormode, 0.0, 2.0, 0, 0, "");
uiButSetFunc(bt, do_picker_new_mode_cb, bt, hexcol);
uiBlockEndAlign(block);
-
- /* sliders or hex */
- width= (SPICK1+DPICK1+14);
- rgb_to_hsv(col[0], col[1], col[2], hsv, hsv+1, hsv+2);
- sprintf(hexcol, "%02X%02X%02X", (unsigned int)(col[0]*255.0), (unsigned int)(col[1]*255.0), (unsigned int)(col[2]*255.0));
+ bt= uiDefIconButO(block, BUT, "UI_OT_eyedropper", WM_OP_INVOKE_DEFAULT, ICON_EYEDROPPER, butwidth+10, -60, UI_UNIT_X, UI_UNIT_Y, NULL);
+ uiButSetFunc(bt, close_popup_cb, bt, NULL);
+
+ /* RGB values */
uiBlockBeginAlign(block);
- bt= uiDefButF(block, NUMSLI, 0, "R ", 0, -60, width, 19, col, 0.0, 1.0, 10, 3, tip);
- uiButSetFunc(bt, do_palette1_cb, bt, hsv);
- bt= uiDefButF(block, NUMSLI, 0, "G ", 0, -80, width, 19, col+1, 0.0, 1.0, 10, 3, tip);
- uiButSetFunc(bt, do_palette1_cb, bt, hsv);
- bt= uiDefButF(block, NUMSLI, 0, "B ", 0, -100, width, 19, col+2, 0.0, 1.0, 10, 3, tip);
- uiButSetFunc(bt, do_palette1_cb, bt, hsv);
- uiBlockEndAlign(block);
-
+ bt= uiDefButR(block, NUMSLI, 0, "R ", 0, -60, butwidth, UI_UNIT_Y, ptr, propname, 0, 0.0, 0.0, 0, 0, "");
+ uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
+ bt= uiDefButR(block, NUMSLI, 0, "G ", 0, -80, butwidth, UI_UNIT_Y, ptr, propname, 1, 0.0, 0.0, 0, 0, "");
+ uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
+ bt= uiDefButR(block, NUMSLI, 0, "B ", 0, -100, butwidth, UI_UNIT_Y, ptr, propname, 2, 0.0, 0.0, 0, 0, "");
+ uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
+ // could use uiItemFullR(col, "", 0, ptr, prop, -1, 0, UI_ITEM_R_EXPAND|UI_ITEM_R_SLIDER);
+ // but need to use uiButSetFunc for updating other fake buttons
+
+ /* HSV values */
uiBlockBeginAlign(block);
- bt= uiDefButF(block, NUMSLI, 0, "H ", 0, -60, width, 19, hsv, 0.0, 1.0, 10, 3, "");
- uiButSetFunc(bt, do_palette2_cb, bt, col);
- bt= uiDefButF(block, NUMSLI, 0, "S ", 0, -80, width, 19, hsv+1, 0.0, 1.0, 10, 3, "");
- uiButSetFunc(bt, do_palette2_cb, bt, col);
- bt= uiDefButF(block, NUMSLI, 0, "V ", 0, -100, width, 19, hsv+2, 0.0, 1.0, 10, 3, "");
- uiButSetFunc(bt, do_palette2_cb, bt, col);
+ bt= uiDefButF(block, NUMSLI, 0, "H ", 0, -60, butwidth, UI_UNIT_Y, hsv, 0.0, 1.0, 10, 3, "");
+ uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
+ bt= uiDefButF(block, NUMSLI, 0, "S ", 0, -80, butwidth, UI_UNIT_Y, hsv+1, 0.0, 1.0, 10, 3, "");
+ uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
+ bt= uiDefButF(block, NUMSLI, 0, "V ", 0, -100, butwidth, UI_UNIT_Y, hsv+2, 0.0, 1.0, 10, 3, "");
+ uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
uiBlockEndAlign(block);
+
+ rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
+ sprintf(hexcol, "%02X%02X%02X", (unsigned int)(rgb[0]*255.0), (unsigned int)(rgb[1]*255.0), (unsigned int)(rgb[2]*255.0));
- bt= uiDefBut(block, TEX, 0, "Hex: ", 0, -80, width, 19, hexcol, 0, 8, 0, 0, "Hex triplet for color (#RRGGBB)");
- uiButSetFunc(bt, do_palette_hex_cb, bt, hexcol);
+ bt= uiDefBut(block, TEX, 0, "Hex: ", 0, -60, butwidth, UI_UNIT_Y, hexcol, 0, 8, 0, 0, "Hex triplet for color (#RRGGBB)");
+ uiButSetFunc(bt, do_hex_rna_cb, bt, hexcol);
picker_new_hide_reveal(block, colormode);
}
@@ -1986,7 +1825,7 @@ static int ui_picker_small_wheel(const bContext *C, uiBlock *block, wmEvent *eve
ui_set_but_vectorf(but, col);
- ui_update_block_buts_hsv(block, but->hsv);
+ ui_update_block_buts_rgb(block, col);
if(popup)
popup->menuretval= UI_RETURN_UPDATE;
@@ -1999,15 +1838,11 @@ static int ui_picker_small_wheel(const bContext *C, uiBlock *block, wmEvent *eve
uiBlock *ui_block_func_COL(bContext *C, uiPopupBlockHandle *handle, void *arg_but)
{
- wmWindow *win= CTX_wm_window(C); // XXX temp, needs to become keymap to detect type?
uiBut *but= arg_but;
uiBlock *block;
- static float hsvcol[3], oldcol[3];
- static char hexcol[128];
block= uiBeginBlock(C, handle->region, "colorpicker", UI_EMBOSS);
- /* XXX ideally the colour picker buttons would reference the rna property itself */
if (but->rnaprop) {
if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
block->color_profile = BLI_PR_NONE;
@@ -2017,26 +1852,12 @@ uiBlock *ui_block_func_COL(bContext *C, uiPopupBlockHandle *handle, void *arg_bu
uiBlockSetFlag(block, UI_BLOCK_MOVEMOUSE_QUIT);
VECCOPY(handle->retvec, but->editvec);
- if(win->eventstate->shift) {
- uiBlockPickerButtons(block, handle->retvec, hsvcol, oldcol, hexcol, 'p', 0);
- block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_KEEP_OPEN;
- uiBoundsBlock(block, 3);
- }
- else if(win->eventstate->alt) {
- uiBlockPickerSmall(block, handle->retvec, hsvcol, oldcol, hexcol, 'p', 0);
- block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1|UI_BLOCK_OUT_1;
- uiBoundsBlock(block, 10);
-
- block->block_event_func= ui_picker_small_wheel;
- }
- else {
- uiBlockPickerNew(block, handle->retvec, hsvcol, oldcol, hexcol, 'p', 0);
- block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_KEEP_OPEN;
- uiBoundsBlock(block, 10);
-
- block->block_event_func= ui_picker_small_wheel;
- }
+
+ uiBlockPicker(block, handle->retvec, &but->rnapoin, but->rnaprop);
+ block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_KEEP_OPEN;
+ uiBoundsBlock(block, 10);
+ block->block_event_func= ui_picker_small_wheel;
/* and lets go */
block->direction= UI_TOP;
@@ -2044,90 +1865,6 @@ uiBlock *ui_block_func_COL(bContext *C, uiPopupBlockHandle *handle, void *arg_bu
return block;
}
-/* ******************** Color band *************** */
-
-static int vergcband(const void *a1, const void *a2)
-{
- const CBData *x1=a1, *x2=a2;
-
- if( x1->pos > x2->pos ) return 1;
- else if( x1->pos < x2->pos) return -1;
- return 0;
-}
-
-static void colorband_pos_cb(bContext *C, void *coba_v, void *unused_v)
-{
- ColorBand *coba= coba_v;
- int a;
-
- if(coba->tot<2) return;
-
- for(a=0; a<coba->tot; a++) coba->data[a].cur= a;
- qsort(coba->data, coba->tot, sizeof(CBData), vergcband);
- for(a=0; a<coba->tot; a++) {
- if(coba->data[a].cur==coba->cur) {
- /* if(coba->cur!=a) addqueue(curarea->win, REDRAW, 0); */ /* button cur */
- coba->cur= a;
- break;
- }
- }
-}
-
-static void colorband_add_cb(bContext *C, void *coba_v, void *unused_v)
-{
- ColorBand *coba= coba_v;
-
- if(coba->tot < MAXCOLORBAND-1) coba->tot++;
- coba->cur= coba->tot-1;
-
- colorband_pos_cb(C, coba, NULL);
-// BIF_undo_push("Add colorband");
-
-}
-
-static void colorband_del_cb(bContext *C, void *coba_v, void *unused_v)
-{
- ColorBand *coba= coba_v;
- int a;
-
- if(coba->tot<2) return;
-
- for(a=coba->cur; a<coba->tot; a++) {
- coba->data[a]= coba->data[a+1];
- }
- if(coba->cur) coba->cur--;
- coba->tot--;
-
-// BIF_undo_push("Delete colorband");
-// BIF_preview_changed(ID_TE);
-}
-
-void uiBlockColorbandButtons(uiBlock *block, ColorBand *coba, rctf *butr, int event)
-{
- CBData *cbd;
- uiBut *bt;
- float unit= (butr->xmax-butr->xmin)/14.0f;
- float xs= butr->xmin;
-
- cbd= coba->data + coba->cur;
-
- uiBlockBeginAlign(block);
- uiDefButF(block, COL, event, "", xs,butr->ymin+20.0f,2.0f*unit,20, &(cbd->r), 0, 0, 0, 0, "");
- uiDefButF(block, NUM, event, "A:", xs+2.0f*unit,butr->ymin+20.0f,4.0f*unit,20, &(cbd->a), 0.0f, 1.0f, 10, 2, "");
- bt= uiDefBut(block, BUT, event, "Add", xs+6.0f*unit,butr->ymin+20.0f,2.0f*unit,20, NULL, 0, 0, 0, 0, "Adds a new color position to the colorband");
- uiButSetFunc(bt, colorband_add_cb, coba, NULL);
- bt= uiDefBut(block, BUT, event, "Del", xs+8.0f*unit, butr->ymin+20.0f, 2.0f*unit, 20, NULL, 0, 0, 0, 0, "Deletes the active position");
- uiButSetFunc(bt, colorband_del_cb, coba, NULL);
-
- uiDefButS(block, MENU, event, "Interpolation %t|Ease %x1|Cardinal %x3|Linear %x0|B-Spline %x2|Constant %x4",
- xs + 10.0f*unit, butr->ymin+20.0f, unit*4.0f, 20, &coba->ipotype, 0.0, 0.0, 0, 0, "Sets interpolation type");
-
- uiDefBut(block, BUT_COLORBAND, event, "", xs, butr->ymin, butr->xmax-butr->xmin, 20.0f, coba, 0, 0, 0, 0, "");
- uiBlockEndAlign(block);
-
-}
-
-
/************************ Popup Menu Memory ****************************/
static int ui_popup_menu_hash(char *str)
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index a2b926003a7..5852f8f8873 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -33,6 +33,7 @@
#include "BLI_string.h"
+#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_icons.h"
#include "BKE_global.h"
@@ -122,6 +123,7 @@ typedef struct TemplateID {
PropertyRNA *prop;
ListBase *idlb;
+ int prv_rows, prv_cols;
} TemplateID;
/* Search browse menu, assign */
@@ -150,7 +152,7 @@ static void id_search_cb(const bContext *C, void *arg_template, char *str, uiSea
/* 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);
+ iconid= ui_id_icon_get((bContext*)C, id, 0);
if(!uiSearchItemAdd(items, id->name+2, id, iconid))
break;
@@ -180,11 +182,26 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem)
block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1);
- /* fake button, it holds space for search items */
- uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
-
- but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, 150, 19, "");
- uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data);
+ /* preview thumbnails */
+ if (template.prv_rows > 0 && template.prv_cols > 0) {
+ int w = 96 * template.prv_cols;
+ int h = 96 * template.prv_rows + 20;
+
+ /* fake button, it holds space for search items */
+ uiDefBut(block, LABEL, 0, "", 10, 15, w, h, NULL, 0, 0, 0, 0, NULL);
+
+ but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, w, 19, template.prv_rows, template.prv_cols, "");
+ uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data);
+ }
+ /* list view */
+ else {
+ /* fake button, it holds space for search items */
+ uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
+
+ but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, 150, 19, 0, 0, "");
+ uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data);
+ }
+
uiBoundsBlock(block, 6);
uiBlockSetDirection(block, UI_DOWN);
@@ -293,9 +310,10 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
}
}
-static void template_ID(bContext *C, uiBlock *block, TemplateID *template, StructRNA *type, int flag, char *newop, char *openop, char *unlinkop)
+static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, StructRNA *type, int flag, char *newop, char *openop, char *unlinkop)
{
uiBut *but;
+ uiBlock *block;
PointerRNA idptr;
ListBase *lb;
ID *id, *idfrom;
@@ -305,11 +323,27 @@ static void template_ID(bContext *C, uiBlock *block, TemplateID *template, Struc
idfrom= template->ptr.id.data;
lb= template->idlb;
+ block= uiLayoutGetBlock(layout);
uiBlockBeginAlign(block);
if(idptr.type)
type= idptr.type;
+ if(flag & UI_ID_PREVIEWS) {
+
+ but= uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X*6, UI_UNIT_Y*6, "Browse ID data");
+ if(type) {
+ but->icon= RNA_struct_ui_icon(type);
+ if (id) but->icon = ui_id_icon_get(C, id, 1);
+ uiButSetFlag(but, UI_HAS_ICON|UI_ICON_PREVIEW);
+ }
+ if((idfrom && idfrom->lib))
+ uiButSetFlag(but, UI_BUT_DISABLED);
+
+
+ uiLayoutRow(layout, 1);
+ } else
+
if(flag & UI_ID_BROWSE) {
but= uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X*1.6, UI_UNIT_Y, "Browse ID data");
if(type) {
@@ -412,10 +446,9 @@ static void template_ID(bContext *C, uiBlock *block, TemplateID *template, Struc
uiBlockEndAlign(block);
}
-void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop)
+static void ui_template_id(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop, int previews, int prv_rows, int prv_cols)
{
TemplateID *template;
- uiBlock *block;
PropertyRNA *prop;
StructRNA *type;
int flag;
@@ -430,14 +463,18 @@ void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname
template= MEM_callocN(sizeof(TemplateID), "TemplateID");
template->ptr= *ptr;
template->prop= prop;
-
+ template->prv_rows = prv_rows;
+ template->prv_cols = prv_cols;
+
flag= UI_ID_BROWSE|UI_ID_RENAME|UI_ID_DELETE;
if(newop)
flag |= UI_ID_ADD_NEW;
if(openop)
flag |= UI_ID_OPEN;
-
+ if(previews)
+ flag |= UI_ID_PREVIEWS;
+
type= RNA_property_pointer_type(ptr, prop);
template->idlb= wich_libbase(CTX_data_main(C), RNA_type_to_ID_code(type));
@@ -446,11 +483,21 @@ void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname
*/
if(template->idlb) {
uiLayoutRow(layout, 1);
- block= uiLayoutGetBlock(layout);
- template_ID(C, block, template, type, flag, newop, openop, unlinkop);
+ template_ID(C, layout, template, type, flag, newop, openop, unlinkop);
}
MEM_freeN(template);
+
+}
+
+void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop)
+{
+ ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop, 0, 0, 0);
+}
+
+void uiTemplateIDPreview(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop, int rows, int cols)
+{
+ ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop, 1, rows, cols);
}
/************************ ID Chooser Template ***************************/
@@ -1402,7 +1449,7 @@ static void colorband_buttons_large(uiLayout *layout, uiBlock *block, ColorBand
if(coba->tot) {
CBData *cbd= coba->data + coba->cur;
-#if 1
+
/* better to use rna so we can animate them */
PointerRNA ptr;
RNA_pointer_create(cb->ptr.id.data, &RNA_ColorRampElement, cbd, &ptr);
@@ -1410,15 +1457,6 @@ static void colorband_buttons_large(uiLayout *layout, uiBlock *block, ColorBand
//uiItemR(layout, NULL, 0, &ptr, "position", 0);
bt= uiDefButF(block, NUM, 0, "Pos:", 0+xoffs,40+yoffs,100, 20, &cbd->pos, 0.0, 1.0, 10, 0, "The position of the active color stop");
uiButSetNFunc(bt, colorband_pos_cb, MEM_dupallocN(cb), coba);
-
-#else
- bt= uiDefButF(block, NUM, 0, "Pos:", 0+xoffs,40+yoffs,100, 20, &cbd->pos, 0.0, 1.0, 10, 0, "The position of the active color stop");
- uiButSetNFunc(bt, colorband_pos_cb, MEM_dupallocN(cb), coba);
- bt= uiDefButF(block, COL, 0, "", 110+xoffs,40+yoffs,80,20, &(cbd->r), 0, 0, 0, B_BANDCOL, "The color value for the active color stop");
- uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
- bt= uiDefButF(block, NUMSLI, 0, "A ", 200+xoffs,40+yoffs,100,20, &cbd->a, 0.0, 1.0, 10, 0, "The alpha value of the active color stop");
- uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
-#endif
}
}
@@ -1437,16 +1475,9 @@ static void colorband_buttons_small(uiLayout *layout, uiBlock *block, ColorBand
if(coba->tot) {
CBData *cbd= coba->data + coba->cur;
-#if 1
PointerRNA ptr;
RNA_pointer_create(cb->ptr.id.data, &RNA_ColorRampElement, cbd, &ptr);
uiItemR(layout, "", 0, &ptr, "color", 0);
-#else
- bt= uiDefButF(block, COL, 0, "", xs+4.0f*unit,butr->ymin+20.0f,2.0f*unit,20, &(cbd->r), 0, 0, 0, B_BANDCOL, "The color value for the active color stop");
- uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
- bt= uiDefButF(block, NUMSLI, 0, "A:", xs+6.0f*unit,butr->ymin+20.0f,4.0f*unit,20, &(cbd->a), 0.0f, 1.0f, 10, 2, "The alpha value of the active color stop");
- uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
-#endif
}
bt= uiDefButS(block, MENU, 0, "Interpolation %t|Ease %x1|Cardinal %x3|Linear %x0|B-Spline %x2|Constant %x4",
@@ -1606,8 +1637,8 @@ static void curvemap_tools_dofunc(bContext *C, void *cumap_v, int event)
CurveMap *cuma= cumap->cm+cumap->cur;
switch(event) {
- case 0:
- curvemap_reset(cuma, &cumap->clipr);
+ case 0: /* reset */
+ curvemap_reset(cuma, &cumap->clipr, CURVE_PRESET_LINE);
curvemapping_changed(cumap, 0);
break;
case 1:
@@ -1629,6 +1660,10 @@ static void curvemap_tools_dofunc(bContext *C, void *cumap_v, int event)
cuma->flag |= CUMA_EXTEND_EXTRAPOLATE;
curvemapping_changed(cumap, 0);
break;
+ case 6: /* reset smooth */
+ curvemap_reset(cuma, &cumap->clipr, CURVE_PRESET_SMOOTH);
+ curvemapping_changed(cumap, 0);
+ break;
}
ED_region_tag_redraw(CTX_wm_region(C));
}
@@ -1655,6 +1690,26 @@ static uiBlock *curvemap_tools_func(bContext *C, struct ARegion *ar, void *cumap
return block;
}
+static uiBlock *curvemap_brush_tools_func(bContext *C, struct ARegion *ar, void *cumap_v)
+{
+ uiBlock *block;
+ short yco= 0, menuwidth=120;
+
+ block= uiBeginBlock(C, ar, "curvemap_tools_func", UI_EMBOSS);
+ uiBlockSetButmFunc(block, curvemap_tools_dofunc, cumap_v);
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reset View", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Vector Handle", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Auto Handle", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reset Curve", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
+
+ uiBlockSetDirection(block, UI_RIGHT);
+ uiTextBoundsBlock(block, 50);
+
+ uiEndBlock(C, block);
+ return block;
+}
+
static void curvemap_buttons_redraw(bContext *C, void *arg1, void *arg2)
{
ED_region_tag_redraw(CTX_wm_region(C));
@@ -1666,7 +1721,7 @@ static void curvemap_buttons_reset(bContext *C, void *cb_v, void *cumap_v)
int a;
for(a=0; a<CM_TOT; a++)
- curvemap_reset(cumap->cm+a, &cumap->clipr);
+ curvemap_reset(cumap->cm+a, &cumap->clipr, CURVE_PRESET_LINE);
cumap->black[0]=cumap->black[1]=cumap->black[2]= 0.0f;
cumap->white[0]=cumap->white[1]=cumap->white[2]= 1.0f;
@@ -1678,7 +1733,7 @@ static void curvemap_buttons_reset(bContext *C, void *cb_v, void *cumap_v)
}
/* still unsure how this call evolves... we use labeltype for defining what curve-channels to show */
-static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labeltype, int levels, RNAUpdateCb *cb)
+static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labeltype, int levels, int brush, RNAUpdateCb *cb)
{
CurveMapping *cumap= ptr->data;
uiLayout *row, *sub, *split;
@@ -1746,7 +1801,11 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe
bt= uiDefIconBut(block, BUT, 0, ICON_ZOOMOUT, 0, 0, dx, 14, NULL, 0.0, 0.0, 0.0, 0.0, "Zoom out");
uiButSetFunc(bt, curvemap_buttons_zoom_out, cumap, NULL);
- bt= uiDefIconBlockBut(block, curvemap_tools_func, cumap, 0, ICON_MODIFIER, 0, 0, dx, 18, "Tools");
+ if(brush)
+ bt= uiDefIconBlockBut(block, curvemap_brush_tools_func, cumap, 0, ICON_MODIFIER, 0, 0, dx, 18, "Tools");
+ else
+ bt= uiDefIconBlockBut(block, curvemap_tools_func, cumap, 0, ICON_MODIFIER, 0, 0, dx, 18, "Tools");
+
uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
if(cumap->flag & CUMA_DO_CLIP) icon= ICON_CLIPUV_HLT; else icon= ICON_CLIPUV_DEHLT;
@@ -1779,7 +1838,7 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe
uiBlockSetNFunc(block, NULL, NULL, NULL);
}
-void uiTemplateCurveMapping(uiLayout *layout, PointerRNA *ptr, char *propname, int type, int levels)
+void uiTemplateCurveMapping(uiLayout *layout, PointerRNA *ptr, char *propname, int type, int levels, int brush)
{
RNAUpdateCb *cb;
PropertyRNA *prop= RNA_struct_find_property(ptr, propname);
@@ -1796,11 +1855,47 @@ void uiTemplateCurveMapping(uiLayout *layout, PointerRNA *ptr, char *propname, i
cb->ptr= *ptr;
cb->prop= prop;
- curvemap_buttons_layout(layout, &cptr, type, levels, cb);
+ curvemap_buttons_layout(layout, &cptr, type, levels, brush, cb);
MEM_freeN(cb);
}
+/********************* ColorWheel Template ************************/
+
+#define WHEEL_SIZE 100
+
+void uiTemplateColorWheel(uiLayout *layout, PointerRNA *ptr, char *propname, int value_slider)
+{
+ PropertyRNA *prop= RNA_struct_find_property(ptr, propname);
+ uiBlock *block= uiLayoutGetBlock(layout);
+ uiLayout *col, *row;
+ uiBut *but;
+
+ if (!prop) {
+ printf("uiTemplateColorWheel: property not found: %s\n", propname);
+ return;
+ }
+
+ col = uiLayoutColumn(layout, 0);
+ row= uiLayoutRow(col, 1);
+
+ uiDefButR(block, HSVCIRCLE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, propname, -1, 0.0, 0.0, 0, 0, "");
+
+ uiItemS(row);
+
+ if (value_slider)
+ uiDefButR(block, HSVCUBE, 0, "", WHEEL_SIZE+6, 0, 14, WHEEL_SIZE, ptr, propname, -1, 0.0, 0.0, 9, 0, "");
+
+ /* maybe a switch for this?
+ row= uiLayoutRow(col, 0);
+ if(ELEM(RNA_property_subtype(prop), PROP_COLOR, PROP_COLOR_GAMMA) && RNA_property_array_length(ptr, prop) == 4) {
+ but= uiDefAutoButR(block, ptr, prop, 3, "A:", 0, 0, 0, WHEEL_SIZE+20, UI_UNIT_Y);
+ }
+ */
+
+}
+
+
/********************* TriColor (ThemeWireColorSet) Template ************************/
void uiTemplateTriColorSet(uiLayout *layout, PointerRNA *ptr, char *propname)
@@ -1944,7 +2039,7 @@ static int list_item_icon_get(bContext *C, PointerRNA *itemptr, int rnaicon)
/* get icon from ID */
if(id) {
- icon= ui_id_icon_get(C, id);
+ icon= ui_id_icon_get(C, id, 1);
if(icon)
return icon;
@@ -1998,6 +2093,11 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe
uiBlockSetEmboss(block, UI_EMBOSS);
uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, ptr, "use_textures", i, 0, 0, 0, 0, NULL);
}
+ else if(RNA_struct_is_a(itemptr->type, &RNA_SceneRenderLayer)) {
+ uiItemL(sub, name, icon);
+ uiBlockSetEmboss(block, UI_EMBOSS);
+ uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "enabled", 0, 0, 0, 0, 0, NULL);
+ }
else if(itemptr->type == &RNA_ShapeKey) {
ob= (Object*)activeptr->data;
@@ -2245,7 +2345,7 @@ void uiTemplateOperatorSearch(uiLayout *layout)
block= uiLayoutGetBlock(layout);
uiBlockSetCurLayout(block, layout);
- but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 0, 0, UI_UNIT_X*6, UI_UNIT_Y, "");
+ but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 0, 0, UI_UNIT_X*6, UI_UNIT_Y, 0, 0, "");
uiButSetSearchFunc(but, operator_search_cb, NULL, operator_call_cb, NULL);
}
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 4c9698974b4..82c79c32c6c 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -695,6 +695,27 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
/* *********************** text/icon ************************************** */
+#define PREVIEW_PAD 4
+
+static void widget_draw_preview(BIFIconID icon, float aspect, float alpha, rcti *rect)
+{
+ int w, h, x, y, size;
+
+ /* only display previews for actual preview images .. ? */
+ if (icon < BIFICONID_LAST)
+ return;
+
+ w = rect->xmax - rect->xmin;
+ h = rect->ymax - rect->ymin;
+ size = MIN2(w, h);
+ size -= PREVIEW_PAD*2; /* padding */
+
+ x = rect->xmin + w/2 - size/2;
+ y = rect->ymin + h/2 - size/2;
+
+ UI_icon_draw_preview_aspect_size(x, y, icon, aspect, size);
+}
+
/* icons have been standardized... and this call draws in untransformed coordinates */
#define ICON_HEIGHT 16.0f
@@ -704,6 +725,11 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect
int xs=0, ys=0;
float aspect, height;
+ if (but->flag & UI_ICON_PREVIEW) {
+ widget_draw_preview(icon, but->block->aspect, alpha, rect);
+ return;
+ }
+
/* this icon doesn't need draw... */
if(icon==ICON_BLANK1 && (but->flag & UI_ICON_SUBMENU)==0) return;
@@ -1512,12 +1538,12 @@ void ui_hsvcircle_vals_from_pos(float *valrad, float *valdist, rcti *rect, float
*valrad= atan2(mx, my)/(2.0f*M_PI) + 0.5f;
}
-void ui_draw_but_HSVCIRCLE(uiBut *but, rcti *rect)
+void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, rcti *rect)
{
/* gouraud triangle fan */
float radstep, ang= 0.0f;
float centx, centy, radius;
- float hsv[3], col[3], colcent[3];
+ float rgb[3], hsv[3], hsvo[3], col[3], colcent[3];
int a, tot= 32;
radstep= 2.0f*M_PI/(float)tot;
@@ -1530,9 +1556,11 @@ void ui_draw_but_HSVCIRCLE(uiBut *but, rcti *rect)
radius= (float)(rect->xmax - rect->xmin)/2;
/* color */
- VECCOPY(hsv, but->hsv);
- hsv[0]= hsv[1]= 0.0f;
- hsv_to_rgb(hsv[0], hsv[1], hsv[2], colcent, colcent+1, colcent+2);
+ ui_get_but_vectorf(but, rgb);
+ rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
+ copy_v3_v3(hsvo, hsv);
+
+ hsv_to_rgb(0.f, 0.f, hsv[2], colcent, colcent+1, colcent+2);
glShadeModel(GL_SMOOTH);
@@ -1558,15 +1586,15 @@ void ui_draw_but_HSVCIRCLE(uiBut *but, rcti *rect)
glTranslatef(centx, centy, 0.0f);
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH );
- glColor3f(0.0f, 0.0f, 0.0f);
+ glColor3ubv((unsigned char*)wcol->outline);
glutil_draw_lined_arc(0.0f, M_PI*2.0, radius, tot);
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH );
glPopMatrix();
/* cursor */
- ang= 2.0f*M_PI*but->hsv[0] + 0.5f*M_PI;
- radius= but->hsv[1]*radius;
+ ang= 2.0f*M_PI*hsvo[0] + 0.5f*M_PI;
+ radius= hsvo[1]*radius;
ui_hsv_cursor(centx + cos(-ang)*radius, centy + sin(-ang)*radius);
}
@@ -1577,46 +1605,63 @@ void ui_draw_but_HSVCIRCLE(uiBut *but, rcti *rect)
static void ui_draw_but_HSVCUBE(uiBut *but, rcti *rect)
{
int a;
- float h,s,v;
+ float rgb[3], h,s,v;
float dx, dy, sx1, sx2, sy, x=0.0f, y=0.0f;
float col0[4][3]; // left half, rect bottom to top
float col1[4][3]; // right half, rect bottom to top
- h= but->hsv[0];
- s= but->hsv[1];
- v= but->hsv[2];
+ ui_get_but_vectorf(but, rgb);
+ rgb_to_hsv(rgb[0], rgb[1], rgb[2], &h, &s, &v);
/* draw series of gouraud rects */
glShadeModel(GL_SMOOTH);
- if(but->a1==0) { // H and V vary
+
+ if(but->a1==0) { // S and V vary
+ hsv_to_rgb(h, 0.0, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]);
+ hsv_to_rgb(h, 0.333, 0.0, &col1[1][0], &col1[1][1], &col1[1][2]);
+ hsv_to_rgb(h, 0.666, 0.0, &col1[2][0], &col1[2][1], &col1[2][2]);
+ hsv_to_rgb(h, 1.0, 0.0, &col1[3][0], &col1[3][1], &col1[3][2]);
+ x= v; y= s;
+ }
+ else if(but->a1==1) { // H and V vary
hsv_to_rgb(0.0, s, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]);
hsv_to_rgb(0.0, s, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
hsv_to_rgb(0.0, s, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
hsv_to_rgb(0.0, s, 1.0, &col1[3][0], &col1[3][1], &col1[3][2]);
x= h; y= v;
}
- else if(but->a1==1) { // H and S vary
+ else if(but->a1==2) { // H and S vary
hsv_to_rgb(0.0, 0.0, v, &col1[0][0], &col1[0][1], &col1[0][2]);
hsv_to_rgb(0.0, 0.333, v, &col1[1][0], &col1[1][1], &col1[1][2]);
hsv_to_rgb(0.0, 0.666, v, &col1[2][0], &col1[2][1], &col1[2][2]);
hsv_to_rgb(0.0, 1.0, v, &col1[3][0], &col1[3][1], &col1[3][2]);
x= h; y= s;
}
- else if(but->a1==2) { // S and V vary
- hsv_to_rgb(h, 0.0, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]);
- hsv_to_rgb(h, 0.333, 0.0, &col1[1][0], &col1[1][1], &col1[1][2]);
- hsv_to_rgb(h, 0.666, 0.0, &col1[2][0], &col1[2][1], &col1[2][2]);
- hsv_to_rgb(h, 1.0, 0.0, &col1[3][0], &col1[3][1], &col1[3][2]);
- x= v; y= s;
- }
- else if(but->a1==3) { // only hue slider
+ else if(but->a1==3) { // only H
hsv_to_rgb(0.0, 1.0, 1.0, &col1[0][0], &col1[0][1], &col1[0][2]);
VECCOPY(col1[1], col1[0]);
VECCOPY(col1[2], col1[0]);
VECCOPY(col1[3], col1[0]);
x= h; y= 0.5;
}
+ else if(but->a1==4) { // only S
+ hsv_to_rgb(1.0, 0.0, 1.0, &col1[1][0], &col1[1][1], &col1[1][2]);
+ VECCOPY(col1[0], col1[1]);
+ VECCOPY(col1[2], col1[1]);
+ VECCOPY(col1[3], col1[1]);
+ x= s; y= 0.5;
+ }
+ else if(but->a1==5) { // only V
+ hsv_to_rgb(1.0, 1.0, 0.0, &col1[2][0], &col1[2][1], &col1[2][2]);
+ VECCOPY(col1[0], col1[2]);
+ VECCOPY(col1[1], col1[2]);
+ VECCOPY(col1[3], col1[2]);
+ x= v; y= 0.5;
+ }
+
+
+ /* old below */
for(dx=0.0; dx<1.0; dx+= 0.05) {
// previous color
@@ -1626,30 +1671,42 @@ static void ui_draw_but_HSVCUBE(uiBut *but, rcti *rect)
VECCOPY(col0[3], col1[3]);
// new color
- if(but->a1==0) { // H and V vary
+ if(but->a1==0) { // S and V vary
+ hsv_to_rgb(h, 0.0, dx, &col1[0][0], &col1[0][1], &col1[0][2]);
+ hsv_to_rgb(h, 0.333, dx, &col1[1][0], &col1[1][1], &col1[1][2]);
+ hsv_to_rgb(h, 0.666, dx, &col1[2][0], &col1[2][1], &col1[2][2]);
+ hsv_to_rgb(h, 1.0, dx, &col1[3][0], &col1[3][1], &col1[3][2]);
+ }
+ else if(but->a1==1) { // H and V vary
hsv_to_rgb(dx, s, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]);
hsv_to_rgb(dx, s, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
hsv_to_rgb(dx, s, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
hsv_to_rgb(dx, s, 1.0, &col1[3][0], &col1[3][1], &col1[3][2]);
}
- else if(but->a1==1) { // H and S vary
+ else if(but->a1==2) { // H and S vary
hsv_to_rgb(dx, 0.0, v, &col1[0][0], &col1[0][1], &col1[0][2]);
hsv_to_rgb(dx, 0.333, v, &col1[1][0], &col1[1][1], &col1[1][2]);
hsv_to_rgb(dx, 0.666, v, &col1[2][0], &col1[2][1], &col1[2][2]);
hsv_to_rgb(dx, 1.0, v, &col1[3][0], &col1[3][1], &col1[3][2]);
}
- else if(but->a1==2) { // S and V vary
- hsv_to_rgb(h, 0.0, dx, &col1[0][0], &col1[0][1], &col1[0][2]);
- hsv_to_rgb(h, 0.333, dx, &col1[1][0], &col1[1][1], &col1[1][2]);
- hsv_to_rgb(h, 0.666, dx, &col1[2][0], &col1[2][1], &col1[2][2]);
- hsv_to_rgb(h, 1.0, dx, &col1[3][0], &col1[3][1], &col1[3][2]);
- }
else if(but->a1==3) { // only H
hsv_to_rgb(dx, 1.0, 1.0, &col1[0][0], &col1[0][1], &col1[0][2]);
VECCOPY(col1[1], col1[0]);
VECCOPY(col1[2], col1[0]);
VECCOPY(col1[3], col1[0]);
}
+ else if(but->a1==4) { // only S
+ hsv_to_rgb(h, dx, 1.0, &col1[1][0], &col1[1][1], &col1[1][2]);
+ VECCOPY(col1[0], col1[1]);
+ VECCOPY(col1[2], col1[1]);
+ VECCOPY(col1[3], col1[1]);
+ }
+ else if(but->a1==5) { // only V
+ hsv_to_rgb(h, 1.0, dx, &col1[2][0], &col1[2][1], &col1[2][2]);
+ VECCOPY(col1[0], col1[2]);
+ VECCOPY(col1[1], col1[2]);
+ VECCOPY(col1[3], col1[2]);
+ }
// rect
sx1= rect->xmin + dx*(rect->xmax-rect->xmin);
@@ -1695,7 +1752,7 @@ static void ui_draw_but_HSV_v(uiBut *but, rcti *rect)
uiWidgetBase wtb;
float rad= 0.5f*(rect->xmax - rect->xmin);
float x, y;
- float v = but->hsv[2];
+ float rgb[3], hsv[3], v;
int color_profile = but->block->color_profile;
if (but->rnaprop) {
@@ -1704,6 +1761,10 @@ static void ui_draw_but_HSV_v(uiBut *but, rcti *rect)
}
}
+ ui_get_but_vectorf(but, rgb);
+ rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
+ v = hsv[2];
+
if (color_profile)
v = linearrgb_to_srgb(v);
@@ -2558,14 +2619,14 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
break;
case HSVCUBE:
- if(but->a1==4) // vertical V slider, uses new widget draw now
+ if(but->a1==9) // vertical V slider, uses new widget draw now
ui_draw_but_HSV_v(but, rect);
else // other HSV pickers...
ui_draw_but_HSVCUBE(but, rect);
break;
case HSVCIRCLE:
- ui_draw_but_HSVCIRCLE(but, rect);
+ ui_draw_but_HSVCIRCLE(but, &tui->wcol_regular, rect);
break;
case BUT_COLORBAND:
@@ -2692,3 +2753,25 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, char *name, int iconid,
}
}
+void ui_draw_preview_item(uiFontStyle *fstyle, rcti *rect, char *name, int iconid, int state)
+{
+ rcti trect = *rect;
+
+ uiWidgetType *wt= widget_type(UI_WTYPE_MENU_ITEM);
+
+ wt->state(wt, state);
+ wt->draw(&wt->wcol, rect, 0, 0);
+
+ widget_draw_preview(iconid, 1.f, 1.f, rect);
+
+ if (state == UI_ACTIVE)
+ glColor3ubv((unsigned char*)wt->wcol.text);
+ else
+ glColor3ubv((unsigned char*)wt->wcol.text_sel);
+
+ trect.xmin += 0;
+ trect.xmax = trect.xmin + BLF_width(name) + 10;
+ trect.ymin += 10;
+ trect.ymax = trect.ymin + BLF_height(name);
+ uiStyleFontDraw(fstyle, &trect, name);
+}
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 47bbbd9292c..15513daa624 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -782,6 +782,26 @@ void UI_GetThemeColor3fv(int colorid, float *col)
col[2]= ((float)cp[2])/255.0;
}
+// get the color, range 0.0-1.0, complete with shading offset
+void UI_GetThemeColorShade3fv(int colorid, int offset, float *col)
+{
+ int r, g, b;
+ char *cp;
+
+ cp= UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
+
+ r= offset + (int) cp[0];
+ CLAMP(r, 0, 255);
+ g= offset + (int) cp[1];
+ CLAMP(g, 0, 255);
+ b= offset + (int) cp[2];
+ CLAMP(b, 0, 255);
+
+ col[0]= ((float)r)/255.0;
+ col[1]= ((float)g)/255.0;
+ col[2]= ((float)b)/255.0;
+}
+
// get the color, in char pointer
void UI_GetThemeColor3ubv(int colorid, char *col)
{
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index 7d1dc00e271..57882b7dd0d 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -236,6 +236,18 @@ static int view_pan_modal(bContext *C, wmOperator *op, wmEvent *event)
break;
case LEFTMOUSE:
+ /* switch to zoom */
+ if (event->val==KM_PRESS) {
+ /* calculate overall delta mouse-movement for redo */
+ RNA_int_set(op->ptr, "deltax", (vpd->startx - vpd->lastx));
+ RNA_int_set(op->ptr, "deltay", (vpd->starty - vpd->lasty));
+
+ view_pan_exit(C, op);
+ WM_cursor_restore(CTX_wm_window(C));
+
+ WM_operator_name_call(C, "VIEW2D_OT_zoom", WM_OP_INVOKE_DEFAULT, NULL);
+ return OPERATOR_FINISHED;
+ }
case MIDDLEMOUSE:
case ESCKEY:
if (event->val==KM_RELEASE) {
diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c
index d7f421331e5..572cf214c6a 100644
--- a/source/blender/editors/mesh/editmesh_add.c
+++ b/source/blender/editors/mesh/editmesh_add.c
@@ -1265,7 +1265,7 @@ static void make_prim(Object *obedit, int type, float mat[4][4], int tot, int se
EM_select_flush(em); /* flushes vertex -> edge -> face selection */
if(type!=PRIM_PLANE && type!=PRIM_MONKEY)
- righthandfaces(em, 1); /* otherwise monkey has eyes in wrong direction */
+ EM_recalc_normal_direction(em, 0, 0); /* otherwise monkey has eyes in wrong direction */
BKE_mesh_end_editmesh(obedit->data, em);
}
diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c
index 827b28f954b..dee831b7fd0 100644
--- a/source/blender/editors/mesh/editmesh_mods.c
+++ b/source/blender/editors/mesh/editmesh_mods.c
@@ -3800,8 +3800,7 @@ void MESH_OT_mark_sharp(wmOperatorType *ot)
/* **************** NORMALS ************** */
-/* XXX value of select is messed up, it means two things */
-void righthandfaces(EditMesh *em, int select) /* makes faces righthand turning */
+void EM_recalc_normal_direction(EditMesh *em, int inside, int select) /* makes faces righthand turning */
{
EditEdge *eed, *ed1, *ed2, *ed3, *ed4;
EditFace *efa, *startvl;
@@ -3893,16 +3892,12 @@ void righthandfaces(EditMesh *em, int select) /* makes faces righthand turning *
cent_tri_v3(cent, startvl->v1->co, startvl->v2->co, startvl->v3->co);
}
/* first normal is oriented this way or the other */
- if(select) {
- if(select==2) {
- if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] > 0.0) flipface(em, startvl);
- }
- else {
- if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] < 0.0) flipface(em, startvl);
- }
+ if(inside) {
+ if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] > 0.0) flipface(em, startvl);
+ }
+ else {
+ if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] < 0.0) flipface(em, startvl);
}
- else if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] < 0.0) flipface(em, startvl);
-
eed= startvl->e1;
if(eed->v1==startvl->v1) eed->f2= 1;
@@ -4012,7 +4007,7 @@ void righthandfaces(EditMesh *em, int select) /* makes faces righthand turning *
}
-static int righthandfaces_exec(bContext *C, wmOperator *op)
+static int normals_make_consistent_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
@@ -4020,7 +4015,7 @@ static int righthandfaces_exec(bContext *C, wmOperator *op)
/* 'standard' behaviour - check if selected, then apply relevant selection */
// XXX need other args
- righthandfaces(em, RNA_boolean_get(op->ptr, "inside"));
+ EM_recalc_normal_direction(em, RNA_boolean_get(op->ptr, "inside"), 1);
BKE_mesh_end_editmesh(obedit->data, em);
@@ -4038,7 +4033,7 @@ void MESH_OT_normals_make_consistent(wmOperatorType *ot)
ot->idname= "MESH_OT_normals_make_consistent";
/* api callbacks */
- ot->exec= righthandfaces_exec;
+ ot->exec= normals_make_consistent_exec;
ot->poll= ED_operator_editmesh;
/* flags */
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index 31e8cb16abc..94bdbdc73aa 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -172,7 +172,7 @@ void MESH_OT_select_nth(struct wmOperatorType *ot);
extern EditEdge *findnearestedge(ViewContext *vc, int *dist);
extern void EM_automerge(Scene *scene, Object *obedit, int update);
void editmesh_select_by_material(EditMesh *em, int index);
-void righthandfaces(EditMesh *em, int select); /* makes faces righthand turning */
+void EM_recalc_normal_direction(EditMesh *em, int inside, int select); /* makes faces righthand turning */
void EM_select_more(EditMesh *em);
void selectconnected_mesh_all(EditMesh *em);
void faceloop_select(EditMesh *em, EditEdge *startedge, int select);
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index c41ac9f6550..8537d39fbd8 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -195,7 +195,7 @@ void ED_operatormacros_mesh(void)
RNA_enum_set(otmacro->ptr, "constraint_orientation", V3D_MANIP_NORMAL);
RNA_boolean_set_array(otmacro->ptr, "constraint_axis", constraint_axis);
- ot= WM_operatortype_append_macro("MESH_OT_extrude_move", "Extrude", OPTYPE_UNDO|OPTYPE_REGISTER);
+ ot= WM_operatortype_append_macro("MESH_OT_extrude_move", "Extrude and Move", OPTYPE_UNDO|OPTYPE_REGISTER);
WM_operatortype_macro_define(ot, "MESH_OT_extrude");
otmacro= WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
RNA_enum_set(otmacro->ptr, "proportional", 0);
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index 1feaa2dc83a..269fc278581 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -76,16 +76,6 @@
#include "BKE_utildefines.h"
#include "BKE_report.h"
-#include "RE_pipeline.h"
-#include "RE_shader_ext.h"
-
-#include "PIL_time.h"
-
-#include "IMB_imbuf_types.h"
-#include "IMB_imbuf.h"
-
-#include "GPU_draw.h"
-
#include "BLO_sys_types.h" // for intptr_t support
#include "ED_mesh.h"
@@ -99,8 +89,6 @@
#include "mesh_intern.h"
/* XXX */
-static void waitcursor(int val) {}
-static void error() {}
static int pupmenu() {return 0;}
/* XXX */
@@ -772,7 +760,7 @@ void sort_faces(Scene *scene, View3D *v3d)
#define MOC_RES 8
#define MOC_NODE_RES 8
-#define MOC_THRESH 0.0002f
+#define MOC_THRESH 0.00002f
typedef struct MocNode {
struct MocNode *next;
@@ -1132,191 +1120,3 @@ int *mesh_get_x_mirror_faces(Object *ob, EditMesh *em)
return mirrorfaces;
}
-
-/* ****************** render BAKING ********************** */
-
-/* threaded break test */
-static int thread_break(void *unused)
-{
- return G.afbreek;
-}
-
-static ScrArea *biggest_image_area(bScreen *screen)
-{
- ScrArea *sa, *big= NULL;
- int size, maxsize= 0;
-
- for(sa= screen->areabase.first; sa; sa= sa->next) {
- if(sa->spacetype==SPACE_IMAGE) {
- size= sa->winx*sa->winy;
- if(sa->winx > 10 && sa->winy > 10 && size > maxsize) {
- maxsize= size;
- big= sa;
- }
- }
- }
- return big;
-}
-
-
-typedef struct BakeRender {
- Render *re;
- struct Object *actob;
- int event, tot, ready;
-} BakeRender;
-
-static void *do_bake_render(void *bake_v)
-{
- BakeRender *bkr= bake_v;
-
- bkr->tot= RE_bake_shade_all_selected(bkr->re, bkr->event, bkr->actob);
- bkr->ready= 1;
-
- return NULL;
-}
-
-
-void objects_bake_render(Scene *scene, short event, char **error_msg)
-{
- Object *actob= OBACT;
- int active= scene->r.bake_flag & R_BAKE_TO_ACTIVE;
- short prev_r_raytrace= 0, prev_wo_amb_occ= 0;
-
- if(event==0) event= scene->r.bake_mode;
-
- if(scene->r.renderer!=R_INTERN) {
- *error_msg = "Bake only supported for Internal Renderer";
- return;
- }
-
- if(active && !actob) {
- *error_msg = "No active object";
- return;
- }
-
- if(event>0) {
- bScreen *screen= NULL; // XXX CTX
- Render *re= RE_NewRender("_Bake View_");
- ScrArea *area= NULL; //biggest_image_area(screen); // XXX
- ListBase threads;
- BakeRender bkr;
- int timer=0, tot; // XXX, sculptmode= G.f & G_SCULPTMODE;
-
-// XXX if(sculptmode) set_sculptmode();
-
- if(event==1) event= RE_BAKE_ALL;
- else if(event==2) event= RE_BAKE_AO;
- else if(event==3) event= RE_BAKE_NORMALS;
- else if(event==4) event= RE_BAKE_TEXTURE;
- else if(event==5) event= RE_BAKE_DISPLACEMENT;
- else event= RE_BAKE_SHADOW;
-
- if(event==RE_BAKE_AO) {
- if(scene->world==NULL) {
- *error_msg = "No world set up";
- return;
- }
-
- /* If raytracing or AO is disabled, switch it on temporarily for baking. */
- prev_wo_amb_occ = (scene->world->mode & WO_AMB_OCC) != 0;
- scene->world->mode |= WO_AMB_OCC;
- }
- if(event==RE_BAKE_AO || active) {
- prev_r_raytrace = (scene->r.mode & R_RAYTRACE) != 0;
- scene->r.mode |= R_RAYTRACE;
- }
-
- waitcursor(1);
- RE_test_break_cb(re, NULL, thread_break);
- G.afbreek= 0; /* blender_test_break uses this global */
-
- RE_Database_Baking(re, scene, event, (active)? actob: NULL);
-
- /* baking itself is threaded, cannot use test_break in threads. we also update optional imagewindow */
-
- BLI_init_threads(&threads, do_bake_render, 1);
- bkr.re= re;
- bkr.event= event;
- bkr.ready= 0;
- bkr.actob= (active)? actob: NULL;
- BLI_insert_thread(&threads, &bkr);
-
- while(bkr.ready==0) {
- PIL_sleep_ms(50);
- if(bkr.ready)
- break;
-
- if (!G.background) {
- blender_test_break();
-
- timer++;
- if(area && timer==20) {
- Image *ima= RE_bake_shade_get_image();
- if(ima) ((SpaceImage *)area->spacedata.first)->image= ima;
-// XX scrarea_do_windraw(area);
-// myswapbuffers();
- timer= 0;
- }
- }
- }
- BLI_end_threads(&threads);
- tot= bkr.tot;
-
- RE_Database_Free(re);
- waitcursor(0);
-
- if(tot==0) *error_msg = "No Images found to bake to";
- else {
- Image *ima;
- /* force OpenGL reload and mipmap recalc */
- for(ima= G.main->image.first; ima; ima= ima->id.next) {
- if(ima->ok==IMA_OK_LOADED) {
- ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
- if(ibuf && (ibuf->userflags & IB_BITMAPDIRTY)) {
- GPU_free_image(ima);
- imb_freemipmapImBuf(ibuf);
- }
- }
- }
- }
-
- /* restore raytrace and AO */
- if(event==RE_BAKE_AO)
- if(prev_wo_amb_occ == 0)
- scene->world->mode &= ~WO_AMB_OCC;
-
- if(event==RE_BAKE_AO || active)
- if(prev_r_raytrace == 0)
- scene->r.mode &= ~R_RAYTRACE;
-
-// XXX if(sculptmode) set_sculptmode();
-
- }
-}
-
-/* all selected meshes with UV maps are rendered for current scene visibility */
-static void objects_bake_render_ui(Scene *scene, short event)
-{
- char *error_msg = NULL;
-// int is_editmode = (obedit!=NULL);
-
- /* Deal with editmode, this is a bit clunky but since UV's are in editmode, users are likely to bake from their */
-// XXX if (is_editmode) exit_editmode(0);
-
- objects_bake_render(scene, event, &error_msg);
-
-// XXX if (is_editmode) enter_editmode(0);
-
- if (error_msg)
- error(error_msg);
-}
-
-void objects_bake_render_menu(Scene *scene)
-{
- short event;
-
- event= pupmenu("Bake Selected Meshes %t|Full Render %x1|Ambient Occlusion %x2|Normals %x3|Texture Only %x4|Displacement %x5|Shadow %x6");
- if (event < 1) return;
- objects_bake_render_ui(scene, event);
-}
-
diff --git a/source/blender/editors/object/Makefile b/source/blender/editors/object/Makefile
index fd2af305d87..7c081355ed5 100644
--- a/source/blender/editors/object/Makefile
+++ b/source/blender/editors/object/Makefile
@@ -48,6 +48,8 @@ CPPFLAGS += -I../../makesrna
CPPFLAGS += -I../../python
CPPFLAGS += -I../../imbuf
CPPFLAGS += -I../../ikplugin
+CPPFLAGS += -I../../gpu
+CPPFLAGS += -I../../render/extern/include
# own include
diff --git a/source/blender/editors/object/SConscript b/source/blender/editors/object/SConscript
index 06d68cd1021..0a94de255cb 100644
--- a/source/blender/editors/object/SConscript
+++ b/source/blender/editors/object/SConscript
@@ -6,9 +6,17 @@ sources = env.Glob('*.c')
incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
incs += ' ../../windowmanager #/intern/guardedalloc'
incs += ' ../../makesrna ../../python ../../ikplugin'
+incs += ' ../../render/extern/include ../../gpu' # for object_bake.c
defs = []
+if env['OURPLATFORM'] == 'linux2':
+ cflags='-pthread'
+ incs += ' ../../../extern/binreloc/include'
+
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
+ incs += ' ' + env['BF_PTHREADS_INC']
+
if not env['WITH_BF_PYTHON']:
defs.append('DISABLE_PYTHON')
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
new file mode 100644
index 00000000000..4b02cd8e623
--- /dev/null
+++ b/source/blender/editors/object/object_bake.c
@@ -0,0 +1,341 @@
+/**
+ * $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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2004 by Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/*
+ meshtools.c: no editmode (violated already :), tools operating on meshes
+*/
+
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_image_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_world_types.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_threads.h"
+
+#include "BKE_blender.h"
+#include "BKE_context.h"
+#include "BKE_global.h"
+#include "BKE_image.h"
+#include "BKE_main.h"
+#include "BKE_object.h"
+#include "BKE_utildefines.h"
+#include "BKE_report.h"
+
+#include "RE_pipeline.h"
+#include "RE_shader_ext.h"
+
+#include "PIL_time.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+
+#include "GPU_draw.h" /* GPU_free_image */
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+
+/* ****************** render BAKING ********************** */
+
+/* threaded break test */
+static int thread_break(void *unused)
+{
+ return G.afbreek;
+}
+
+static ScrArea *biggest_image_area(bScreen *screen)
+{
+ ScrArea *sa, *big= NULL;
+ int size, maxsize= 0;
+
+ for(sa= screen->areabase.first; sa; sa= sa->next) {
+ if(sa->spacetype==SPACE_IMAGE) {
+ size= sa->winx*sa->winy;
+ if(sa->winx > 10 && sa->winy > 10 && size > maxsize) {
+ maxsize= size;
+ big= sa;
+ }
+ }
+ }
+ return big;
+}
+
+
+typedef struct BakeRender {
+ Render *re;
+ Scene *scene;
+ struct Object *actob;
+ int tot, ready;
+
+ ReportList *reports;
+
+ short *stop;
+ short *do_update;
+
+ ListBase threads;
+
+ /* backup */
+ short prev_wo_amb_occ;
+ short prev_r_raytrace;
+
+ /* for redrawing */
+ ScrArea *sa;
+} BakeRender;
+
+/* use by exec and invoke */
+int test_bake_internal(bContext *C, ReportList *reports)
+{
+ Scene *scene= CTX_data_scene(C);
+
+ if(scene->r.renderer!=R_INTERN) {
+ BKE_report(reports, RPT_ERROR, "Bake only supported for Internal Renderer");
+ } else if((scene->r.bake_flag & R_BAKE_TO_ACTIVE) && CTX_data_active_object(C)==NULL) {
+ BKE_report(reports, RPT_ERROR, "No active object");
+ }
+ else if(scene->r.bake_mode==RE_BAKE_AO && scene->world==NULL) {
+ BKE_report(reports, RPT_ERROR, "No world set up");
+ }
+ else {
+ return 1;
+ }
+
+ return 0;
+}
+
+static void init_bake_internal(BakeRender *bkr, bContext *C)
+{
+ Scene *scene= CTX_data_scene(C);
+
+ bkr->sa= biggest_image_area(CTX_wm_screen(C)); /* can be NULL */
+ bkr->scene= scene;
+ bkr->actob= (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT : NULL;
+ bkr->re= RE_NewRender("_Bake View_");
+
+ if(scene->r.bake_mode==RE_BAKE_AO) {
+ /* If raytracing or AO is disabled, switch it on temporarily for baking. */
+ bkr->prev_wo_amb_occ = (scene->world->mode & WO_AMB_OCC) != 0;
+ scene->world->mode |= WO_AMB_OCC;
+ }
+ if(scene->r.bake_mode==RE_BAKE_AO || bkr->actob) {
+ bkr->prev_r_raytrace = (scene->r.mode & R_RAYTRACE) != 0;
+ scene->r.mode |= R_RAYTRACE;
+ }
+}
+
+static void finish_bake_internal(BakeRender *bkr)
+{
+ RE_Database_Free(bkr->re);
+
+ /* restore raytrace and AO */
+ if(bkr->scene->r.bake_mode==RE_BAKE_AO)
+ if(bkr->prev_wo_amb_occ == 0)
+ bkr->scene->world->mode &= ~WO_AMB_OCC;
+
+ if(bkr->scene->r.bake_mode==RE_BAKE_AO || bkr->actob)
+ if(bkr->prev_r_raytrace == 0)
+ bkr->scene->r.mode &= ~R_RAYTRACE;
+
+ if(bkr->tot) {
+ Image *ima;
+ /* force OpenGL reload and mipmap recalc */
+ for(ima= G.main->image.first; ima; ima= ima->id.next) {
+ if(ima->ok==IMA_OK_LOADED) {
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+ if(ibuf && (ibuf->userflags & IB_BITMAPDIRTY)) {
+ GPU_free_image(ima);
+ imb_freemipmapImBuf(ibuf);
+ }
+ }
+ }
+ }
+}
+
+static void *do_bake_render(void *bake_v)
+{
+ BakeRender *bkr= bake_v;
+
+ bkr->tot= RE_bake_shade_all_selected(bkr->re, bkr->scene->r.bake_mode, bkr->actob, NULL);
+ bkr->ready= 1;
+
+ return NULL;
+}
+
+static void bake_startjob(void *bkv, short *stop, short *do_update)
+{
+ BakeRender *bkr= bkv;
+ Scene *scene= bkr->scene;
+
+ bkr->stop= stop;
+ bkr->do_update= do_update;
+
+ RE_test_break_cb(bkr->re, NULL, thread_break);
+ G.afbreek= 0; /* blender_test_break uses this global */
+
+ RE_Database_Baking(bkr->re, scene, scene->r.bake_mode, bkr->actob);
+
+ /* baking itself is threaded, cannot use test_break in threads. we also update optional imagewindow */
+ bkr->tot= RE_bake_shade_all_selected(bkr->re, scene->r.bake_mode, bkr->actob, bkr->do_update);
+}
+
+static void bake_update(void *bkv)
+{
+ BakeRender *bkr= bkv;
+
+ if(bkr->sa && bkr->sa->spacetype==SPACE_IMAGE) { /* incase the user changed while baking */
+ SpaceImage *sima= bkr->sa->spacedata.first;
+ sima->image= RE_bake_shade_get_image();
+ }
+}
+
+static void bake_freejob(void *bkv)
+{
+ BakeRender *bkr= bkv;
+ BLI_end_threads(&bkr->threads);
+ finish_bake_internal(bkr);
+
+ if(bkr->tot==0) BKE_report(bkr->reports, RPT_ERROR, "No Images found to bake to");
+ MEM_freeN(bkr);
+}
+
+/* catch esc */
+static int objects_bake_render_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ /* no running blender, remove handler and pass through */
+ if(0==WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C)))
+ return OPERATOR_FINISHED|OPERATOR_PASS_THROUGH;
+
+ /* running render */
+ switch (event->type) {
+ case ESCKEY:
+ return OPERATOR_RUNNING_MODAL;
+ break;
+ }
+ return OPERATOR_PASS_THROUGH;
+}
+
+static int objects_bake_render_invoke(bContext *C, wmOperator *op, wmEvent *_event)
+{
+ Scene *scene= CTX_data_scene(C);
+
+ if(test_bake_internal(C, op->reports)==0) {
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ BakeRender *bkr= MEM_callocN(sizeof(BakeRender), "render bake");
+ wmJob *steve;
+
+ init_bake_internal(bkr, C);
+ bkr->reports= op->reports;
+
+ /* setup job */
+ steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY);
+ WM_jobs_customdata(steve, bkr, bake_freejob);
+ WM_jobs_timer(steve, 0.2, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */
+ WM_jobs_callbacks(steve, bake_startjob, NULL, bake_update);
+
+ G.afbreek= 0;
+
+ WM_jobs_start(CTX_wm_manager(C), steve);
+
+ WM_cursor_wait(0);
+ WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, scene);
+
+ /* add modal handler for ESC */
+ WM_event_add_modal_handler(C, op);
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+
+static int bake_image_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene= CTX_data_scene(C);
+
+
+ if(test_bake_internal(C, op->reports)==0) {
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ ListBase threads;
+ BakeRender bkr;
+
+ memset(&bkr, 0, sizeof(bkr));
+
+ init_bake_internal(&bkr, C);
+ bkr.reports= op->reports;
+
+ RE_test_break_cb(bkr.re, NULL, thread_break);
+ G.afbreek= 0; /* blender_test_break uses this global */
+
+ RE_Database_Baking(bkr.re, scene, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE)? OBACT: NULL);
+
+ /* baking itself is threaded, cannot use test_break in threads */
+ BLI_init_threads(&threads, do_bake_render, 1);
+ bkr.ready= 0;
+ BLI_insert_thread(&threads, &bkr);
+
+ while(bkr.ready==0) {
+ PIL_sleep_ms(50);
+ if(bkr.ready)
+ break;
+
+ /* used to redraw in 2.4x but this is just for exec in 2.5 */
+ if (!G.background)
+ blender_test_break();
+ }
+ BLI_end_threads(&threads);
+
+ if(bkr.tot==0) BKE_report(op->reports, RPT_ERROR, "No Images found to bake to");
+
+ finish_bake_internal(&bkr);
+ }
+
+ WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, scene);
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_bake_image(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Bake";
+ ot->description= "Bake image textures of selected objects.";
+ ot->idname= "OBJECT_OT_bake_image";
+
+ /* api callbacks */
+ ot->exec= bake_image_exec;
+ ot->invoke= objects_bake_render_invoke;
+ ot->modal= objects_bake_render_modal;
+}
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 790db0dc564..9ef1fafff82 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -1671,34 +1671,6 @@ void OBJECT_OT_shade_smooth(wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
-/* bake */
-
-static int bake_image_exec(bContext *C, wmOperator *op)
-{
- Scene *scene= CTX_data_scene(C);
- char *error_msg= NULL;
- objects_bake_render(scene, 0, &error_msg);
-
- if(error_msg) {
- BKE_report(op->reports, RPT_ERROR, error_msg);
- return OPERATOR_CANCELLED;
- }
- else {
- WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, scene);
- return OPERATOR_FINISHED;
- }
-}
-
-void OBJECT_OT_bake_image(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "Bake";
- ot->description= "Bake selected objects.";
- ot->idname= "OBJECT_OT_bake_image";
-
- /* api callbacks */
- ot->exec= bake_image_exec;
-}
/* ********************** */
diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c
index 1e5b93aa6dc..50fc5f5d2fe 100644
--- a/source/blender/editors/object/object_group.c
+++ b/source/blender/editors/object/object_group.c
@@ -287,8 +287,9 @@ void OBJECT_OT_group_add(wmOperatorType *ot)
PropertyRNA *prop;
/* identifiers */
- ot->name= "Add Group";
+ ot->name= "Add to Group";
ot->idname= "OBJECT_OT_group_add";
+ ot->description = "Add an object to an existing group, or create new.";
/* api callbacks */
ot->exec= group_add_exec;
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index c5bb61b4403..d47cecb762b 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -79,7 +79,6 @@ void OBJECT_OT_restrictview_clear(struct wmOperatorType *ot);
void OBJECT_OT_proxy_make(struct wmOperatorType *ot);
void OBJECT_OT_shade_smooth(struct wmOperatorType *ot);
void OBJECT_OT_shade_flat(struct wmOperatorType *ot);
-void OBJECT_OT_bake_image(struct wmOperatorType *ot);
/* object_select.c */
void OBJECT_OT_select_all(struct wmOperatorType *ot);
@@ -203,5 +202,8 @@ void OBJECT_OT_shape_key_move(struct wmOperatorType *ot);
void OBJECT_OT_group_add(struct wmOperatorType *ot);
void OBJECT_OT_group_remove(struct wmOperatorType *ot);
+/* object_bake.c */
+void OBJECT_OT_bake_image(wmOperatorType *ot);
+
#endif /* ED_OBJECT_INTERN_H */
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 3e9b1cfe7c7..a44ad47b94f 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -165,6 +165,7 @@ int ED_object_modifier_remove(ReportList *reports, Scene *scene, Object *ob, Mod
BLI_remlink(&ob->particlesystem, psmd->psys);
psys_free(ob, psmd->psys);
+ psmd->psys= NULL;
}
else if(md->type == eModifierType_Softbody) {
if(ob->soft) {
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 05eab6528fd..eb2086fe95d 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -81,7 +81,6 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_restrictview_set);
WM_operatortype_append(OBJECT_OT_shade_smooth);
WM_operatortype_append(OBJECT_OT_shade_flat);
- WM_operatortype_append(OBJECT_OT_bake_image);
WM_operatortype_append(OBJECT_OT_parent_set);
WM_operatortype_append(OBJECT_OT_parent_no_inverse_set);
@@ -197,6 +196,8 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_hook_assign);
WM_operatortype_append(OBJECT_OT_hook_reset);
WM_operatortype_append(OBJECT_OT_hook_recenter);
+
+ WM_operatortype_append(OBJECT_OT_bake_image);
}
void ED_operatormacros_object(void)
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index b8839360296..d4bf721e14e 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -1183,6 +1183,7 @@ enum {
MAKE_LINKS_MATERIALS,
MAKE_LINKS_ANIMDATA,
MAKE_LINKS_DUPLIGROUP,
+ MAKE_LINKS_MODIFIERS
};
static int make_links_data_exec(bContext *C, wmOperator *op)
@@ -1235,6 +1236,10 @@ static int make_links_data_exec(bContext *C, wmOperator *op)
obt->transflag |= OB_DUPLIGROUP;
}
break;
+ case MAKE_LINKS_MODIFIERS:
+ object_link_modifiers(obt, ob);
+ obt->recalc |= OB_RECALC;
+ break;
}
}
}
@@ -1274,6 +1279,7 @@ void OBJECT_OT_make_links_data(wmOperatorType *ot)
{MAKE_LINKS_MATERIALS, "MATERIAL", 0, "Materials", ""},
{MAKE_LINKS_ANIMDATA, "ANIMATION", 0, "Animation Data", ""},
{MAKE_LINKS_DUPLIGROUP, "DUPLIGROUP", 0, "DupliGroup", ""},
+ {MAKE_LINKS_MODIFIERS, "MODIFIERS", 0, "Modifiers", ""},
{0, NULL, 0, NULL, NULL}};
PropertyRNA *prop;
diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c
index 99b35b998c2..226c630f2e8 100644
--- a/source/blender/editors/object/object_shapekey.c
+++ b/source/blender/editors/object/object_shapekey.c
@@ -260,7 +260,7 @@ void OBJECT_OT_shape_key_add(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* properties */
- RNA_def_boolean(ot->srna, "from_mix", 0, "From Mix", "Create the new shape key from the existing mix of keys.");
+ RNA_def_boolean(ot->srna, "from_mix", 1, "From Mix", "Create the new shape key from the existing mix of keys.");
}
static int shape_key_remove_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index a16b0f2a7ac..43382562a8a 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -506,7 +506,6 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo
mul_m4_v3(mat, bezt->vec[1]);
mul_m4_v3(mat, bezt->vec[2]);
bezt->radius *= scale;
- bezt++;
}
}
else {
diff --git a/source/blender/editors/physics/Makefile b/source/blender/editors/physics/Makefile
index 63968fdd537..e9260b66087 100644
--- a/source/blender/editors/physics/Makefile
+++ b/source/blender/editors/physics/Makefile
@@ -53,4 +53,10 @@ CPPFLAGS += -I../../render/extern/include
# own include
-CPPFLAGS += -I../include
+CPPFLAGS += -I../include
+
+ifeq ($(OS), darwin)
+ ifeq ($(WITH_BF_OPENMP), true)
+ CPPFLAGS += -DPARALLEL=1
+ endif
+endif
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index eccb257dab5..8a73dc0e050 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -316,6 +316,14 @@ void PE_hide_keys_time(Scene *scene, PTCacheEdit *edit, float cfra)
}
}
+static int pe_x_mirror(Object *ob)
+{
+ if(ob->type == OB_MESH)
+ return (((Mesh*)ob->data)->editflag & ME_EDIT_MIRROR_X);
+
+ return 0;
+}
+
/****************** common struct passed to callbacks ******************/
typedef struct PEData {
@@ -580,25 +588,34 @@ static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected
unit_m4(mat);
LOOP_VISIBLE_POINTS {
- if(edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) {
- psys_mat_hair_to_global(data->ob, psmd->dm, psys->part->from, psys->particles + p, mat);
- invert_m4_m4(imat,mat);
- }
-
if(pset->selectmode==SCE_SELECT_END) {
/* only do end keys */
key= point->keys + point->totkey-1;
- if(selected==0 || key->flag & PEK_SELECT)
- if(key_inside_circle(data, data->rad, KEY_WCO, &data->dist))
+ if(selected==0 || key->flag & PEK_SELECT) {
+ if(key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) {
+ if(edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) {
+ psys_mat_hair_to_global(data->ob, psmd->dm, psys->part->from, psys->particles + p, mat);
+ invert_m4_m4(imat,mat);
+ }
+
func(data, mat, imat, p, point->totkey-1, key);
+ }
+ }
}
else {
/* do all keys */
LOOP_VISIBLE_KEYS {
- if(selected==0 || key->flag & PEK_SELECT)
- if(key_inside_circle(data, data->rad, KEY_WCO, &data->dist))
+ if(selected==0 || key->flag & PEK_SELECT) {
+ if(key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) {
+ if(edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) {
+ psys_mat_hair_to_global(data->ob, psmd->dm, psys->part->from, psys->particles + p, mat);
+ invert_m4_m4(imat,mat);
+ }
+
func(data, mat, imat, p, k, key);
+ }
+ }
}
}
}
@@ -1185,7 +1202,7 @@ void PE_update_object(Scene *scene, Object *ob, int useflag)
pe_iterate_lengths(scene, edit);
pe_deflect_emitter(scene, ob, edit);
PE_apply_lengths(scene, edit);
- if(pset->flag & PE_X_MIRROR)
+ if(pe_x_mirror(ob))
PE_apply_mirror(ob,edit->psys);
if(edit->psys)
update_world_cos(ob, edit);
@@ -1997,17 +2014,16 @@ static void rekey_particle_to_time(Scene *scene, Object *ob, int pa_index, float
/************************* utilities **************************/
-static int remove_tagged_particles(Scene *scene, Object *ob, ParticleSystem *psys)
+static int remove_tagged_particles(Scene *scene, Object *ob, ParticleSystem *psys, int mirror)
{
PTCacheEdit *edit = psys->edit;
- ParticleEditSettings *pset= PE_settings(scene);
ParticleData *pa, *npa=0, *new_pars=0;
POINT_P;
PTCacheEditPoint *npoint=0, *new_points=0;
ParticleSystemModifierData *psmd;
int i, totpart, new_totpart= psys->totpart, removed= 0;
- if(pset->flag & PE_X_MIRROR) {
+ if(mirror) {
/* mirror tags */
psmd= psys_get_modifier(ob, psys);
totpart= psys->totpart;
@@ -2071,14 +2087,13 @@ static int remove_tagged_particles(Scene *scene, Object *ob, ParticleSystem *psy
static void remove_tagged_keys(Scene *scene, Object *ob, ParticleSystem *psys)
{
PTCacheEdit *edit= psys->edit;
- ParticleEditSettings *pset= PE_settings(scene);
ParticleData *pa;
HairKey *hkey, *nhkey, *new_hkeys=0;
POINT_P; KEY_K;
ParticleSystemModifierData *psmd;
short new_totkey;
- if(pset->flag & PE_X_MIRROR) {
+ if(pe_x_mirror(ob)) {
/* mirror key tags */
psmd= psys_get_modifier(ob, psys);
@@ -2099,7 +2114,7 @@ static void remove_tagged_keys(Scene *scene, Object *ob, ParticleSystem *psys)
if(new_totkey < 2)
point->flag |= PEP_TAG;
}
- remove_tagged_particles(scene, ob, psys);
+ remove_tagged_particles(scene, ob, psys, pe_x_mirror(ob));
LOOP_POINTS {
pa = psys->particles + p;
@@ -2262,7 +2277,6 @@ static int remove_doubles_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
Object *ob= CTX_data_active_object(C);
- ParticleEditSettings *pset=PE_settings(scene);
PTCacheEdit *edit= PE_get_current(scene, ob);
ParticleSystem *psys = edit->psys;
ParticleSystemModifierData *psmd;
@@ -2270,7 +2284,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op)
KDTreeNearest nearest[10];
POINT_P;
float mat[4][4], co[3], threshold= RNA_float_get(op->ptr, "threshold");
- int n, totn, removed, flag, totremoved;
+ int n, totn, removed, totremoved;
if(psys->flag & PSYS_GLOBAL_HAIR)
return OPERATOR_CANCELLED;
@@ -2316,10 +2330,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op)
BLI_kdtree_free(tree);
/* remove tagged particles - don't do mirror here! */
- flag= pset->flag;
- pset->flag &= ~PE_X_MIRROR;
- remove_tagged_particles(scene, ob, psys);
- pset->flag= flag;
+ remove_tagged_particles(scene, ob, psys, 0);
totremoved += removed;
} while(removed);
@@ -2500,7 +2511,7 @@ static int delete_exec(bContext *C, wmOperator *op)
}
else if(type == DEL_PARTICLE) {
foreach_selected_point(&data, set_delete_particle);
- remove_tagged_particles(data.scene, data.ob, data.edit->psys);
+ remove_tagged_particles(data.scene, data.ob, data.edit->psys, pe_x_mirror(data.ob));
recalc_lengths(data.edit);
}
@@ -2603,9 +2614,11 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged)
newpa= psys->particles + totpart;
newpoint= edit->points + totpart;
- LOOP_VISIBLE_POINTS {
+ for(p=0, point=edit->points; p<totpart; p++, point++) {
pa = psys->particles + p;
+ if(point->flag & PEP_HIDE)
+ continue;
if(!(point->flag & PEP_TAG) || mirrorfaces[pa->num*2] == -1)
continue;
@@ -3097,7 +3110,7 @@ static int brush_add(PEData *data, short number)
initialize_particle(&sim, pa,i);
reset_particle(&sim, pa, 0.0, 1.0);
point->flag |= PEP_EDIT_RECALC;
- if(pset->flag & PE_X_MIRROR)
+ if(pe_x_mirror(ob))
point->flag |= PEP_TAG; /* signal for duplicate */
framestep= pa->lifetime/(float)(pset->totaddkey-1);
@@ -3304,7 +3317,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
else
foreach_point(&data, brush_cut);
- removed= remove_tagged_particles(scene, ob, edit->psys);
+ removed= remove_tagged_particles(scene, ob, edit->psys, pe_x_mirror(ob));
if(pset->flag & PE_KEEP_LENGTHS)
recalc_lengths(edit);
}
@@ -3403,7 +3416,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
recalc_lengths(edit);
if(ELEM(pset->brushtype, PE_BRUSH_ADD, PE_BRUSH_CUT) && (added || removed)) {
- if(pset->brushtype == PE_BRUSH_ADD && (pset->flag & PE_X_MIRROR))
+ if(pset->brushtype == PE_BRUSH_ADD && pe_x_mirror(ob))
PE_mirror_x(scene, ob, 1);
update_world_cos(ob,edit);
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 74e1cca5579..03fe772c09b 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -717,7 +717,7 @@ void BIF_view3d_previewrender(Scene *scene, ScrArea *sa)
rdata.layers.first= rdata.layers.last= NULL;
rdata.renderer= R_INTERN;
- RE_InitState(re, NULL, &rdata, sa->winx, sa->winy, &ri->disprect);
+ RE_InitState(re, NULL, &rdata, NULL, sa->winx, sa->winy, &ri->disprect);
if(orth)
RE_SetOrtho(re, &viewplane, clipsta, clipend);
@@ -923,7 +923,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
else sizex= sp->sizex;
/* allocates or re-uses render result */
- RE_InitState(re, NULL, &sce->r, sizex, sp->sizey, NULL);
+ RE_InitState(re, NULL, &sce->r, NULL, sizex, sp->sizey, NULL);
/* callbacs are cleared on GetRender() */
if(sp->pr_method==PR_BUTS_RENDER) {
diff --git a/source/blender/editors/screen/CMakeLists.txt b/source/blender/editors/screen/CMakeLists.txt
index ad7770e12fa..75811735d25 100644
--- a/source/blender/editors/screen/CMakeLists.txt
+++ b/source/blender/editors/screen/CMakeLists.txt
@@ -70,10 +70,9 @@ IF(WIN32)
SET(INC ${INC} ${PTHREADS_INC})
ENDIF(WIN32)
-# TODO buildinfo
-IF(BF_BUILDINFO)
+IF(WITH_BUILDINFO)
ADD_DEFINITIONS(-DNAN_BUILDINFO)
-ENDIF(BF_BUILDINFO)
+ENDIF(WITH_BUILDINFO)
BLENDERLIB_NOLIST(bf_editors "${SRC}" "${INC}")
diff --git a/source/blender/editors/screen/Makefile b/source/blender/editors/screen/Makefile
index 87ba3337caa..23c9d130eec 100644
--- a/source/blender/editors/screen/Makefile
+++ b/source/blender/editors/screen/Makefile
@@ -60,3 +60,8 @@ ifeq ($(WITH_OPENEXR), true)
CPPFLAGS += -DWITH_OPENEXR
endif
+ifeq ($(OS), darwin)
+ ifeq ($(WITH_BF_OPENMP), true)
+ CPPFLAGS += -DPARALLEL=1
+ endif
+endif
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index d9d76e963a3..c494afac79e 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -1107,10 +1107,10 @@ void ED_area_prevspace(bContext *C, ScrArea *sa)
ED_area_tag_redraw(sa);
}
-static char *windowtype_pup(void)
+static char *editortype_pup(void)
{
return(
- "Window type:%t"
+ "Editor type:%t"
"|3D View %x1"
"|%l"
@@ -1160,9 +1160,9 @@ int ED_area_header_switchbutton(const bContext *C, uiBlock *block, int yco)
int xco= 8;
but= uiDefIconTextButC(block, ICONTEXTROW, 0, ICON_VIEW3D,
- windowtype_pup(), xco, yco, XIC+10, YIC,
+ editortype_pup(), xco, yco, XIC+10, YIC,
&(sa->butspacetype), 1.0, SPACEICONMAX, 0, 0,
- "Displays Current Window Type. "
+ "Displays Current Editor Type. "
"Click for menu of available types.");
uiButSetFunc(but, spacefunc, NULL, NULL);
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 9db9247287c..a0df3a2360e 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -26,6 +26,7 @@
#include <math.h>
#include <string.h>
+#include <stddef.h>
#include <GL/glew.h>
@@ -2262,9 +2263,9 @@ static int header_toolbox_invoke(bContext *C, wmOperator *op, wmEvent *event)
/* file browser should be fullscreen all the time, but other regions can be maximised/restored... */
if (sa->spacetype != SPACE_FILE) {
if (sa->full)
- uiItemO(layout, "Tile Window", 0, "SCREEN_OT_screen_full_area");
+ uiItemO(layout, "Tile Area", 0, "SCREEN_OT_screen_full_area");
else
- uiItemO(layout, "Maximize Window", 0, "SCREEN_OT_screen_full_area");
+ uiItemO(layout, "Maximize Area", 0, "SCREEN_OT_screen_full_area");
}
uiPupMenuEnd(C, pup);
@@ -2815,7 +2816,7 @@ static int screen_render_exec(bContext *C, wmOperator *op)
if(RNA_boolean_get(op->ptr, "animation"))
RE_BlenderAnim(re, scene, scene->r.sfra, scene->r.efra, scene->r.frame_step, op->reports);
else
- RE_BlenderFrame(re, scene, scene->r.cfra);
+ RE_BlenderFrame(re, scene, NULL, scene->r.cfra);
// no redraw needed, we leave state as we entered it
ED_update_for_newframe(C, 1);
@@ -2829,6 +2830,7 @@ typedef struct RenderJob {
Scene *scene;
Render *re;
wmWindow *win;
+ SceneRenderLayer *srl;
int anim;
Image *image;
ImageUser iuser;
@@ -3041,7 +3043,7 @@ static void render_startjob(void *rjv, short *stop, short *do_update)
if(rj->anim)
RE_BlenderAnim(rj->re, rj->scene, rj->scene->r.sfra, rj->scene->r.efra, rj->scene->r.frame_step, rj->reports);
else
- RE_BlenderFrame(rj->re, rj->scene, rj->scene->r.cfra);
+ RE_BlenderFrame(rj->re, rj->scene, rj->srl, rj->scene->r.cfra);
}
/* called by render, check job 'stop' value or the global */
@@ -3077,6 +3079,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
/* new render clears all callbacks */
Scene *scene= CTX_data_scene(C);
+ SceneRenderLayer *srl=NULL;
Render *re;
wmJob *steve;
RenderJob *rj;
@@ -3108,10 +3111,29 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
/* ensure at least 1 area shows result */
screen_set_image_output(C, event->x, event->y);
+ /* single layer re-render */
+ if(RNA_property_is_set(op->ptr, "layer")) {
+ SceneRenderLayer *rl;
+ Scene *scn;
+ char scene_name[19], rl_name[RE_MAXNAME];
+
+ RNA_string_get(op->ptr, "layer", rl_name);
+ RNA_string_get(op->ptr, "scene", scene_name);
+
+ scn = (Scene *)BLI_findstring(&CTX_data_main(C)->scene, scene_name, offsetof(ID, name) + 2);
+ rl = (SceneRenderLayer *)BLI_findstring(&scene->r.layers, rl_name, offsetof(SceneRenderLayer, name));
+
+ if (scn && rl) {
+ scene = scn;
+ srl = rl;
+ }
+ }
+
/* job custom data */
rj= MEM_callocN(sizeof(RenderJob), "render job");
rj->scene= scene;
rj->win= CTX_wm_window(C);
+ rj->srl = srl;
rj->anim= RNA_boolean_get(op->ptr, "animation");
rj->iuser.scene= scene;
rj->iuser.ok= 1;
@@ -3173,6 +3195,8 @@ static void SCREEN_OT_render(wmOperatorType *ot)
ot->poll= ED_operator_screenactive;
RNA_def_boolean(ot->srna, "animation", 0, "Animation", "");
+ RNA_def_string(ot->srna, "layer", "", RE_MAXNAME, "Render Layer", "Single render layer to re-render");
+ RNA_def_string(ot->srna, "scene", "", 19, "Scene", "Re-render single layer in this scene");
}
/* ****************************** opengl render *************************** */
@@ -3295,7 +3319,7 @@ static int screen_opengl_render_init(bContext *C, wmOperator *op)
/* create render and render result */
oglrender->re= RE_NewRender(scene->id.name);
- RE_InitState(oglrender->re, NULL, &scene->r, sizex, sizey, NULL);
+ RE_InitState(oglrender->re, NULL, &scene->r, NULL, sizex, sizey, NULL);
rr= RE_AcquireResultWrite(oglrender->re);
if(rr->rectf==NULL)
@@ -3395,7 +3419,7 @@ static int screen_opengl_render_modal(bContext *C, wmOperator *op, wmEvent *even
printf("Append frame %d", scene->r.cfra);
}
else {
- BKE_makepicstring(scene, name, scene->r.pic, scene->r.cfra, scene->r.imtype);
+ BKE_makepicstring(name, scene->r.pic, scene->r.cfra, scene->r.imtype, scene->r.scemode & R_EXTENSION);
ok= BKE_write_ibuf(scene, ibuf, name, scene->r.imtype, scene->r.subimtype, scene->r.quality);
if(ok==0) printf("write error: cannot save %s\n", name);
@@ -3941,6 +3965,9 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", LEFTARROWKEY, KM_PRESS, 0, 0)->ptr, "delta", -1);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", RIGHTARROWKEY, KM_PRESS, 0, 0)->ptr, "delta", 1);
+ RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", WHEELDOWNMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "delta", 1);
+ RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", WHEELUPMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "delta", -1);
+
WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", DOWNARROWKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", RIGHTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "end", 1);
RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", LEFTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "end", 0);
diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c
index 088be194fe8..7fea28304ba 100644
--- a/source/blender/editors/screen/screendump.c
+++ b/source/blender/editors/screen/screendump.c
@@ -84,7 +84,7 @@ static int screenshot_exec(bContext *C, wmOperator *op)
/* BKE_add_image_extension() checks for if extension was already set */
if(scene->r.scemode & R_EXTENSION)
if(strlen(path)<FILE_MAXDIR+FILE_MAXFILE-5)
- BKE_add_image_extension(scene, path, scene->r.imtype);
+ BKE_add_image_extension(path, scene->r.imtype);
ibuf= IMB_allocImBuf(scd->dumpsx, scd->dumpsy, 24, 0, 0);
ibuf->rect= scd->dumprect;
@@ -258,7 +258,7 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update)
char name[FILE_MAXDIR+FILE_MAXFILE];
int ok;
- BKE_makepicstring(sj->scene, name, rd.pic, cfra, rd.imtype);
+ BKE_makepicstring(name, rd.pic, cfra, rd.imtype, rd.scemode & R_EXTENSION);
ibuf->rect= sj->dumprect;
ok= BKE_write_ibuf(sj->scene, ibuf, name, rd.imtype, rd.subimtype, rd.quality);
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 526eb2d6661..77e90e3c7b1 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -1001,8 +1001,7 @@ static void uv_image_outset(float (*orig_uv)[2], float (*outset_uv)[2], const fl
float puv[4][2]; /* pixelspace uv's */
float no1[2], no2[2], no3[2], no4[2]; /* normals */
float dir1[2], dir2[2], dir3[2], dir4[2];
- float ibuf_x_inv = 1.0f / (float)ibuf_x;
- float ibuf_y_inv = 1.0f / (float)ibuf_y;
+ float ibuf_inv[2] = {1.0f / (float)ibuf_x, 1.0f / (float)ibuf_y};
/* make UV's in pixel space so we can */
puv[0][0] = orig_uv[0][0] * ibuf_x;
@@ -1035,17 +1034,20 @@ static void uv_image_outset(float (*orig_uv)[2], float (*outset_uv)[2], const fl
sub_v2_v2v2(dir3, puv[0], puv[2]);
normalize_v2(dir3);
}
-
+
+ /* TODO - angle_normalized_v2v2(...) * (M_PI/180.0f)
+ * This is incorrect. Its already given radians but without it wont work.
+ * need to look into a fix - campbell */
if (is_quad) {
- a1 = shell_angle_to_dist(angle_normalized_v2v2(dir4, dir1));
- a2 = shell_angle_to_dist(angle_normalized_v2v2(dir1, dir2));
- a3 = shell_angle_to_dist(angle_normalized_v2v2(dir2, dir3));
- a4 = shell_angle_to_dist(angle_normalized_v2v2(dir3, dir4));
+ a1 = shell_angle_to_dist(angle_normalized_v2v2(dir4, dir1) * (M_PI/180.0f));
+ a2 = shell_angle_to_dist(angle_normalized_v2v2(dir1, dir2) * (M_PI/180.0f));
+ a3 = shell_angle_to_dist(angle_normalized_v2v2(dir2, dir3) * (M_PI/180.0f));
+ a4 = shell_angle_to_dist(angle_normalized_v2v2(dir3, dir4) * (M_PI/180.0f));
}
else {
- a1 = shell_angle_to_dist(angle_normalized_v2v2(dir3, dir1));
- a2 = shell_angle_to_dist(angle_normalized_v2v2(dir1, dir2));
- a3 = shell_angle_to_dist(angle_normalized_v2v2(dir2, dir3));
+ a1 = shell_angle_to_dist(angle_normalized_v2v2(dir3, dir1) * (M_PI/180.0f));
+ a2 = shell_angle_to_dist(angle_normalized_v2v2(dir1, dir2) * (M_PI/180.0f));
+ a3 = shell_angle_to_dist(angle_normalized_v2v2(dir2, dir3) * (M_PI/180.0f));
}
if (is_quad) {
@@ -1065,17 +1067,10 @@ static void uv_image_outset(float (*orig_uv)[2], float (*outset_uv)[2], const fl
add_v2_v2v2(outset_uv[1], puv[1], no2);
add_v2_v2v2(outset_uv[2], puv[2], no3);
add_v2_v2v2(outset_uv[3], puv[3], no4);
- outset_uv[0][0] *= ibuf_x_inv;
- outset_uv[0][1] *= ibuf_y_inv;
-
- outset_uv[1][0] *= ibuf_x_inv;
- outset_uv[1][1] *= ibuf_y_inv;
-
- outset_uv[2][0] *= ibuf_x_inv;
- outset_uv[2][1] *= ibuf_y_inv;
-
- outset_uv[3][0] *= ibuf_x_inv;
- outset_uv[3][1] *= ibuf_y_inv;
+ mul_v2_v2(outset_uv[0], ibuf_inv);
+ mul_v2_v2(outset_uv[1], ibuf_inv);
+ mul_v2_v2(outset_uv[2], ibuf_inv);
+ mul_v2_v2(outset_uv[3], ibuf_inv);
}
else {
sub_v2_v2v2(no1, dir3, dir1);
@@ -1090,14 +1085,10 @@ static void uv_image_outset(float (*orig_uv)[2], float (*outset_uv)[2], const fl
add_v2_v2v2(outset_uv[0], puv[0], no1);
add_v2_v2v2(outset_uv[1], puv[1], no2);
add_v2_v2v2(outset_uv[2], puv[2], no3);
- outset_uv[0][0] *= ibuf_x_inv;
- outset_uv[0][1] *= ibuf_y_inv;
-
- outset_uv[1][0] *= ibuf_x_inv;
- outset_uv[1][1] *= ibuf_y_inv;
-
- outset_uv[2][0] *= ibuf_x_inv;
- outset_uv[2][1] *= ibuf_y_inv;
+
+ mul_v2_v2(outset_uv[0], ibuf_inv);
+ mul_v2_v2(outset_uv[1], ibuf_inv);
+ mul_v2_v2(outset_uv[2], ibuf_inv);
}
}
@@ -2890,7 +2881,7 @@ static void project_paint_begin(ProjPaintState *ps)
ps->is_airbrush = (ps->brush->flag & BRUSH_AIRBRUSH) ? 1 : 0;
- ps->is_texbrush = (ps->brush->mtex[ps->brush->texact] && ps->brush->mtex[ps->brush->texact]->tex) ? 1 : 0;
+ ps->is_texbrush = (ps->brush->mtex.tex) ? 1 : 0;
/* calculate vert screen coords
@@ -4090,10 +4081,17 @@ static int imapaint_canvas_set(ImagePaintState *s, Image *ima)
s->clonecanvas= ibuf;
+ /* temporarily add float rect for cloning */
if(s->canvas->rect_float && !s->clonecanvas->rect_float) {
- /* temporarily add float rect for cloning */
+ int profile = IB_PROFILE_NONE;
+
+ /* Don't want to color manage, but don't disturb existing profiles */
+ SWAP(int, s->clonecanvas->profile, profile);
+
IMB_float_from_rect(s->clonecanvas);
s->clonefreefloat= 1;
+
+ SWAP(int, s->clonecanvas->profile, profile);
}
else if(!s->canvas->rect_float && !s->clonecanvas->rect)
IMB_rect_from_float(s->clonecanvas);
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index 108be50267d..6bb5f432b0d 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -52,6 +52,8 @@ typedef void (*StrokeDone)(struct bContext *C, struct PaintStroke *stroke);
struct PaintStroke *paint_stroke_new(struct bContext *C,
StrokeGetLocation get_location, StrokeTestStart test_start,
StrokeUpdateStep update_step, StrokeDone done);
+void paint_stroke_free(struct PaintStroke *stroke);
+
int paint_stroke_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
int paint_stroke_exec(struct bContext *C, struct wmOperator *op);
struct ViewContext *paint_stroke_view_context(struct PaintStroke *stroke);
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index 57b56da2fcd..715a41e6431 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -176,6 +176,21 @@ static void ed_keymap_paint_brush_switch(wmKeyMap *keymap, const char *path)
RNA_int_set(kmi->ptr, "value", 9);
}
+static void ed_keymap_paint_brush_size(wmKeyMap *keymap, const char *path)
+{
+ wmKeyMapItem *kmi;
+
+ kmi= WM_keymap_add_item(keymap, "WM_OT_context_set_int", LEFTBRACKETKEY, KM_PRESS, 0, 0);
+ RNA_string_set(kmi->ptr, "path", path);
+ RNA_int_set(kmi->ptr, "value", -20);
+ RNA_boolean_set(kmi->ptr, "relative", 1);
+
+ kmi= WM_keymap_add_item(keymap, "WM_OT_context_set_int", RIGHTBRACKETKEY, KM_PRESS, 0, 0);
+ RNA_string_set(kmi->ptr, "path", path);
+ RNA_int_set(kmi->ptr, "value", 20);
+ RNA_boolean_set(kmi->ptr, "relative", 1);
+}
+
void ED_keymap_paint(wmKeyConfig *keyconf)
{
wmKeyMap *keymap;
@@ -205,8 +220,8 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
RNA_int_set(kmi->ptr, "level", -1);
RNA_boolean_set(kmi->ptr, "relative", 1);
- /* toggles */
ed_keymap_paint_brush_switch(keymap, "tool_settings.sculpt.active_brush_index");
+ ed_keymap_paint_brush_size(keymap, "tool_settings.sculpt.brush.size");
kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", AKEY, KM_PRESS, 0, 0);
RNA_string_set(kmi->ptr, "path", "tool_settings.sculpt.brush.use_anchor");
@@ -259,6 +274,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
"PAINT_OT_vertex_color_set",KKEY, KM_PRESS, KM_SHIFT, 0);
ed_keymap_paint_brush_switch(keymap, "tool_settings.vertex_paint.active_brush_index");
+ ed_keymap_paint_brush_size(keymap, "tool_settings.vertex_paint.brush.size");
/* Weight Paint mode */
keymap= WM_keymap_find(keyconf, "Weight Paint", 0, 0);
@@ -273,6 +289,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
"PAINT_OT_weight_set", KKEY, KM_PRESS, KM_SHIFT, 0);
ed_keymap_paint_brush_switch(keymap, "tool_settings.weight_paint.active_brush_index");
+ ed_keymap_paint_brush_size(keymap, "tool_settings.weight_paint.brush.size");
/* Image/Texture Paint mode */
keymap= WM_keymap_find(keyconf, "Image Paint", 0, 0);
@@ -286,6 +303,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "PAINT_OT_clone_cursor_set", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
ed_keymap_paint_brush_switch(keymap, "tool_settings.image_paint.active_brush_index");
+ ed_keymap_paint_brush_size(keymap, "tool_settings.image_paint.brush.size");
/* face-mask mode */
keymap= WM_keymap_find(keyconf, "Face Mask", 0, 0);
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index e26b1945e7f..89c5443bf99 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -237,6 +237,11 @@ PaintStroke *paint_stroke_new(bContext *C,
return stroke;
}
+void paint_stroke_free(PaintStroke *stroke)
+{
+ MEM_freeN(stroke);
+}
+
int paint_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
{
PaintStroke *stroke = op->customdata;
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index b968930128a..606fae3d8bb 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -16,6 +16,7 @@
#include "BLI_math.h"
#include "BKE_brush.h"
+#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
@@ -214,9 +215,9 @@ static int brush_curve_preset_poll(bContext *C)
void BRUSH_OT_curve_preset(wmOperatorType *ot)
{
static EnumPropertyItem prop_shape_items[] = {
- {BRUSH_PRESET_SHARP, "SHARP", 0, "Sharp", ""},
- {BRUSH_PRESET_SMOOTH, "SMOOTH", 0, "Smooth", ""},
- {BRUSH_PRESET_MAX, "MAX", 0, "Max", ""},
+ {CURVE_PRESET_SHARP, "SHARP", 0, "Sharp", ""},
+ {CURVE_PRESET_SMOOTH, "SMOOTH", 0, "Smooth", ""},
+ {CURVE_PRESET_MAX, "MAX", 0, "Max", ""},
{0, NULL, 0, NULL, NULL}};
ot->name= "Preset";
@@ -228,7 +229,7 @@ void BRUSH_OT_curve_preset(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
- RNA_def_enum(ot->srna, "shape", prop_shape_items, BRUSH_PRESET_SHARP, "Mode", "");
+ RNA_def_enum(ot->srna, "shape", prop_shape_items, CURVE_PRESET_SMOOTH, "Mode", "");
}
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 09b99f4f43c..6671fec783e 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -614,12 +614,9 @@ static float get_texcache_pixel_bilinear(const SculptSession *ss, float u, float
/* Return a multiplier for brush strength on a particular vertex. */
static float tex_strength(SculptSession *ss, Brush *br, float *point, const float len)
{
- MTex *tex = NULL;
+ MTex *tex = &br->mtex;
float avg= 1;
- if(br->texact >= 0)
- tex = br->mtex[br->texact];
-
if(!tex) {
avg= 1;
}
@@ -917,6 +914,8 @@ static void do_mesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node)
if(sculpt_brush_test(&test, vd.co)) {
float fade = tex_strength(ss, brush, vd.co, test.dist)*bstrength;
float avg[3], val[3];
+
+ CLAMP(fade, 0.0f, 1.0f);
neighbor_average(ss, avg, vd.vert_indices[vd.i]);
val[0] = vd.co[0]+(avg[0]-vd.co[0])*fade;
@@ -993,6 +992,8 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no
if(y == 0 || y == gridsize - 1)
mul_v3_fl(avg, 2.0f);
+ CLAMP(fade, 0.0f, 1.0f);
+
val[0] = co[0]+(avg[0]-co[0])*fade;
val[1] = co[1]+(avg[1]-co[1])*fade;
val[2] = co[2]+(avg[2]-co[2])*fade;
@@ -1016,15 +1017,15 @@ static void do_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int
for(n=0; n<totnode; n++) {
sculpt_undo_push_node(ss, nodes[n]);
- if(ss->fmap)
- do_mesh_smooth_brush(sd, ss, nodes[n]);
- else
+ if(ss->multires)
do_multires_smooth_brush(sd, ss, nodes[n]);
+ else if(ss->fmap)
+ do_mesh_smooth_brush(sd, ss, nodes[n]);
BLI_pbvh_node_mark_update(nodes[n]);
}
- if(!ss->fmap)
+ if(ss->multires)
multires_stitch_grids(ss->ob);
}
}
@@ -1547,7 +1548,7 @@ void sculpt_update_mesh_elements(Scene *scene, Object *ob, int need_fmap)
}
ss->tree = dm->getPBVH(ob, dm);
- ss->fmap = (need_fmap && dm->getFaceMap)? dm->getFaceMap(dm): NULL;
+ ss->fmap = (need_fmap && dm->getFaceMap)? dm->getFaceMap(ob, dm): NULL;
}
static int sculpt_mode_poll(bContext *C)
@@ -1746,7 +1747,7 @@ static void sculpt_update_cache_variants(Sculpt *sd, SculptSession *ss, struct P
if(cache->first_time)
cache->initial_radius = unproject_brush_radius(ss->ob, cache->vc, cache->true_location, brush->size);
- if(brush->flag & BRUSH_SIZE_PRESSURE) {
+ if(brush->flag & BRUSH_SIZE_PRESSURE && brush->sculpt_tool != SCULPT_TOOL_GRAB) {
cache->pixel_radius *= cache->pressure;
cache->radius = cache->initial_radius * cache->pressure;
}
@@ -1800,8 +1801,12 @@ static void sculpt_update_cache_variants(Sculpt *sd, SculptSession *ss, struct P
static void sculpt_stroke_modifiers_check(bContext *C, SculptSession *ss)
{
- if(sculpt_modifiers_active(ss->ob))
- sculpt_update_mesh_elements(CTX_data_scene(C), ss->ob, 0); // XXX brush->sculpt_tool == SCULPT_TOOL_SMOOTH);
+ if(sculpt_modifiers_active(ss->ob)) {
+ Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+ Brush *brush = paint_brush(&sd->paint);
+
+ sculpt_update_mesh_elements(CTX_data_scene(C), ss->ob, brush->sculpt_tool == SCULPT_TOOL_SMOOTH);
+ }
}
typedef struct {
@@ -1836,7 +1841,7 @@ int sculpt_stroke_get_location(bContext *C, struct PaintStroke *stroke, float ou
ViewContext *vc = paint_stroke_view_context(stroke);
SculptSession *ss= vc->obact->sculpt;
StrokeCache *cache= ss->cache;
- float ray_start[3], ray_normal[3];
+ float ray_start[3], ray_end[3], ray_normal[3], dist;
float obimat[4][4];
float mval[2] = {mouse[0] - vc->ar->winrct.xmin,
mouse[1] - vc->ar->winrct.ymin};
@@ -1844,7 +1849,9 @@ int sculpt_stroke_get_location(bContext *C, struct PaintStroke *stroke, float ou
sculpt_stroke_modifiers_check(C, ss);
- viewray(vc->ar, vc->v3d, mval, ray_start, ray_normal);
+ viewline(vc->ar, vc->v3d, mval, ray_start, ray_end);
+ sub_v3_v3v3(ray_normal, ray_end, ray_start);
+ dist= normalize_v3(ray_normal);
invert_m4_m4(obimat, ss->ob->obmat);
mul_m4_v3(obimat, ray_start);
@@ -1854,7 +1861,7 @@ int sculpt_stroke_get_location(bContext *C, struct PaintStroke *stroke, float ou
srd.ss = vc->obact->sculpt;
srd.ray_start = ray_start;
srd.ray_normal = ray_normal;
- srd.dist = FLT_MAX;
+ srd.dist = dist;
srd.hit = 0;
srd.original = (cache)? cache->original: 0;
BLI_pbvh_raycast(ss->tree, sculpt_raycast_cb, &srd,
@@ -2003,15 +2010,20 @@ static void sculpt_flush_update(bContext *C)
}
}
-static int sculpt_stroke_test_start(bContext *C, struct wmOperator *op, wmEvent *event)
+/* Returns whether the mouse/stylus is over the mesh (1)
+ or over the background (0) */
+static int over_mesh(bContext *C, struct wmOperator *op, float x, float y)
{
- float mouse[2] = {event->x, event->y}, location[3];
- int over_mesh;
-
- over_mesh = sculpt_stroke_get_location(C, op->customdata, location, mouse);
+ float mouse[2] = {x, y}, co[3];
+ return (int)sculpt_stroke_get_location(C, op->customdata, co, mouse);
+}
+
+static int sculpt_stroke_test_start(bContext *C, struct wmOperator *op,
+ wmEvent *event)
+{
/* Don't start the stroke until mouse goes over the mesh */
- if(over_mesh) {
+ if(over_mesh(C, op, event->x, event->y)) {
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
@@ -2069,14 +2081,27 @@ static void sculpt_stroke_done(bContext *C, struct PaintStroke *stroke)
static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
+ struct PaintStroke *stroke;
+ int ignore_background_click;
+
if(!sculpt_brush_stroke_init(C, op->reports))
return OPERATOR_CANCELLED;
- op->customdata = paint_stroke_new(C, sculpt_stroke_get_location,
- sculpt_stroke_test_start,
- sculpt_stroke_update_step,
- sculpt_stroke_done);
+ stroke = paint_stroke_new(C, sculpt_stroke_get_location,
+ sculpt_stroke_test_start,
+ sculpt_stroke_update_step,
+ sculpt_stroke_done);
+ op->customdata = stroke;
+
+ /* For tablet rotation */
+ ignore_background_click = RNA_boolean_get(op->ptr,
+ "ignore_background_click");
+ if(ignore_background_click && !over_mesh(C, op, event->x, event->y)) {
+ paint_stroke_free(stroke);
+ return OPERATOR_PASS_THROUGH;
+ }
+
/* add modal handler */
WM_event_add_modal_handler(C, op);
@@ -2137,6 +2162,10 @@ static void SCULPT_OT_brush_stroke(wmOperatorType *ot)
/* The initial 2D location of the mouse */
RNA_def_float_vector(ot->srna, "initial_mouse", 2, NULL, INT_MIN, INT_MAX, "initial_mouse", "", INT_MIN, INT_MAX);
+
+ RNA_def_boolean(ot->srna, "ignore_background_click", 0,
+ "Ignore Background Click",
+ "Clicks on the background don't start the stroke");
}
/**** Reset the copy of the mesh that is being sculpted on (currently just for the layer brush) ****/
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index 3b42fc7b382..d48a322f562 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -81,7 +81,7 @@ static int open_exec(bContext *C, wmOperator *op)
info = AUD_getInfo(sound->handle);
- if (info.specs.format == AUD_FORMAT_INVALID) {
+ if (info.specs.channels == AUD_CHANNELS_INVALID) {
sound_delete(C, sound);
BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
return OPERATOR_CANCELLED;
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index e7b1dcb677d..687e7c53644 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -497,11 +497,11 @@ static int actkeys_insertkey_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void ACT_OT_keyframe_insert (wmOperatorType *ot)
+void ACTION_OT_keyframe_insert (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Insert Keyframes";
- ot->idname= "ACT_OT_keyframe_insert";
+ ot->idname= "ACTION_OT_keyframe_insert";
ot->description= "Insert keyframes for the specified channels.";
/* api callbacks */
diff --git a/source/blender/editors/space_action/action_intern.h b/source/blender/editors/space_action/action_intern.h
index e45b2d05fac..166004a5742 100644
--- a/source/blender/editors/space_action/action_intern.h
+++ b/source/blender/editors/space_action/action_intern.h
@@ -83,7 +83,7 @@ void ACTION_OT_view_all(struct wmOperatorType *ot);
void ACTION_OT_copy(struct wmOperatorType *ot);
void ACTION_OT_paste(struct wmOperatorType *ot);
-void ACT_OT_keyframe_insert(struct wmOperatorType *ot);
+void ACTION_OT_keyframe_insert(struct wmOperatorType *ot);
void ACTION_OT_duplicate(struct wmOperatorType *ot);
void ACTION_OT_delete(struct wmOperatorType *ot);
void ACTION_OT_clean(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c
index f02974c2ea4..7792247fe81 100644
--- a/source/blender/editors/space_action/action_ops.c
+++ b/source/blender/editors/space_action/action_ops.c
@@ -80,7 +80,7 @@ void action_operatortypes(void)
WM_operatortype_append(ACTION_OT_clean);
WM_operatortype_append(ACTION_OT_delete);
WM_operatortype_append(ACTION_OT_duplicate);
- WM_operatortype_append(ACT_OT_keyframe_insert);
+ WM_operatortype_append(ACTION_OT_keyframe_insert);
WM_operatortype_append(ACTION_OT_copy);
WM_operatortype_append(ACTION_OT_paste);
WM_operatortype_append(ACTION_OT_new);
@@ -145,7 +145,7 @@ static void action_keymap_keyframes (wmKeyConfig *keyconf, wmKeyMap *keymap)
WM_keymap_add_item(keymap, "ACTION_OT_delete", DELKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "ACTION_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_add_item(keymap, "ACT_OT_keyframe_insert", IKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "ACTION_OT_keyframe_insert", IKEY, KM_PRESS, 0, 0);
/* copy/paste */
WM_keymap_add_item(keymap, "ACTION_OT_copy", CKEY, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index 18ba149d7ed..c4bdd3a6c5b 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -626,7 +626,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
Brush *br= ptr->data;
if(br)
- CTX_data_pointer_set(result, &br->id, &RNA_BrushTextureSlot, br->mtex[(int)br->texact]);
+ CTX_data_pointer_set(result, &br->id, &RNA_BrushTextureSlot, &br->mtex);
}
return 1;
diff --git a/source/blender/editors/space_buttons/buttons_header.c b/source/blender/editors/space_buttons/buttons_header.c
index 0fb7ea9283c..c9df1f76dd9 100644
--- a/source/blender/editors/space_buttons/buttons_header.c
+++ b/source/blender/editors/space_buttons/buttons_header.c
@@ -67,7 +67,7 @@ static void do_buttons_buttons(bContext *C, void *arg, int event)
{
SpaceButs *sbuts= CTX_wm_space_buts(C);
- if(!sbuts) /* window type switch */
+ if(!sbuts) /* editor type switch */
return;
switch(event) {
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index 7e51ee2a5e9..8d35e6ed69e 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -322,6 +322,7 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn)
switch(wmn->data) {
case ND_SHADING:
case ND_SHADING_DRAW:
+ case ND_NODES:
/* currently works by redraws... if preview is set, it (re)starts job */
sbuts->preview= 1;
break;
@@ -335,6 +336,10 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn)
buttons_area_redraw(sa, BCONTEXT_DATA);
sbuts->preview= 1;
break;
+ case NC_BRUSH:
+ buttons_area_redraw(sa, BCONTEXT_TEXTURE);
+ sbuts->preview= 1;
+ break;
case NC_TEXTURE:
ED_area_tag_redraw(sa);
sbuts->preview= 1;
@@ -347,6 +352,12 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn)
if(wmn->action == NA_RENAME)
ED_area_tag_redraw(sa);
break;
+ case NC_ANIMATION:
+ switch(wmn->data) {
+ case ND_KEYFRAME_EDIT:
+ ED_area_tag_redraw(sa);
+ break;
+ }
}
if(wmn->data == ND_KEYS)
diff --git a/source/blender/editors/space_console/console_intern.h b/source/blender/editors/space_console/console_intern.h
index 92ab3eb3d0c..a90e434246f 100644
--- a/source/blender/editors/space_console/console_intern.h
+++ b/source/blender/editors/space_console/console_intern.h
@@ -63,7 +63,6 @@ void CONSOLE_OT_clear(struct wmOperatorType *ot);
void CONSOLE_OT_history_cycle(struct wmOperatorType *ot);
void CONSOLE_OT_copy(struct wmOperatorType *ot);
void CONSOLE_OT_paste(struct wmOperatorType *ot);
-void CONSOLE_OT_zoom(struct wmOperatorType *ot);
void CONSOLE_OT_select_set(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c
index e615ae8f140..76e1231b0d4 100644
--- a/source/blender/editors/space_console/console_ops.c
+++ b/source/blender/editors/space_console/console_ops.c
@@ -750,38 +750,6 @@ void CONSOLE_OT_paste(wmOperatorType *ot)
/* properties */
}
-static int zoom_exec(bContext *C, wmOperator *op)
-{
- SpaceConsole *sc= CTX_wm_space_console(C);
-
- int delta= RNA_int_get(op->ptr, "delta");
-
- sc->lheight += delta;
- CLAMP(sc->lheight, 8, 32);
-
- ED_area_tag_redraw(CTX_wm_area(C));
-
- return OPERATOR_FINISHED;
-}
-
-
-void CONSOLE_OT_zoom(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "Console Zoom";
- /*optionals -
- "Zoom view font." */
- ot->description= "Zoom screen area.";
- ot->idname= "CONSOLE_OT_zoom";
-
- /* api callbacks */
- ot->exec= zoom_exec;
- ot->poll= console_poll;
-
- /* properties */
- RNA_def_int(ot->srna, "delta", 0, 0, INT_MAX, "Delta", "Scale the view font.", 0, 1000);
-}
-
typedef struct SetConsoleCursor {
int sel_old[2];
int sel_init;
@@ -824,7 +792,7 @@ static void console_modal_select_apply(bContext *C, wmOperator *op, wmEvent *eve
static void set_cursor_exit(bContext *C, wmOperator *op)
{
- SpaceConsole *sc= CTX_wm_space_console(C);
+// SpaceConsole *sc= CTX_wm_space_console(C);
SetConsoleCursor *scu= op->customdata;
/*
@@ -840,7 +808,7 @@ static void set_cursor_exit(bContext *C, wmOperator *op)
static int console_modal_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
SpaceConsole *sc= CTX_wm_space_console(C);
- ARegion *ar= CTX_wm_region(C);
+// ARegion *ar= CTX_wm_region(C);
SetConsoleCursor *scu;
op->customdata= MEM_callocN(sizeof(SetConsoleCursor), "SetConsoleCursor");
@@ -891,5 +859,5 @@ void CONSOLE_OT_select_set(wmOperatorType *ot)
ot->invoke= console_modal_select_invoke;
ot->modal= console_modal_select;
ot->cancel= console_modal_select_cancel;
- ot->poll= console_poll;
+ ot->poll= console_edit_poll;
}
diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c
index f4058f4eefb..e9e87a865ef 100644
--- a/source/blender/editors/space_console/space_console.c
+++ b/source/blender/editors/space_console/space_console.c
@@ -207,7 +207,6 @@ void console_operatortypes(void)
WM_operatortype_append(CONSOLE_OT_history_cycle);
WM_operatortype_append(CONSOLE_OT_copy);
WM_operatortype_append(CONSOLE_OT_paste);
- WM_operatortype_append(CONSOLE_OT_zoom);
WM_operatortype_append(CONSOLE_OT_select_set);
/* console_report.c */
@@ -223,6 +222,7 @@ void console_operatortypes(void)
void console_keymap(struct wmKeyConfig *keyconf)
{
wmKeyMap *keymap= WM_keymap_find(keyconf, "Console", SPACE_CONSOLE, 0);
+ wmKeyMapItem *kmi;
#ifdef __APPLE__
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN);
@@ -235,13 +235,22 @@ void console_keymap(struct wmKeyConfig *keyconf)
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", HOMEKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_BEGIN);
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", ENDKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_END);
- RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_zoom", WHEELUPMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "delta", 1);
- RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_zoom", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "delta", -1);
-
- RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_zoom", PADPLUSKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", 1);
- RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_zoom", PADMINUS, KM_PRESS, KM_CTRL, 0)->ptr, "delta", -1);
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", WHEELUPMOUSE, KM_PRESS, KM_CTRL, 0);
+ RNA_string_set(kmi->ptr, "path", "space_data.font_size");
+ RNA_boolean_set(kmi->ptr, "reverse", 0);
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL, 0);
+ RNA_string_set(kmi->ptr, "path", "space_data.font_size");
+ RNA_boolean_set(kmi->ptr, "reverse", 1);
+
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
+ RNA_string_set(kmi->ptr, "path", "space_data.font_size");
+ RNA_boolean_set(kmi->ptr, "reverse", 0);
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", PADMINUS, KM_PRESS, KM_CTRL, 0);
+ RNA_string_set(kmi->ptr, "path", "space_data.font_size");
+ RNA_boolean_set(kmi->ptr, "reverse", 1);
+
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, 0, 0)->ptr, "type", PREV_CHAR);
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, 0, 0)->ptr, "type", NEXT_CHAR);
diff --git a/source/blender/editors/space_file/writeimage.c b/source/blender/editors/space_file/writeimage.c
index 045c790b9cd..9e8e3b7b058 100644
--- a/source/blender/editors/space_file/writeimage.c
+++ b/source/blender/editors/space_file/writeimage.c
@@ -102,7 +102,7 @@ static void save_rendered_image_cb_real(char *name, int confirm)
/* BKE_add_image_extension() checks for if extension was already set */
if(scene->r.scemode & R_EXTENSION)
if(strlen(name)<FILE_MAXDIR+FILE_MAXFILE-5)
- BKE_add_image_extension(scene, name, scene->r.imtype);
+ BKE_add_image_extension(name, scene->r.imtype);
strcpy(str, name);
BLI_convertstringcode(str, G.sce);
diff --git a/source/blender/editors/space_graph/Makefile b/source/blender/editors/space_graph/Makefile
index e04a354fb1d..65cdf1a3ffb 100644
--- a/source/blender/editors/space_graph/Makefile
+++ b/source/blender/editors/space_graph/Makefile
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -37,6 +39,8 @@ CFLAGS += $(LEVEL_1_C_WARNINGS)
CPPFLAGS += -I$(NAN_GLEW)/include
CPPFLAGS += -I$(OPENGL_HEADERS)
+CPPFLAGS += -I$(NAN_AUDASPACE)/include
+CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
# not very neat....
CPPFLAGS += -I../../windowmanager
@@ -47,8 +51,6 @@ CPPFLAGS += -I../../makesdna
CPPFLAGS += -I../../makesrna
CPPFLAGS += -I../../imbuf
CPPFLAGS += -I../../python
-CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
-
-# own include
-CPPFLAGS += -I../include
+# own include
+CPPFLAGS += -I../include
diff --git a/source/blender/editors/space_graph/SConscript b/source/blender/editors/space_graph/SConscript
index cc9812678e9..174894ddfad 100644
--- a/source/blender/editors/space_graph/SConscript
+++ b/source/blender/editors/space_graph/SConscript
@@ -5,5 +5,6 @@ sources = env.Glob('*.c')
incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../makesrna ../../imbuf'
incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
+incs += ' #/intern/audaspace/intern'
env.BlenderLib ( 'bf_editors_space_graph', sources, Split(incs), [], libtype=['core'], priority=[50] )
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index 3faba9bbba7..a866ebd75e2 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -264,18 +264,18 @@ static void driver_add_var_cb (bContext *C, void *driver_v, void *dummy_v)
{
ChannelDriver *driver= (ChannelDriver *)driver_v;
- /* add a new var */
- driver_add_new_target(driver);
+ /* add a new variable */
+ driver_add_new_variable(driver);
}
/* callback to remove target variable from active driver */
-static void driver_delete_var_cb (bContext *C, void *driver_v, void *dtar_v)
+static void driver_delete_var_cb (bContext *C, void *driver_v, void *dvar_v)
{
ChannelDriver *driver= (ChannelDriver *)driver_v;
- DriverTarget *dtar= (DriverTarget *)dtar_v;
+ DriverVar *dvar= (DriverVar *)dvar_v;
- /* remove the active target */
- driver_free_target(driver, dtar);
+ /* remove the active variable */
+ driver_free_variable(driver, dvar);
}
/* callback to reset the driver's flags */
@@ -301,13 +301,146 @@ static int graph_panel_drivers_poll(const bContext *C, PanelType *pt)
}
+/* settings for 'single property' driver variable type */
+static void graph_panel_driverVar__singleProp(const bContext *C, uiLayout *layout, ID *id, DriverVar *dvar)
+{
+ DriverTarget *dtar= &dvar->targets[0];
+ PointerRNA dtar_ptr;
+ uiLayout *row, *col;
+ uiBlock *block;
+
+ /* initialise RNA pointer to the target */
+ RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
+
+ /* Target ID */
+ row= uiLayoutRow(layout, 0);
+ uiTemplateAnyID(row, (bContext *)C, &dtar_ptr, "id", "id_type", "Value:");
+
+ /* Target Property */
+ // TODO: make this less technical...
+ if (dtar->id) {
+ PointerRNA root_ptr;
+
+ /* get pointer for resolving the property selected */
+ RNA_id_pointer_create(dtar->id, &root_ptr);
+
+ col= uiLayoutColumn(layout, 1);
+ block= uiLayoutGetBlock(col);
+ /* rna path */
+ uiTemplatePathBuilder(col, (bContext *)C, &dtar_ptr, "data_path", &root_ptr, "Path");
+ }
+}
+
+/* settings for 'rotation difference' driver variable type */
+static void graph_panel_driverVar__rotDiff(const bContext *C, uiLayout *layout, ID *id, DriverVar *dvar)
+{
+ DriverTarget *dtar= &dvar->targets[0];
+ DriverTarget *dtar2= &dvar->targets[1];
+ Object *ob1 = (Object *)dtar->id;
+ Object *ob2 = (Object *)dtar2->id;
+ PointerRNA dtar_ptr, dtar2_ptr;
+ uiLayout *col;
+
+ /* initialise RNA pointer to the target */
+ RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
+ RNA_pointer_create(id, &RNA_DriverTarget, dtar2, &dtar2_ptr);
+
+ /* Bone 1 */
+ col= uiLayoutColumn(layout, 1);
+ uiTemplateAnyID(col, (bContext *)C, &dtar_ptr, "id", "id_type", "Bone 1:");
+
+ if (dtar->id && ob1->pose) {
+ PointerRNA tar_ptr;
+
+ RNA_pointer_create(dtar->id, &RNA_Pose, ob1->pose, &tar_ptr);
+ uiItemPointerR(col, "", ICON_BONE_DATA, &dtar_ptr, "bone_target", &tar_ptr, "bones");
+ }
+
+ col= uiLayoutColumn(layout, 1);
+ uiTemplateAnyID(col, (bContext *)C, &dtar2_ptr, "id", "id_type", "Bone 2:");
+
+ if (dtar2->id && ob2->pose) {
+ PointerRNA tar_ptr;
+
+ RNA_pointer_create(dtar2->id, &RNA_Pose, ob2->pose, &tar_ptr);
+ uiItemPointerR(col, "", ICON_BONE_DATA, &dtar2_ptr, "bone_target", &tar_ptr, "bones");
+ }
+}
+
+/* settings for 'location difference' driver variable type */
+static void graph_panel_driverVar__locDiff(const bContext *C, uiLayout *layout, ID *id, DriverVar *dvar)
+{
+ DriverTarget *dtar= &dvar->targets[0];
+ DriverTarget *dtar2= &dvar->targets[1];
+ Object *ob1 = (Object *)dtar->id;
+ Object *ob2 = (Object *)dtar2->id;
+ PointerRNA dtar_ptr, dtar2_ptr;
+ uiLayout *col;
+
+ /* initialise RNA pointer to the target */
+ RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
+ RNA_pointer_create(id, &RNA_DriverTarget, dtar2, &dtar2_ptr);
+
+ /* Bone 1 */
+ col= uiLayoutColumn(layout, 1);
+ uiTemplateAnyID(col, (bContext *)C, &dtar_ptr, "id", "id_type", "Ob/Bone 1:");
+
+ if (dtar->id && ob1->pose) {
+ PointerRNA tar_ptr;
+
+ RNA_pointer_create(dtar->id, &RNA_Pose, ob1->pose, &tar_ptr);
+ uiItemPointerR(col, "", ICON_BONE_DATA, &dtar_ptr, "bone_target", &tar_ptr, "bones");
+ }
+
+ uiItemR(col, NULL, 0, &dtar_ptr, "use_local_space_transforms", 0);
+
+ col= uiLayoutColumn(layout, 1);
+ uiTemplateAnyID(col, (bContext *)C, &dtar2_ptr, "id", "id_type", "Ob/Bone 2:");
+
+ if (dtar2->id && ob2->pose) {
+ PointerRNA tar_ptr;
+
+ RNA_pointer_create(dtar2->id, &RNA_Pose, ob2->pose, &tar_ptr);
+ uiItemPointerR(col, "", ICON_BONE_DATA, &dtar2_ptr, "bone_target", &tar_ptr, "bones");
+ }
+
+ uiItemR(col, NULL, 0, &dtar2_ptr, "use_local_space_transforms", 0);
+}
+
+/* settings for 'transform channel' driver variable type */
+static void graph_panel_driverVar__transChan(const bContext *C, uiLayout *layout, ID *id, DriverVar *dvar)
+{
+ DriverTarget *dtar= &dvar->targets[0];
+ Object *ob = (Object *)dtar->id;
+ PointerRNA dtar_ptr;
+ uiLayout *col, *row;
+
+ /* initialise RNA pointer to the target */
+ RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
+
+ /* properties */
+ col= uiLayoutColumn(layout, 1);
+ uiTemplateAnyID(col, (bContext *)C, &dtar_ptr, "id", "id_type", "Ob/Bone:");
+
+ if (dtar->id && ob->pose) {
+ PointerRNA tar_ptr;
+
+ RNA_pointer_create(dtar->id, &RNA_Pose, ob->pose, &tar_ptr);
+ uiItemPointerR(col, "", ICON_BONE_DATA, &dtar_ptr, "bone_target", &tar_ptr, "bones");
+ }
+
+ row= uiLayoutRow(layout, 1);
+ uiItemR(row, "", 0, &dtar_ptr, "transform_type", 0);
+ uiItemR(row, NULL, 0, &dtar_ptr, "use_local_space_transforms", 0);
+}
+
/* driver settings for active F-Curve (only for 'Drivers' mode) */
static void graph_panel_drivers(const bContext *C, Panel *pa)
{
bAnimListElem *ale;
FCurve *fcu;
ChannelDriver *driver;
- DriverTarget *dtar;
+ DriverVar *dvar;
PointerRNA driver_ptr;
uiLayout *col;
@@ -354,56 +487,57 @@ static void graph_panel_drivers(const bContext *C, Panel *pa)
uiItemL(col, "ERROR: invalid target channel(s)", ICON_ERROR);
}
- /* add driver target variables */
+ /* add driver variables */
col= uiLayoutColumn(pa->layout, 0);
block= uiLayoutGetBlock(col);
- but= uiDefBut(block, BUT, B_IPO_DEPCHANGE, "Add Target", 0, 0, 10*UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "Add a new target variable for this Driver");
+ but= uiDefBut(block, BUT, B_IPO_DEPCHANGE, "Add Variable", 0, 0, 10*UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "Add a new target variable for this Driver");
uiButSetFunc(but, driver_add_var_cb, driver, NULL);
/* loop over targets, drawing them */
- for (dtar= driver->targets.first; dtar; dtar= dtar->next) {
- PointerRNA dtar_ptr;
+ for (dvar= driver->variables.first; dvar; dvar= dvar->next) {
+ PointerRNA dvar_ptr;
uiLayout *box, *row;
- /* panel holding the buttons */
- box= uiLayoutBox(pa->layout);
-
- /* first row context info for driver */
- RNA_pointer_create(ale->id, &RNA_DriverTarget, dtar, &dtar_ptr);
-
- row= uiLayoutRow(box, 0);
- block= uiLayoutGetBlock(row);
- /* variable name */
- uiItemR(row, "", 0, &dtar_ptr, "name", 0);
-
- /* remove button */
- but= uiDefIconBut(block, BUT, B_IPO_DEPCHANGE, ICON_X, 290, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, "Delete target variable.");
- uiButSetFunc(but, driver_delete_var_cb, driver, dtar);
-
-
- /* Target ID */
- row= uiLayoutRow(box, 0);
- uiTemplateAnyID(row, (bContext *)C, &dtar_ptr, "id", "id_type", "Value:");
+ /* sub-layout column for this variable's settings */
+ col= uiLayoutColumn(pa->layout, 1);
- /* Target Property */
- // TODO: make this less technical...
- if (dtar->id) {
- PointerRNA root_ptr;
+ /* header panel */
+ box= uiLayoutBox(col);
+ /* first row context info for driver */
+ RNA_pointer_create(ale->id, &RNA_DriverVariable, dvar, &dvar_ptr);
- /* get pointer for resolving the property selected */
- RNA_id_pointer_create(dtar->id, &root_ptr);
+ row= uiLayoutRow(box, 0);
+ block= uiLayoutGetBlock(row);
+ /* variable name */
+ uiItemR(row, "", 0, &dvar_ptr, "name", 0);
+
+ /* remove button */
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+ but= uiDefIconBut(block, BUT, B_IPO_DEPCHANGE, ICON_X, 290, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, "Delete target variable.");
+ uiButSetFunc(but, driver_delete_var_cb, driver, dvar);
+ uiBlockSetEmboss(block, UI_EMBOSS);
- col= uiLayoutColumn(box, 1);
- block= uiLayoutGetBlock(col);
- /* rna path */
- uiTemplatePathBuilder(col, (bContext *)C, &dtar_ptr, "data_path", &root_ptr, "Path");
+ /* variable type */
+ row= uiLayoutRow(box, 0);
+ uiItemR(row, "", 0, &dvar_ptr, "type", 0);
- /* array index */
- // TODO: this needs selector which limits it to ok values
- // NOTE: for for now, the array index box still gets shown when non-zero (i.e. for tweaking rigs as necessary)
- if (dtar->array_index)
- uiItemR(col, "Index", 0, &dtar_ptr, "array_index", 0);
- }
+ /* variable type settings */
+ box= uiLayoutBox(col);
+ /* controls to draw depends on the type of variable */
+ switch (dvar->type) {
+ case DVAR_TYPE_SINGLE_PROP: /* single property */
+ graph_panel_driverVar__singleProp(C, box, ale->id, dvar);
+ break;
+ case DVAR_TYPE_ROT_DIFF: /* rotational difference */
+ graph_panel_driverVar__rotDiff(C, box, ale->id, dvar);
+ break;
+ case DVAR_TYPE_LOC_DIFF: /* location difference */
+ graph_panel_driverVar__locDiff(C, box, ale->id, dvar);
+ break;
+ case DVAR_TYPE_TRANSFORM_CHAN: /* transform channel */
+ graph_panel_driverVar__transChan(C, box, ale->id, dvar);
+ break;
+ }
}
/* cleanup */
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 8ac3f2efefb..ffc450b5368 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -36,6 +36,8 @@
#include <config.h>
#endif
+#include "AUD_C-API.h"
+
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
@@ -990,6 +992,147 @@ void GRAPH_OT_bake (wmOperatorType *ot)
// todo: add props for start/end frames
}
+/* ******************** Sound Bake F-Curve Operator *********************** */
+/* This operator bakes the given sound to the selected F-Curves */
+
+/* ------------------- */
+
+/* Custom data storage passed to the F-Sample-ing function,
+ * which provides the necessary info for baking the sound
+ */
+typedef struct tSoundBakeInfo {
+ float* samples;
+ int length;
+ int cfra;
+} tSoundBakeInfo;
+
+/* ------------------- */
+
+/* Sampling callback used to determine the value from the sound to
+ * save in the F-Curve at the specified frame
+ */
+static float fcurve_samplingcb_sound (FCurve *fcu, void *data, float evaltime)
+{
+ tSoundBakeInfo *sbi= (tSoundBakeInfo *)data;
+
+ int position = evaltime - sbi->cfra;
+ if((position < 0) || (position >= sbi->length))
+ return 0.0f;
+
+ return sbi->samples[position];
+}
+
+/* ------------------- */
+
+static int graphkeys_sound_bake_exec(bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ tSoundBakeInfo sbi;
+ Scene *scene= NULL;
+ int start, end;
+
+ char path[FILE_MAX];
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ RNA_string_get(op->ptr, "path", path);
+
+ scene= ac.scene; /* current scene */
+
+ /* store necessary data for the baking steps */
+ sbi.samples = AUD_readSoundBuffer(path,
+ RNA_float_get(op->ptr, "low"),
+ RNA_float_get(op->ptr, "high"),
+ RNA_float_get(op->ptr, "attack"),
+ RNA_float_get(op->ptr, "release"),
+ RNA_float_get(op->ptr, "threshold"),
+ RNA_boolean_get(op->ptr, "accumulate"),
+ RNA_boolean_get(op->ptr, "additive"),
+ RNA_boolean_get(op->ptr, "square"),
+ RNA_float_get(op->ptr, "sthreshold"),
+ FPS, &sbi.length);
+
+ if (sbi.samples == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* determine extents of the baking */
+ sbi.cfra = start = CFRA;
+ end = CFRA + sbi.length - 1;
+
+ /* filter anim channels */
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ /* loop through all selected F-Curves, replacing its data with the sound samples */
+ for (ale= anim_data.first; ale; ale= ale->next) {
+ FCurve *fcu= (FCurve *)ale->key_data;
+
+ /* sample the sound */
+ fcurve_store_samples(fcu, &sbi, start, end, fcurve_samplingcb_sound);
+ }
+
+ /* free sample data */
+ free(sbi.samples);
+
+ /* admin and redraws */
+ BLI_freelistN(&anim_data);
+
+ /* validate keyframes after editing */
+ ANIM_editkeyframes_refresh(&ac);
+
+ /* set notifier that 'keyframes' have changed */
+ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+static int graphkeys_sound_bake_invoke (bContext *C, wmOperator *op, wmEvent *event)
+{
+ bAnimContext ac;
+
+ /* verify editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ return WM_operator_filesel(C, op, event);
+}
+
+void GRAPH_OT_sound_bake (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Bake Sound to F-Curves";
+ ot->idname= "GRAPH_OT_sound_bake";
+ ot->description= "Bakes a sound wave to selected F-Curves.";
+
+ /* api callbacks */
+ ot->invoke= graphkeys_sound_bake_invoke;
+ ot->exec= graphkeys_sound_bake_exec;
+ ot->poll= graphop_selected_fcurve_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE|MOVIEFILE, FILE_SPECIAL);
+ RNA_def_float(ot->srna, "low", 0.0f, 0.0, 100000.0, "Lowest frequency", "", 0.1, 1000.00);
+ RNA_def_float(ot->srna, "high", 100000.0, 0.0, 100000.0, "Highest frequency", "", 0.1, 1000.00);
+ RNA_def_float(ot->srna, "attack", 0.005, 0.0, 2.0, "Attack time", "", 0.01, 0.1);
+ RNA_def_float(ot->srna, "release", 0.2, 0.0, 5.0, "Release time", "", 0.01, 0.2);
+ RNA_def_float(ot->srna, "threshold", 0.0, 0.0, 1.0, "Threshold", "", 0.01, 0.1);
+ RNA_def_boolean(ot->srna, "accumulate", 0, "Accumulate", "");
+ RNA_def_boolean(ot->srna, "additive", 0, "Additive", "");
+ RNA_def_boolean(ot->srna, "square", 0, "Square", "");
+ RNA_def_float(ot->srna, "sthreshold", 0.1, 0.0, 1.0, "Square Threshold", "", 0.01, 0.1);
+}
+
/* ******************** Sample Keyframes Operator *********************** */
/* This operator 'bakes' the values of the curve into new keyframes between pairs
* of selected keyframes. It is useful for creating keyframes for tweaking overlap.
diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h
index 87e03247353..ec6f38c93b7 100644
--- a/source/blender/editors/space_graph/graph_intern.h
+++ b/source/blender/editors/space_graph/graph_intern.h
@@ -100,6 +100,7 @@ void GRAPH_OT_delete(struct wmOperatorType *ot);
void GRAPH_OT_clean(struct wmOperatorType *ot);
void GRAPH_OT_sample(struct wmOperatorType *ot);
void GRAPH_OT_bake(struct wmOperatorType *ot);
+void GRAPH_OT_sound_bake(struct wmOperatorType *ot);
void GRAPH_OT_smooth(struct wmOperatorType *ot);
void GRAPH_OT_handle_type(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index 295ee869979..7be2d7b3e4b 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -247,6 +247,7 @@ void graphedit_operatortypes(void)
WM_operatortype_append(GRAPH_OT_extrapolation_type);
WM_operatortype_append(GRAPH_OT_sample);
WM_operatortype_append(GRAPH_OT_bake);
+ WM_operatortype_append(GRAPH_OT_sound_bake);
WM_operatortype_append(GRAPH_OT_smooth);
WM_operatortype_append(GRAPH_OT_clean);
WM_operatortype_append(GRAPH_OT_delete);
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index 4811eb411ec..6b92fc3fe4f 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -389,7 +389,7 @@ static void image_panel_curves(const bContext *C, Panel *pa)
levels= (ibuf->channels==4);
RNA_pointer_create(&sc->id, &RNA_SpaceImageEditor, sima, &simaptr);
- uiTemplateCurveMapping(pa->layout, &simaptr, "curves", 'c', levels);
+ uiTemplateCurveMapping(pa->layout, &simaptr, "curves", 'c', levels, 0);
}
ED_space_image_release_buffer(sima, lock);
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index 46ec41eda58..ea526b13219 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -126,7 +126,7 @@ static void image_verify_buffer_float(SpaceImage *sima, Image *ima, ImBuf *ibuf,
else {
if (color_manage) {
if (ima && ima->source == IMA_SRC_VIEWER)
- ibuf->profile = IB_PROFILE_SRGB;
+ ibuf->profile = IB_PROFILE_LINEAR_RGB;
} else {
ibuf->profile = IB_PROFILE_NONE;
}
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 897b02404ef..827b2ddeac2 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -649,7 +649,8 @@ static int open_exec(bContext *C, wmOperator *op)
char str[FILE_MAX];
RNA_string_get(op->ptr, "path", str);
- ima= BKE_add_image_file(str, scene->r.cfra);
+ /* default to frame 1 if there's no scene in context */
+ ima= BKE_add_image_file(str, scene ? scene->r.cfra : 1);
if(!ima) {
if(op->customdata) MEM_freeN(op->customdata);
@@ -784,8 +785,7 @@ static void save_image_doit(bContext *C, SpaceImage *sima, Scene *scene, wmOpera
BLI_convertstringframe(name, scene->r.cfra);
if(scene->r.scemode & R_EXTENSION) {
- BKE_add_image_extension(scene, name, sima->imtypenr);
- BKE_add_image_extension(scene, name, sima->imtypenr);
+ BKE_add_image_extension(name, sima->imtypenr);
}
/* enforce user setting for RGB or RGBA, but skip BW */
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index a077357d03e..4622962bac5 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -290,7 +290,7 @@ static void image_listener(ScrArea *sa, wmNotifier *wmn)
break;
}
break;
- case NC_IMAGE:
+ case NC_IMAGE:
ED_area_tag_redraw(sa);
break;
case NC_SPACE:
diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c
index 13bcd3276af..81506d42d87 100644
--- a/source/blender/editors/space_info/info_ops.c
+++ b/source/blender/editors/space_info/info_ops.c
@@ -196,21 +196,12 @@ void FILE_OT_unpack_all(wmOperatorType *ot)
static int make_paths_relative_exec(bContext *C, wmOperator *op)
{
- char txtname[24]; /* text block name */
- int tot, changed, failed, linked;
-
if(!G.relbase_valid) {
BKE_report(op->reports, RPT_WARNING, "Can't set relative paths with an unsaved blend file.");
return OPERATOR_CANCELLED;
}
- txtname[0] = '\0';
- makeFilesRelative(txtname, &tot, &changed, &failed, &linked);
-
- if(failed)
- BKE_reportf(op->reports, RPT_ERROR, "Total files %i|Changed %i|Failed %i, See Text \"%s\"|Linked %i", tot, changed, failed, txtname, linked);
- else
- BKE_reportf(op->reports, RPT_INFO, "Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked);
+ makeFilesRelative(G.sce, op->reports);
return OPERATOR_FINISHED;
}
@@ -232,22 +223,12 @@ void FILE_OT_make_paths_relative(wmOperatorType *ot)
static int make_paths_absolute_exec(bContext *C, wmOperator *op)
{
- char txtname[24]; /* text block name */
- int tot, changed, failed, linked;
-
if(!G.relbase_valid) {
BKE_report(op->reports, RPT_WARNING, "Can't set absolute paths with an unsaved blend file.");
return OPERATOR_CANCELLED;
}
- txtname[0] = '\0';
- makeFilesAbsolute(txtname, &tot, &changed, &failed, &linked);
-
- if(failed)
- BKE_reportf(op->reports, RPT_ERROR, "Total files %i|Changed %i|Failed %i, See Text \"%s\"|Linked %i", tot, changed, failed, txtname, linked);
- else
- BKE_reportf(op->reports, RPT_INFO, "Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked);
-
+ makeFilesAbsolute(G.sce, op->reports);
return OPERATOR_FINISHED;
}
@@ -273,12 +254,7 @@ static int report_missing_files_exec(bContext *C, wmOperator *op)
txtname[0] = '\0';
/* run the missing file check */
- checkMissingFiles(txtname);
-
- if(txtname[0] == '\0')
- BKE_report(op->reports, RPT_INFO, "No external files missing.");
- else
- BKE_reportf(op->reports, RPT_ERROR, "Missing files listed in Text \"%s\"", txtname);
+ checkMissingFiles(G.sce, op->reports);
return OPERATOR_FINISHED;
}
@@ -303,7 +279,7 @@ static int find_missing_files_exec(bContext *C, wmOperator *op)
char *path;
path= RNA_string_get_alloc(op->ptr, "path", NULL, 0);
- findMissingFiles(path);
+ findMissingFiles(path, G.sce);
MEM_freeN(path);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 30212abd4da..7f8bf2618a4 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -166,6 +166,7 @@ static void node_buts_rgb(uiLayout *layout, bContext *C, PointerRNA *ptr)
RNA_property_collection_lookup_int(ptr, prop, 0, &sockptr);
col = uiLayoutColumn(layout, 0);
+ uiTemplateColorWheel(col, &sockptr, "default_value", 1);
uiItemR(col, "", 0, &sockptr, "default_value", 0);
}
@@ -196,7 +197,7 @@ static void node_buts_time(uiLayout *layout, bContext *C, PointerRNA *ptr)
}
#endif
- uiTemplateCurveMapping(layout, ptr, "curve", 's', 0);
+ uiTemplateCurveMapping(layout, ptr, "curve", 's', 0, 0);
row= uiLayoutRow(layout, 1);
uiItemR(row, "Sta", 0, ptr, "start", 0);
@@ -210,7 +211,7 @@ static void node_buts_colorramp(uiLayout *layout, bContext *C, PointerRNA *ptr)
static void node_buts_curvevec(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
- uiTemplateCurveMapping(layout, ptr, "mapping", 'v', 0);
+ uiTemplateCurveMapping(layout, ptr, "mapping", 'v', 0, 0);
}
static float *_sample_col= NULL; // bad bad, 2.5 will do better?
@@ -231,7 +232,7 @@ static void node_buts_curvecol(uiLayout *layout, bContext *C, PointerRNA *ptr)
else
cumap->flag &= ~CUMA_DRAW_SAMPLE;
- uiTemplateCurveMapping(layout, ptr, "mapping", 'c', 0);
+ uiTemplateCurveMapping(layout, ptr, "mapping", 'c', 0, 0);
}
static void node_buts_normal(uiLayout *layout, bContext *C, PointerRNA *ptr)
@@ -545,16 +546,33 @@ static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA *
static void node_composit_buts_renderlayers(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
bNode *node= ptr->data;
- uiLayout *col;
-
+ uiLayout *col, *row;
+ PointerRNA op_ptr;
+ PointerRNA scn_ptr;
+ PropertyRNA *prop;
+ const char *layer_name;
+ char scene_name[19];
+
uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL);
if(!node->id) return;
col= uiLayoutColumn(layout, 0);
- uiItemR(col, "", 0, ptr, "layer", 0);
+ row = uiLayoutRow(col, 0);
+ uiItemR(row, "", 0, ptr, "layer", 0);
- /* XXX Missing 're-render this layer' button - needs completely new implementation */
+ prop = RNA_struct_find_property(ptr, "layer");
+ if (!(RNA_property_enum_identifier(C, ptr, prop, RNA_property_enum_get(ptr, prop), &layer_name)))
+ return;
+
+ scn_ptr = RNA_pointer_get(ptr, "scene");
+ RNA_string_get(&scn_ptr, "name", scene_name);
+
+ WM_operator_properties_create(&op_ptr, "SCREEN_OT_render");
+ RNA_string_set(&op_ptr, "layer", layer_name);
+ RNA_string_set(&op_ptr, "scene", scene_name);
+ uiItemFullO(row, "", ICON_RENDER_STILL, "SCREEN_OT_render", op_ptr.data, WM_OP_INVOKE_DEFAULT, 0);
+
}
@@ -1251,7 +1269,7 @@ void draw_nodespace_back_pix(ARegion *ar, SpaceNode *snode, int color_manage)
if(!ibuf->rect) {
if(color_manage)
- ibuf->profile= IB_PROFILE_SRGB;
+ ibuf->profile = IB_PROFILE_LINEAR_RGB;
else
ibuf->profile = IB_PROFILE_NONE;
IMB_rect_from_float(ibuf);
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index 59085ce19cd..4fc0d37f6a6 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -506,9 +506,7 @@ static void socket_circle_draw(bNodeSocket *sock, float size)
/* choose color based on sock flags */
if(sock->flag & SELECT) {
- if(sock->flag & SOCK_SEL) {
- col[0]= 240; col[1]= 200; col[2]= 40;}
- else if(sock->type==SOCK_VALUE) {
+ if(sock->type==SOCK_VALUE) {
col[0]= 200; col[1]= 200; col[2]= 200;}
else if(sock->type==SOCK_VECTOR) {
col[0]= 140; col[1]= 140; col[2]= 240;}
@@ -517,8 +515,6 @@ static void socket_circle_draw(bNodeSocket *sock, float size)
else {
col[0]= 140; col[1]= 240; col[2]= 140;}
}
- else if(sock->flag & SOCK_SEL) {
- col[0]= 200; col[1]= 160; col[2]= 0;}
else {
if(sock->type==-1) {
col[0]= 0; col[1]= 0; col[2]= 0;}
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index f177e1a2622..c177cb7f1f5 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -222,116 +222,6 @@ void snode_handle_recalc(bContext *C, SpaceNode *snode)
WM_event_add_notifier(C, NC_TEXTURE|ND_NODES, snode->id);
}
-#if 0
-static int image_detect_file_sequence(int *start_p, int *frames_p, char *str)
-{
- SpaceFile *sfile;
- char name[FILE_MAX], head[FILE_MAX], tail[FILE_MAX], filename[FILE_MAX];
- int a, frame, totframe, found, minframe;
- unsigned short numlen;
-
- sfile= scrarea_find_space_of_type(curarea, SPACE_FILE);
- if(sfile==NULL || sfile->filelist==NULL)
- return 0;
-
- /* find first frame */
- found= 0;
- minframe= 0;
-
- for(a=0; a<sfile->totfile; a++) {
- if(sfile->filelist[a].flags & ACTIVE) {
- BLI_strncpy(name, sfile->filelist[a].relname, sizeof(name));
- frame= BLI_stringdec(name, head, tail, &numlen);
-
- if(!found || frame < minframe) {
- BLI_strncpy(filename, name, sizeof(name));
- minframe= frame;
- found= 1;
- }
- }
- }
-
- /* not one frame found */
- if(!found)
- return 0;
-
- /* counter number of following frames */
- found= 1;
- totframe= 0;
-
- for(frame=minframe; found; frame++) {
- found= 0;
- BLI_strncpy(name, filename, sizeof(name));
- BLI_stringenc(name, head, tail, numlen, frame);
-
- for(a=0; a<sfile->totfile; a++) {
- if(sfile->filelist[a].flags & ACTIVE) {
- if(strcmp(sfile->filelist[a].relname, name) == 0) {
- found= 1;
- totframe++;
- break;
- }
- }
- }
- }
-
- if(totframe > 1) {
- BLI_strncpy(str, sfile->dir, sizeof(name));
- strcat(str, filename);
-
- *start_p= minframe;
- *frames_p= totframe;
- return 1;
- }
-
- return 0;
-}
-
-static void load_node_image(char *str) /* called from fileselect */
-{
- SpaceNode *snode= curarea->spacedata.first;
- bNode *node= nodeGetActive(snode->edittree);
- Image *ima= NULL;
- ImageUser *iuser= node->storage;
- char filename[FILE_MAX];
- int start=0, frames=0, sequence;
-
- sequence= image_detect_file_sequence(&start, &frames, filename);
- if(sequence)
- str= filename;
-
- ima= BKE_add_image_file(str);
- if(ima) {
- if(node->id)
- node->id->us--;
-
- node->id= &ima->id;
- id_us_plus(node->id);
-
- BLI_strncpy(node->name, node->id->name+2, 21);
-
- if(sequence) {
- ima->source= IMA_SRC_SEQUENCE;
- iuser->frames= frames;
- iuser->offset= start-1;
- }
-
- BKE_image_signal(ima, node->storage, IMA_SIGNAL_RELOAD);
-
- NodeTagChanged(snode->edittree, node);
- // XXX snode_handle_recalc(C, snode);
- }
-}
-
-static void set_node_imagepath(char *str) /* called from fileselect */
-{
- SpaceNode *snode= curarea->spacedata.first;
- bNode *node= nodeGetActive(snode->edittree);
- BLI_strncpy(((NodeImageFile *)node->storage)->name, str, sizeof( ((NodeImageFile *)node->storage)->name ));
-}
-
-#endif /* 0 */
-
bNode *node_tree_get_editgroup(bNodeTree *nodetree)
{
bNode *gnode;
@@ -343,136 +233,6 @@ bNode *node_tree_get_editgroup(bNodeTree *nodetree)
return gnode;
}
-#if 0
-
-/* node has to be of type 'render layers' */
-/* is a bit clumsy copying renderdata here... scene nodes use render size of current render */
-static void composite_node_render(SpaceNode *snode, bNode *node)
-{
- RenderData rd;
- Scene *scene= NULL;
- int scemode, actlay;
-
- /* the button press won't show up otherwise, button hilites disabled */
- force_draw(0);
-
- if(node->id && node->id!=(ID *)G.scene) {
- scene= G.scene;
- set_scene_bg((Scene *)node->id);
- rd= G.scene->r;
- G.scene->r.xsch= scene->r.xsch;
- G.scene->r.ysch= scene->r.ysch;
- G.scene->r.size= scene->r.size;
- G.scene->r.mode &= ~(R_BORDER|R_DOCOMP);
- G.scene->r.mode |= scene->r.mode & R_BORDER;
- G.scene->r.border= scene->r.border;
- G.scene->r.cfra= scene->r.cfra;
- }
-
- scemode= G.scene->r.scemode;
- actlay= G.scene->r.actlay;
-
- G.scene->r.scemode |= R_SINGLE_LAYER|R_COMP_RERENDER;
- G.scene->r.actlay= node->custom1;
-
- BIF_do_render(0);
-
- G.scene->r.scemode= scemode;
- G.scene->r.actlay= actlay;
-
- node->custom2= 0;
-
- if(scene) {
- G.scene->r= rd;
- set_scene_bg(scene);
- }
-}
-
-static void composit_node_event(SpaceNode *snode, short event)
-{
-
- switch(event) {
- case B_REDR:
- // allqueue(REDRAWNODE, 1);
- break;
- case B_NODE_SETIMAGE:
- {
- bNode *node= nodeGetActive(snode->edittree);
- char name[FILE_MAXDIR+FILE_MAXFILE];
-
- strcpy(name, ((NodeImageFile *)node->storage)->name);
- if (G.qual & LR_CTRLKEY) {
- activate_imageselect(FILE_SPECIAL, "SELECT OUTPUT DIR", name, set_node_imagepath);
- } else {
- activate_fileselect(FILE_SPECIAL, "SELECT OUTPUT DIR", name, set_node_imagepath);
- }
- break;
- }
- case B_NODE_TREE_EXEC:
- // XXX snode_handle_recalc(snode);
- break;
- default:
- /* B_NODE_EXEC */
- {
- bNode *node= BLI_findlink(&snode->edittree->nodes, event-B_NODE_EXEC);
- if(node) {
- NodeTagChanged(snode->edittree, node);
- /* don't use NodeTagIDChanged, it gives far too many recomposites for image, scene layers, ... */
-
- /* not the best implementation of the world... but we need it to work now :) */
- if(node->type==CMP_NODE_R_LAYERS && node->custom2) {
- /* add event for this window (after render curarea can be changed) */
- addqueue(curarea->win, UI_BUT_EVENT, B_NODE_TREE_EXEC);
-
- composite_node_render(snode, node);
- // XXX snode_handle_recalc(snode);
-
- /* add another event, a render can go fullscreen and open new window */
- addqueue(curarea->win, UI_BUT_EVENT, B_NODE_TREE_EXEC);
- }
- else {
- node= node_tree_get_editgroup(snode->nodetree);
- if(node)
- NodeTagIDChanged(snode->nodetree, node->id);
-
- // XXX snode_handle_recalc(snode);
- }
- }
- }
- }
-}
-
-static void texture_node_event(SpaceNode *snode, short event)
-{
- switch(event) {
- case B_REDR:
- // allqueue(REDRAWNODE, 1);
- break;
- case B_NODE_LOADIMAGE:
- {
- bNode *node= nodeGetActive(snode->edittree);
- char name[FILE_MAXDIR+FILE_MAXFILE];
-
- if(node->id)
- strcpy(name, ((Image *)node->id)->name);
- else strcpy(name, U.textudir);
- if (G.qual & LR_CTRLKEY) {
- activate_imageselect(FILE_SPECIAL, "SELECT IMAGE", name, load_node_image);
- } else {
- activate_fileselect(FILE_SPECIAL, "SELECT IMAGE", name, load_node_image);
- }
- break;
- }
- default:
- /* B_NODE_EXEC */
- ntreeTexCheckCyclics( snode->nodetree );
- // XXX snode_handle_recalc(snode);
- // allqueue(REDRAWNODE, 1);
- break;
- }
-}
-
-#endif /* 0 */
/* assumes nothing being done in ntree yet, sets the default in/out node */
/* called from shading buttons or header */
void ED_node_shader_default(Material *ma)
@@ -663,29 +423,6 @@ void snode_set_context(SpaceNode *snode, Scene *scene)
node_tree_from_ID(snode->id, &snode->nodetree, &snode->edittree, NULL);
}
-#if 0
-/* on activate image viewer, check if we show it */
-static void node_active_image(Image *ima)
-{
- ScrArea *sa;
- SpaceImage *sima= NULL;
-
- /* find an imagewindow showing render result */
- for(sa=G.curscreen->areabase.first; sa; sa= sa->next) {
- if(sa->spacetype==SPACE_IMAGE) {
- sima= sa->spacedata.first;
- if(sima->image && sima->image->source!=IMA_SRC_VIEWER)
- break;
- }
- }
- if(sa && sima) {
- sima->image= ima;
- scrarea_queue_winredraw(sa);
- scrarea_queue_headredraw(sa);
- }
-}
-#endif /* 0 */
-
void node_set_active(SpaceNode *snode, bNode *node)
{
nodeSetActive(snode->edittree, node);
@@ -735,18 +472,9 @@ void node_set_active(SpaceNode *snode, bNode *node)
/* addnode() doesnt link this yet... */
node->id= (ID *)BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
}
- else if(node->type==CMP_NODE_IMAGE) {
- // XXX
-#if 0
- if(node->id)
- node_active_image((Image *)node->id);
-#endif
- }
else if(node->type==CMP_NODE_R_LAYERS) {
if(node->id==NULL || node->id==(ID *)scene) {
scene->r.actlay= node->custom1;
- // XXX
- // allqueue(REDRAWBUTSSCENE, 0);
}
}
}
@@ -808,13 +536,6 @@ void snode_make_group_editable(SpaceNode *snode, bNode *gnode)
snode->edittree= snode->nodetree;
ntreeSolveOrder(snode->nodetree);
-
- /* finally send out events for new active node */
- if(snode->treetype==NTREE_SHADER) {
- // allqueue(REDRAWBUTSSHADING, 0);
-
- // XXX BIF_preview_changed(-1); /* temp hack to force texture preview to update */
- }
}
static int node_group_edit_exec(bContext *C, wmOperator *op)
@@ -1139,31 +860,8 @@ void NODE_OT_resize(wmOperatorType *ot)
ot->flag= OPTYPE_BLOCKING;
}
-
-#if 0
-
/* ********************** select ******************** */
-/* used in buttons to check context, also checks for edited groups */
-bNode *editnode_get_active_idnode(bNodeTree *ntree, short id_code)
-{
- return nodeGetActiveID(ntree, id_code);
-}
-
-/* used in buttons to check context, also checks for edited groups */
-Material *editnode_get_active_material(Material *ma)
-{
- if(ma && ma->use_nodes && ma->nodetree) {
- bNode *node= editnode_get_active_idnode(ma->nodetree, ID_MA);
- if(node)
- return (Material *)node->id;
- else
- return NULL;
- }
- return ma;
-}
-#endif /* 0 */
-
/* no undo here! */
void node_deselectall(SpaceNode *snode)
@@ -1215,8 +913,6 @@ static void node_link_viewer(SpaceNode *snode, bNode *tonode)
link->fromnode= tonode;
link->fromsock= tonode->outputs.first;
NodeTagChanged(snode->edittree, node);
-
-// XXX snode_handle_recalc(snode);
}
}
}
@@ -1353,59 +1049,156 @@ static int node_socket_hilights(SpaceNode *snode, int in_out)
/* ****************** Add *********************** */
-void snode_autoconnect(SpaceNode *snode, bNode *node_to, int flag)
+
+typedef struct bNodeListItem {
+ struct bNodeListItem *next, *prev;
+ struct bNode *node;
+} bNodeListItem;
+
+int sort_nodes_locx(void *a, void *b)
{
- bNodeSocket *sock, *sockfrom[8];
- bNode *node, *nodefrom[8];
- int totsock= 0, socktype=0;
+ bNodeListItem *nli1 = (bNodeListItem *)a;
+ bNodeListItem *nli2 = (bNodeListItem *)b;
+ bNode *node1 = nli1->node;
+ bNode *node2 = nli2->node;
+
+ if (node1->locx > node2->locx)
+ return 1;
+ else
+ return 0;
+}
- if(node_to==NULL || node_to->inputs.first==NULL)
- return;
+static int socket_is_available(bNodeTree *ntree, bNodeSocket *sock, int allow_used)
+{
+ if (sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))
+ return 0;
- /* no inputs for node allowed (code it) */
+ if (!allow_used) {
+ if (nodeCountSocketLinks(ntree, sock) > 0)
+ return 0;
+ }
+ return 1;
+}
- /* connect first 1 socket type now */
- for(sock= node_to->inputs.first; sock; sock= sock->next)
- if(socktype<sock->type)
- socktype= sock->type;
+static bNodeSocket *best_socket_output(bNodeTree *ntree, bNode *node, bNodeSocket *sock_target, int allow_multiple)
+{
+ bNodeSocket *sock;
+
+ /* first try to find a socket with a matching name */
+ for (sock=node->outputs.first; sock; sock=sock->next) {
+ if (!socket_is_available(ntree, sock, allow_multiple))
+ continue;
+
+ /* check for same types */
+ if (sock->type == sock_target->type) {
+ if (strcmp(sock->name, sock_target->name)==0)
+ return sock;
+ }
+ }
- /* find potential sockets, max 8 should work */
- for(node= snode->edittree->nodes.first; node; node= node->next) {
- if((node->flag & flag) && node!=node_to) {
- for(sock= node->outputs.first; sock; sock= sock->next) {
- if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) {
- sockfrom[totsock]= sock;
- nodefrom[totsock]= node;
- totsock++;
- if(totsock>7)
- break;
- }
+ /* otherwise settle for the first available socket of the right type */
+ for (sock=node->outputs.first; sock; sock=sock->next) {
+
+ if (!socket_is_available(ntree, sock, allow_multiple))
+ continue;
+
+ /* check for same types */
+ if (sock->type == sock_target->type) {
+ return sock;
+ }
+ }
+
+ return NULL;
+}
+
+/* this is a bit complicated, but designed to prioritise finding
+ * sockets of higher types, such as image, first */
+static bNodeSocket *best_socket_input(bNodeTree *ntree, bNode *node, int num, int replace)
+{
+ bNodeSocket *sock;
+ int socktype, maxtype=0;
+ int a;
+
+ for (sock=node->inputs.first; sock; sock=sock->next) {
+ maxtype = MAX2(sock->type, maxtype);
+ }
+
+ /* find sockets of higher 'types' first (i.e. image) */
+ for (socktype=maxtype; socktype >= 0; socktype--) {
+ for (sock=node->inputs.first; sock; sock=sock->next) {
+
+ if (!socket_is_available(ntree, sock, replace)) {
+ a++;
+ continue;
+ }
+
+ if (sock->type == socktype) {
+ /* increment to make sure we don't keep finding
+ * the same socket on every attempt running this function */
+ a++;
+ if (a > num)
+ return sock;
}
}
- if(totsock>7)
- break;
}
+
+ return NULL;
+}
- /* now just get matching socket types and create links */
- for(sock= node_to->inputs.first; sock; sock= sock->next) {
- int a;
+void snode_autoconnect(SpaceNode *snode, int allow_multiple, int replace)
+{
+ ListBase *nodelist = MEM_callocN(sizeof(ListBase), "items_list");
+ bNodeListItem *nli;
+ bNode *node;
+ int i;
+
+ for(node= snode->edittree->nodes.first; node; node= node->next) {
+ if(node->flag & NODE_SELECT) {
+ nli = MEM_mallocN(sizeof(bNodeListItem), "temporary node list item");
+ nli->node = node;
+ BLI_addtail(nodelist, nli);
+ }
+ }
+
+ /* sort nodes left to right */
+ BLI_sortlist(nodelist, sort_nodes_locx);
+
+ for (nli=nodelist->first; nli; nli=nli->next) {
+ bNode *node_fr, *node_to;
+ bNodeSocket *sock_fr, *sock_to;
- for(a=0; a<totsock; a++) {
- if(sockfrom[a]) {
- if(sock->type==sockfrom[a]->type && sock->type==socktype) {
- nodeAddLink(snode->edittree, nodefrom[a], sockfrom[a], node_to, sock);
- sockfrom[a]= NULL;
- break;
- }
- }
+ if (nli->next == NULL) break;
+
+ node_fr = nli->node;
+ node_to = nli->next->node;
+
+ /* check over input sockets first */
+ for (i=0; i<BLI_countlist(&node_to->inputs); i++) {
+
+ /* find the best guess input socket */
+ sock_to = best_socket_input(snode->edittree, node_to, i, replace);
+ if (!sock_to) continue;
+
+ /* check for an appropriate output socket to connect from */
+ sock_fr = best_socket_output(snode->edittree, node_fr, sock_to, allow_multiple);
+ if (!sock_fr) continue;
+
+ /* then we can connect */
+ if (replace)
+ nodeRemSocketLinks(snode->edittree, sock_to);
+ nodeAddLink(snode->edittree, node_fr, sock_fr, node_to, sock_to);
+ NodeTagChanged(snode->edittree, node_to);
+ break;
}
}
ntreeSolveOrder(snode->edittree);
+
+ BLI_freelistN(nodelist);
+ MEM_freeN(nodelist);
}
-
/* can be called from menus too, but they should do own undopush and redraws */
bNode *node_add_node(SpaceNode *snode, Scene *scene, int type, float locx, float locy)
{
@@ -1506,24 +1299,6 @@ typedef struct NodeLinkDrag
int in_out;
} NodeLinkDrag;
-/*static*/ void reset_sel_socket(SpaceNode *snode, int in_out)
-{
- bNode *node;
- bNodeSocket *sock;
-
- for(node= snode->edittree->nodes.first; node; node= node->next) {
- if(in_out & SOCK_IN) {
- for(sock= node->inputs.first; sock; sock= sock->next)
- if(sock->flag & SOCK_SEL) sock->flag&= ~SOCK_SEL;
- }
- if(in_out & SOCK_OUT) {
- for(sock= node->outputs.first; sock; sock= sock->next)
- if(sock->flag & SOCK_SEL) sock->flag&= ~SOCK_SEL;
- }
- }
-}
-
-
static void node_remove_extra_links(SpaceNode *snode, bNodeSocket *tsock, bNodeLink *link)
{
bNodeLink *tlink;
@@ -1745,31 +1520,10 @@ void NODE_OT_link(wmOperatorType *ot)
static int node_make_link_exec(bContext *C, wmOperator *op)
{
SpaceNode *snode= CTX_wm_space_node(C);
- bNode *fromnode, *tonode;
- bNodeLink *link;
- bNodeSocket *outsock= snode->edittree->selout;
- bNodeSocket *insock= snode->edittree->selin;
-
- if (!insock || !outsock) {
- BKE_report(op->reports, RPT_ERROR, "No input or output socket(s) selected");
- return OPERATOR_CANCELLED;
- }
- if (nodeFindLink(snode->edittree, outsock, insock)) {
- BKE_report(op->reports, RPT_ERROR, "There is already a link between these sockets");
- return OPERATOR_CANCELLED;
- }
+ int replace = RNA_boolean_get(op->ptr, "replace");
- if (nodeFindNode(snode->edittree, outsock, &fromnode, NULL) &&
- nodeFindNode(snode->edittree, insock, &tonode, NULL))
- {
- link= nodeAddLink(snode->edittree, fromnode, outsock, tonode, insock);
- NodeTagChanged(snode->edittree, tonode);
- node_remove_extra_links(snode, insock, link);
- }
- else
- return OPERATOR_CANCELLED;
+ snode_autoconnect(snode, 0, replace);
- ntreeSolveOrder(snode->edittree);
node_tree_verify_groups(snode->nodetree);
snode_handle_recalc(C, snode);
@@ -1789,6 +1543,8 @@ void NODE_OT_link_make(wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ RNA_def_boolean(ot->srna, "replace", 0, "Replace", "Replace socket connections with the new links");
}
/* ********************** Cut Link operator ***************** */
@@ -2091,18 +1847,10 @@ static int node_delete_exec(bContext *C, wmOperator *op)
{
SpaceNode *snode= CTX_wm_space_node(C);
bNode *node, *next;
- bNodeSocket *sock;
for(node= snode->edittree->nodes.first; node; node= next) {
next= node->next;
if(node->flag & SELECT) {
- /* set selin and selout NULL if the sockets belong to a node to be deleted */
- for(sock= node->inputs.first; sock; sock= sock->next)
- if(snode->edittree->selin == sock) snode->edittree->selin= NULL;
-
- for(sock= node->outputs.first; sock; sock= sock->next)
- if(snode->edittree->selout == sock) snode->edittree->selout= NULL;
-
/* check id user here, nodeFreeNode is called for free dbase too */
if(node->id)
node->id->us--;
diff --git a/source/blender/editors/space_node/node_header.c b/source/blender/editors/space_node/node_header.c
index 4cedbe3f666..d8a14c6412b 100644
--- a/source/blender/editors/space_node/node_header.c
+++ b/source/blender/editors/space_node/node_header.c
@@ -78,8 +78,17 @@ static void do_node_add(bContext *C, void *arg, int event)
node= node_add_node(snode, CTX_data_scene(C), event, snode->mx, snode->my);
- /* uses test flag */
- snode_autoconnect(snode, node, NODE_TEST);
+ /* select previous selection before autoconnect */
+ for(node= snode->edittree->nodes.first; node; node= node->next) {
+ if(node->flag & NODE_TEST) node->flag |= NODE_SELECT;
+ }
+
+ snode_autoconnect(snode, 1, 0);
+
+ /* deselect after autoconnection */
+ for(node= snode->edittree->nodes.first; node; node= node->next) {
+ if(node->flag & NODE_TEST) node->flag &= ~NODE_SELECT;
+ }
snode_handle_recalc(C, snode);
}
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index 84729dd18ec..1ff2f7d7128 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -81,7 +81,7 @@ void node_deselectall(SpaceNode *snode);
void snode_composite_job(const struct bContext *C, ScrArea *sa);
bNode *node_tree_get_editgroup(bNodeTree *ntree);
void node_tree_verify_groups(bNodeTree *nodetree);
-void snode_autoconnect(SpaceNode *snode, bNode *node_to, int flag);
+void snode_autoconnect(SpaceNode *snode, int allow_multiple, int replace);
int node_has_hidden_sockets(bNode *node);
void NODE_OT_duplicate(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c
index 534ca0aa99c..bc04268c6f0 100644
--- a/source/blender/editors/space_node/node_ops.c
+++ b/source/blender/editors/space_node/node_ops.c
@@ -109,14 +109,16 @@ void node_keymap(struct wmKeyConfig *keyconf)
RNA_boolean_set(kmi->ptr, "extend", 1);
kmi= WM_keymap_add_item(keymap, "NODE_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "extend", 1);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "NODE_OT_select_border", EVT_TWEAK_S, KM_ANY, 0, 0)->ptr, "tweak", 1);
/* each of these falls through if not handled... */
WM_keymap_add_item(keymap, "NODE_OT_link", LEFTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "NODE_OT_resize", LEFTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "NODE_OT_visibility_toggle", LEFTMOUSE, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "NODE_OT_links_cut", RIGHTMOUSE, KM_PRESS, KM_ALT, 0);
+ WM_keymap_add_item(keymap, "NODE_OT_links_cut", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "NODE_OT_link_make", FKEY, KM_PRESS, 0, 0);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "NODE_OT_link_make", FKEY, KM_PRESS, KM_CTRL, 0)->ptr, "replace", 1);
WM_keymap_add_menu(keymap, "NODE_MT_add", AKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "NODE_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0);
diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c
index c81cfb47f5b..518901bcbec 100644
--- a/source/blender/editors/space_node/node_select.c
+++ b/source/blender/editors/space_node/node_select.c
@@ -55,7 +55,21 @@
#include "UI_view2d.h"
#include "node_intern.h"
-
+
+/* ****** helpers ****** */
+
+static bNode *node_under_mouse(bNodeTree *ntree, int mx, int my)
+{
+ bNode *node;
+
+ for(next_node(ntree); (node=next_node(NULL));) {
+ /* node body (header and scale are in other operators) */
+ if (BLI_in_rctf(&node->totr, mx, my))
+ return node;
+ }
+ return NULL;
+}
+
/* ****** Click Select ****** */
static bNode *node_mouse_select(SpaceNode *snode, ARegion *ar, short *mval, short extend)
@@ -70,11 +84,7 @@ static bNode *node_mouse_select(SpaceNode *snode, ARegion *ar, short *mval, shor
UI_view2d_region_to_view(&ar->v2d, mval[0], mval[1], &mx, &my);
/* find the closest visible node */
- for(next_node(snode->edittree); (node=next_node(NULL));) {
- /* node body (header and scale are in other operators) */
- if (BLI_in_rctf(&node->totr, mx, my))
- break;
- }
+ node = node_under_mouse(snode->edittree, mx, my);
if (node) {
if (extend == 0) {
@@ -177,9 +187,6 @@ static int node_borderselect_exec(bContext *C, wmOperator *op)
rect.ymax= RNA_int_get(op->ptr, "ymax");
UI_view2d_region_to_view(&ar->v2d, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax);
- if (snode->edittree == NULL) // XXX should this be in poll()? - campbell
- return OPERATOR_FINISHED;
-
for(node= snode->edittree->nodes.first; node; node= node->next) {
if(BLI_isect_rctf(&rectf, &node->totr, NULL)) {
if(gesture_mode==GESTURE_MODAL_SELECT)
@@ -194,6 +201,34 @@ static int node_borderselect_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+static int node_border_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ int tweak = RNA_boolean_get(op->ptr, "tweak");
+
+ if (tweak) {
+ /* prevent initiating the border select if the mouse is over a node */
+ /* this allows border select on empty space, but drag-translate on nodes */
+ SpaceNode *snode= CTX_wm_space_node(C);
+ ARegion *ar= CTX_wm_region(C);
+ short mval[2];
+ float mx, my;
+
+ mval[0]= event->x - ar->winrct.xmin;
+ mval[1]= event->y - ar->winrct.ymin;
+
+ /* get mouse coordinates in view2d space */
+ mx= (float)mval[0];
+ my= (float)mval[1];
+
+ UI_view2d_region_to_view(&ar->v2d, mval[0], mval[1], &mx, &my);
+
+ if (node_under_mouse(snode->edittree, mx, my))
+ return OPERATOR_CANCELLED|OPERATOR_PASS_THROUGH;
+ }
+
+ return WM_border_select_invoke(C, op, event);
+}
+
void NODE_OT_select_border(wmOperatorType *ot)
{
/* identifiers */
@@ -201,7 +236,7 @@ void NODE_OT_select_border(wmOperatorType *ot)
ot->idname= "NODE_OT_select_border";
/* api callbacks */
- ot->invoke= WM_border_select_invoke;
+ ot->invoke= node_border_select_invoke;
ot->exec= node_borderselect_exec;
ot->modal= WM_border_select_modal;
@@ -212,6 +247,7 @@ void NODE_OT_select_border(wmOperatorType *ot)
/* rna */
WM_operator_properties_gesture_border(ot, FALSE);
+ RNA_def_boolean(ot->srna, "tweak", 0, "Tweak", "Only activate when mouse is not over a node - useful for tweak gesture");
}
/* ****** Select/Deselect All ****** */
diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c
index f3485328c52..93b32086614 100644
--- a/source/blender/editors/space_outliner/outliner.c
+++ b/source/blender/editors/space_outliner/outliner.c
@@ -69,6 +69,7 @@
#include "BKE_context.h"
#include "BKE_deform.h"
#include "BKE_depsgraph.h"
+#include "BKE_fcurve.h"
#include "BKE_global.h"
#include "BKE_group.h"
#include "BKE_library.h"
@@ -913,18 +914,25 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
TreeElement *ted= outliner_add_element(soops, &te->subtree, adt, te, TSE_DRIVER_BASE, 0);
ID *lastadded= NULL;
FCurve *fcu;
- DriverTarget *dtar;
ted->name= "Drivers";
for (fcu= adt->drivers.first; fcu; fcu= fcu->next) {
- if (fcu->driver && fcu->driver->targets.first) {
- for (dtar= fcu->driver->targets.first; dtar; dtar= dtar->next) {
- if (lastadded != dtar->id) {
- // XXX this lastadded check is rather lame, and also fails quite badly...
- outliner_add_element(soops, &ted->subtree, dtar->id, ted, TSE_LINKED_OB, 0);
- lastadded= dtar->id;
+ if (fcu->driver && fcu->driver->variables.first) {
+ ChannelDriver *driver= fcu->driver;
+ DriverVar *dvar;
+
+ for (dvar= driver->variables.first; dvar; dvar= dvar->next) {
+ /* loop over all targets used here */
+ DRIVER_TARGETS_USED_LOOPER(dvar)
+ {
+ if (lastadded != dtar->id) {
+ // XXX this lastadded check is rather lame, and also fails quite badly...
+ outliner_add_element(soops, &ted->subtree, dtar->id, ted, TSE_LINKED_OB, 0);
+ lastadded= dtar->id;
+ }
}
+ DRIVER_TARGETS_LOOPER_END
}
}
}
@@ -5029,7 +5037,7 @@ static uiBlock *operator_search_menu(bContext *C, ARegion *ar, void *arg_kmi)
/* fake button, it holds space for search items */
uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
- but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, 150, 19, "");
+ but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, 150, 19, 0, 0, "");
uiButSetSearchFunc(but, operator_search_cb, arg_kmi, operator_call_cb, ot);
uiBoundsBlock(block, 6);
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index a2525430a10..37bb75a5efd 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -699,8 +699,14 @@ void draw_image_seq(Scene *scene, ARegion *ar, SpaceSeq *sseq)
break;
}
- if(ibuf->rect_float && ibuf->rect==NULL)
- IMB_rect_from_float(ibuf);
+ if(ibuf->rect_float && ibuf->rect==NULL) {
+ if (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) {
+ ibuf->profile = IB_PROFILE_LINEAR_RGB;
+ } else {
+ ibuf->profile = IB_PROFILE_NONE;
+ }
+ IMB_rect_from_float(ibuf);
+ }
/* needed for gla draw */
glaDefine2DArea(&ar->winrct);
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index f174e96120c..bd1db4c29b6 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -382,55 +382,6 @@ Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, short mval[2])
return 0;
}
-void update_seq_ipo_rect(Scene *scene, View2D *v2d, Sequence *seq)
-{
- float start;
- float end;
-
- if (!seq || !seq->ipo) {
- return;
- }
- start = -5.0;
- end = 105.0;
-
-
- /* Adjust IPO window to sequence and
- avoid annoying snap-back to startframe
- when Lock Time is on */
- if (0) { // XXX v2d->flag & V2D_VIEWLOCK) {
- if ((seq->flag & SEQ_IPO_FRAME_LOCKED) != 0) {
- start = -5.0 + seq->startdisp;
- end = 5.0 + seq->enddisp;
- } else {
- start = (float)scene->r.sfra - 0.1;
- end = scene->r.efra;
- }
- }
-
- seq->ipo->cur.xmin= start;
- seq->ipo->cur.xmax= end;
-}
-
-void update_seq_icu_rects(Sequence * seq)
-{
- IpoCurve *icu= NULL;
- struct SeqEffectHandle sh;
-
- if (!seq || !seq->ipo) {
- return;
- }
-
- if(!(seq->type & SEQ_EFFECT)) {
- return;
- }
-
- sh = get_sequence_effect(seq);
-
- for(icu= seq->ipo->curve.first; icu; icu= icu->next) {
- sh.store_icu_yrange(seq, icu->adrcode, &icu->ymin, &icu->ymax);
- }
-}
-
static int seq_is_parent(Sequence *par, Sequence *seq)
{
@@ -2331,11 +2282,13 @@ void SEQUENCER_OT_view_all_preview(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER;
}
+#if 0
static EnumPropertyItem view_type_items[] = {
{SEQ_VIEW_SEQUENCE, "SEQUENCER", ICON_SEQ_SEQUENCER, "Sequencer", ""},
{SEQ_VIEW_PREVIEW, "PREVIEW", ICON_SEQ_PREVIEW, "Image Preview", ""},
{SEQ_VIEW_SEQUENCE_PREVIEW, "SEQUENCER_PREVIEW", ICON_SEQ_SEQUENCER, "Sequencer and Image Preview", ""},
{0, NULL, 0, NULL, NULL}};
+#endif
/* view_all operator */
static int sequencer_view_toggle_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c
index 2f0e631e927..292249bb0e8 100644
--- a/source/blender/editors/space_text/space_text.c
+++ b/source/blender/editors/space_text/space_text.c
@@ -209,6 +209,7 @@ static void text_operatortypes(void)
static void text_keymap(struct wmKeyConfig *keyconf)
{
wmKeyMap *keymap;
+ wmKeyMapItem *kmi;
keymap= WM_keymap_find(keyconf, "Text", SPACE_TEXT, 0);
@@ -229,6 +230,22 @@ static void text_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "TEXT_OT_select_line", AKEY, KM_PRESS, KM_SHIFT|KM_OSKEY, 0);
#endif
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", WHEELUPMOUSE, KM_PRESS, KM_CTRL, 0);
+ RNA_string_set(kmi->ptr, "path", "space_data.font_size");
+ RNA_boolean_set(kmi->ptr, "reverse", 0);
+
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL, 0);
+ RNA_string_set(kmi->ptr, "path", "space_data.font_size");
+ RNA_boolean_set(kmi->ptr, "reverse", 1);
+
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
+ RNA_string_set(kmi->ptr, "path", "space_data.font_size");
+ RNA_boolean_set(kmi->ptr, "reverse", 0);
+
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", PADMINUS, KM_PRESS, KM_CTRL, 0);
+ RNA_string_set(kmi->ptr, "path", "space_data.font_size");
+ RNA_boolean_set(kmi->ptr, "reverse", 1);
+
WM_keymap_add_item(keymap, "TEXT_OT_new", NKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "TEXT_OT_open", OKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "TEXT_OT_reload", RKEY, KM_PRESS, KM_ALT, 0);
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index 1a23b9ecc42..0504db51a72 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -526,6 +526,11 @@ void TEXT_OT_save_as(wmOperatorType *ot)
/******************* run script operator *********************/
+static int run_script_poll(bContext *C)
+{
+ return (CTX_data_edit_text(C) != NULL);
+}
+
static int run_script_exec(bContext *C, wmOperator *op)
{
#ifdef DISABLE_PYTHON
@@ -534,12 +539,13 @@ static int run_script_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
#else
Text *text= CTX_data_edit_text(C);
+ SpaceText *st= CTX_wm_space_text(C);
if (BPY_run_python_script(C, NULL, text, op->reports))
return OPERATOR_FINISHED;
/* Dont report error messages while live editing */
- if(!CTX_wm_space_text(C)->live_edit)
+ if(!(st && st->live_edit))
BKE_report(op->reports, RPT_ERROR, "Python script fail, look in the console for now...");
return OPERATOR_CANCELLED;
@@ -554,8 +560,8 @@ void TEXT_OT_run_script(wmOperatorType *ot)
ot->description= "Run active script.";
/* api callbacks */
+ ot->poll= run_script_poll;
ot->exec= run_script_exec;
-// ot->poll= text_edit_poll; // dont do this since linked texts cant run
}
diff --git a/source/blender/editors/space_view3d/drawanimviz.c b/source/blender/editors/space_view3d/drawanimviz.c
new file mode 100644
index 00000000000..b8184a60cee
--- /dev/null
+++ b/source/blender/editors/space_view3d/drawanimviz.c
@@ -0,0 +1,564 @@
+/**
+ * $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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2009 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Joshua Leung
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_anim_types.h"
+#include "DNA_action_types.h"
+#include "DNA_armature_types.h"
+#include "DNA_constraint_types.h"
+#include "DNA_ID.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_userdef_types.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_dlrbTree.h"
+
+#include "BKE_anim.h"
+#include "BKE_animsys.h"
+#include "BKE_action.h"
+#include "BKE_armature.h"
+#include "BKE_constraint.h"
+#include "BKE_context.h"
+#include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_modifier.h"
+#include "BKE_nla.h"
+#include "BKE_object.h"
+#include "BKE_utildefines.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
+#include "ED_armature.h"
+#include "ED_anim_api.h"
+#include "ED_keyframes_draw.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+#include "BLF_api.h"
+
+#include "UI_resources.h"
+
+#include "view3d_intern.h"
+
+/* ************************************ Motion Paths ************************************* */
+
+// TODO:
+// - options to draw paths with lines
+// - include support for editing the path verts
+
+/* Set up drawing environment for drawing motion paths */
+void draw_motion_paths_init(Scene *scene, View3D *v3d, ARegion *ar)
+{
+ RegionView3D *rv3d= ar->regiondata;
+
+ if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
+
+ glPushMatrix();
+ glLoadMatrixf(rv3d->viewmat);
+}
+
+/* Draw the given motion path for an Object or a Bone
+ * - assumes that the viewport has already been initialised properly
+ * i.e. draw_motion_paths_init() has been called
+ */
+void draw_motion_path_instance(Scene *scene, View3D *v3d, ARegion *ar,
+ Object *ob, bPoseChannel *pchan, bAnimVizSettings *avs, bMotionPath *mpath)
+{
+ //RegionView3D *rv3d= ar->regiondata;
+ bMotionPathVert *mpv, *mpv_start;
+ int i, stepsize= avs->path_step;
+ int sfra, efra, len;
+
+
+ /* get frame ranges */
+ if (avs->path_type == MOTIONPATH_TYPE_ACFRA) {
+ int sind;
+
+ /* With "Around Current", we only choose frames from around
+ * the current frame to draw. However, this range is still
+ * restricted by the limits of the original path.
+ */
+ sfra= CFRA - avs->path_bc;
+ efra= CFRA + avs->path_ac;
+ if (sfra < mpath->start_frame) sfra= mpath->start_frame;
+ if (efra > mpath->end_frame) efra= mpath->end_frame;
+
+ len= efra - sfra;
+
+ sind= sfra - mpath->start_frame;
+ mpv_start= (mpath->points + sind);
+ }
+ else {
+ sfra= mpath->start_frame;
+ efra = sfra + mpath->length;
+ len = mpath->length;
+ mpv_start= mpath->points;
+ }
+
+ /* draw curve-line of path */
+ glShadeModel(GL_SMOOTH);
+
+ glBegin(GL_LINE_STRIP);
+ for (i=0, mpv=mpv_start; i < len; i++, mpv++) {
+ short sel= (pchan) ? (pchan->bone->flag & BONE_SELECTED) : (ob->flag & SELECT);
+ float intensity; /* how faint */
+
+ /* set color
+ * - more intense for active/selected bones, less intense for unselected bones
+ * - black for before current frame, green for current frame, blue for after current frame
+ * - intensity decreases as distance from current frame increases
+ */
+ #define SET_INTENSITY(A, B, C, min, max) (((1.0f - ((C - B) / (C - A))) * (max-min)) + min)
+ if ((sfra+i) < CFRA) {
+ /* black - before cfra */
+ if (sel) {
+ // intensity= 0.5f;
+ intensity = SET_INTENSITY(sfra, i, CFRA, 0.25f, 0.75f);
+ }
+ else {
+ //intensity= 0.8f;
+ intensity = SET_INTENSITY(sfra, i, CFRA, 0.68f, 0.92f);
+ }
+ UI_ThemeColorBlend(TH_WIRE, TH_BACK, intensity);
+ }
+ else if ((sfra+i) > CFRA) {
+ /* blue - after cfra */
+ if (sel) {
+ //intensity = 0.5f;
+ intensity = SET_INTENSITY(CFRA, i, efra, 0.25f, 0.75f);
+ }
+ else {
+ //intensity = 0.8f;
+ intensity = SET_INTENSITY(CFRA, i, efra, 0.68f, 0.92f);
+ }
+ UI_ThemeColorBlend(TH_BONE_POSE, TH_BACK, intensity);
+ }
+ else {
+ /* green - on cfra */
+ if (sel) {
+ intensity= 0.5f;
+ }
+ else {
+ intensity= 0.99f;
+ }
+ UI_ThemeColorBlendShade(TH_CFRAME, TH_BACK, intensity, 10);
+ }
+
+ /* draw a vertex with this color */
+ glVertex3fv(mpv->co);
+ }
+
+ glEnd();
+ glShadeModel(GL_FLAT);
+
+ glPointSize(1.0);
+
+ /* draw little black point at each frame
+ * NOTE: this is not really visible/noticable
+ */
+ glBegin(GL_POINTS);
+ for (i=0, mpv=mpv_start; i < len; i++, mpv++)
+ glVertex3fv(mpv->co);
+ glEnd();
+
+ /* Draw little white dots at each framestep value */
+ UI_ThemeColor(TH_TEXT_HI);
+ glBegin(GL_POINTS);
+ for (i=0, mpv=mpv_start; i < len; i+=stepsize, mpv+=stepsize)
+ glVertex3fv(mpv->co);
+ glEnd();
+
+ /* Draw frame numbers at each framestep value */
+ if (avs->path_viewflag & MOTIONPATH_VIEW_FNUMS) {
+ for (i=0, mpv=mpv_start; i < len; i+=stepsize, mpv+=stepsize) {
+ char str[32];
+
+ /* only draw framenum if several consecutive highlighted points don't occur on same point */
+ if (i == 0) {
+ sprintf(str, "%d", (i+sfra));
+ view3d_cached_text_draw_add(mpv->co[0], mpv->co[1], mpv->co[2], str, 0);
+ }
+ else if ((i > stepsize) && (i < len-stepsize)) {
+ bMotionPathVert *mpvP = (mpv - stepsize);
+ bMotionPathVert *mpvN = (mpv + stepsize);
+
+ if ((equals_v3v3(mpv->co, mpvP->co)==0) || (equals_v3v3(mpv->co, mpvN->co)==0)) {
+ sprintf(str, "%d", (sfra+i));
+ view3d_cached_text_draw_add(mpv->co[0], mpv->co[1], mpv->co[2], str, 0);
+ }
+ }
+ }
+ }
+
+ /* Keyframes - dots and numbers */
+ if (avs->path_viewflag & MOTIONPATH_VIEW_KFNOS) {
+ AnimData *adt= BKE_animdata_from_id(&ob->id);
+ DLRBT_Tree keys;
+
+ /* build list of all keyframes in active action for object or pchan */
+ BLI_dlrbTree_init(&keys);
+
+ if (adt) {
+ /* for now, it is assumed that keyframes for bones are all grouped in a single group */
+ if (pchan) {
+ bActionGroup *agrp= action_groups_find_named(adt->action, pchan->name);
+
+ if (agrp) {
+ agroup_to_keylist(adt, agrp, &keys, NULL);
+ BLI_dlrbTree_linkedlist_sync(&keys);
+ }
+ }
+ else {
+ action_to_keylist(adt, adt->action, &keys, NULL);
+ BLI_dlrbTree_linkedlist_sync(&keys);
+ }
+ }
+
+ /* Draw slightly-larger yellow dots at each keyframe */
+ UI_ThemeColor(TH_VERTEX_SELECT);
+ glPointSize(4.0f); // XXX perhaps a bit too big
+
+ glBegin(GL_POINTS);
+ for (i=0, mpv=mpv_start; i < len; i++, mpv++) {
+ float mframe= (float)(sfra + i);
+
+ if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe))
+ glVertex3fv(mpv->co);
+ }
+ glEnd();
+
+ glPointSize(1.0f);
+
+ /* Draw frame numbers of keyframes */
+ if (avs->path_viewflag & (MOTIONPATH_VIEW_FNUMS|MOTIONPATH_VIEW_KFNOS)) {
+ for (i=0, mpv=mpv_start; i < len; i++, mpv++) {
+ float mframe= (float)(sfra + i);
+
+ if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe)) {
+ char str[32];
+
+ sprintf(str, "%d", (sfra+i));
+ view3d_cached_text_draw_add(mpv->co[0], mpv->co[1], mpv->co[2], str, 0);
+ }
+ }
+ }
+
+ BLI_dlrbTree_free(&keys);
+ }
+}
+
+/* Clean up drawing environment after drawing motion paths */
+void draw_motion_paths_cleanup(Scene *scene, View3D *v3d, ARegion *ar)
+{
+ if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
+ glPopMatrix();
+}
+
+#if 0 // XXX temp file guards
+
+/* ***************************** Onion Skinning (Ghosts) ******************************** */
+
+#if 0 // XXX only for bones
+/* helper function for ghost drawing - sets/removes flags for temporarily
+ * hiding unselected bones while drawing ghosts
+ */
+static void ghost_poses_tag_unselected(Object *ob, short unset)
+{
+ bArmature *arm= ob->data;
+ bPose *pose= ob->pose;
+ bPoseChannel *pchan;
+
+ /* don't do anything if no hiding any bones */
+ if ((arm->flag & ARM_GHOST_ONLYSEL)==0)
+ return;
+
+ /* loop over all pchans, adding/removing tags as appropriate */
+ for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
+ if ((pchan->bone) && (arm->layer & pchan->bone->layer)) {
+ if (unset) {
+ /* remove tags from all pchans if cleaning up */
+ pchan->bone->flag &= ~BONE_HIDDEN_PG;
+ }
+ else {
+ /* set tags on unselected pchans only */
+ if ((pchan->bone->flag & BONE_SELECTED)==0)
+ pchan->bone->flag |= BONE_HIDDEN_PG;
+ }
+ }
+ }
+}
+#endif // XXX only for bones
+
+/* draw ghosts that occur within a frame range
+ * note: object should be in posemode
+ */
+static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
+{
+ Object *ob= base->object;
+ AnimData *adt= BKE_animdata_from_id(&ob->id);
+ bArmature *arm= ob->data;
+ bPose *posen, *poseo;
+ float start, end, stepsize, range, colfac;
+ int cfrao, flago, ipoflago;
+
+ start = (float)arm->ghostsf;
+ end = (float)arm->ghostef;
+ if (end <= start)
+ return;
+
+ stepsize= (float)(arm->ghostsize);
+ range= (float)(end - start);
+
+ /* store values */
+ ob->mode &= ~OB_MODE_POSE;
+ cfrao= CFRA;
+ flago= arm->flag;
+ arm->flag &= ~(ARM_DRAWNAMES|ARM_DRAWAXES);
+ ipoflago= ob->ipoflag;
+ ob->ipoflag |= OB_DISABLE_PATH;
+
+ /* copy the pose */
+ poseo= ob->pose;
+ copy_pose(&posen, ob->pose, 1);
+ ob->pose= posen;
+ armature_rebuild_pose(ob, ob->data); /* child pointers for IK */
+ ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */
+
+ glEnable(GL_BLEND);
+ if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
+
+ /* draw from first frame of range to last */
+ for (CFRA= (int)start; CFRA < end; CFRA += (int)stepsize) {
+ colfac = (end - (float)CFRA) / range;
+ UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0*sqrt(colfac)));
+
+ BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
+ where_is_pose(scene, ob);
+ draw_pose_bones(scene, v3d, ar, base, OB_WIRE);
+ }
+ glDisable(GL_BLEND);
+ if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
+
+ ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */
+ free_pose(posen);
+
+ /* restore */
+ CFRA= cfrao;
+ ob->pose= poseo;
+ arm->flag= flago;
+ armature_rebuild_pose(ob, ob->data);
+ ob->mode |= OB_MODE_POSE;
+ ob->ipoflag= ipoflago;
+}
+
+/* draw ghosts on keyframes in action within range
+ * - object should be in posemode
+ */
+static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
+{
+ Object *ob= base->object;
+ AnimData *adt= BKE_animdata_from_id(&ob->id);
+ bAction *act= (adt) ? adt->action : NULL;
+ bArmature *arm= ob->data;
+ bPose *posen, *poseo;
+ DLRBT_Tree keys;
+ ActKeyColumn *ak, *akn;
+ float start, end, range, colfac, i;
+ int cfrao, flago;
+
+ start = (float)arm->ghostsf;
+ end = (float)arm->ghostef;
+ if (end <= start)
+ return;
+
+ /* get keyframes - then clip to only within range */
+ BLI_dlrbTree_init(&keys);
+ action_to_keylist(adt, act, &keys, NULL);
+ BLI_dlrbTree_linkedlist_sync(&keys);
+
+ range= 0;
+ for (ak= keys.first; ak; ak= akn) {
+ akn= ak->next;
+
+ if ((ak->cfra < start) || (ak->cfra > end))
+ BLI_freelinkN((ListBase *)&keys, ak);
+ else
+ range++;
+ }
+ if (range == 0) return;
+
+ /* store values */
+ ob->mode &= ~OB_MODE_POSE;
+ cfrao= CFRA;
+ flago= arm->flag;
+ arm->flag &= ~(ARM_DRAWNAMES|ARM_DRAWAXES);
+ ob->ipoflag |= OB_DISABLE_PATH;
+
+ /* copy the pose */
+ poseo= ob->pose;
+ copy_pose(&posen, ob->pose, 1);
+ ob->pose= posen;
+ armature_rebuild_pose(ob, ob->data); /* child pointers for IK */
+ ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */
+
+ glEnable(GL_BLEND);
+ if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
+
+ /* draw from first frame of range to last */
+ for (ak=keys.first, i=0; ak; ak=ak->next, i++) {
+ colfac = i/range;
+ UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0*sqrt(colfac)));
+
+ CFRA= (int)ak->cfra;
+
+ BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
+ where_is_pose(scene, ob);
+ draw_pose_bones(scene, v3d, ar, base, OB_WIRE);
+ }
+ glDisable(GL_BLEND);
+ if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
+
+ ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */
+ BLI_dlrbTree_free(&keys);
+ free_pose(posen);
+
+ /* restore */
+ CFRA= cfrao;
+ ob->pose= poseo;
+ arm->flag= flago;
+ armature_rebuild_pose(ob, ob->data);
+ ob->mode |= OB_MODE_POSE;
+}
+
+/* draw ghosts around current frame
+ * - object is supposed to be armature in posemode
+ */
+static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
+{
+ Object *ob= base->object;
+ AnimData *adt= BKE_animdata_from_id(&ob->id);
+ bArmature *arm= ob->data;
+ bPose *posen, *poseo;
+ float cur, start, end, stepsize, range, colfac, actframe, ctime;
+ int cfrao, flago;
+
+ /* pre conditions, get an action with sufficient frames */
+ if ELEM(NULL, adt, adt->action)
+ return;
+
+ calc_action_range(adt->action, &start, &end, 0);
+ if (start == end)
+ return;
+
+ stepsize= (float)(arm->ghostsize);
+ range= (float)(arm->ghostep)*stepsize + 0.5f; /* plus half to make the for loop end correct */
+
+ /* store values */
+ ob->mode &= ~OB_MODE_POSE;
+ cfrao= CFRA;
+ actframe= BKE_nla_tweakedit_remap(adt, (float)CFRA, 0);
+ flago= arm->flag;
+ arm->flag &= ~(ARM_DRAWNAMES|ARM_DRAWAXES);
+
+ /* copy the pose */
+ poseo= ob->pose;
+ copy_pose(&posen, ob->pose, 1);
+ ob->pose= posen;
+ armature_rebuild_pose(ob, ob->data); /* child pointers for IK */
+ ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */
+
+ glEnable(GL_BLEND);
+ if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
+
+ /* draw from darkest blend to lowest */
+ for(cur= stepsize; cur<range; cur+=stepsize) {
+ ctime= cur - (float)fmod(cfrao, stepsize); /* ensures consistant stepping */
+ colfac= ctime/range;
+ UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0*sqrt(colfac)));
+
+ /* only within action range */
+ if (actframe+ctime >= start && actframe+ctime <= end) {
+ CFRA= (int)BKE_nla_tweakedit_remap(adt, actframe+ctime, NLATIME_CONVERT_MAP);
+
+ if (CFRA != cfrao) {
+ BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
+ where_is_pose(scene, ob);
+ draw_pose_bones(scene, v3d, ar, base, OB_WIRE);
+ }
+ }
+
+ ctime= cur + (float)fmod((float)cfrao, stepsize) - stepsize+1.0f; /* ensures consistant stepping */
+ colfac= ctime/range;
+ UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0*sqrt(colfac)));
+
+ /* only within action range */
+ if ((actframe-ctime >= start) && (actframe-ctime <= end)) {
+ CFRA= (int)BKE_nla_tweakedit_remap(adt, actframe-ctime, NLATIME_CONVERT_MAP);
+
+ if (CFRA != cfrao) {
+ BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
+ where_is_pose(scene, ob);
+ draw_pose_bones(scene, v3d, ar, base, OB_WIRE);
+ }
+ }
+ }
+ glDisable(GL_BLEND);
+ if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
+
+ ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */
+ free_pose(posen);
+
+ /* restore */
+ CFRA= cfrao;
+ ob->pose= poseo;
+ arm->flag= flago;
+ armature_rebuild_pose(ob, ob->data);
+ ob->mode |= OB_MODE_POSE;
+}
+
+
+
+#endif // XXX temp file guards
diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c
index d8c2fb9d43e..c59c5cddb3f 100644
--- a/source/blender/editors/space_view3d/drawarmature.c
+++ b/source/blender/editors/space_view3d/drawarmature.c
@@ -1622,8 +1622,14 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
if ( (bone) && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG)) ) {
if (bone->layer & arm->layer) {
+ int use_custom = (pchan->custom) && !(arm->flag & ARM_NO_CUSTOM);
glPushMatrix();
- glMultMatrixf(pchan->pose_mat);
+
+ if(use_custom && pchan->custom_tx) {
+ glMultMatrixf(pchan->custom_tx->pose_mat);
+ } else {
+ glMultMatrixf(pchan->pose_mat);
+ }
/* catch exception for bone with hidden parent */
flag= bone->flag;
@@ -1637,7 +1643,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
/* set color-set to use */
set_pchan_colorset(ob, pchan);
- if ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) {
+ if (use_custom) {
/* if drawwire, don't try to draw in solid */
if (pchan->bone->flag & BONE_DRAWWIRE)
draw_wire= 1;
@@ -1687,7 +1693,12 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
if (pchan->custom) {
if ((dt < OB_SOLID) || (bone->flag & BONE_DRAWWIRE)) {
glPushMatrix();
- glMultMatrixf(pchan->pose_mat);
+
+ if(pchan->custom_tx) {
+ glMultMatrixf(pchan->custom_tx->pose_mat);
+ } else {
+ glMultMatrixf(pchan->pose_mat);
+ }
/* prepare colors */
if (arm->flag & ARM_POSEMODE)
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index c689b4d338f..77d8ed0f24d 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -103,7 +103,6 @@
#include "GPU_draw.h"
#include "GPU_material.h"
#include "GPU_extensions.h"
-#include "gpu_buffers.h"
#include "ED_mesh.h"
#include "ED_particle.h"
@@ -798,25 +797,30 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
curcol[3]= 0.6;
glColor4fv(curcol);
- if(ob->id.us>1) {
- if (ob==OBACT || (ob->flag & SELECT)) glColor4ub(0x88, 0xFF, 0xFF, 155);
- else glColor4ub(0x77, 0xCC, 0xCC, 155);
- }
-
- /* Inner Circle */
- VECCOPY(vec, ob->obmat[3]);
- glEnable(GL_BLEND);
- drawcircball(GL_LINE_LOOP, vec, lampsize, imat);
- glDisable(GL_BLEND);
- drawcircball(GL_POLYGON, vec, lampsize, imat);
-
- /* restore */
- if(ob->id.us>1)
- glColor4fv(curcol);
+ if(lampsize > 0.0f) {
+
+ if(ob->id.us>1) {
+ if (ob==OBACT || (ob->flag & SELECT)) glColor4ub(0x88, 0xFF, 0xFF, 155);
+ else glColor4ub(0x77, 0xCC, 0xCC, 155);
+ }
+
+ /* Inner Circle */
+ VECCOPY(vec, ob->obmat[3]);
+ glEnable(GL_BLEND);
+ drawcircball(GL_LINE_LOOP, vec, lampsize, imat);
+ glDisable(GL_BLEND);
+ drawcircball(GL_POLYGON, vec, lampsize, imat);
- /* Outer circle */
- circrad = 3.0f*lampsize;
- drawcircball(GL_LINE_LOOP, vec, circrad, imat);
+ /* restore */
+ if(ob->id.us>1)
+ glColor4fv(curcol);
+
+ /* Outer circle */
+ circrad = 3.0f*lampsize;
+ drawcircball(GL_LINE_LOOP, vec, circrad, imat);
+ }
+ else
+ circrad = 0.0f;
setlinestyle(3);
@@ -1572,82 +1576,15 @@ static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float *
}
}
-/* disabled because it crashes combined with e.g. subsurf modifier,
- * the derivedmesh can't be assumed to be an EditMeshDerivedMesh,
- * nor should this struct be copied around, it should be defined in
- * a single place only to avoid them getting out of sync */
-#if 0
-/* originally defined in DerivedMesh.c */
-typedef struct {
- DerivedMesh dm;
-
- EditMesh *em;
- float (*vertexCos)[3];
- float (*vertexNos)[3];
- float (*faceNos)[3];
-} EditMeshDerivedMesh;
-#endif
-
static void draw_dm_verts(DerivedMesh *dm, int sel, EditVert *eve_act)
{
struct { int sel; EditVert *eve_act; } data;
- //GPUBuffer *buffer;
- //float *varray;
data.sel = sel;
data.eve_act = eve_act;
-#if 0
- /* first come the unselected vertices, then the selected */
- buffer = GPU_buffer_legacy(dm)?0:GPU_buffer_alloc( sizeof(float)*3*dm->getNumVerts(dm)*2, 0 );
-
- if( (varray = GPU_buffer_lock_stream( buffer )) && bglPointHack() == 0 ) {
- EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
- EditVert *eve;
- int i;
- int numverts = 0, numselected = 0;
- int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_END };
- GPU_buffer_unlock( buffer );
- GPU_interleaved_setup( buffer, datatype );
- varray = GPU_buffer_lock_stream( buffer );
-
- glBegin(GL_POINTS);
- for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) {
- if (eve->h==0 && (eve->f&SELECT)==data.sel) {
- if (eve==data.eve_act) {
- if (emdm->vertexCos) {
- VECCOPY(&varray[3*(dm->getNumVerts(dm)+numselected)],emdm->vertexCos[i]);
- }
- else {
- VECCOPY(&varray[3*(dm->getNumVerts(dm)+numselected)],eve->co);
- }
- numselected++;
- } else {
- if (emdm->vertexCos) {
- VECCOPY(&varray[3*numverts],emdm->vertexCos[i]);
- } else {
- VECCOPY(&varray[3*numverts],eve->co);
- }
- numverts++;
- }
- }
- }
- glEnd();
- GPU_buffer_unlock( buffer );
- glDrawArrays(GL_POINTS,0,numverts);
- UI_ThemeColor4(TH_EDITMESH_ACTIVE);
- glDrawArrays(GL_POINTS,dm->getNumVerts(dm),numselected);
- UI_ThemeColor4(data.sel?TH_VERTEX_SELECT:TH_VERTEX);
- GPU_buffer_unbind();
- }
- {
-#endif
- bglBegin(GL_POINTS);
- dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data);
- bglEnd();
-#if 0
- }
- GPU_buffer_free( buffer, 0 );
-#endif
+ bglBegin(GL_POINTS);
+ dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data);
+ bglEnd();
}
/* Draw edges with color set based on selection */
@@ -1719,55 +1656,8 @@ static void draw_dm_edges_sel_interp__setDrawInterpOptions(void *userData, int i
static void draw_dm_edges_sel_interp(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol)
{
unsigned char *cols[2] = {baseCol, selCol};
-#if 0
- int elemsize = sizeof(float)*3+sizeof(unsigned char)*4;
- EditMeshDerivedMesh *emdm = (EditMeshDerivedMesh *)dm;
- EditMesh *em= emdm->em;
- unsigned char *varray;
- int i;
- GPUBuffer *buffer;
-
- buffer = GPU_buffer_legacy(dm)?0:GPU_buffer_alloc( elemsize*em->totedge*2, 0 );
- if( (varray = GPU_buffer_lock_stream( buffer )) ) {
- EditEdge *eed;
- int numedges = 0;
- int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_C4UB, GPU_BUFFER_INTER_END };
- GPU_buffer_unlock( buffer );
- GPU_interleaved_setup( buffer, datatype );
- varray = GPU_buffer_lock_stream( buffer );
- for (i=0,eed= em->edges.first; eed; i++,eed= eed->next) {
- if(eed->h==0) {
- unsigned char *col0 = cols[(eed->v1->f&SELECT)?1:0];
- unsigned char *col1 = cols[(eed->v2->f&SELECT)?1:0];
-
- if( emdm->vertexCos ) {
- VECCOPY(((float *)&varray[elemsize*numedges*2]),emdm->vertexCos[(int) eed->v1->tmp.l]);
- }
- else {
- VECCOPY(((float *)&varray[elemsize*numedges*2]),eed->v1->co);
- }
- QUATCOPY(&varray[elemsize*numedges*2+sizeof(float)*3],col0);
- if( emdm->vertexCos ) {
- VECCOPY(((float *)&varray[elemsize*numedges*2+elemsize]),emdm->vertexCos[(int) eed->v2->tmp.l]);
- }
- else {
- VECCOPY(((float *)&varray[elemsize*numedges*2+elemsize]),eed->v2->co);
- }
- QUATCOPY(&varray[elemsize*numedges*2+elemsize+sizeof(float)*3],col1);
- numedges++;
- }
- }
- GPU_buffer_unlock( buffer );
- glDrawArrays(GL_LINES,0,numedges*2);
- GPU_buffer_unbind();
- }
- else {
-#endif
- dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, cols);
-#if 0
- }
- GPU_buffer_free( buffer, 0 );
-#endif
+
+ dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, cols);
}
/* Draw only seam edges */
@@ -1821,236 +1711,12 @@ static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *dra
static void draw_dm_faces_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, EditFace *efa_act)
{
struct { unsigned char *cols[3]; EditFace *efa_act; } data;
- //EditMeshDerivedMesh *emdm = (EditMeshDerivedMesh *)dm;
- EditFace *efa;
- unsigned char *col;
- GPUBuffer *buffer;
- unsigned char *varray;
- unsigned char black[] = { 0, 0, 0, 0 };
- int i, draw=0;
- int elemsize = (sizeof(float)*6+sizeof(unsigned char)*4);
data.cols[0] = baseCol;
data.cols[1] = selCol;
data.cols[2] = actCol;
data.efa_act = efa_act;
-
- buffer = GPU_buffer_legacy(dm)?0:GPU_buffer_alloc( elemsize*dm->getNumFaces(dm)*3*2, 0 );
- if( dm->getVertCos == 0 && (varray = GPU_buffer_lock_stream( buffer )) ) {
- int prevdraw = 0;
- int numfaces = 0;
- int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_N3F, GPU_BUFFER_INTER_C4UB, GPU_BUFFER_INTER_END };
- GPU_buffer_unlock( buffer );
- GPU_interleaved_setup( buffer, datatype );
- glShadeModel(GL_SMOOTH);
- varray = GPU_buffer_lock_stream( buffer );
- for (i=0,efa= efa_act; efa; i++,efa= efa->next) {
- int drawSmooth = (efa->flag & ME_SMOOTH);
- if (efa->h==0) {
- if (efa == data.efa_act) {
- draw = 2;
- } else {
- col = data.cols[(efa->f&SELECT)?1:0];
- if (col[3]==0) draw = 0;
- else draw = 1;
- }
- }
- else {
- draw = 0;
- }
- if( prevdraw != draw && prevdraw != 0 && numfaces > 0) {
- if( prevdraw==2 ) {
- glEnable(GL_POLYGON_STIPPLE);
- glPolygonStipple(stipple_quarttone);
- }
- GPU_buffer_unlock( buffer );
- glDrawArrays(GL_TRIANGLES,0,numfaces*3);
- if( prevdraw==2 ) {
- glDisable(GL_POLYGON_STIPPLE);
- }
- varray = GPU_buffer_lock_stream( buffer );
- numfaces = 0;
- }
-
- if( draw != 0 ) {
- if(!drawSmooth) {
- /*if (emdm->vertexCos) {
- VECCOPY((float *)&varray[elemsize*3*numfaces],emdm->vertexCos[(int) efa->v1->tmp.l]);
- VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],emdm->faceNos[i]);
-
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],emdm->vertexCos[(int) efa->v2->tmp.l]);
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],emdm->faceNos[i]);
-
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],emdm->vertexCos[(int) efa->v3->tmp.l]);
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],emdm->faceNos[i]);
- }
- else {*/
- VECCOPY((float *)&varray[elemsize*3*numfaces],efa->v1->co);
- VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],efa->n);
-
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],efa->v2->co);
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],efa->n);
-
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],efa->v3->co);
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],efa->n);
- /*}*/
- if( draw == 2 ) {
- QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[2]);
- QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[2]);
- QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[2]);
- }
- else if( draw == 1 ) {
- QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
- QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
- QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
- }
- else {
- QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],black);
- QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],black);
- QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],black);
- }
-
- numfaces++;
- if( efa->v4 ) {
- /*if (emdm->vertexCos) {
- VECCOPY((float *)&varray[elemsize*3*numfaces],emdm->vertexCos[(int) efa->v3->tmp.l]);
- VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],emdm->faceNos[i]);
-
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],emdm->vertexCos[(int) efa->v4->tmp.l]);
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],emdm->faceNos[i]);
-
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],emdm->vertexCos[(int) efa->v1->tmp.l]);
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],emdm->faceNos[i]);
- }
- else {*/
- VECCOPY((float *)&varray[elemsize*3*numfaces],efa->v3->co);
- VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],efa->n);
-
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],efa->v4->co);
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],efa->n);
-
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],efa->v1->co);
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],efa->n);
- /*}*/
-
- if( draw == 2 ) {
- QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[2]);
- QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[2]);
- QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[2]);
- }
- else if( draw == 1 ) {
- QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
- QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
- QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
- }
- else {
- QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],black);
- QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],black);
- QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],black);
- }
-
- numfaces++;
- }
- }
- else {
- /*if (emdm->vertexCos) {
- VECCOPY((float *)&varray[elemsize*3*numfaces],emdm->vertexCos[(int) efa->v1->tmp.l]);
- VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],emdm->vertexNos[(int) efa->v1->tmp.l]);
-
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],emdm->vertexCos[(int) efa->v2->tmp.l]);
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],emdm->vertexNos[(int) efa->v2->tmp.l]);
-
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],emdm->vertexCos[(int) efa->v3->tmp.l]);
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],emdm->vertexNos[(int) efa->v3->tmp.l]);
- }
- else {*/
- VECCOPY((float *)&varray[elemsize*3*numfaces],efa->v1->co);
- VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],efa->v1->no);
-
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],efa->v2->co);
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],efa->v2->no);
-
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],efa->v3->co);
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],efa->v3->no);
- /*}*/
-
- if( draw == 2 ) {
- QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[2]);
- QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[2]);
- QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[2]);
- }
- else if( draw == 1 ) {
- QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
- QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
- QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
- }
- else {
- QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],black);
- QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],black);
- QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],black);
- }
-
- numfaces++;
- if( efa->v4 ) {
- /*if (emdm->vertexCos) {
- VECCOPY((float *)&varray[elemsize*3*numfaces],emdm->vertexCos[(int) efa->v3->tmp.l]);
- VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],emdm->vertexNos[(int) efa->v1->tmp.l]);
-
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],emdm->vertexCos[(int) efa->v4->tmp.l]);
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],emdm->vertexNos[(int) efa->v2->tmp.l]);
-
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],emdm->vertexCos[(int) efa->v1->tmp.l]);
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],emdm->vertexNos[(int) efa->v3->tmp.l]);
- }
- else {*/
- VECCOPY((float *)&varray[elemsize*3*numfaces],efa->v3->co);
- VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],efa->v3->no);
-
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],efa->v4->co);
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],efa->v4->no);
-
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],efa->v1->co);
- VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],efa->v1->no);
- /*}*/
-
- if( draw == 2 ) {
- QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[2]);
- QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[2]);
- QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[2]);
- }
- else if( draw == 1 ) {
- QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
- QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
- QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
- }
- else {
- QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],black);
- QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],black);
- QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],black);
- }
-
- numfaces++;
- }
- }
- }
- prevdraw = draw;
- }
- GPU_buffer_unlock( buffer );
- if( prevdraw != 0 && numfaces > 0) {
- if( prevdraw==2 ) {
- glEnable(GL_POLYGON_STIPPLE);
- glPolygonStipple(stipple_quarttone);
- }
- glDrawArrays(GL_TRIANGLES,0,numfaces*3);
- if( prevdraw==2 ) {
- glDisable(GL_POLYGON_STIPPLE);
- }
- }
- GPU_buffer_unbind();
- } else {
- dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, &data, 0);
- }
- GPU_buffer_free( buffer, 0 );
+ dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, &data, 0);
}
static int draw_dm_creases__setDrawOptions(void *userData, int index)
@@ -2464,114 +2130,12 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object
}
else {
/* 3 floats for position, 3 for normal and times two because the faces may actually be quads instead of triangles */
- GPUBuffer *buffer = GPU_buffer_legacy(em->derivedFinal)?0:GPU_buffer_alloc( sizeof(float)*6*em->totface*3*2, 0 );
- float *varray;
- EditFace *efa;
- int i, curmat = 0, draw = 0;
-
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, me->flag & ME_TWOSIDED);
glEnable(GL_LIGHTING);
glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
- if( finalDM->getVertCos == 0 && (varray = GPU_buffer_lock_stream( buffer )) ) {
- int prevdraw = 0, prevmat = 0;
- int numfaces = 0;
- int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_N3F, GPU_BUFFER_INTER_END };
- GPU_buffer_unlock( buffer );
- GPU_interleaved_setup( buffer, datatype );
- glShadeModel(GL_SMOOTH);
- varray = GPU_buffer_lock_stream( buffer );
- for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
- int drawSmooth = (efa->flag & ME_SMOOTH);
- if( efa->h == 0 ) {
- curmat = efa->mat_nr+1;
- draw = 1;
- }
- else {
- draw = 0;
- }
- if( ((prevdraw != draw) || (curmat != prevmat)) && prevdraw != 0 && numfaces > 0) {
- if( prevdraw==2 ) {
- glEnable(GL_POLYGON_STIPPLE);
- glPolygonStipple(stipple_quarttone);
- }
- GPU_buffer_unlock( buffer );
- GPU_enable_material(prevmat, NULL);
- glDrawArrays(GL_TRIANGLES,0,numfaces*3);
- if( prevdraw==2 ) {
- glDisable(GL_POLYGON_STIPPLE);
- }
- varray = GPU_buffer_lock_stream( buffer );
- numfaces = 0;
- }
- if( draw != 0 ) {
- if(!drawSmooth) {
- VECCOPY(&varray[numfaces*18],efa->v1->co);
- VECCOPY(&varray[numfaces*18+3],efa->n);
-
- VECCOPY(&varray[numfaces*18+6],efa->v2->co);
- VECCOPY(&varray[numfaces*18+9],efa->n);
-
- VECCOPY(&varray[numfaces*18+12],efa->v3->co);
- VECCOPY(&varray[numfaces*18+15],efa->n);
- numfaces++;
- if( efa->v4 ) {
- VECCOPY(&varray[numfaces*18],efa->v3->co);
- VECCOPY(&varray[numfaces*18+3],efa->n);
-
- VECCOPY(&varray[numfaces*18+6],efa->v4->co);
- VECCOPY(&varray[numfaces*18+9],efa->n);
-
- VECCOPY(&varray[numfaces*18+12],efa->v1->co);
- VECCOPY(&varray[numfaces*18+15],efa->n);
- numfaces++;
- }
- }
- else {
- VECCOPY(&varray[numfaces*18],efa->v1->co);
- VECCOPY(&varray[numfaces*18+3],efa->v1->no);
-
- VECCOPY(&varray[numfaces*18+6],efa->v2->co);
- VECCOPY(&varray[numfaces*18+9],efa->v2->no);
-
- VECCOPY(&varray[numfaces*18+12],efa->v3->co);
- VECCOPY(&varray[numfaces*18+15],efa->v3->no);
- numfaces++;
- if( efa->v4 ) {
- VECCOPY(&varray[numfaces*18],efa->v3->co);
- VECCOPY(&varray[numfaces*18+3],efa->v3->no);
-
- VECCOPY(&varray[numfaces*18+6],efa->v4->co);
- VECCOPY(&varray[numfaces*18+9],efa->v4->no);
-
- VECCOPY(&varray[numfaces*18+12],efa->v1->co);
- VECCOPY(&varray[numfaces*18+15],efa->v1->no);
- numfaces++;
- }
- }
- }
- prevdraw = draw;
- prevmat = curmat;
- }
- GPU_buffer_unlock( buffer );
- if( prevdraw != 0 && numfaces > 0) {
- if( prevdraw==2 ) {
- glEnable(GL_POLYGON_STIPPLE);
- glPolygonStipple(stipple_quarttone);
- }
- GPU_enable_material(prevmat, NULL);
- glDrawArrays(GL_TRIANGLES,0,numfaces*3);
- if( prevdraw==2 ) {
- glDisable(GL_POLYGON_STIPPLE);
- }
- }
- GPU_buffer_unbind();
- }
- else {
- finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, 0, 0);
- }
- GPU_buffer_free(buffer,0);
+ finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, 0, 0);
glFrontFace(GL_CCW);
glDisable(GL_LIGHTING);
@@ -6154,7 +5718,10 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
}
else if((flag & DRAW_CONSTCOLOR)==0) {
/* we don't draw centers for duplicators and sets */
- drawcentercircle(v3d, rv3d, ob->obmat[3], do_draw_center, ob->id.lib || ob->id.us>1);
+ if(U.obcenter_dia > 0) {
+ /* check > 0 otherwise grease pencil can draw into the circle select which is annoying. */
+ drawcentercircle(v3d, rv3d, ob->obmat[3], do_draw_center, ob->id.lib || ob->id.us>1);
+ }
}
}
}
@@ -6306,24 +5873,13 @@ static void bbs_mesh_solid_EM(Scene *scene, View3D *v3d, Object *ob, DerivedMesh
}
}
-static int bbs_mesh_solid_hide__setDrawOpts(void *userData, int index, int *drawSmooth_r)
-{
- Mesh *me = userData;
-
- if (!(me->mface[index].flag&ME_HIDE)) {
- return 1;
- } else {
- return 0;
- }
-}
-
-static int bbs_mesh_solid__setDrawOpts_legacy(void *userData, int index, int *drawSmooth_r)
+static int bbs_mesh_solid__setDrawOpts(void *userData, int index, int *drawSmooth_r)
{
WM_set_framebuffer_index_color(index+1);
return 1;
}
-static int bbs_mesh_solid_hide__setDrawOpts_legacy(void *userData, int index, int *drawSmooth_r)
+static int bbs_mesh_solid_hide__setDrawOpts(void *userData, int index, int *drawSmooth_r)
{
Mesh *me = userData;
@@ -6339,43 +5895,12 @@ static void bbs_mesh_solid(Scene *scene, View3D *v3d, Object *ob)
{
DerivedMesh *dm = mesh_get_derived_final(scene, ob, v3d->customdata_mask);
Mesh *me = (Mesh*)ob->data;
- MCol *colors;
- int i,j;
int face_sel_mode = (me->flag & ME_EDIT_PAINT_MASK) ? 1:0;
glColor3ub(0, 0, 0);
- if( !GPU_buffer_legacy(dm) ) {
- int *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
- int ind;
- colors = MEM_mallocN(dm->getNumFaces(dm)*sizeof(MCol)*4,"bbs_mesh_solid");
- for(i=0;i<dm->getNumFaces(dm);i++) {
- ind= ( index )? index[i]: i;
-
- if (face_sel_mode==0 || !(me->mface[ind].flag&ME_HIDE)) {
- unsigned int fbindex = index_to_framebuffer(ind+1);
- for(j=0;j<4;j++) {
- colors[i*4+j].b = ((fbindex)&0xFF);
- colors[i*4+j].g = (((fbindex)>>8)&0xFF);
- colors[i*4+j].r = (((fbindex)>>16)&0xFF);
- }
- }
- else {
- memset(&colors[i*4],0,sizeof(MCol)*4);
- }
- }
-
- CustomData_add_layer( &dm->faceData, CD_ID_MCOL, CD_ASSIGN, colors, dm->numFaceData );
- GPU_buffer_free(dm->drawObject->colors,0);
- dm->drawObject->colors = 0;
-
- if(face_sel_mode) dm->drawMappedFaces(dm, bbs_mesh_solid_hide__setDrawOpts, me, 1);
- else dm->drawMappedFaces(dm, NULL, me, 1);
- }
- else {
- if(face_sel_mode) dm->drawMappedFaces(dm, bbs_mesh_solid_hide__setDrawOpts_legacy, me, 0);
- else dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts_legacy, me, 0);
- }
+ if(face_sel_mode) dm->drawMappedFaces(dm, bbs_mesh_solid_hide__setDrawOpts, me, 0);
+ else dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, me, 0);
dm->release(dm);
}
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index f1db3ca53fc..6ee0e341849 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -488,6 +488,10 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
/* all group ops for now */
ED_region_tag_redraw(ar);
break;
+ case NC_BRUSH:
+ if(wmn->action == NA_EDITED)
+ ED_region_tag_redraw(ar);
+ break;
case NC_MATERIAL:
switch(wmn->data) {
case ND_SHADING_DRAW:
@@ -636,6 +640,10 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
break;
}
break;
+ case NC_TEXTURE:
+ /* for brush textures */
+ ED_region_tag_redraw(ar);
+ break;
case NC_BRUSH:
if(wmn->action==NA_EDITED)
ED_region_tag_redraw(ar);
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 2cef7461e85..8af16641c00 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -1044,14 +1044,6 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
UI_ThemeColor(TH_WIRE);
glRectf(x1, y1, x2, y2);
- /* camera name - draw in highlighted text color */
- if (ca && (ca->flag & CAM_SHOWNAME)) {
- UI_ThemeColor(TH_TEXT_HI);
- BLF_draw_default(x1, y1-15, 0.0f, v3d->camera->id.name+2);
- UI_ThemeColor(TH_WIRE);
- }
-
-
/* border */
if(scene->r.mode & R_BORDER) {
@@ -1086,6 +1078,12 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
setlinestyle(0);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ /* camera name - draw in highlighted text color */
+ if (ca && (ca->flag & CAM_SHOWNAME)) {
+ UI_ThemeColor(TH_TEXT_HI);
+ BLF_draw_default(x1, y1-15, 0.0f, v3d->camera->id.name+2);
+ UI_ThemeColor(TH_WIRE);
+ }
}
/* *********************** backdraw for selection *************** */
@@ -1096,16 +1094,6 @@ void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
struct Base *base = scene->basact;
rcti winrct;
-/*for 2.43 release, don't use glext and just define the constant.
- this to avoid possibly breaking platforms before release.*/
-#ifndef GL_MULTISAMPLE_ARB
- #define GL_MULTISAMPLE_ARB 0x809D
-#endif
-
-#ifdef GL_MULTISAMPLE_ARB
- int m;
-#endif
-
if(base && (base->object->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT) ||
paint_facesel_test(base->object)));
else if((base && (base->object->mode & OB_MODE_TEXTURE_PAINT)) &&
@@ -1126,16 +1114,6 @@ void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
// }
// }
- /* Disable FSAA for backbuffer selection.
-
- Only works if GL_MULTISAMPLE_ARB is defined by the header
- file, which is should be for every OS that supports FSAA.*/
-
-#ifdef GL_MULTISAMPLE_ARB
- m = glIsEnabled(GL_MULTISAMPLE_ARB);
- if (m) glDisable(GL_MULTISAMPLE_ARB);
-#endif
-
if(v3d->drawtype > OB_WIRE) v3d->zbuf= TRUE;
glDisable(GL_DITHER);
@@ -1172,10 +1150,6 @@ void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
if(rv3d->rflag & RV3D_CLIPPING)
view3d_clr_clipping();
-#ifdef GL_MULTISAMPLE_ARB
- if (m) glEnable(GL_MULTISAMPLE_ARB);
-#endif
-
/* it is important to end a view in a transform compatible with buttons */
// persp(PERSP_WIN); // set ortho
@@ -1643,22 +1617,46 @@ void view3d_update_depths(ARegion *ar, View3D *v3d)
}
}
+void draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d)
+{
+ short zbuf= v3d->zbuf;
+ RegionView3D *rv3d= ar->regiondata;
+
+ setwinmatrixview3d(ar, v3d, NULL); /* 0= no pick rect */
+ setviewmatrixview3d(scene, v3d, rv3d); /* note: calls where_is_object for camera... */
+
+ mul_m4_m4m4(rv3d->persmat, rv3d->viewmat, rv3d->winmat);
+ invert_m4_m4(rv3d->persinv, rv3d->persmat);
+ invert_m4_m4(rv3d->viewinv, rv3d->viewmat);
+
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ wmLoadMatrix(rv3d->viewmat);
+
+ v3d->zbuf= TRUE;
+ glEnable(GL_DEPTH_TEST);
+
+ draw_gpencil_3dview_ext(scene, ar, 1);
+
+ v3d->zbuf= zbuf;
+
+}
+
void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (* func)(void *))
{
RegionView3D *rv3d= ar->regiondata;
Base *base;
Scene *sce;
- short zbuf, flag;
- float glalphaclip;
+ short zbuf= v3d->zbuf;
+ short flag= v3d->flag;
+ float glalphaclip= U.glalphaclip;
+ int obcenter_dia= U.obcenter_dia;
/* temp set drawtype to solid */
/* Setting these temporarily is not nice */
- zbuf = v3d->zbuf;
- flag = v3d->flag;
- glalphaclip = U.glalphaclip;
-
- U.glalphaclip = 0.5; /* not that nice but means we wont zoom into billboards */
v3d->flag &= ~V3D_SELECT_OUTLINE;
+ U.glalphaclip = 0.5; /* not that nice but means we wont zoom into billboards */
+ U.obcenter_dia= 0;
setwinmatrixview3d(ar, v3d, NULL); /* 0= no pick rect */
setviewmatrixview3d(scene, v3d, rv3d); /* note: calls where_is_object for camera... */
@@ -1742,6 +1740,7 @@ void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (* func)(void *))
v3d->zbuf = zbuf;
U.glalphaclip = glalphaclip;
v3d->flag = flag;
+ U.obcenter_dia= obcenter_dia;
}
typedef struct View3DShadow {
@@ -1928,8 +1927,16 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx,
G.f |= G_RENDER_OGL;
GPU_free_images();
- /* set background color */
- glClearColor(scene->world->horr, scene->world->horg, scene->world->horb, 0.0);
+ /* set background color, fallback on the view background color */
+ if(scene->world) {
+ glClearColor(scene->world->horr, scene->world->horg, scene->world->horb, 0.0);
+ }
+ else {
+ float col[3];
+ UI_GetThemeColor3fv(TH_BACK, col);
+ glClearColor(col[0], col[1], col[2], 0.0);
+ }
+
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
/* setup view matrices */
@@ -2032,6 +2039,10 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar)
}
else
v3d->zbuf= FALSE;
+
+ /* enables anti-aliasing for 3D view drawing */
+ if (!(U.gameflags & USER_DISABLE_AA))
+ glEnable(GL_MULTISAMPLE_ARB);
// needs to be done always, gridview is adjusted in drawgrid() now
rv3d->gridview= v3d->grid;
@@ -2139,6 +2150,10 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar)
BIF_draw_manipulator(C);
+ /* Disable back anti-aliasing */
+ if (!(U.gameflags & USER_DISABLE_AA))
+ glDisable(GL_MULTISAMPLE_ARB);
+
if(v3d->zbuf) {
v3d->zbuf= FALSE;
glDisable(GL_DEPTH_TEST);
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index e8c2b48e4be..3d4cc8ef309 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -445,7 +445,9 @@ enum {
#define VIEW_MODAL_CONFIRM 1 /* used for all view operations */
#define VIEWROT_MODAL_AXIS_SNAP_ENABLE 2
#define VIEWROT_MODAL_AXIS_SNAP_DISABLE 3
-
+#define VIEWROT_MODAL_SWITCH_ZOOM 4
+#define VIEWROT_MODAL_SWITCH_MOVE 5
+#define VIEWROT_MODAL_SWITCH_ROTATE 6
/* called in transform_ops.c, on each regeneration of keymaps */
void viewrotate_modal_keymap(wmKeyConfig *keyconf)
@@ -454,7 +456,10 @@ void viewrotate_modal_keymap(wmKeyConfig *keyconf)
{VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Cancel", ""},
{VIEWROT_MODAL_AXIS_SNAP_ENABLE, "AXIS_SNAP_ENABLE", 0, "Enable Axis Snap", ""},
- {VIEWROT_MODAL_AXIS_SNAP_DISABLE, "AXIS_SNAP_DISABLE", 0, "Enable Axis Snap", ""},
+ {VIEWROT_MODAL_AXIS_SNAP_DISABLE, "AXIS_SNAP_DISABLE", 0, "Disable Axis Snap", ""},
+
+ {VIEWROT_MODAL_SWITCH_ZOOM, "SWITCH_TO_ZOOM", 0, "Switch to Zoom"},
+ {VIEWROT_MODAL_SWITCH_MOVE, "SWITCH_TO_MOVE", 0, "Switch to Move"},
{0, NULL, 0, NULL, NULL}};
@@ -469,9 +474,13 @@ void viewrotate_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM);
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM);
- WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_AXIS_SNAP_ENABLE);
- WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_AXIS_SNAP_DISABLE);
+ WM_modalkeymap_add_item(keymap, LEFTALTKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_AXIS_SNAP_ENABLE);
+ WM_modalkeymap_add_item(keymap, LEFTALTKEY, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_AXIS_SNAP_DISABLE);
+ WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ZOOM);
+ WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ZOOM);
+ WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_MOVE);
+
/* assign map to operators */
WM_modalkeymap_assign(keymap, "VIEW3D_OT_rotate");
@@ -633,6 +642,14 @@ static int viewrotate_modal(bContext *C, wmOperator *op, wmEvent *event)
vod->axis_snap= FALSE;
event_code= VIEW_APPLY;
break;
+ case VIEWROT_MODAL_SWITCH_ZOOM:
+ WM_operator_name_call(C, "VIEW3D_OT_zoom", WM_OP_INVOKE_DEFAULT, NULL);
+ event_code= VIEW_CONFIRM;
+ break;
+ case VIEWROT_MODAL_SWITCH_MOVE:
+ WM_operator_name_call(C, "VIEW3D_OT_move", WM_OP_INVOKE_DEFAULT, NULL);
+ event_code= VIEW_CONFIRM;
+ break;
}
}
else if(event->type==vod->origkey && event->val==KM_RELEASE) {
@@ -680,6 +697,20 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
+static int ED_operator_view3d_rotate(bContext *C)
+{
+ if (!ED_operator_view3d_active(C)) {
+ return 0;
+ } else {
+ RegionView3D *rv3d= CTX_wm_region_view3d(C);
+ /* rv3d is null in menus, but it's ok when the menu is clicked on */
+ /* XXX of course, this doesn't work with quadview
+ * Maybe having exec return PASSTHROUGH would be better than polling here
+ * Poll functions are full of problems anyway.
+ * */
+ return rv3d == NULL || rv3d->viewlock == 0;
+ }
+}
void VIEW3D_OT_rotate(wmOperatorType *ot)
{
@@ -722,6 +753,10 @@ void viewmove_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM);
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM);
+ WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ZOOM);
+ WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ZOOM);
+ WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
+
/* assign map to operators */
WM_modalkeymap_assign(keymap, "VIEW3D_OT_move");
}
@@ -770,6 +805,14 @@ static int viewmove_modal(bContext *C, wmOperator *op, wmEvent *event)
case VIEW_MODAL_CONFIRM:
event_code= VIEW_CONFIRM;
break;
+ case VIEWROT_MODAL_SWITCH_ZOOM:
+ WM_operator_name_call(C, "VIEW3D_OT_zoom", WM_OP_INVOKE_DEFAULT, NULL);
+ event_code= VIEW_CONFIRM;
+ break;
+ case VIEWROT_MODAL_SWITCH_ROTATE:
+ WM_operator_name_call(C, "VIEW3D_OT_rotate", WM_OP_INVOKE_DEFAULT, NULL);
+ event_code= VIEW_CONFIRM;
+ break;
}
}
else if(event->type==vod->origkey && event->val==KM_RELEASE) {
@@ -840,6 +883,10 @@ void viewzoom_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM);
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM);
+ WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
+ WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
+ WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_MOVE);
+
/* assign map to operators */
WM_modalkeymap_assign(keymap, "VIEW3D_OT_zoom");
}
@@ -981,6 +1028,14 @@ static int viewzoom_modal(bContext *C, wmOperator *op, wmEvent *event)
case VIEW_MODAL_CONFIRM:
event_code= VIEW_CONFIRM;
break;
+ case VIEWROT_MODAL_SWITCH_MOVE:
+ WM_operator_name_call(C, "VIEW3D_OT_move", WM_OP_INVOKE_DEFAULT, NULL);
+ event_code= VIEW_CONFIRM;
+ break;
+ case VIEWROT_MODAL_SWITCH_ROTATE:
+ WM_operator_name_call(C, "VIEW3D_OT_rotate", WM_OP_INVOKE_DEFAULT, NULL);
+ event_code= VIEW_CONFIRM;
+ break;
}
}
else if(event->type==vod->origkey && event->val==KM_RELEASE) {
@@ -1460,7 +1515,7 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
/* ZBuffer depth vars */
bglMats mats;
- float depth, depth_close= MAXFLOAT;
+ float depth, depth_close= FLT_MAX;
int had_depth = 0;
double cent[2], p[3];
int xs, ys;
@@ -1517,7 +1572,7 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
double p_corner[3];
/* no depths to use, we cant do anything! */
- if (depth_close==MAXFLOAT){
+ if (depth_close==FLT_MAX){
BKE_report(op->reports, RPT_ERROR, "Depth Too Large");
return OPERATOR_CANCELLED;
}
@@ -1545,7 +1600,7 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
new_dist = rv3d->dist;
/* convert the drawn rectangle into 3d space */
- if (depth_close!=MAXFLOAT && gluUnProject(cent[0], cent[1], depth_close, mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2])) {
+ if (depth_close!=FLT_MAX && gluUnProject(cent[0], cent[1], depth_close, mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2])) {
new_ofs[0] = -p[0];
new_ofs[1] = -p[1];
new_ofs[2] = -p[2];
@@ -1822,9 +1877,8 @@ static EnumPropertyItem prop_view_orbit_items[] = {
static int vieworbit_exec(bContext *C, wmOperator *op)
{
- ARegion *ar= CTX_wm_region(C);
RegionView3D *rv3d= CTX_wm_region_view3d(C);
- float phi, si, q1[4];
+ float phi, si, q1[4], new_quat[4];
int orbitdir;
orbitdir = RNA_enum_get(op->ptr, "type");
@@ -1840,10 +1894,10 @@ static int vieworbit_exec(bContext *C, wmOperator *op)
q1[0]= (float)cos(phi);
q1[1]= q1[2]= 0.0;
q1[3]= si;
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
+ mul_qt_qtqt(new_quat, rv3d->viewquat, q1);
rv3d->view= 0;
}
- if(orbitdir == V3D_VIEW_STEPDOWN || orbitdir == V3D_VIEW_STEPUP) {
+ else if(orbitdir == V3D_VIEW_STEPDOWN || orbitdir == V3D_VIEW_STEPUP) {
/* horizontal axis */
VECCOPY(q1+1, rv3d->viewinv[0]);
@@ -1855,10 +1909,11 @@ static int vieworbit_exec(bContext *C, wmOperator *op)
q1[1]*= si;
q1[2]*= si;
q1[3]*= si;
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
+ mul_qt_qtqt(new_quat, rv3d->viewquat, q1);
rv3d->view= 0;
}
- ED_region_tag_redraw(ar);
+
+ smooth_view(C, NULL, NULL, NULL, new_quat, NULL, NULL);
}
}
@@ -2183,22 +2238,66 @@ void VIEW3D_OT_manipulator(wmOperatorType *ot)
/* ************************* below the line! *********************** */
+static float view_autodist_depth_margin(ARegion *ar, short *mval, int margin)
+{
+ RegionView3D *rv3d= ar->regiondata;
+ float depth= FLT_MAX;
+
+ if(margin==0) {
+ if (mval[0] < 0) return 0;
+ if (mval[1] < 0) return 0;
+ if (mval[0] >= rv3d->depths->w) return 0;
+ if (mval[1] >= rv3d->depths->h) return 0;
+
+ /* Get Z Depths, needed for perspective, nice for ortho */
+ depth= rv3d->depths->depths[mval[1]*rv3d->depths->w+mval[0]];
+ if(depth >= rv3d->depths->depth_range[1] || depth <= rv3d->depths->depth_range[0]) {
+ depth= FLT_MAX;
+ }
+ }
+ else {
+ rcti rect;
+ float depth_close= FLT_MAX;
+ int xs, ys;
+
+ rect.xmax = mval[0] + margin;
+ rect.ymax = mval[1] + margin;
+
+ rect.xmin = mval[0] - margin;
+ rect.ymin = mval[1] - margin;
+
+ /* Constrain rect to depth bounds */
+ if (rect.xmin < 0) rect.xmin = 0;
+ if (rect.ymin < 0) rect.ymin = 0;
+ if (rect.xmax >= rv3d->depths->w) rect.xmax = rv3d->depths->w-1;
+ if (rect.ymax >= rv3d->depths->h) rect.ymax = rv3d->depths->h-1;
+
+ /* Find the closest Z pixel */
+ for (xs=rect.xmin; xs < rect.xmax; xs++) {
+ for (ys=rect.ymin; ys < rect.ymax; ys++) {
+ depth= rv3d->depths->depths[ys*rv3d->depths->w+xs];
+ if(depth < rv3d->depths->depth_range[1] && depth > rv3d->depths->depth_range[0]) {
+ if (depth_close > depth) {
+ depth_close = depth;
+ }
+ }
+ }
+ }
+
+ depth= depth_close;
+ }
+
+ return depth;
+}
+
/* XXX todo Zooms in on a border drawn by the user */
int view_autodist(Scene *scene, ARegion *ar, View3D *v3d, short *mval, float mouse_worldloc[3] ) //, float *autodist )
{
RegionView3D *rv3d= ar->regiondata;
bglMats mats; /* ZBuffer depth vars */
- rcti rect;
- float depth, depth_close= MAXFLOAT;
+ float depth_close= FLT_MAX;
int had_depth = 0;
double cent[2], p[3];
- int xs, ys;
-
- rect.xmax = mval[0] + 4;
- rect.ymax = mval[1] + 4;
-
- rect.xmin = mval[0] - 4;
- rect.ymin = mval[1] - 4;
/* Get Z Depths, needed for perspective, nice for ortho */
bgl_get_mats(&mats);
@@ -2212,25 +2311,9 @@ int view_autodist(Scene *scene, ARegion *ar, View3D *v3d, short *mval, float mou
view3d_update_depths(ar, v3d);
- /* Constrain rect to depth bounds */
- if (rect.xmin < 0) rect.xmin = 0;
- if (rect.ymin < 0) rect.ymin = 0;
- if (rect.xmax >= rv3d->depths->w) rect.xmax = rv3d->depths->w-1;
- if (rect.ymax >= rv3d->depths->h) rect.ymax = rv3d->depths->h-1;
+ depth_close= view_autodist_depth_margin(ar, mval, 4);
- /* Find the closest Z pixel */
- for (xs=rect.xmin; xs < rect.xmax; xs++) {
- for (ys=rect.ymin; ys < rect.ymax; ys++) {
- depth= rv3d->depths->depths[ys*rv3d->depths->w+xs];
- if(depth < rv3d->depths->depth_range[1] && depth > rv3d->depths->depth_range[0]) {
- if (depth_close > depth) {
- depth_close = depth;
- }
- }
- }
- }
-
- if (depth_close==MAXFLOAT)
+ if (depth_close==FLT_MAX)
return 0;
if (had_depth==0) {
@@ -2251,12 +2334,19 @@ int view_autodist(Scene *scene, ARegion *ar, View3D *v3d, short *mval, float mou
return 1;
}
-int view_autodist_init(Scene *scene, ARegion *ar, View3D *v3d) //, float *autodist )
+int view_autodist_init(Scene *scene, ARegion *ar, View3D *v3d, int mode) //, float *autodist )
{
RegionView3D *rv3d= ar->regiondata;
/* Get Z Depths, needed for perspective, nice for ortho */
- draw_depth(scene, ar, v3d, NULL);
+ switch(mode) {
+ case 0:
+ draw_depth(scene, ar, v3d, NULL);
+ break;
+ case 1:
+ draw_depth_gpencil(scene, ar, v3d);
+ break;
+ }
/* force updating */
if (rv3d->depths) {
@@ -2268,28 +2358,25 @@ int view_autodist_init(Scene *scene, ARegion *ar, View3D *v3d) //, float *autodi
}
// no 4x4 sampling, run view_autodist_init first
-int view_autodist_simple(ARegion *ar, short *mval, float mouse_worldloc[3] ) //, float *autodist )
+int view_autodist_simple(ARegion *ar, short *mval, float mouse_worldloc[3], int margin, float *force_depth) //, float *autodist )
{
- RegionView3D *rv3d= ar->regiondata;
bglMats mats; /* ZBuffer depth vars, could cache? */
float depth;
double cent[2], p[3];
- if (mval[0] < 0) return 0;
- if (mval[1] < 0) return 0;
- if (mval[0] >= rv3d->depths->w) return 0;
- if (mval[1] >= rv3d->depths->h) return 0;
-
/* Get Z Depths, needed for perspective, nice for ortho */
- bgl_get_mats(&mats);
- depth= rv3d->depths->depths[mval[1]*rv3d->depths->w+mval[0]];
+ if(force_depth)
+ depth= *force_depth;
+ else
+ depth= view_autodist_depth_margin(ar, mval, margin);
- if (depth==MAXFLOAT)
+ if (depth==FLT_MAX)
return 0;
cent[0] = (double)mval[0];
cent[1] = (double)mval[1];
+ bgl_get_mats(&mats);
if (!gluUnProject(cent[0], cent[1], depth, mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2]))
return 0;
@@ -2299,6 +2386,14 @@ int view_autodist_simple(ARegion *ar, short *mval, float mouse_worldloc[3] ) //,
return 1;
}
+int view_autodist_depth(struct ARegion *ar, short *mval, int margin, float *depth)
+{
+ *depth= view_autodist_depth_margin(ar, mval, margin);
+
+ return (*depth==FLT_MAX) ? 0:1;
+ return 0;
+}
+
/* ********************* NDOF ************************ */
/* note: this code is confusing and unclear... (ton) */
/* **************************************************** */
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index 9b6cfc6cbd0..98f0f2fec65 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -173,6 +173,7 @@ static int layers_exec(bContext *C, wmOperator *op)
ScrArea *sa= CTX_wm_area(C);
View3D *v3d= sa->spacedata.first;
int nr= RNA_int_get(op->ptr, "nr");
+ int toggle= RNA_boolean_get(op->ptr, "toggle");
if(nr < 0)
return OPERATOR_CANCELLED;
@@ -188,9 +189,12 @@ static int layers_exec(bContext *C, wmOperator *op)
else {
nr--;
- if(RNA_boolean_get(op->ptr, "extend"))
- v3d->lay |= (1<<nr);
- else
+ if(RNA_boolean_get(op->ptr, "extend")) {
+ if(toggle && v3d->lay & (1<<nr) && (v3d->lay & ~(1<<nr)))
+ v3d->lay &= ~(1<<nr);
+ else
+ v3d->lay |= (1<<nr);
+ } else
v3d->lay = (1<<nr);
/* set active layer, ensure to always have one */
@@ -238,6 +242,11 @@ static int layers_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_FINISHED;
}
+int layers_poll(bContext *C)
+{
+ return (ED_operator_view3d_active(C) && CTX_wm_view3d(C)->localvd==NULL);
+}
+
void VIEW3D_OT_layers(wmOperatorType *ot)
{
/* identifiers */
@@ -248,13 +257,14 @@ void VIEW3D_OT_layers(wmOperatorType *ot)
/* api callbacks */
ot->invoke= layers_invoke;
ot->exec= layers_exec;
- ot->poll= ED_operator_view3d_active;
+ ot->poll= layers_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
RNA_def_int(ot->srna, "nr", 1, 0, 20, "Number", "The layer number to set, zero for all layers", 0, 20);
RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Add this layer to the current view layers");
+ RNA_def_boolean(ot->srna, "toggle", 1, "Toggle", "Toggle the layer");
}
static char *view3d_modeselect_pup(Scene *scene)
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index bf5d516c03a..a5d4c61bc01 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -43,6 +43,9 @@ struct wmWindowManager;
struct EditMesh;
struct ViewContext;
struct ARegionType;
+struct bPoseChannel;
+struct bAnimVizSettings;
+struct bMotionPath;
#define BL_NEAR_CLIP 0.001
@@ -84,6 +87,15 @@ void VIEW3D_OT_drawtype(struct wmOperatorType *ot);
void view3d_boxview_copy(ScrArea *sa, ARegion *ar);
+/* drawanim.c */
+void draw_motion_paths_init(Scene *scene, View3D *v3d, struct ARegion *ar);
+void draw_motion_path_instance(Scene *scene, View3D *v3d, struct ARegion *ar,
+ struct Object *ob, struct bPoseChannel *pchan,
+ struct bAnimVizSettings *avs, struct bMotionPath *mpath);
+void draw_motion_paths_cleanup(Scene *scene, View3D *v3d, struct ARegion *ar);
+
+
+
/* drawobject.c */
void draw_object(Scene *scene, struct ARegion *ar, View3D *v3d, Base *base, int flag);
int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt);
@@ -104,6 +116,7 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *o
/* view3d_draw.c */
void view3d_main_area_draw(const struct bContext *C, struct ARegion *ar);
void draw_depth(Scene *scene, struct ARegion *ar, View3D *v3d, int (* func)(void *));
+void draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d);
void view3d_clr_clipping(void);
void view3d_set_clipping(RegionView3D *rv3d);
void add_view3d_after(View3D *v3d, Base *base, int type, int flag);
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index c211e55d7a0..2bcd78b3d3d 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -159,7 +159,17 @@ void view3d_keymap(wmKeyConfig *keyconf)
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_pan", PAD4, KM_PRESS, KM_CTRL, 0)->ptr, "type", V3D_VIEW_PANLEFT);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_pan", PAD6, KM_PRESS, KM_CTRL, 0)->ptr, "type", V3D_VIEW_PANRIGHT);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_pan", PAD8, KM_PRESS, KM_CTRL, 0)->ptr, "type", V3D_VIEW_PANUP);
-
+
+ RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_pan", WHEELUPMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "type", V3D_VIEW_PANRIGHT);
+ RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_pan", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "type", V3D_VIEW_PANLEFT);
+ RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_pan", WHEELUPMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "type", V3D_VIEW_PANUP);
+ RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_pan", WHEELDOWNMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "type", V3D_VIEW_PANDOWN);
+
+ RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_orbit", WHEELUPMOUSE, KM_PRESS, KM_CTRL|KM_ALT, 0)->ptr, "type", V3D_VIEW_STEPLEFT);
+ RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_orbit", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL|KM_ALT, 0)->ptr, "type", V3D_VIEW_STEPRIGHT);
+ RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_orbit", WHEELUPMOUSE, KM_PRESS, KM_SHIFT|KM_ALT, 0)->ptr, "type", V3D_VIEW_STEPUP);
+ RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_orbit", WHEELDOWNMOUSE, KM_PRESS, KM_SHIFT|KM_ALT, 0)->ptr, "type", V3D_VIEW_STEPDOWN);
+
/* active aligned, replaces '*' key in 2.4x */
kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD1, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_FRONT);
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index e7c8070b7c5..0ed7f4c0d0a 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -94,14 +94,14 @@
#include "view3d_intern.h" // own include
-
+// TODO: should return whether there is valid context to continue
void view3d_set_viewcontext(bContext *C, ViewContext *vc)
{
memset(vc, 0, sizeof(ViewContext));
vc->ar= CTX_wm_region(C);
vc->scene= CTX_data_scene(C);
vc->v3d= CTX_wm_view3d(C);
- vc->rv3d= vc->ar->regiondata;
+ vc->rv3d= CTX_wm_region_view3d(C);
vc->obact= CTX_data_active_object(C);
vc->obedit= CTX_data_edit_object(C);
}
@@ -1424,6 +1424,8 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op)
else if(obedit==NULL && (obact && obact->mode & OB_MODE_PARTICLE_EDIT)) {
return PE_border_select(C, &rect, selecting, extend);
}
+ else if(obedit==NULL && (obact && obact->mode & OB_MODE_SCULPT))
+ return OPERATOR_CANCELLED;
if(obedit) {
if(obedit->type==OB_MESH) {
@@ -1689,6 +1691,8 @@ static int view3d_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
retval = mouse_mball(C, event->mval, extend);
}
+ else if(obact && obact->mode & OB_MODE_SCULPT)
+ return OPERATOR_CANCELLED;
else if(obact && obact->mode & OB_MODE_PARTICLE_EDIT)
return PE_mouse_particles(C, event->mval, extend);
else if(obact && paint_facesel_test(obact))
@@ -2012,6 +2016,9 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
else
return PE_circle_select(C, selecting, mval, (float)radius);
}
+ else if(obact && obact->mode & OB_MODE_SCULPT) {
+ return OPERATOR_CANCELLED;
+ }
else {
Base *base;
selecting= selecting?BA_SELECT:BA_DESELECT;
diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c
index 0384a23579e..b05043cd76e 100644
--- a/source/blender/editors/space_view3d/view3d_toolbar.c
+++ b/source/blender/editors/space_view3d/view3d_toolbar.c
@@ -239,7 +239,7 @@ static uiBlock *tool_search_menu(bContext *C, ARegion *ar, void *arg_listbase)
/* fake button, it holds space for search items */
uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
- but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, OP_MAX_TYPENAME, 10, 0, 150, 19, "");
+ but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, OP_MAX_TYPENAME, 10, 0, 150, 19, 0, 0, "");
uiButSetSearchFunc(but, operator_search_cb, arg_listbase, operator_call_cb, NULL);
uiBoundsBlock(block, 6);
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 48f3c77091f..adb1e6c6f1c 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -536,6 +536,7 @@ void viewline(ARegion *ar, View3D *v3d, float mval[2], float ray_start[3], float
{
RegionView3D *rv3d= ar->regiondata;
float vec[4];
+ int a;
if(rv3d->persp != RV3D_ORTHO){
vec[0]= 2.0f * mval[0] / ar->winx - 1;
@@ -564,6 +565,11 @@ void viewline(ARegion *ar, View3D *v3d, float mval[2], float ray_start[3], float
VECADDFAC(ray_start, vec, rv3d->viewinv[2], 1000.0f);
VECADDFAC(ray_end, vec, rv3d->viewinv[2], -1000.0f);
}
+
+ /* clipping */
+ if(rv3d->rflag & RV3D_CLIPPING)
+ for(a=0; a<4; a++)
+ clip_line_plane(ray_start, ray_end, rv3d->clip[a]);
}
/* create intersection ray in view Z direction at mouse coordinates */
@@ -1650,11 +1656,6 @@ void game_set_commmandline_options(GameData *gm)
if ( (syshandle = SYS_GetSystem()) ) {
/* User defined settings */
- test= (U.gameflags & USER_DISABLE_SOUND);
- /* if user already disabled audio at the command-line, don't re-enable it */
- if (test)
- SYS_WriteCommandLineInt(syshandle, "noaudio", test);
-
test= (U.gameflags & USER_DISABLE_MIPMAP);
GPU_set_mipmap(!test);
SYS_WriteCommandLineInt(syshandle, "nomipmap", test);
@@ -2480,14 +2481,7 @@ static int flyApply(FlyInfo *fly)
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);
-
- { //XXX - some reason setcameratoview3d doesnt copy, shouldnt not be needed!
- VECCOPY(v3d->camera->loc, rv3d->ofs);
- negate_v3(v3d->camera->loc);
- }
-
rv3d->persp= RV3D_CAMOB;
#if 0 //XXX2.5
/* record the motion */
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index fa435f29773..93abe0d6cfe 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -1381,6 +1381,11 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
RNA_float_set(op->ptr, "proportional_size", t->prop_size);
}
+ if (RNA_struct_find_property(op->ptr, "axis"))
+ {
+ RNA_float_set_array(op->ptr, "axis", t->axis);
+ }
+
if (RNA_struct_find_property(op->ptr, "mirror"))
{
RNA_boolean_set(op->ptr, "mirror", t->flag & T_MIRROR);
@@ -1574,6 +1579,13 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int
t->flag |= T_AUTOVALUES;
}
+ /* Transformation axis from operator */
+ if (RNA_struct_find_property(op->ptr, "axis") && RNA_property_is_set(op->ptr, "axis"))
+ {
+ RNA_float_get_array(op->ptr, "axis", t->axis);
+ normalize_v3(t->axis);
+ }
+
/* Constraint init from operator */
if (RNA_struct_find_property(op->ptr, "constraint_axis") && RNA_property_is_set(op->ptr, "constraint_axis"))
{
@@ -2662,6 +2674,10 @@ void initRotation(TransInfo *t)
if (t->flag & T_2D_EDIT)
t->flag |= T_NO_CONSTRAINT;
+
+ VECCOPY(t->axis, t->viewinv[2]);
+ mul_v3_fl(t->axis, -1.0f);
+ normalize_v3(t->axis);
}
static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short around) {
@@ -2906,13 +2922,8 @@ int Rotation(TransInfo *t, short mval[2])
float final;
- float axis[3];
float mat[3][3];
- VECCOPY(axis, t->viewinv[2]);
- mul_v3_fl(axis, -1.0f);
- normalize_v3(axis);
-
final = t->values[0];
applyNDofInput(&t->ndof, &final);
@@ -2920,7 +2931,7 @@ int Rotation(TransInfo *t, short mval[2])
snapGrid(t, &final);
if (t->con.applyRot) {
- t->con.applyRot(t, NULL, axis, &final);
+ t->con.applyRot(t, NULL, t->axis, &final);
}
applySnapping(t, &final);
@@ -2947,13 +2958,13 @@ int Rotation(TransInfo *t, short mval[2])
sprintf(str, "Rot: %.2f%s %s", 180.0*final/M_PI, t->con.text, t->proptext);
}
- vec_rot_to_mat3( mat,axis, final);
+ vec_rot_to_mat3( mat, t->axis, final);
// TRANSFORM_FIX_ME
// t->values[0] = final; // used in manipulator
// copy_m3_m3(t->mat, mat); // used in manipulator
- applyRotation(t, final, axis);
+ applyRotation(t, final, t->axis);
recalcData(t);
@@ -3085,9 +3096,11 @@ void initTranslation(TransInfo *t)
if(t->spacetype == SPACE_VIEW3D) {
RegionView3D *rv3d = t->ar->regiondata;
- t->snap[0] = 0.0f;
- t->snap[1] = rv3d->gridview * 1.0f;
- t->snap[2] = t->snap[1] * 0.1f;
+ if (rv3d) {
+ t->snap[0] = 0.0f;
+ t->snap[1] = rv3d->gridview * 1.0f;
+ t->snap[2] = t->snap[1] * 0.1f;
+ }
}
else if(t->spacetype == SPACE_IMAGE) {
t->snap[0] = 0.0f;
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 72d970c967a..fd4f67f4f27 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -315,6 +315,8 @@ typedef struct TransInfo {
float values[4];
float auto_values[4];
+ float axis[3];
+
void *view;
struct ScrArea *sa;
struct ARegion *ar;
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 822c0e5a961..7a89765fef2 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -332,7 +332,7 @@ static void createTransTexspace(bContext *C, TransInfo *t)
/* ********************* edge (for crease) ***** */
static void createTransEdge(bContext *C, TransInfo *t) {
-#if 0 // TRANSFORM_FIX_ME
+ EditMesh *em = ((Mesh *)t->obedit->data)->edit_mesh;
TransData *td = NULL;
EditEdge *eed;
float mtx[3][3], smtx[3][3];
@@ -390,7 +390,6 @@ static void createTransEdge(bContext *C, TransInfo *t) {
td++;
}
}
-#endif
}
/* ********************* pose mode ************* */
@@ -5148,11 +5147,11 @@ void createTransData(bContext *C, TransInfo *t)
Scene *scene = CTX_data_scene(C);
Object *ob = OBACT;
- if (t->options == CTX_TEXTURE) {
+ if (t->options & CTX_TEXTURE) {
t->flag |= T_TEXTURE;
createTransTexspace(C, t);
}
- else if (t->options == CTX_EDGE) {
+ else if (t->options & CTX_EDGE) {
t->ext = NULL;
t->flag |= T_EDIT;
createTransEdge(C, t);
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 061b2adbd79..3be863fc3f7 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -919,6 +919,11 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
t->flag |= T_MODAL;
}
+ /* Crease needs edge flag */
+ if (t->mode == TFM_CREASE) {
+ t->options |= CTX_EDGE;
+ }
+
t->spacetype = sa->spacetype;
if(t->spacetype == SPACE_VIEW3D)
{
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 4c118aa2625..f3789880ce9 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -67,6 +67,7 @@ char OP_TILT[] = "TRANSFORM_OT_tilt";
char OP_TRACKBALL[] = "TRANSFORM_OT_trackball";
char OP_MIRROR[] = "TRANSFORM_OT_mirror";
char OP_EDGE_SLIDE[] = "TRANSFORM_OT_edge_slide";
+char OP_EDGE_CREASE[] = "TRANSFORM_OT_edge_crease";
char OP_SEQ_SLIDE[] = "TRANSFORM_OT_seq_slide";
void TRANSFORM_OT_translate(struct wmOperatorType *ot);
@@ -80,6 +81,7 @@ void TRANSFORM_OT_tilt(struct wmOperatorType *ot);
void TRANSFORM_OT_trackball(struct wmOperatorType *ot);
void TRANSFORM_OT_mirror(struct wmOperatorType *ot);
void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot);
+void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot);
void TRANSFORM_OT_seq_slide(struct wmOperatorType *ot);
TransformModeItem transform_modes[] =
@@ -95,6 +97,7 @@ TransformModeItem transform_modes[] =
{OP_TRACKBALL, TFM_TRACKBALL, TRANSFORM_OT_trackball},
{OP_MIRROR, TFM_MIRROR, TRANSFORM_OT_mirror},
{OP_EDGE_SLIDE, TFM_EDGE_SLIDE, TRANSFORM_OT_edge_slide},
+ {OP_EDGE_CREASE, TFM_CREASE, TRANSFORM_OT_edge_crease},
{OP_SEQ_SLIDE, TFM_SEQ_SLIDE, TRANSFORM_OT_seq_slide},
{NULL, 0}
};
@@ -385,6 +388,15 @@ void Properties_Proportional(struct wmOperatorType *ot)
RNA_def_float(ot->srna, "proportional_size", 1, 0, FLT_MAX, "Proportional Size", "", 0, 100);
}
+void Properties_Axis(struct wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ prop= RNA_def_property(ot->srna, "axis", PROP_FLOAT, PROP_DIRECTION);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Axis", "The axis around which the transformation occurs.");
+}
+
void Properties_Snapping(struct wmOperatorType *ot, short fullsnap, short align)
{
RNA_def_boolean(ot->srna, "snap", 0, "Use Snapping Options", "");
@@ -504,6 +516,8 @@ void TRANSFORM_OT_rotate(struct wmOperatorType *ot)
RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI*2, M_PI*2);
+ Properties_Axis(ot);
+
Properties_Proportional(ot);
RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
@@ -686,6 +700,26 @@ void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot)
Properties_Snapping(ot, 0, 0);
}
+void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Edge Crease";
+ ot->description= "Change the crease of edges.";
+ ot->idname = OP_EDGE_CREASE;
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
+
+ /* api callbacks */
+ ot->invoke = transform_invoke;
+ ot->exec = transform_exec;
+ ot->modal = transform_modal;
+ ot->cancel = transform_cancel;
+ ot->poll = ED_operator_editmesh;
+
+ RNA_def_float_factor(ot->srna, "value", 0, -1.0f, 1.0f, "Factor", "", -1.0f, 1.0f);
+
+ Properties_Snapping(ot, 0, 0);
+}
+
void TRANSFORM_OT_seq_slide(struct wmOperatorType *ot)
{
/* identifiers */
@@ -757,6 +791,8 @@ void TRANSFORM_OT_transform(struct wmOperatorType *ot)
RNA_def_float_vector(ot->srna, "value", 4, NULL, -FLT_MAX, FLT_MAX, "Values", "", -FLT_MAX, FLT_MAX);
+ Properties_Axis(ot);
+
Properties_Proportional(ot);
RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
index e16568b5cf6..2a29576a981 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
@@ -268,6 +268,6 @@ Render* BlenderStrokeRenderer::RenderScene( Render *re ) {
Render* freestyle_render = RE_NewRender(freestyle_scene->id.name);
- RE_BlenderFrame( freestyle_render, freestyle_scene, 1);
+ RE_BlenderFrame( freestyle_render, freestyle_scene, NULL, 1);
return freestyle_render;
}
diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h
index fabe1420e83..36af91f140b 100644
--- a/source/blender/gpu/GPU_draw.h
+++ b/source/blender/gpu/GPU_draw.h
@@ -57,6 +57,10 @@ struct SmokeModifierData;
void GPU_state_init(void);
+/* Debugging */
+
+void GPU_state_print(void);
+
/* Material drawing
* - first the state is initialized by a particular object and
* it's materials
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index db6c7fa5ce0..74b9f362939 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -1313,5 +1313,370 @@ void GPU_state_init(void)
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
glDisable(GL_CULL_FACE);
+
+ glDisable(GL_MULTISAMPLE_ARB);
+}
+
+/* debugging aid */
+static void gpu_get_print(const char *name, GLenum type)
+{
+ float value[16];
+ int a;
+
+ memset(value, 0, sizeof(value));
+ glGetFloatv(type, value);
+
+ printf("%s: ", name);
+ for(a=0; a<16; a++)
+ printf("%.2f ", value[a]);
+ printf("\n");
+}
+
+void GPU_state_print(void)
+{
+ gpu_get_print("GL_ACCUM_ALPHA_BITS", GL_ACCUM_ALPHA_BITS);
+ gpu_get_print("GL_ACCUM_BLUE_BITS", GL_ACCUM_BLUE_BITS);
+ gpu_get_print("GL_ACCUM_CLEAR_VALUE", GL_ACCUM_CLEAR_VALUE);
+ gpu_get_print("GL_ACCUM_GREEN_BITS", GL_ACCUM_GREEN_BITS);
+ gpu_get_print("GL_ACCUM_RED_BITS", GL_ACCUM_RED_BITS);
+ gpu_get_print("GL_ACTIVE_TEXTURE", GL_ACTIVE_TEXTURE);
+ gpu_get_print("GL_ALIASED_POINT_SIZE_RANGE", GL_ALIASED_POINT_SIZE_RANGE);
+ gpu_get_print("GL_ALIASED_LINE_WIDTH_RANGE", GL_ALIASED_LINE_WIDTH_RANGE);
+ gpu_get_print("GL_ALPHA_BIAS", GL_ALPHA_BIAS);
+ gpu_get_print("GL_ALPHA_BITS", GL_ALPHA_BITS);
+ gpu_get_print("GL_ALPHA_SCALE", GL_ALPHA_SCALE);
+ gpu_get_print("GL_ALPHA_TEST", GL_ALPHA_TEST);
+ gpu_get_print("GL_ALPHA_TEST_FUNC", GL_ALPHA_TEST_FUNC);
+ gpu_get_print("GL_ALPHA_TEST_REF", GL_ALPHA_TEST_REF);
+ gpu_get_print("GL_ARRAY_BUFFER_BINDING", GL_ARRAY_BUFFER_BINDING);
+ gpu_get_print("GL_ATTRIB_STACK_DEPTH", GL_ATTRIB_STACK_DEPTH);
+ gpu_get_print("GL_AUTO_NORMAL", GL_AUTO_NORMAL);
+ gpu_get_print("GL_AUX_BUFFERS", GL_AUX_BUFFERS);
+ gpu_get_print("GL_BLEND", GL_BLEND);
+ gpu_get_print("GL_BLEND_COLOR", GL_BLEND_COLOR);
+ gpu_get_print("GL_BLEND_DST_ALPHA", GL_BLEND_DST_ALPHA);
+ gpu_get_print("GL_BLEND_DST_RGB", GL_BLEND_DST_RGB);
+ gpu_get_print("GL_BLEND_EQUATION_RGB", GL_BLEND_EQUATION_RGB);
+ gpu_get_print("GL_BLEND_EQUATION_ALPHA", GL_BLEND_EQUATION_ALPHA);
+ gpu_get_print("GL_BLEND_SRC_ALPHA", GL_BLEND_SRC_ALPHA);
+ gpu_get_print("GL_BLEND_SRC_RGB", GL_BLEND_SRC_RGB);
+ gpu_get_print("GL_BLUE_BIAS", GL_BLUE_BIAS);
+ gpu_get_print("GL_BLUE_BITS", GL_BLUE_BITS);
+ gpu_get_print("GL_BLUE_SCALE", GL_BLUE_SCALE);
+ gpu_get_print("GL_CLIENT_ACTIVE_TEXTURE", GL_CLIENT_ACTIVE_TEXTURE);
+ gpu_get_print("GL_CLIENT_ATTRIB_STACK_DEPTH", GL_CLIENT_ATTRIB_STACK_DEPTH);
+ gpu_get_print("GL_CLIP_PLANE0", GL_CLIP_PLANE0);
+ gpu_get_print("GL_COLOR_ARRAY", GL_COLOR_ARRAY);
+ gpu_get_print("GL_COLOR_ARRAY_BUFFER_BINDING", GL_COLOR_ARRAY_BUFFER_BINDING);
+ gpu_get_print("GL_COLOR_ARRAY_SIZE", GL_COLOR_ARRAY_SIZE);
+ gpu_get_print("GL_COLOR_ARRAY_STRIDE", GL_COLOR_ARRAY_STRIDE);
+ gpu_get_print("GL_COLOR_ARRAY_TYPE", GL_COLOR_ARRAY_TYPE);
+ gpu_get_print("GL_COLOR_CLEAR_VALUE", GL_COLOR_CLEAR_VALUE);
+ gpu_get_print("GL_COLOR_LOGIC_OP", GL_COLOR_LOGIC_OP);
+ gpu_get_print("GL_COLOR_MATERIAL", GL_COLOR_MATERIAL);
+ gpu_get_print("GL_COLOR_MATERIAL_FACE", GL_COLOR_MATERIAL_FACE);
+ gpu_get_print("GL_COLOR_MATERIAL_PARAMETER", GL_COLOR_MATERIAL_PARAMETER);
+ gpu_get_print("GL_COLOR_MATRIX", GL_COLOR_MATRIX);
+ gpu_get_print("GL_COLOR_MATRIX_STACK_DEPTH", GL_COLOR_MATRIX_STACK_DEPTH);
+ gpu_get_print("GL_COLOR_SUM", GL_COLOR_SUM);
+ gpu_get_print("GL_COLOR_TABLE", GL_COLOR_TABLE);
+ gpu_get_print("GL_COLOR_WRITEMASK", GL_COLOR_WRITEMASK);
+ gpu_get_print("GL_COMPRESSED_TEXTURE_FORMATS", GL_COMPRESSED_TEXTURE_FORMATS);
+ gpu_get_print("GL_CONVOLUTION_1D", GL_CONVOLUTION_1D);
+ gpu_get_print("GL_CONVOLUTION_2D", GL_CONVOLUTION_2D);
+ gpu_get_print("GL_CULL_FACE", GL_CULL_FACE);
+ gpu_get_print("GL_CULL_FACE_MODE", GL_CULL_FACE_MODE);
+ gpu_get_print("GL_CURRENT_COLOR", GL_CURRENT_COLOR);
+ gpu_get_print("GL_CURRENT_FOG_COORD", GL_CURRENT_FOG_COORD);
+ gpu_get_print("GL_CURRENT_INDEX", GL_CURRENT_INDEX);
+ gpu_get_print("GL_CURRENT_NORMAL", GL_CURRENT_NORMAL);
+ gpu_get_print("GL_CURRENT_PROGRAM", GL_CURRENT_PROGRAM);
+ gpu_get_print("GL_CURRENT_RASTER_COLOR", GL_CURRENT_RASTER_COLOR);
+ gpu_get_print("GL_CURRENT_RASTER_DISTANCE", GL_CURRENT_RASTER_DISTANCE);
+ gpu_get_print("GL_CURRENT_RASTER_INDEX", GL_CURRENT_RASTER_INDEX);
+ gpu_get_print("GL_CURRENT_RASTER_POSITION", GL_CURRENT_RASTER_POSITION);
+ gpu_get_print("GL_CURRENT_RASTER_POSITION_VALID", GL_CURRENT_RASTER_POSITION_VALID);
+ gpu_get_print("GL_CURRENT_RASTER_SECONDARY_COLOR", GL_CURRENT_RASTER_SECONDARY_COLOR);
+ gpu_get_print("GL_CURRENT_RASTER_TEXTURE_COORDS", GL_CURRENT_RASTER_TEXTURE_COORDS);
+ gpu_get_print("GL_CURRENT_SECONDARY_COLOR", GL_CURRENT_SECONDARY_COLOR);
+ gpu_get_print("GL_CURRENT_TEXTURE_COORDS", GL_CURRENT_TEXTURE_COORDS);
+ gpu_get_print("GL_DEPTH_BIAS", GL_DEPTH_BIAS);
+ gpu_get_print("GL_DEPTH_BITS", GL_DEPTH_BITS);
+ gpu_get_print("GL_DEPTH_CLEAR_VALUE", GL_DEPTH_CLEAR_VALUE);
+ gpu_get_print("GL_DEPTH_FUNC", GL_DEPTH_FUNC);
+ gpu_get_print("GL_DEPTH_RANGE", GL_DEPTH_RANGE);
+ gpu_get_print("GL_DEPTH_SCALE", GL_DEPTH_SCALE);
+ gpu_get_print("GL_DEPTH_TEST", GL_DEPTH_TEST);
+ gpu_get_print("GL_DEPTH_WRITEMASK", GL_DEPTH_WRITEMASK);
+ gpu_get_print("GL_DITHER", GL_DITHER);
+ gpu_get_print("GL_DOUBLEBUFFER", GL_DOUBLEBUFFER);
+ gpu_get_print("GL_DRAW_BUFFER", GL_DRAW_BUFFER);
+ gpu_get_print("GL_DRAW_BUFFER0", GL_DRAW_BUFFER0);
+ gpu_get_print("GL_EDGE_FLAG", GL_EDGE_FLAG);
+ gpu_get_print("GL_EDGE_FLAG_ARRAY", GL_EDGE_FLAG_ARRAY);
+ gpu_get_print("GL_EDGE_FLAG_ARRAY_BUFFER_BINDING", GL_EDGE_FLAG_ARRAY_BUFFER_BINDING);
+ gpu_get_print("GL_EDGE_FLAG_ARRAY_STRIDE", GL_EDGE_FLAG_ARRAY_STRIDE);
+ gpu_get_print("GL_ELEMENT_ARRAY_BUFFER_BINDING", GL_ELEMENT_ARRAY_BUFFER_BINDING);
+ gpu_get_print("GL_FEEDBACK_BUFFER_SIZE", GL_FEEDBACK_BUFFER_SIZE);
+ gpu_get_print("GL_FEEDBACK_BUFFER_TYPE", GL_FEEDBACK_BUFFER_TYPE);
+ gpu_get_print("GL_FOG", GL_FOG);
+ gpu_get_print("GL_FOG_COORD_ARRAY", GL_FOG_COORD_ARRAY);
+ gpu_get_print("GL_FOG_COORD_ARRAY_BUFFER_BINDING", GL_FOG_COORD_ARRAY_BUFFER_BINDING);
+ gpu_get_print("GL_FOG_COORD_ARRAY_STRIDE", GL_FOG_COORD_ARRAY_STRIDE);
+ gpu_get_print("GL_FOG_COORD_ARRAY_TYPE", GL_FOG_COORD_ARRAY_TYPE);
+ gpu_get_print("GL_FOG_COORD_SRC", GL_FOG_COORD_SRC);
+ gpu_get_print("GL_FOG_COLOR", GL_FOG_COLOR);
+ gpu_get_print("GL_FOG_DENSITY", GL_FOG_DENSITY);
+ gpu_get_print("GL_FOG_END", GL_FOG_END);
+ gpu_get_print("GL_FOG_HINT", GL_FOG_HINT);
+ gpu_get_print("GL_FOG_INDEX", GL_FOG_INDEX);
+ gpu_get_print("GL_FOG_MODE", GL_FOG_MODE);
+ gpu_get_print("GL_FOG_START", GL_FOG_START);
+ gpu_get_print("GL_FRAGMENT_SHADER_DERIVATIVE_HINT", GL_FRAGMENT_SHADER_DERIVATIVE_HINT);
+ gpu_get_print("GL_FRONT_FACE", GL_FRONT_FACE);
+ gpu_get_print("GL_GENERATE_MIPMAP_HINT", GL_GENERATE_MIPMAP_HINT);
+ gpu_get_print("GL_GREEN_BIAS", GL_GREEN_BIAS);
+ gpu_get_print("GL_GREEN_BITS", GL_GREEN_BITS);
+ gpu_get_print("GL_GREEN_SCALE", GL_GREEN_SCALE);
+ gpu_get_print("GL_HISTOGRAM", GL_HISTOGRAM);
+ gpu_get_print("GL_INDEX_ARRAY", GL_INDEX_ARRAY);
+ gpu_get_print("GL_INDEX_ARRAY_BUFFER_BINDING", GL_INDEX_ARRAY_BUFFER_BINDING);
+ gpu_get_print("GL_INDEX_ARRAY_STRIDE", GL_INDEX_ARRAY_STRIDE);
+ gpu_get_print("GL_INDEX_ARRAY_TYPE", GL_INDEX_ARRAY_TYPE);
+ gpu_get_print("GL_INDEX_BITS", GL_INDEX_BITS);
+ gpu_get_print("GL_INDEX_CLEAR_VALUE", GL_INDEX_CLEAR_VALUE);
+ gpu_get_print("GL_INDEX_LOGIC_OP", GL_INDEX_LOGIC_OP);
+ gpu_get_print("GL_INDEX_MODE", GL_INDEX_MODE);
+ gpu_get_print("GL_INDEX_OFFSET", GL_INDEX_OFFSET);
+ gpu_get_print("GL_INDEX_SHIFT", GL_INDEX_SHIFT);
+ gpu_get_print("GL_INDEX_WRITEMASK", GL_INDEX_WRITEMASK);
+ gpu_get_print("GL_LIGHT0", GL_LIGHT0);
+ gpu_get_print("GL_LIGHTING", GL_LIGHTING);
+ gpu_get_print("GL_LIGHT_MODEL_AMBIENT", GL_LIGHT_MODEL_AMBIENT);
+ gpu_get_print("GL_LIGHT_MODEL_COLOR_CONTROL", GL_LIGHT_MODEL_COLOR_CONTROL);
+ gpu_get_print("GL_LIGHT_MODEL_LOCAL_VIEWER", GL_LIGHT_MODEL_LOCAL_VIEWER);
+ gpu_get_print("GL_LIGHT_MODEL_TWO_SIDE", GL_LIGHT_MODEL_TWO_SIDE);
+ gpu_get_print("GL_LINE_SMOOTH", GL_LINE_SMOOTH);
+ gpu_get_print("GL_LINE_SMOOTH_HINT", GL_LINE_SMOOTH_HINT);
+ gpu_get_print("GL_LINE_STIPPLE", GL_LINE_STIPPLE);
+ gpu_get_print("GL_LINE_STIPPLE_PATTERN", GL_LINE_STIPPLE_PATTERN);
+ gpu_get_print("GL_LINE_STIPPLE_REPEAT", GL_LINE_STIPPLE_REPEAT);
+ gpu_get_print("GL_LINE_WIDTH", GL_LINE_WIDTH);
+ gpu_get_print("GL_LINE_WIDTH_GRANULARITY", GL_LINE_WIDTH_GRANULARITY);
+ gpu_get_print("GL_LINE_WIDTH_RANGE", GL_LINE_WIDTH_RANGE);
+ gpu_get_print("GL_LIST_BASE", GL_LIST_BASE);
+ gpu_get_print("GL_LIST_INDEX", GL_LIST_INDEX);
+ gpu_get_print("GL_LIST_MODE", GL_LIST_MODE);
+ gpu_get_print("GL_LOGIC_OP_MODE", GL_LOGIC_OP_MODE);
+ gpu_get_print("GL_MAP1_COLOR_4", GL_MAP1_COLOR_4);
+ gpu_get_print("GL_MAP1_GRID_DOMAIN", GL_MAP1_GRID_DOMAIN);
+ gpu_get_print("GL_MAP1_GRID_SEGMENTS", GL_MAP1_GRID_SEGMENTS);
+ gpu_get_print("GL_MAP1_INDEX", GL_MAP1_INDEX);
+ gpu_get_print("GL_MAP1_NORMAL", GL_MAP1_NORMAL);
+ gpu_get_print("GL_MAP1_TEXTURE_COORD_1", GL_MAP1_TEXTURE_COORD_1);
+ gpu_get_print("GL_MAP1_TEXTURE_COORD_2", GL_MAP1_TEXTURE_COORD_2);
+ gpu_get_print("GL_MAP1_TEXTURE_COORD_3", GL_MAP1_TEXTURE_COORD_3);
+ gpu_get_print("GL_MAP1_TEXTURE_COORD_4", GL_MAP1_TEXTURE_COORD_4);
+ gpu_get_print("GL_MAP1_VERTEX_3", GL_MAP1_VERTEX_3);
+ gpu_get_print("GL_MAP1_VERTEX_4", GL_MAP1_VERTEX_4);
+ gpu_get_print("GL_MAP2_COLOR_4", GL_MAP2_COLOR_4);
+ gpu_get_print("GL_MAP2_GRID_DOMAIN", GL_MAP2_GRID_DOMAIN);
+ gpu_get_print("GL_MAP2_GRID_SEGMENTS", GL_MAP2_GRID_SEGMENTS);
+ gpu_get_print("GL_MAP2_INDEX", GL_MAP2_INDEX);
+ gpu_get_print("GL_MAP2_NORMAL", GL_MAP2_NORMAL);
+ gpu_get_print("GL_MAP2_TEXTURE_COORD_1", GL_MAP2_TEXTURE_COORD_1);
+ gpu_get_print("GL_MAP2_TEXTURE_COORD_2", GL_MAP2_TEXTURE_COORD_2);
+ gpu_get_print("GL_MAP2_TEXTURE_COORD_3", GL_MAP2_TEXTURE_COORD_3);
+ gpu_get_print("GL_MAP2_TEXTURE_COORD_4", GL_MAP2_TEXTURE_COORD_4);
+ gpu_get_print("GL_MAP2_VERTEX_3", GL_MAP2_VERTEX_3);
+ gpu_get_print("GL_MAP2_VERTEX_4", GL_MAP2_VERTEX_4);
+ gpu_get_print("GL_MAP_COLOR", GL_MAP_COLOR);
+ gpu_get_print("GL_MAP_STENCIL", GL_MAP_STENCIL);
+ gpu_get_print("GL_MATRIX_MODE", GL_MATRIX_MODE);
+ gpu_get_print("GL_MAX_3D_TEXTURE_SIZE", GL_MAX_3D_TEXTURE_SIZE);
+ gpu_get_print("GL_MAX_CLIENT_ATTRIB_STACK_DEPTH", GL_MAX_CLIENT_ATTRIB_STACK_DEPTH);
+ gpu_get_print("GL_MAX_ATTRIB_STACK_DEPTH", GL_MAX_ATTRIB_STACK_DEPTH);
+ gpu_get_print("GL_MAX_CLIP_PLANES", GL_MAX_CLIP_PLANES);
+ gpu_get_print("GL_MAX_COLOR_MATRIX_STACK_DEPTH", GL_MAX_COLOR_MATRIX_STACK_DEPTH);
+ gpu_get_print("GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS", GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+ gpu_get_print("GL_MAX_CUBE_MAP_TEXTURE_SIZE", GL_MAX_CUBE_MAP_TEXTURE_SIZE);
+ gpu_get_print("GL_MAX_DRAW_BUFFERS", GL_MAX_DRAW_BUFFERS);
+ gpu_get_print("GL_MAX_ELEMENTS_INDICES", GL_MAX_ELEMENTS_INDICES);
+ gpu_get_print("GL_MAX_ELEMENTS_VERTICES", GL_MAX_ELEMENTS_VERTICES);
+ gpu_get_print("GL_MAX_EVAL_ORDER", GL_MAX_EVAL_ORDER);
+ gpu_get_print("GL_MAX_FRAGMENT_UNIFORM_COMPONENTS", GL_MAX_FRAGMENT_UNIFORM_COMPONENTS);
+ gpu_get_print("GL_MAX_LIGHTS", GL_MAX_LIGHTS);
+ gpu_get_print("GL_MAX_LIST_NESTING", GL_MAX_LIST_NESTING);
+ gpu_get_print("GL_MAX_MODELVIEW_STACK_DEPTH", GL_MAX_MODELVIEW_STACK_DEPTH);
+ gpu_get_print("GL_MAX_NAME_STACK_DEPTH", GL_MAX_NAME_STACK_DEPTH);
+ gpu_get_print("GL_MAX_PIXEL_MAP_TABLE", GL_MAX_PIXEL_MAP_TABLE);
+ gpu_get_print("GL_MAX_PROJECTION_STACK_DEPTH", GL_MAX_PROJECTION_STACK_DEPTH);
+ gpu_get_print("GL_MAX_TEXTURE_COORDS", GL_MAX_TEXTURE_COORDS);
+ gpu_get_print("GL_MAX_TEXTURE_IMAGE_UNITS", GL_MAX_TEXTURE_IMAGE_UNITS);
+ gpu_get_print("GL_MAX_TEXTURE_LOD_BIAS", GL_MAX_TEXTURE_LOD_BIAS);
+ gpu_get_print("GL_MAX_TEXTURE_SIZE", GL_MAX_TEXTURE_SIZE);
+ gpu_get_print("GL_MAX_TEXTURE_STACK_DEPTH", GL_MAX_TEXTURE_STACK_DEPTH);
+ gpu_get_print("GL_MAX_TEXTURE_UNITS", GL_MAX_TEXTURE_UNITS);
+ gpu_get_print("GL_MAX_VARYING_FLOATS", GL_MAX_VARYING_FLOATS);
+ gpu_get_print("GL_MAX_VERTEX_ATTRIBS", GL_MAX_VERTEX_ATTRIBS);
+ gpu_get_print("GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS", GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
+ gpu_get_print("GL_MAX_VERTEX_UNIFORM_COMPONENTS", GL_MAX_VERTEX_UNIFORM_COMPONENTS);
+ gpu_get_print("GL_MAX_VIEWPORT_DIMS", GL_MAX_VIEWPORT_DIMS);
+ gpu_get_print("GL_MINMAX", GL_MINMAX);
+ gpu_get_print("GL_MODELVIEW_MATRIX", GL_MODELVIEW_MATRIX);
+ gpu_get_print("GL_MODELVIEW_STACK_DEPTH", GL_MODELVIEW_STACK_DEPTH);
+ gpu_get_print("GL_NAME_STACK_DEPTH", GL_NAME_STACK_DEPTH);
+ gpu_get_print("GL_NORMAL_ARRAY", GL_NORMAL_ARRAY);
+ gpu_get_print("GL_NORMAL_ARRAY_BUFFER_BINDING", GL_NORMAL_ARRAY_BUFFER_BINDING);
+ gpu_get_print("GL_NORMAL_ARRAY_STRIDE", GL_NORMAL_ARRAY_STRIDE);
+ gpu_get_print("GL_NORMAL_ARRAY_TYPE", GL_NORMAL_ARRAY_TYPE);
+ gpu_get_print("GL_NORMALIZE", GL_NORMALIZE);
+ gpu_get_print("GL_NUM_COMPRESSED_TEXTURE_FORMATS", GL_NUM_COMPRESSED_TEXTURE_FORMATS);
+ gpu_get_print("GL_PACK_ALIGNMENT", GL_PACK_ALIGNMENT);
+ gpu_get_print("GL_PACK_IMAGE_HEIGHT", GL_PACK_IMAGE_HEIGHT);
+ gpu_get_print("GL_PACK_LSB_FIRST", GL_PACK_LSB_FIRST);
+ gpu_get_print("GL_PACK_ROW_LENGTH", GL_PACK_ROW_LENGTH);
+ gpu_get_print("GL_PACK_SKIP_IMAGES", GL_PACK_SKIP_IMAGES);
+ gpu_get_print("GL_PACK_SKIP_PIXELS", GL_PACK_SKIP_PIXELS);
+ gpu_get_print("GL_PACK_SKIP_ROWS", GL_PACK_SKIP_ROWS);
+ gpu_get_print("GL_PACK_SWAP_BYTES", GL_PACK_SWAP_BYTES);
+ gpu_get_print("GL_PERSPECTIVE_CORRECTION_HINT", GL_PERSPECTIVE_CORRECTION_HINT);
+ gpu_get_print("GL_PIXEL_MAP_A_TO_A_SIZE", GL_PIXEL_MAP_A_TO_A_SIZE);
+ gpu_get_print("GL_PIXEL_MAP_B_TO_B_SIZE", GL_PIXEL_MAP_B_TO_B_SIZE);
+ gpu_get_print("GL_PIXEL_MAP_G_TO_G_SIZE", GL_PIXEL_MAP_G_TO_G_SIZE);
+ gpu_get_print("GL_PIXEL_MAP_I_TO_A_SIZE", GL_PIXEL_MAP_I_TO_A_SIZE);
+ gpu_get_print("GL_PIXEL_MAP_I_TO_B_SIZE", GL_PIXEL_MAP_I_TO_B_SIZE);
+ gpu_get_print("GL_PIXEL_MAP_I_TO_G_SIZE", GL_PIXEL_MAP_I_TO_G_SIZE);
+ gpu_get_print("GL_PIXEL_MAP_I_TO_I_SIZE", GL_PIXEL_MAP_I_TO_I_SIZE);
+ gpu_get_print("GL_PIXEL_MAP_I_TO_R_SIZE", GL_PIXEL_MAP_I_TO_R_SIZE);
+ gpu_get_print("GL_PIXEL_MAP_R_TO_R_SIZE", GL_PIXEL_MAP_R_TO_R_SIZE);
+ gpu_get_print("GL_PIXEL_MAP_S_TO_S_SIZE", GL_PIXEL_MAP_S_TO_S_SIZE);
+ gpu_get_print("GL_PIXEL_PACK_BUFFER_BINDING", GL_PIXEL_PACK_BUFFER_BINDING);
+ gpu_get_print("GL_PIXEL_UNPACK_BUFFER_BINDING", GL_PIXEL_UNPACK_BUFFER_BINDING);
+ gpu_get_print("GL_POINT_DISTANCE_ATTENUATION", GL_POINT_DISTANCE_ATTENUATION);
+ gpu_get_print("GL_POINT_FADE_THRESHOLD_SIZE", GL_POINT_FADE_THRESHOLD_SIZE);
+ gpu_get_print("GL_POINT_SIZE", GL_POINT_SIZE);
+ gpu_get_print("GL_POINT_SIZE_GRANULARITY", GL_POINT_SIZE_GRANULARITY);
+ gpu_get_print("GL_POINT_SIZE_MAX", GL_POINT_SIZE_MAX);
+ gpu_get_print("GL_POINT_SIZE_MIN", GL_POINT_SIZE_MIN);
+ gpu_get_print("GL_POINT_SIZE_RANGE", GL_POINT_SIZE_RANGE);
+ gpu_get_print("GL_POINT_SMOOTH", GL_POINT_SMOOTH);
+ gpu_get_print("GL_POINT_SMOOTH_HINT", GL_POINT_SMOOTH_HINT);
+ gpu_get_print("GL_POINT_SPRITE", GL_POINT_SPRITE);
+ gpu_get_print("GL_POLYGON_MODE", GL_POLYGON_MODE);
+ gpu_get_print("GL_POLYGON_OFFSET_FACTOR", GL_POLYGON_OFFSET_FACTOR);
+ gpu_get_print("GL_POLYGON_OFFSET_UNITS", GL_POLYGON_OFFSET_UNITS);
+ gpu_get_print("GL_POLYGON_OFFSET_FILL", GL_POLYGON_OFFSET_FILL);
+ gpu_get_print("GL_POLYGON_OFFSET_LINE", GL_POLYGON_OFFSET_LINE);
+ gpu_get_print("GL_POLYGON_OFFSET_POINT", GL_POLYGON_OFFSET_POINT);
+ gpu_get_print("GL_POLYGON_SMOOTH", GL_POLYGON_SMOOTH);
+ gpu_get_print("GL_POLYGON_SMOOTH_HINT", GL_POLYGON_SMOOTH_HINT);
+ gpu_get_print("GL_POLYGON_STIPPLE", GL_POLYGON_STIPPLE);
+ gpu_get_print("GL_POST_COLOR_MATRIX_COLOR_TABLE", GL_POST_COLOR_MATRIX_COLOR_TABLE);
+ gpu_get_print("GL_POST_COLOR_MATRIX_RED_BIAS", GL_POST_COLOR_MATRIX_RED_BIAS);
+ gpu_get_print("GL_POST_COLOR_MATRIX_GREEN_BIAS", GL_POST_COLOR_MATRIX_GREEN_BIAS);
+ gpu_get_print("GL_POST_COLOR_MATRIX_BLUE_BIAS", GL_POST_COLOR_MATRIX_BLUE_BIAS);
+ gpu_get_print("GL_POST_COLOR_MATRIX_ALPHA_BIAS", GL_POST_COLOR_MATRIX_ALPHA_BIAS);
+ gpu_get_print("GL_POST_COLOR_MATRIX_RED_SCALE", GL_POST_COLOR_MATRIX_RED_SCALE);
+ gpu_get_print("GL_POST_COLOR_MATRIX_GREEN_SCALE", GL_POST_COLOR_MATRIX_GREEN_SCALE);
+ gpu_get_print("GL_POST_COLOR_MATRIX_BLUE_SCALE", GL_POST_COLOR_MATRIX_BLUE_SCALE);
+ gpu_get_print("GL_POST_COLOR_MATRIX_ALPHA_SCALE", GL_POST_COLOR_MATRIX_ALPHA_SCALE);
+ gpu_get_print("GL_POST_CONVOLUTION_COLOR_TABLE", GL_POST_CONVOLUTION_COLOR_TABLE);
+ gpu_get_print("GL_POST_CONVOLUTION_RED_BIAS", GL_POST_CONVOLUTION_RED_BIAS);
+ gpu_get_print("GL_POST_CONVOLUTION_GREEN_BIAS", GL_POST_CONVOLUTION_GREEN_BIAS);
+ gpu_get_print("GL_POST_CONVOLUTION_BLUE_BIAS", GL_POST_CONVOLUTION_BLUE_BIAS);
+ gpu_get_print("GL_POST_CONVOLUTION_ALPHA_BIAS", GL_POST_CONVOLUTION_ALPHA_BIAS);
+ gpu_get_print("GL_POST_CONVOLUTION_RED_SCALE", GL_POST_CONVOLUTION_RED_SCALE);
+ gpu_get_print("GL_POST_CONVOLUTION_GREEN_SCALE", GL_POST_CONVOLUTION_GREEN_SCALE);
+ gpu_get_print("GL_POST_CONVOLUTION_BLUE_SCALE", GL_POST_CONVOLUTION_BLUE_SCALE);
+ gpu_get_print("GL_POST_CONVOLUTION_ALPHA_SCALE", GL_POST_CONVOLUTION_ALPHA_SCALE);
+ gpu_get_print("GL_PROJECTION_MATRIX", GL_PROJECTION_MATRIX);
+ gpu_get_print("GL_PROJECTION_STACK_DEPTH", GL_PROJECTION_STACK_DEPTH);
+ gpu_get_print("GL_READ_BUFFER", GL_READ_BUFFER);
+ gpu_get_print("GL_RED_BIAS", GL_RED_BIAS);
+ gpu_get_print("GL_RED_BITS", GL_RED_BITS);
+ gpu_get_print("GL_RED_SCALE", GL_RED_SCALE);
+ gpu_get_print("GL_RENDER_MODE", GL_RENDER_MODE);
+ gpu_get_print("GL_RESCALE_NORMAL", GL_RESCALE_NORMAL);
+ gpu_get_print("GL_RGBA_MODE", GL_RGBA_MODE);
+ gpu_get_print("GL_SAMPLE_BUFFERS", GL_SAMPLE_BUFFERS);
+ gpu_get_print("GL_SAMPLE_COVERAGE_VALUE", GL_SAMPLE_COVERAGE_VALUE);
+ gpu_get_print("GL_SAMPLE_COVERAGE_INVERT", GL_SAMPLE_COVERAGE_INVERT);
+ gpu_get_print("GL_SAMPLES", GL_SAMPLES);
+ gpu_get_print("GL_SCISSOR_BOX", GL_SCISSOR_BOX);
+ gpu_get_print("GL_SCISSOR_TEST", GL_SCISSOR_TEST);
+ gpu_get_print("GL_SECONDARY_COLOR_ARRAY", GL_SECONDARY_COLOR_ARRAY);
+ gpu_get_print("GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING", GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING);
+ gpu_get_print("GL_SECONDARY_COLOR_ARRAY_SIZE", GL_SECONDARY_COLOR_ARRAY_SIZE);
+ gpu_get_print("GL_SECONDARY_COLOR_ARRAY_STRIDE", GL_SECONDARY_COLOR_ARRAY_STRIDE);
+ gpu_get_print("GL_SECONDARY_COLOR_ARRAY_TYPE", GL_SECONDARY_COLOR_ARRAY_TYPE);
+ gpu_get_print("GL_SELECTION_BUFFER_SIZE", GL_SELECTION_BUFFER_SIZE);
+ gpu_get_print("GL_SEPARABLE_2D", GL_SEPARABLE_2D);
+ gpu_get_print("GL_SHADE_MODEL", GL_SHADE_MODEL);
+ gpu_get_print("GL_SMOOTH_LINE_WIDTH_RANGE", GL_SMOOTH_LINE_WIDTH_RANGE);
+ gpu_get_print("GL_SMOOTH_LINE_WIDTH_GRANULARITY", GL_SMOOTH_LINE_WIDTH_GRANULARITY);
+ gpu_get_print("GL_SMOOTH_POINT_SIZE_RANGE", GL_SMOOTH_POINT_SIZE_RANGE);
+ gpu_get_print("GL_SMOOTH_POINT_SIZE_GRANULARITY", GL_SMOOTH_POINT_SIZE_GRANULARITY);
+ gpu_get_print("GL_STENCIL_BACK_FAIL", GL_STENCIL_BACK_FAIL);
+ gpu_get_print("GL_STENCIL_BACK_FUNC", GL_STENCIL_BACK_FUNC);
+ gpu_get_print("GL_STENCIL_BACK_PASS_DEPTH_FAIL", GL_STENCIL_BACK_PASS_DEPTH_FAIL);
+ gpu_get_print("GL_STENCIL_BACK_PASS_DEPTH_PASS", GL_STENCIL_BACK_PASS_DEPTH_PASS);
+ gpu_get_print("GL_STENCIL_BACK_REF", GL_STENCIL_BACK_REF);
+ gpu_get_print("GL_STENCIL_BACK_VALUE_MASK", GL_STENCIL_BACK_VALUE_MASK);
+ gpu_get_print("GL_STENCIL_BACK_WRITEMASK", GL_STENCIL_BACK_WRITEMASK);
+ gpu_get_print("GL_STENCIL_BITS", GL_STENCIL_BITS);
+ gpu_get_print("GL_STENCIL_CLEAR_VALUE", GL_STENCIL_CLEAR_VALUE);
+ gpu_get_print("GL_STENCIL_FAIL", GL_STENCIL_FAIL);
+ gpu_get_print("GL_STENCIL_FUNC", GL_STENCIL_FUNC);
+ gpu_get_print("GL_STENCIL_PASS_DEPTH_FAIL", GL_STENCIL_PASS_DEPTH_FAIL);
+ gpu_get_print("GL_STENCIL_PASS_DEPTH_PASS", GL_STENCIL_PASS_DEPTH_PASS);
+ gpu_get_print("GL_STENCIL_REF", GL_STENCIL_REF);
+ gpu_get_print("GL_STENCIL_TEST", GL_STENCIL_TEST);
+ gpu_get_print("GL_STENCIL_VALUE_MASK", GL_STENCIL_VALUE_MASK);
+ gpu_get_print("GL_STENCIL_WRITEMASK", GL_STENCIL_WRITEMASK);
+ gpu_get_print("GL_STEREO", GL_STEREO);
+ gpu_get_print("GL_SUBPIXEL_BITS", GL_SUBPIXEL_BITS);
+ gpu_get_print("GL_TEXTURE_1D", GL_TEXTURE_1D);
+ gpu_get_print("GL_TEXTURE_BINDING_1D", GL_TEXTURE_BINDING_1D);
+ gpu_get_print("GL_TEXTURE_2D", GL_TEXTURE_2D);
+ gpu_get_print("GL_TEXTURE_BINDING_2D", GL_TEXTURE_BINDING_2D);
+ gpu_get_print("GL_TEXTURE_3D", GL_TEXTURE_3D);
+ gpu_get_print("GL_TEXTURE_BINDING_3D", GL_TEXTURE_BINDING_3D);
+ gpu_get_print("GL_TEXTURE_BINDING_CUBE_MAP", GL_TEXTURE_BINDING_CUBE_MAP);
+ gpu_get_print("GL_TEXTURE_COMPRESSION_HINT", GL_TEXTURE_COMPRESSION_HINT);
+ gpu_get_print("GL_TEXTURE_COORD_ARRAY", GL_TEXTURE_COORD_ARRAY);
+ gpu_get_print("GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING", GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING);
+ gpu_get_print("GL_TEXTURE_COORD_ARRAY_SIZE", GL_TEXTURE_COORD_ARRAY_SIZE);
+ gpu_get_print("GL_TEXTURE_COORD_ARRAY_STRIDE", GL_TEXTURE_COORD_ARRAY_STRIDE);
+ gpu_get_print("GL_TEXTURE_COORD_ARRAY_TYPE", GL_TEXTURE_COORD_ARRAY_TYPE);
+ gpu_get_print("GL_TEXTURE_CUBE_MAP", GL_TEXTURE_CUBE_MAP);
+ gpu_get_print("GL_TEXTURE_GEN_Q", GL_TEXTURE_GEN_Q);
+ gpu_get_print("GL_TEXTURE_GEN_R", GL_TEXTURE_GEN_R);
+ gpu_get_print("GL_TEXTURE_GEN_S", GL_TEXTURE_GEN_S);
+ gpu_get_print("GL_TEXTURE_GEN_T", GL_TEXTURE_GEN_T);
+ gpu_get_print("GL_TEXTURE_MATRIX", GL_TEXTURE_MATRIX);
+ gpu_get_print("GL_TEXTURE_STACK_DEPTH", GL_TEXTURE_STACK_DEPTH);
+ gpu_get_print("GL_TRANSPOSE_COLOR_MATRIX", GL_TRANSPOSE_COLOR_MATRIX);
+ gpu_get_print("GL_TRANSPOSE_MODELVIEW_MATRIX", GL_TRANSPOSE_MODELVIEW_MATRIX);
+ gpu_get_print("GL_TRANSPOSE_PROJECTION_MATRIX", GL_TRANSPOSE_PROJECTION_MATRIX);
+ gpu_get_print("GL_TRANSPOSE_TEXTURE_MATRIX", GL_TRANSPOSE_TEXTURE_MATRIX);
+ gpu_get_print("GL_UNPACK_ALIGNMENT", GL_UNPACK_ALIGNMENT);
+ gpu_get_print("GL_UNPACK_IMAGE_HEIGHT", GL_UNPACK_IMAGE_HEIGHT);
+ gpu_get_print("GL_UNPACK_LSB_FIRST", GL_UNPACK_LSB_FIRST);
+ gpu_get_print("GL_UNPACK_ROW_LENGTH", GL_UNPACK_ROW_LENGTH);
+ gpu_get_print("GL_UNPACK_SKIP_IMAGES", GL_UNPACK_SKIP_IMAGES);
+ gpu_get_print("GL_UNPACK_SKIP_PIXELS", GL_UNPACK_SKIP_PIXELS);
+ gpu_get_print("GL_UNPACK_SKIP_ROWS", GL_UNPACK_SKIP_ROWS);
+ gpu_get_print("GL_UNPACK_SWAP_BYTES", GL_UNPACK_SWAP_BYTES);
+ gpu_get_print("GL_VERTEX_ARRAY", GL_VERTEX_ARRAY);
+ gpu_get_print("GL_VERTEX_ARRAY_BUFFER_BINDING", GL_VERTEX_ARRAY_BUFFER_BINDING);
+ gpu_get_print("GL_VERTEX_ARRAY_SIZE", GL_VERTEX_ARRAY_SIZE);
+ gpu_get_print("GL_VERTEX_ARRAY_STRIDE", GL_VERTEX_ARRAY_STRIDE);
+ gpu_get_print("GL_VERTEX_ARRAY_TYPE", GL_VERTEX_ARRAY_TYPE);
+ gpu_get_print("GL_VERTEX_PROGRAM_POINT_SIZE", GL_VERTEX_PROGRAM_POINT_SIZE);
+ gpu_get_print("GL_VERTEX_PROGRAM_TWO_SIDE", GL_VERTEX_PROGRAM_TWO_SIDE);
+ gpu_get_print("GL_VIEWPORT", GL_VIEWPORT);
+ gpu_get_print("GL_ZOOM_X", GL_ZOOM_X);
+ gpu_get_print("GL_ZOOM_Y", GL_ZOOM_Y);
}
diff --git a/source/blender/imbuf/intern/amiga.c b/source/blender/imbuf/intern/amiga.c
index f84740826ae..91638a7ea72 100644
--- a/source/blender/imbuf/intern/amiga.c
+++ b/source/blender/imbuf/intern/amiga.c
@@ -452,6 +452,7 @@ struct ImBuf *imb_loadamiga(int *iffmem,int flags)
if (ibuf == 0) return (0);
ibuf->ftype = (ftype | AMI);
+ ibuf->profile = IB_PROFILE_SRGB;
if (cmap){
ibuf->mincol = 0;
diff --git a/source/blender/imbuf/intern/bmp.c b/source/blender/imbuf/intern/bmp.c
index 141b8a985cf..ada5fcebf73 100644
--- a/source/blender/imbuf/intern/bmp.c
+++ b/source/blender/imbuf/intern/bmp.c
@@ -175,6 +175,7 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, int size, int flags)
if (ibuf) {
ibuf->ftype = BMP;
+ ibuf->profile = IB_PROFILE_SRGB;
}
return(ibuf);
diff --git a/source/blender/imbuf/intern/dds/dds_api.cpp b/source/blender/imbuf/intern/dds/dds_api.cpp
index cf2f6c16d08..d7ff4761605 100644
--- a/source/blender/imbuf/intern/dds/dds_api.cpp
+++ b/source/blender/imbuf/intern/dds/dds_api.cpp
@@ -101,6 +101,7 @@ struct ImBuf *imb_load_dds(unsigned char *mem, int size, int flags)
if (ibuf == 0) return(0); /* memory allocation failed */
ibuf->ftype = DDS;
+ ibuf->profile = IB_PROFILE_SRGB;
if ((flags & IB_test) == 0) {
if (!imb_addrectImBuf(ibuf)) return(ibuf);
diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c
index 35be1f716e6..bcf913e6caf 100644
--- a/source/blender/imbuf/intern/divers.c
+++ b/source/blender/imbuf/intern/divers.c
@@ -175,12 +175,14 @@ void IMB_gamwarp(struct ImBuf *ibuf, double gamma)
}
+/* assume converting from linear float to sRGB byte */
void IMB_rect_from_float(struct ImBuf *ibuf)
{
/* quick method to convert floatbuf to byte */
float *tof = (float *)ibuf->rect_float;
- float dither= ibuf->dither;
- float srgb[3];
+ int do_dither = ibuf->dither != 0.f;
+ float dither= ibuf->dither / 255.0;
+ float srgb[4];
int i, channels= ibuf->channels;
short profile= ibuf->profile;
unsigned char *to = (unsigned char *) ibuf->rect;
@@ -195,7 +197,7 @@ void IMB_rect_from_float(struct ImBuf *ibuf)
for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof++)
to[1]= to[2]= to[3]= to[0] = FTOCHAR(tof[0]);
}
- else if (profile == IB_PROFILE_SRGB) {
+ else if (profile == IB_PROFILE_LINEAR_RGB) {
if(channels == 3) {
for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof+=3) {
srgb[0]= linearrgb_to_srgb(tof[0]);
@@ -209,10 +211,26 @@ void IMB_rect_from_float(struct ImBuf *ibuf)
}
}
else if (channels == 4) {
- floatbuf_to_srgb_byte(tof, to, 0, ibuf->x, 0, ibuf->y, ibuf->x);
+ if (dither != 0.f) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof+=4) {
+ const float d = (BLI_frand()-0.5)*dither;
+
+ srgb[0]= d + linearrgb_to_srgb(tof[0]);
+ srgb[1]= d + linearrgb_to_srgb(tof[1]);
+ srgb[2]= d + linearrgb_to_srgb(tof[2]);
+ srgb[3]= d + tof[3];
+
+ to[0] = FTOCHAR(srgb[0]);
+ to[1] = FTOCHAR(srgb[1]);
+ to[2] = FTOCHAR(srgb[2]);
+ to[3] = FTOCHAR(srgb[3]);
+ }
+ } else {
+ floatbuf_to_srgb_byte(tof, to, 0, ibuf->x, 0, ibuf->y, ibuf->x);
+ }
}
}
- else if(ELEM(profile, IB_PROFILE_NONE, IB_PROFILE_LINEAR_RGB) && dither==0.0f) {
+ else if(ELEM(profile, IB_PROFILE_NONE, IB_PROFILE_SRGB)) {
if(channels==3) {
for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof+=3) {
to[0] = FTOCHAR(tof[0]);
@@ -222,32 +240,26 @@ void IMB_rect_from_float(struct ImBuf *ibuf)
}
}
else {
- for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof+=4) {
- to[0] = FTOCHAR(tof[0]);
- to[1] = FTOCHAR(tof[1]);
- to[2] = FTOCHAR(tof[2]);
- to[3] = FTOCHAR(tof[3]);
+ if (dither != 0.f) {
+ float col[3];
+ for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof+=4) {
+ const float d = (BLI_frand()-0.5)*dither;
+ const float col[4] = {d+tof[0], d+tof[1], d+tof[2], d+tof[3]};
+ to[0] = FTOCHAR(col[0]);
+ to[1] = FTOCHAR(col[1]);
+ to[2] = FTOCHAR(col[2]);
+ to[3] = FTOCHAR(col[3]);
+ }
+ } else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof+=4) {
+ to[0] = FTOCHAR(tof[0]);
+ to[1] = FTOCHAR(tof[1]);
+ to[2] = FTOCHAR(tof[2]);
+ to[3] = FTOCHAR(tof[3]);
+ }
}
}
}
- else {
- float dither_value, col;
- dither= dither/255.0f;
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- dither_value = (BLI_frand()-0.5)*dither;
- col= tof[0] + dither_value;
- to[0] = FTOCHAR(col);
- col= tof[1] + dither_value;
- to[1] = FTOCHAR(col);
- col= tof[2] + dither_value;
- to[2] = FTOCHAR(col);
- col= tof[3] + dither_value;
- to[3] = FTOCHAR(col);
-
- to += 4;
- tof += 4;
- }
- }
}
void IMB_float_from_rect(struct ImBuf *ibuf)
@@ -263,8 +275,11 @@ void IMB_float_from_rect(struct ImBuf *ibuf)
tof = ibuf->rect_float;
}
- if (ibuf->profile == IB_PROFILE_SRGB) {
- /* convert from srgb to linear rgb */
+ /* Float bufs should be stored linear */
+
+ if (ibuf->profile != IB_PROFILE_NONE) {
+ /* if the image has been given a profile then we're working
+ * with color management in mind, so convert it to linear space */
for (i = ibuf->x * ibuf->y; i > 0; i--)
{
diff --git a/source/blender/imbuf/intern/hamx.c b/source/blender/imbuf/intern/hamx.c
index 258c196fcdf..222604121f9 100644
--- a/source/blender/imbuf/intern/hamx.c
+++ b/source/blender/imbuf/intern/hamx.c
@@ -387,6 +387,7 @@ struct ImBuf *imb_loadanim(int *iffmem, int flags)
if (ibuf==0) return (0);
ibuf->ftype = (Anim | adat.type);
+ ibuf->profile = IB_PROFILE_SRGB;
ibuf->xorig = adat.xorig;
ibuf->yorig = adat.yorig;
ibuf->flags = flags;
diff --git a/source/blender/imbuf/intern/iris.c b/source/blender/imbuf/intern/iris.c
index 7b8c383ddb9..4389eea8939 100644
--- a/source/blender/imbuf/intern/iris.c
+++ b/source/blender/imbuf/intern/iris.c
@@ -494,6 +494,7 @@ struct ImBuf *imb_loadiris(unsigned char *mem, int flags)
}
ibuf->ftype = IMAGIC;
+ ibuf->profile = IB_PROFILE_SRGB;
if (flags & IB_ttob) IMB_flipy(ibuf);
test_endian_zbuf(ibuf);
diff --git a/source/blender/imbuf/intern/jpeg.c b/source/blender/imbuf/intern/jpeg.c
index 2df522ff4a2..2b2d17784e2 100644
--- a/source/blender/imbuf/intern/jpeg.c
+++ b/source/blender/imbuf/intern/jpeg.c
@@ -416,6 +416,7 @@ next_stamp_marker:
jpeg_destroy((j_common_ptr) cinfo);
ibuf->ftype = ibuf_ftype;
+ ibuf->profile = IB_PROFILE_SRGB;
}
return(ibuf);
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index a780727b1a2..18462121810 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -933,6 +933,9 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags)
ibuf = IMB_allocImBuf(width, height, 32, 0, 0);
ibuf->ftype = OPENEXR;
+
+ /* openEXR is linear as per EXR spec */
+ ibuf->profile = IB_PROFILE_LINEAR_RGB;
if (!(flags & IB_test))
{
diff --git a/source/blender/imbuf/intern/png.c b/source/blender/imbuf/intern/png.c
index 3d42eafe623..724f209884c 100644
--- a/source/blender/imbuf/intern/png.c
+++ b/source/blender/imbuf/intern/png.c
@@ -368,6 +368,7 @@ struct ImBuf *imb_loadpng(unsigned char *mem, int size, int flags)
if (ibuf) {
ibuf->ftype = PNG;
+ ibuf->profile = IB_PROFILE_SRGB;
} else {
printf("Couldn't allocate memory for PNG image\n");
}
diff --git a/source/blender/imbuf/intern/radiance_hdr.c b/source/blender/imbuf/intern/radiance_hdr.c
index 69c4970df38..5acde1232fd 100644
--- a/source/blender/imbuf/intern/radiance_hdr.c
+++ b/source/blender/imbuf/intern/radiance_hdr.c
@@ -204,6 +204,7 @@ struct ImBuf *imb_loadhdr(unsigned char *mem, int size, int flags)
if (ibuf==NULL) return NULL;
ibuf->ftype = RADHDR;
+ ibuf->profile = IB_PROFILE_LINEAR_RGB;
ibuf->xorig = ibuf->yorig = 0;
if (flags & IB_test) return ibuf;
diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c
index 61254944001..ce3d6f9ce91 100644
--- a/source/blender/imbuf/intern/readimage.c
+++ b/source/blender/imbuf/intern/readimage.c
@@ -161,6 +161,7 @@ ImBuf *IMB_ibImageFromMemory(int *mem, int size, int flags) {
ibuf = imb_cocoaLoadImage((uchar *)mem, size, flags);
if(ibuf) {
ibuf->ftype = TIF;
+ ibuf->profile = IB_PROFILE_SRGB;
return ibuf;
}
#else
diff --git a/source/blender/imbuf/intern/targa.c b/source/blender/imbuf/intern/targa.c
index acc3e06448f..9e6a774e4e5 100644
--- a/source/blender/imbuf/intern/targa.c
+++ b/source/blender/imbuf/intern/targa.c
@@ -569,6 +569,7 @@ struct ImBuf *imb_loadtarga(unsigned char *mem, int mem_size, int flags)
if (ibuf == 0) return(0);
ibuf->ftype = TGA;
+ ibuf->profile = IB_PROFILE_SRGB;
ibuf->xorig = tga.xorig;
ibuf->yorig = tga.yorig;
mem = mem + 18 + tga.numid;
diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c
index b2465d6cc2f..0a81e903d05 100644
--- a/source/blender/imbuf/intern/tiff.c
+++ b/source/blender/imbuf/intern/tiff.c
@@ -347,6 +347,7 @@ struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags)
ibuf = IMB_allocImBuf(width, height, 8*bytesperpixel, 0, 0);
if (ibuf) {
ibuf->ftype = TIF;
+ ibuf->profile = IB_PROFILE_SRGB;
} else {
fprintf(stderr,
"imb_loadtiff: could not allocate memory for TIFF " \
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 0c38421a3f5..8c835dd7ca7 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -212,8 +212,8 @@ typedef struct PreviewImage {
#define LIB_FAKEUSER 512
/* free test flag */
#define LIB_DOIT 1024
-/* */
-#define LIB_APPEND_TAG 2048
+/* tag existing data before linking so we know what is new */
+#define LIB_PRE_EXISTING 2048
#ifdef __cplusplus
}
diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h
index 9847b3a9219..dbc715ba87f 100644
--- a/source/blender/makesdna/DNA_action_types.h
+++ b/source/blender/makesdna/DNA_action_types.h
@@ -46,13 +46,23 @@ struct Object;
/* Motion Paths ------------------------------------ */
/* (used for Pose Channels and Objects) */
-/* Data point for motion path */
+/* Data point for motion path (mpv) */
typedef struct bMotionPathVert {
float co[3]; /* coordinates of point in 3D-space */
int flag; /* quick settings */
} bMotionPathVert;
-/* Motion Path data cache - for elements providing transforms (i.e. Objects or PoseChannels) */
+/* bMotionPathVert->flag */
+typedef enum eMotionPathVert_Flag {
+ /* vert is selected */
+ MOTIONPATH_VERT_SEL = (1<<0),
+} eMotionPathVert_Flag;
+
+/* ........ */
+
+/* Motion Path data cache (mpath)
+ * - for elements providing transforms (i.e. Objects or PoseChannels)
+ */
typedef struct bMotionPath {
bMotionPathVert *points; /* path samples */
int length; /* the number of cached verts */
@@ -60,33 +70,97 @@ typedef struct bMotionPath {
int start_frame; /* for drawing paths, the start frame number */
int end_frame; /* for drawing paths, the end frame number */
- int flag; /* extra settings */
+ int flag; /* baking settings - eMotionPath_Flag */
} bMotionPath;
+/* bMotionPath->flag */
+typedef enum eMotionPath_Flag {
+ /* (for bones) path represents the head of the bone */
+ MOTIONPATH_FLAG_BHEAD = (1<<0),
+ /* motion path is being edited */
+ MOTIONPATH_FLAG_EDIT = (1<<1),
+} eMotionPath_Flag;
+/* Visualisation General --------------------------- */
+/* for Objects or Poses (but NOT PoseChannels) */
-/* Animation Visualisation Settings - for Objects or Armatures (not PoseChannels) */
+/* Animation Visualisation Settings (avs) */
typedef struct bAnimVizSettings {
- int pad;
- int pathflag; /* eMotionPath_Settings */
+ /* Onion-Skinning Settings ----------------- */
+ int ghost_sf, ghost_ef; /* start and end frames of ghost-drawing range (only used for GHOST_TYPE_RANGE) */
+ int ghost_bc, ghost_ac; /* number of frames before/after current frame to show */
+
+ short ghost_type; /* eOnionSkin_Types */
+ short ghost_step; /* number of frames between each ghost shown (not for GHOST_TYPE_KEYS) */
+
+ short ghost_flag; /* eOnionSkin_Flag */
+
+ /* General Settings ------------------------ */
+ short recalc; /* eAnimViz_RecalcFlags */
+
+ /* Motion Path Settings ------------------- */
+ short path_type; /* eMotionPath_Types */
+ short path_step; /* number of frames between points indicated on the paths */
- int pathsf, pathef; /* start and end frames of path-calculation range */
- int pathbc, pathac; /* number of frames before/after current frame of path-calculation */
+ short path_viewflag; /* eMotionPaths_ViewFlag */
+ short path_bakeflag; /* eMotionPaths_BakeFlag */
+
+ int path_sf, path_ef; /* start and end frames of path-calculation range */
+ int path_bc, path_ac; /* number of frames before/after current frame to show */
} bAnimVizSettings;
-/* bMotionPathSettings->flag */
-typedef enum eMotionPath_Settings {
+
+/* bAnimVizSettings->recalc */
+typedef enum eAnimViz_RecalcFlags {
+ /* motionpaths need recalculating */
+ ANIMVIZ_RECALC_PATHS = (1<<0),
+} eAnimViz_RecalcFlags;
+
+
+/* bAnimVizSettings->ghost_type */
+typedef enum eOnionSkin_Types {
+ /* no ghosts at all */
+ GHOST_TYPE_NONE = 0,
+ /* around current frame */
+ GHOST_TYPE_ACFRA,
+ /* show ghosts within the specified frame range */
+ GHOST_TYPE_RANGE,
+ /* show ghosts on keyframes within the specified range only */
+ GHOST_TYPE_KEYS,
+} eOnionSkin_Types;
+
+/* bAnimVizSettings->ghost_flag */
+typedef enum eOnionSkin_Flag {
+ /* only show selected bones in ghosts */
+ GHOST_FLAG_ONLYSEL = (1<<0),
+} eOnionSkin_Flag;
+
+
+/* bAnimVizSettings->path_type */
+typedef enum eMotionPaths_Types {
+ /* show the paths along their entire ranges */
+ MOTIONPATH_TYPE_RANGE = 0,
+ /* only show the parts of the paths around the current frame */
+ MOTIONPATH_TYPE_ACFRA,
+} eMotionPath_Types;
+
+/* bAnimVizSettings->path_viewflag */
+typedef enum eMotionPaths_ViewFlag {
/* show frames on path */
- MOTIONPATH_FLAG_FNUMS = (1<<0),
+ MOTIONPATH_VIEW_FNUMS = (1<<0),
/* show keyframes on path */
- MOTIONPATH_FLAG_KFRAS = (1<<1),
- /* for bones - calculate head-points for curves instead of tips */
- MOTIONPATH_FLAG_HEADS = (1<<2),
- /* show path around current frame */
- MOTIONPATH_FLAG_ACFRA = (1<<3),
+ MOTIONPATH_VIEW_KFRAS = (1<<1),
/* show keyframe/frame numbers */
- MOTIONPATH_FLAG_KFNOS = (1<<4)
-} eMotionPath_Settings;
+ MOTIONPATH_VIEW_KFNOS = (1<<2),
+} eMotionPath_ViewFlag;
+
+/* bAnimVizSettings->path_bakeflag */
+typedef enum eMotionPaths_BakeFlag {
+ /* motion paths directly associated with this block of settings needs updating */
+ MOTIONPATH_BAKE_NEEDS_RECALC = (1<<0),
+ /* for bones - calculate head-points for curves instead of tips */
+ MOTIONPATH_BAKE_HEADS = (1<<1),
+} eMotionPath_BakeFlag;
/* ************************************************ */
/* Poses */
@@ -113,9 +187,11 @@ typedef struct bPoseChannel {
short protectflag; /* protect channels from being transformed */
short agrp_index; /* index of action-group this bone belongs to (0 = default/no group) */
+// XXX depreceated.... old animation system (armature only viz) ----
int pathlen; /* for drawing paths, the amount of frames */
int pathsf; /* for drawing paths, the start frame number */
int pathef; /* for drawing paths, the end frame number */
+// XXX end of depreceated code -------------------------------------
struct Bone *bone; /* set on read file or rebuild pose */
struct bPoseChannel *parent; /* set on read file or rebuild pose */
@@ -152,8 +228,10 @@ typedef struct bPoseChannel {
float ikrotweight; /* weight of joint rotation constraint */
float iklinweight; /* weight of joint stretch constraint */
- float *path; /* totpath x 3 x float */
- struct Object *custom; /* draws custom object instead of this channel */
+ float *path; /* totpath x 3 x float */ // XXX depreceated... old animation system (armature only viz)
+ bMotionPath *mpath; /* motion path cache for this bone */
+ struct Object *custom; /* draws custom object instead of default bone shape */
+ struct bPoseChannel *custom_tx; /* odd feature, display with another bones transform. needed in rare cases for advanced rigs, since the alternative is highly complicated - campbell */
} bPoseChannel;
@@ -259,6 +337,8 @@ typedef struct bPose {
int iksolver; /* ik solver to use, see ePose_IKSolverType */
void *ikdata; /* temporary IK data, depends on the IK solver. Not saved in file */
void *ikparam; /* IK solver parameters, structure depends on iksolver */
+
+ bAnimVizSettings avs; /* settings for visualisation of bone animation */
} bPose;
@@ -283,7 +363,7 @@ typedef enum ePose_Flags {
/* IK Solvers ------------------------------------ */
/* bPose->iksolver and bPose->ikparam->iksolver */
-typedef enum {
+typedef enum ePose_IKSolverType {
IKSOLVER_LEGACY = 0,
IKSOLVER_ITASC,
} ePose_IKSolverType;
@@ -310,7 +390,7 @@ typedef struct bItasc {
} bItasc;
/* bItasc->flag */
-typedef enum {
+typedef enum eItasc_Flags {
ITASC_AUTO_STEP = (1<<0),
ITASC_INITIAL_REITERATION = (1<<1),
ITASC_REITERATION = (1<<2),
@@ -318,7 +398,7 @@ typedef enum {
} eItasc_Flags;
/* bItasc->solver */
-typedef enum {
+typedef enum eItasc_Solver {
ITASC_SOLVER_SDLS = 0, /* selective damped least square, suitable for CopyPose constraint */
ITASC_SOLVER_DLS /* damped least square with numerical filtering of damping */
} eItasc_Solver;
@@ -509,15 +589,14 @@ typedef enum eSAction_Flag {
} eSAction_Flag;
/* SpaceAction Mode Settings */
-// XXX should this be used by other editors too?
typedef enum eAnimEdit_Context {
- /* action (default) */
+ /* action on the active object */
SACTCONT_ACTION = 0,
- /* editing of shapekey's IPO block */
+ /* list of all shapekeys on the active object, linked with their F-Curves */
SACTCONT_SHAPEKEY,
/* editing of gpencil data */
SACTCONT_GPENCIL,
- /* dopesheet */
+ /* dopesheet (default) */
SACTCONT_DOPESHEET,
} eAnimEdit_Context;
diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h
index dcb10d0f2cf..958add428a4 100644
--- a/source/blender/makesdna/DNA_anim_types.h
+++ b/source/blender/makesdna/DNA_anim_types.h
@@ -232,27 +232,93 @@ typedef enum eFMod_Noise_Modifications {
/* Drivers -------------------------------------- */
-/* Driver Target
+/* Driver Target (dtar)
*
- * A 'variable' for use as a target of the driver/expression.
- * Defines a way of accessing some channel to use, that can be
- * referred to in the expression as a variable, thus simplifying
- * expressions and also Depsgraph building.
+ * Defines how to access a dependency needed for a driver variable.
*/
typedef struct DriverTarget {
- struct DriverTarget *next, *prev;
+ ID *id; /* ID-block which owns the target */
- ID *id; /* ID-block which owns the target */
- char *rna_path; /* target channel to use as driver value */
- int array_index; /* if applicable, the index of the RNA-array item to use as driver */
+ char *rna_path; /* RNA path defining the setting to use (for DVAR_TYPE_SINGLE_PROP) */
- int idtype; /* type of ID-block that this target can use */
- int flags; /* flags for the validity of the target */
- int pad;
+ char pchan_name[32]; /* name of the posebone to use (for vars where DTAR_FLAG_STRUCT_REF is used) */
+ short transChan; /* transform channel index (for DVAR_TYPE_TRANSFORM_CHAN)*/
- char name[64]; /* name of the variable */
+ short flag; /* flags for the validity of the target (NOTE: these get reset everytime the types change) */
+ int idtype; /* type of ID-block that this target can use */
} DriverTarget;
+/* Driver Target flags */
+typedef enum eDriverTarget_Flag {
+ /* used for targets that use the pchan_name instead of RNA path
+ * (i.e. rotation difference)
+ */
+ DTAR_FLAG_STRUCT_REF = (1<<0),
+ /* idtype can only be 'Object' */
+ DTAR_FLAG_ID_OB_ONLY = (1<<1),
+ /* toggles localspace (where transforms are manually obtained) */
+ DTAR_FLAG_LOCALSPACE = (1<<2),
+} eDriverTarget_Flag;
+
+/* Transform Channels for Driver Targets */
+typedef enum eDriverTarget_TransformChannels {
+ DTAR_TRANSCHAN_LOCX = 0,
+ DTAR_TRANSCHAN_LOCY,
+ DTAR_TRANSCHAN_LOCZ,
+ DTAR_TRANSCHAN_ROTX,
+ DTAR_TRANSCHAN_ROTY,
+ DTAR_TRANSCHAN_ROTZ,
+ DTAR_TRANSCHAN_SCALEX,
+ DTAR_TRANSCHAN_SCALEY,
+ DTAR_TRANSCHAN_SCALEZ,
+
+ MAX_DTAR_TRANSCHAN_TYPES
+} eDriverTarget_TransformChannels;
+
+/* --- */
+
+/* maximum number of driver targets per variable */
+#define MAX_DRIVER_TARGETS 8
+
+
+/* Driver Variable (dvar)
+ *
+ * A 'variable' for use as an input for the driver evaluation.
+ * Defines a way of accessing some channel to use, that can be
+ * referred to in the expression as a variable, thus simplifying
+ * expressions and also Depsgraph building.
+ */
+typedef struct DriverVar {
+ struct DriverVar *next, *prev;
+
+ char name[64]; /* name of the variable to use in py-expression (must be valid python identifier) */
+
+ DriverTarget targets[8]; /* MAX_DRIVER_TARGETS, target slots */
+ int num_targets; /* number of targets actually used by this variable */
+
+ int type; /* type of driver target (eDriverTarget_Types) */
+} DriverVar;
+
+/* Driver Variable Types */
+typedef enum eDriverVar_Types {
+ /* single RNA property */
+ DVAR_TYPE_SINGLE_PROP = 0,
+ /* rotation difference (between 2 bones) */
+ DVAR_TYPE_ROT_DIFF,
+ /* distance between objects/bones */
+ DVAR_TYPE_LOC_DIFF,
+ /* 'final' transform for object/bones */
+ DVAR_TYPE_TRANSFORM_CHAN,
+
+ /* maximum number of variable types
+ * NOTE: this must always be th last item in this list,
+ * so add new types above this line
+ */
+ MAX_DVAR_TYPES
+} eDriverVar_Types;
+
+/* --- */
+
/* Channel Driver (i.e. Drivers / Expressions) (driver)
*
* Channel Drivers are part of the dependency system, and are executed in addition to
@@ -265,7 +331,7 @@ typedef struct DriverTarget {
* evaluated in. This order is set by the Depsgraph's sorting stuff.
*/
typedef struct ChannelDriver {
- ListBase targets; /* targets for this driver (i.e. list of DriverTarget) */
+ ListBase variables; /* targets for this driver (i.e. list of DriverVar) */
/* python expression to execute (may call functions defined in an accessory file)
* which relates the target 'variables' in some way to yield a single usable value
@@ -287,10 +353,12 @@ typedef enum eDriver_Types {
DRIVER_TYPE_AVERAGE = 0,
/* python expression/function relates targets */
DRIVER_TYPE_PYTHON,
- /* rotational difference (must use rotation channels only) */
- DRIVER_TYPE_ROTDIFF,
/* sum of all values */
DRIVER_TYPE_SUM,
+ /* smallest value */
+ DRIVER_TYPE_MIN,
+ /* largest value */
+ DRIVER_TYPE_MAX,
} eDriver_Types;
/* driver flags */
@@ -301,9 +369,11 @@ typedef enum eDriver_Flags {
DRIVER_FLAG_RECALC = (1<<1),
/* driver does replace value, but overrides (for layering of animation over driver) */
// TODO: this needs to be implemented at some stage or left out...
- DRIVER_FLAG_LAYERING = (1<<2),
+ //DRIVER_FLAG_LAYERING = (1<<2),
/* use when the expression needs to be recompiled */
- DRIVER_FLAG_RECOMPILE = (1<<3),
+ DRIVER_FLAG_RECOMPILE = (1<<3),
+ /* the names are cached so they dont need have python unicode versions created each time */
+ DRIVER_FLAG_RENAMEVAR = (1<<4),
} eDriver_Flags;
/* F-Curves -------------------------------------- */
diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h
index ea549f9aeba..010f210d5aa 100644
--- a/source/blender/makesdna/DNA_armature_types.h
+++ b/source/blender/makesdna/DNA_armature_types.h
@@ -92,11 +92,14 @@ typedef struct bArmature {
int pad;
int layer, layer_protected; /* for buttons to work, both variables in this order together */
+
+// XXX depreceated... old animaton system (armature only viz) ---
short ghostep, ghostsize; /* number of frames to ghosts to show, and step between them */
short ghosttype, pathsize; /* ghost drawing options and number of frames between points of path */
int ghostsf, ghostef; /* start and end frames of ghost-drawing range */
int pathsf, pathef; /* start and end frames of path-calculation range for all bones */
int pathbc, pathac; /* number of frames before/after current frame of path-calculation for all bones */
+// XXX end of depreceated code ----------------------------------
} bArmature;
/* armature->flag */
@@ -114,7 +117,7 @@ typedef enum eArmature_Flag {
ARM_AUTO_IK = (1<<9),
ARM_NO_CUSTOM = (1<<10), /* made option negative, for backwards compat */
ARM_COL_CUSTOM = (1<<11), /* draw custom colours */
- ARM_GHOST_ONLYSEL = (1<<12), /* when ghosting, only show selected bones (this should belong to ghostflag instead) */
+ ARM_GHOST_ONLYSEL = (1<<12), /* when ghosting, only show selected bones (this should belong to ghostflag instead) */ // XXX depreceated
ARM_DS_EXPAND = (1<<13)
} eArmature_Flag;
@@ -136,6 +139,7 @@ typedef enum eArmature_DeformFlag {
} eArmature_DeformFlag;
/* armature->pathflag */
+// XXX depreceated... old animation system (armature only viz)
typedef enum eArmature_PathFlag {
ARM_PATH_FNUMS = (1<<0),
ARM_PATH_KFRAS = (1<<1),
@@ -145,6 +149,7 @@ typedef enum eArmature_PathFlag {
} eArmature_PathFlag;
/* armature->ghosttype */
+// XXX depreceated... old animation system (armature only viz)
typedef enum eArmature_GhostType {
ARM_GHOST_CUR = 0,
ARM_GHOST_RANGE,
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index c8fc14ca0f0..4738b0d81e8 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -31,6 +31,7 @@
#define DNA_BRUSH_TYPES_H
#include "DNA_ID.h"
+#include "DNA_texture_types.h"
#ifndef MAX_MTEX
#define MAX_MTEX 18
@@ -50,9 +51,8 @@ typedef struct Brush {
ID id;
struct BrushClone clone;
-
struct CurveMapping *curve; /* falloff curve */
- struct MTex *mtex[18]; /* MAX_MTEX */
+ struct MTex mtex;
short flag, blend; /* general purpose flag, blend mode */
int size; /* brush diameter */
@@ -65,10 +65,8 @@ typedef struct Brush {
float rgb[3]; /* color */
float alpha; /* opacity */
- short texact; /* active texture */
char sculpt_tool; /* active tool */
-
- char pad[1];
+ char pad2[3];
} Brush;
/* Brush.flag */
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index 0476d69544a..163933da12a 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -200,6 +200,20 @@ typedef struct bLocateLikeConstraint {
char subtarget[32];
} bLocateLikeConstraint;
+/* Copy Scale Constraint */
+typedef struct bSizeLikeConstraint {
+ Object *tar;
+ int flag;
+ int reserved1;
+ char subtarget[32];
+} bSizeLikeConstraint;
+
+/* Copy Transform Constraint */
+typedef struct bTransLikeConstraint {
+ Object *tar;
+ char subtarget[32];
+} bTransLikeConstraint;
+
/* Floor Constraint */
typedef struct bMinMaxConstraint {
Object *tar;
@@ -211,14 +225,6 @@ typedef struct bMinMaxConstraint {
char subtarget[32];
} bMinMaxConstraint;
-/* Copy Scale Constraint */
-typedef struct bSizeLikeConstraint {
- Object *tar;
- int flag;
- int reserved1;
- char subtarget[32];
-} bSizeLikeConstraint;
-
/* Action Constraint */
typedef struct bActionConstraint {
Object *tar;
@@ -401,6 +407,7 @@ typedef enum eBConstraint_Types {
CONSTRAINT_TYPE_SHRINKWRAP, /* shrinkwrap (loc/rot) constraint */
CONSTRAINT_TYPE_DAMPTRACK, /* New Tracking constraint that minimises twisting */
CONSTRAINT_TYPE_SPLINEIK, /* Spline-IK - Align 'n' bones to a curve */
+ CONSTRAINT_TYPE_TRANSLIKE, /* Copy transform matrix */
/* NOTE: no constraints are allowed to be added after this */
NUM_CONSTRAINT_TYPES
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index 4bae9935ea7..00afd687f79 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -113,6 +113,8 @@ typedef struct bGPDlayer {
#define GP_LAYER_ONIONSKIN (1<<4)
/* for editing in Action Editor */
#define GP_LAYER_SELECT (1<<5)
+ /* current frame for layer can't be changed */
+#define GP_LAYER_FRAMELOCK (1<<6)
/* Grease-Pencil Annotations - 'DataBlock' */
@@ -146,5 +148,10 @@ typedef struct bGPdata {
#define GP_DATA_EDITPAINT (1<<3)
/* new strokes are added in viewport space */
#define GP_DATA_VIEWALIGN (1<<4)
+ /* Project into the screens Z values */
+#define GP_DATA_DEPTH_VIEW (1<<5)
+#define GP_DATA_DEPTH_STROKE (1<<6)
+
+#define GP_DATA_DEPTH_STROKE_ENDPOINTS (1<<7)
#endif /* DNA_GPENCIL_TYPES_H */
diff --git a/source/blender/makesdna/DNA_lamp_types.h b/source/blender/makesdna/DNA_lamp_types.h
index 0a0046f8470..c321c9feea7 100644
--- a/source/blender/makesdna/DNA_lamp_types.h
+++ b/source/blender/makesdna/DNA_lamp_types.h
@@ -136,7 +136,7 @@ typedef struct Lamp {
#define LA_SQUARE 128
#define LA_TEXTURE 256
#define LA_OSATEX 512
-#define LA_DEEP_SHADOW 1024
+/* #define LA_DEEP_SHADOW 1024 */ /* not used anywhere */
#define LA_NO_DIFF 2048
#define LA_NO_SPEC 4096
#define LA_SHAD_RAY 8192
diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h
index 36de890e6dc..7a19262b0cd 100644
--- a/source/blender/makesdna/DNA_material_types.h
+++ b/source/blender/makesdna/DNA_material_types.h
@@ -69,7 +69,7 @@ typedef struct VolumeSettings {
float stepsize;
float ms_diff;
float ms_intensity;
- int ms_steps;
+ float ms_spread;
} VolumeSettings;
typedef struct Material {
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 7ca8cea0763..9b433c5bf8c 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -95,8 +95,6 @@ typedef struct bNodeSocket {
#define SOCK_IN_USE 4
/* unavailable is for dynamic sockets */
#define SOCK_UNAVAIL 8
- /* flag for selection status */
-#define SOCK_SEL 16
#
#
typedef struct bNodePreview {
@@ -185,10 +183,8 @@ typedef struct bNodeTree {
ListBase alltypes; /* type definitions */
struct bNodeType *owntype; /* for groups or dynamic trees, no read/write */
- /* selected input/output socket */
- bNodeSocket *selin;
- bNodeSocket *selout;
-
+ int pad2[2];
+
/* callbacks */
void (*timecursor)(void *, int nr);
void (*stats_draw)(void *, char *str);
diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h
index 99b8f400a5e..b3cdd6135e7 100644
--- a/source/blender/makesdna/DNA_object_force.h
+++ b/source/blender/makesdna/DNA_object_force.h
@@ -87,8 +87,9 @@ typedef struct PartDeflect {
float pdef_perm; /* Chance of particle passing through mesh */
float pdef_frict; /* Friction factor for particle deflection */
float pdef_rfrict; /* Random element of friction for deflection */
+ float pdef_stickness;/* surface particle stickness */
- float absorption, pad; /* used for forces */
+ float absorption; /* used for forces */
/* softbody collisions */
float pdef_sbdamp; /* Damping factor for softbody deflection */
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index d780aec7895..ace56e78a46 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -35,12 +35,12 @@
#include "DNA_listBase.h"
#include "DNA_ID.h"
+#include "DNA_action_types.h"
#ifdef __cplusplus
extern "C" {
#endif
-
-struct bPose;
+
struct Object;
struct AnimData;
struct Ipo;
@@ -115,6 +115,9 @@ typedef struct Object {
struct bGPdata *gpd; /* Grease Pencil data */
+ bAnimVizSettings avs; /* settings for visualisation of object-transform animation */
+ bMotionPath *mpath; /* motion path cache for this object */
+
ListBase constraintChannels; // XXX depreceated... old animation system
ListBase effect;
ListBase disp;
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 38a9eb0356a..ae370f9a4db 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -1135,7 +1135,7 @@ typedef enum SculptFlags {
#define PE_DEFLECT_EMITTER 4
#define PE_INTERPOLATE_ADDED 8
#define PE_DRAW_PART 16
-#define PE_X_MIRROR 64
+#define PE_X_MIRROR 64 /* deprecated */
#define PE_FADE_TIME 128
#define PE_AUTO_VELOCITY 256
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index 2bc7b1e8431..12f61cbb026 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -212,14 +212,16 @@ typedef struct ARegion {
#define SCREEN_HANDLER_VERSE 3
/* regiontype, first two are the default set */
-#define RGN_TYPE_WINDOW 0
-#define RGN_TYPE_HEADER 1
-#define RGN_TYPE_CHANNELS 2
-#define RGN_TYPE_TEMPORARY 3
-#define RGN_TYPE_UI 4
-#define RGN_TYPE_TOOLS 5
-#define RGN_TYPE_TOOL_PROPS 6
-#define RGN_TYPE_PREVIEW 7
+enum {
+ RGN_TYPE_WINDOW = 0,
+ RGN_TYPE_HEADER,
+ RGN_TYPE_CHANNELS,
+ RGN_TYPE_TEMPORARY,
+ RGN_TYPE_UI,
+ RGN_TYPE_TOOLS,
+ RGN_TYPE_TOOL_PROPS,
+ RGN_TYPE_PREVIEW
+};
/* region alignment */
#define RGN_ALIGN_NONE 0
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index e06aa899c49..56323c54491 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -657,6 +657,7 @@ enum FileSortTypeE {
#define FILE_SYNCPOSE 128
#define FILE_FILTER 256
#define FILE_BOOKMARKS 512
+#define FILE_GROUP_INSTANCE 1024
/* files in filesel list: 2=ACTIVE */
#define EDITING 1
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index a6be7256170..bd8573fe8ce 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -266,7 +266,7 @@ typedef struct bTheme {
ThemeWireColor tarm[20];
/*ThemeWireColor tobj[20];*/
- int active_theme_group, pad;
+ int active_theme_area, pad;
} bTheme;
@@ -337,6 +337,8 @@ typedef struct UserDef {
short glreslimit;
short ndof_pan, ndof_rotate;
short curssize, ipo_new;
+ short color_picker_type;
+ short pad2[3];
char versemaster[160];
char verseuser[160];
@@ -465,9 +467,11 @@ extern UserDef U; /* from blenkernel blender.c */
/* gameflags */
#define USER_DEPRECATED_FLAG 1
-#define USER_DISABLE_SOUND 2
+// #define USER_DISABLE_SOUND 2 deprecated, don't use without checking for
+// backwards compatibilty in do_versions!
#define USER_DISABLE_MIPMAP 4
#define USER_DISABLE_VBO 8
+#define USER_DISABLE_AA 16
/* wm draw method */
#define USER_DRAW_TRIPLE 0
@@ -480,6 +484,12 @@ extern UserDef U; /* from blenkernel blender.c */
#define GP_PAINT_DOSMOOTH (1<<0)
#define GP_PAINT_DOSIMPLIFY (1<<1)
+/* color picker types */
+#define USER_CP_CIRCLE 0
+#define USER_CP_SQUARE_SV 1
+#define USER_CP_SQUARE_HS 2
+#define USER_CP_SQUARE_HV 3
+
/* theme drawtypes */
#define TH_MINIMAL 0
#define TH_ROUNDSHADED 1
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index 48d67714f15..7df49bfb2e2 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -182,7 +182,7 @@ typedef struct wmOperatorTypeMacro {
struct wmOperatorTypeMacro *next, *prev;
/* operator id */
- char idname[MAX_ID_NAME];
+ char idname[64];
/* rna pointer to access properties, like keymap */
struct IDProperty *properties; /* operator properties, assigned to ptr->data and can be written to a file */
struct PointerRNA *ptr;
@@ -194,7 +194,7 @@ typedef struct wmKeyMapItem {
struct wmKeyMapItem *next, *prev;
/* operator */
- char idname[64]; /* used to retrieve operator type pointer */
+ char idname[64]; /* used to retrieve operator type pointer */
IDProperty *properties; /* operator properties, assigned to ptr->data and can be written to a file */
/* modal */
@@ -267,7 +267,7 @@ typedef struct wmOperator {
struct wmOperator *next, *prev;
/* saved */
- char idname[64]; /* used to retrieve type pointer */
+ char idname[64];/* used to retrieve type pointer */
IDProperty *properties; /* saved, user-settable properties */
/* runtime */
diff --git a/source/blender/makesdna/intern/Makefile b/source/blender/makesdna/intern/Makefile
index 857e53d2573..01c4d87a4fc 100644
--- a/source/blender/makesdna/intern/Makefile
+++ b/source/blender/makesdna/intern/Makefile
@@ -56,6 +56,10 @@ ifeq ($(OS),windows)
endif
endif
+ifeq ($(OS), darwin)
+ LDFLAGS += -arch $(MACOSX_ARCHITECTURE) #-isysroot $(MACOSX_SDK) -mmacosx-version-min=$(MACOSX_MIN_VERS)
+endif
+
clean::
@$(RM) $(DIR)/makesdna* $(DIR)/DNA.c
@$(RM) $(DIR)/debug/makesdna* $(DIR)/debug/DNA.c
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index e5ab692165f..c7cc74c2798 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -52,6 +52,9 @@ extern StructRNA RNA_ActuatorSensor;
extern StructRNA RNA_AlwaysSensor;
extern StructRNA RNA_AndController;
extern StructRNA RNA_AnimData;
+extern StructRNA RNA_AnimViz;
+extern StructRNA RNA_AnimVizOnionSkinning;
+extern StructRNA RNA_AnimVizMotionPaths;
extern StructRNA RNA_AnyType;
extern StructRNA RNA_Area;
extern StructRNA RNA_AreaLamp;
@@ -167,6 +170,7 @@ extern StructRNA RNA_Controller;
extern StructRNA RNA_CopyLocationConstraint;
extern StructRNA RNA_CopyRotationConstraint;
extern StructRNA RNA_CopyScaleConstraint;
+extern StructRNA RNA_CopyTransformsConstraint;
extern StructRNA RNA_Curve;
extern StructRNA RNA_CurveMap;
extern StructRNA RNA_CurveMapping;
@@ -181,6 +185,7 @@ extern StructRNA RNA_DistortedNoiseTexture;
extern StructRNA RNA_DomainFluidSettings;
extern StructRNA RNA_Driver;
extern StructRNA RNA_DriverTarget;
+extern StructRNA RNA_DriverVariable;
extern StructRNA RNA_DupliObject;
extern StructRNA RNA_EdgeSplitModifier;
extern StructRNA RNA_EditBone;
@@ -304,6 +309,8 @@ extern StructRNA RNA_MirrorModifier;
extern StructRNA RNA_Modifier;
extern StructRNA RNA_MouseSensor;
extern StructRNA RNA_MovieSequence;
+extern StructRNA RNA_MotionPath;
+extern StructRNA RNA_MotionPathVert;
extern StructRNA RNA_MultiresModifier;
extern StructRNA RNA_MusgraveTexture;
extern StructRNA RNA_NandController;
@@ -320,6 +327,7 @@ extern StructRNA RNA_Object;
extern StructRNA RNA_ObjectBase;
extern StructRNA RNA_ObstacleFluidSettings;
extern StructRNA RNA_Operator;
+extern StructRNA RNA_Macro;
extern StructRNA RNA_OperatorFileListElement;
extern StructRNA RNA_OperatorMousePath;
extern StructRNA RNA_OperatorProperties;
@@ -853,7 +861,6 @@ char *RNA_pointer_as_string(PointerRNA *ptr);
/* Function */
const char *RNA_function_identifier(FunctionRNA *func);
-PropertyRNA *RNA_function_return(FunctionRNA *func);
const char *RNA_function_ui_description(FunctionRNA *func);
int RNA_function_flag(FunctionRNA *func);
int RNA_function_defined(FunctionRNA *func);
diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h
index 37abe44f128..f340834d93b 100644
--- a/source/blender/makesrna/RNA_define.h
+++ b/source/blender/makesrna/RNA_define.h
@@ -172,6 +172,7 @@ void RNA_def_property_srna(PropertyRNA *prop, const char *type);
FunctionRNA *RNA_def_function(StructRNA *srna, const char *identifier, const char *call);
FunctionRNA *RNA_def_function_runtime(StructRNA *srna, const char *identifier, CallFunc call);
void RNA_def_function_return(FunctionRNA *func, PropertyRNA *ret);
+void RNA_def_function_return_mark(FunctionRNA *func, PropertyRNA *ret);
void RNA_def_function_flag(FunctionRNA *func, int flag);
void RNA_def_function_ui_description(FunctionRNA *func, const char *description);
diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h
index 8cc949f628e..4e60fb413db 100644
--- a/source/blender/makesrna/RNA_types.h
+++ b/source/blender/makesrna/RNA_types.h
@@ -210,6 +210,7 @@ typedef struct CollectionPointerLink {
} CollectionPointerLink;
typedef enum RawPropertyType {
+ PROP_RAW_UNSET=-1,
PROP_RAW_INT, // XXX - abused for types that are not set, eg. MFace.verts, needs fixing.
PROP_RAW_SHORT,
PROP_RAW_CHAR,
diff --git a/source/blender/makesrna/intern/Makefile b/source/blender/makesrna/intern/Makefile
index e4e4e859ed3..5fefb2ae15b 100644
--- a/source/blender/makesrna/intern/Makefile
+++ b/source/blender/makesrna/intern/Makefile
@@ -104,6 +104,10 @@ ifeq ($(OS),windows)
endif
endif
+ifeq ($(OS), darwin)
+ LDFLAGS += -arch $(MACOSX_ARCHITECTURE) #-isysroot $(MACOSX_SDK) -mmacosx-version-min=$(MACOSX_MIN_VERS)
+endif
+
clean::
@$(RM) $(DIR)/makesrna* $(DIR)/rna*
@$(RM) $(DIR)/debug/makesrna* $(DIR)/debug/rna*
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index 5bdfe228e89..a03903eb652 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -1236,16 +1236,21 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
for(; dparm; dparm= dparm->next) {
if(dparm->prop->arraydimension)
ptrstr= "*";
- else if(dparm->prop==func->ret)
+ else if(dparm->prop==func->c_ret)
ptrstr= ((dparm->prop->type == PROP_POINTER) && !(dparm->prop->flag & PROP_RNAPTR))? "*": "";
- else
+ else if ((dparm->prop->flag & PROP_RETURN)) {
+ if ((dparm->prop->flag & PROP_THICK_WRAP) && (dparm->prop->type == PROP_STRING))
+ ptrstr= "";
+ else
+ ptrstr= ((dparm->prop->type == PROP_POINTER) && !(dparm->prop->flag & PROP_RNAPTR))? "**": "*";
+ } else
ptrstr= (dparm->prop->type == PROP_POINTER)? "*": "";
-
+
fprintf(f, "\t%s%s %s%s;\n", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr, dparm->prop->identifier);
}
fprintf(f, "\tchar *_data");
- if(func->ret) fprintf(f, ", *_retdata");
+ if(func->c_ret) fprintf(f, ", *_retdata");
fprintf(f, ";\n");
fprintf(f, "\t\n");
@@ -1259,7 +1264,12 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
dparm= dfunc->cont.properties.first;
for(; dparm; dparm= dparm->next) {
- if(dparm->prop==func->ret)
+ if ((dparm->prop->flag & PROP_RETURN))
+ ptrstr= "";
+ else
+ ptrstr= "*";
+
+ if(dparm->prop==func->c_ret)
fprintf(f, "\t_retdata= _data;\n");
else if(dparm->prop->arraydimension)
fprintf(f, "\t%s= ((%s%s*)_data);\n", dparm->prop->identifier, rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop));
@@ -1267,10 +1277,14 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
if(dparm->prop->flag & PROP_RNAPTR)
fprintf(f, "\t%s= ((%s%s*)_data);\n", dparm->prop->identifier, rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop));
else
- fprintf(f, "\t%s= *((%s%s**)_data);\n", dparm->prop->identifier, rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop));
+ fprintf(f, "\t%s= %s((%s%s**)_data);\n", dparm->prop->identifier, ptrstr, rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop));
+ }
+ else {
+ if ((dparm->prop->flag & PROP_THICK_WRAP) && (dparm->prop->type == PROP_STRING))
+ fprintf(f, "\t%s= %s((%s%s)_data);\n", dparm->prop->identifier, ptrstr, rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop));
+ else
+ fprintf(f, "\t%s= %s((%s%s*)_data);\n", dparm->prop->identifier, ptrstr, rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop));
}
- else
- fprintf(f, "\t%s= *((%s%s*)_data);\n", dparm->prop->identifier, rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop));
if(dparm->next)
fprintf(f, "\t_data+= %d;\n", rna_parameter_size(dparm->prop));
@@ -1279,7 +1293,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
if(dfunc->call) {
fprintf(f, "\t\n");
fprintf(f, "\t");
- if(func->ret) fprintf(f, "%s= ", func->ret->identifier);
+ if(func->c_ret) fprintf(f, "%s= ", func->c_ret->identifier);
fprintf(f, "%s(", dfunc->call);
first= 1;
@@ -1303,7 +1317,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
dparm= dfunc->cont.properties.first;
for(; dparm; dparm= dparm->next) {
- if(dparm->prop==func->ret)
+ if(dparm->prop==func->c_ret)
continue;
if(!first) fprintf(f, ", ");
@@ -1314,10 +1328,10 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
fprintf(f, ");\n");
- if(func->ret) {
- dparm= rna_find_parameter_def(func->ret);
+ if(func->c_ret) {
+ dparm= rna_find_parameter_def(func->c_ret);
ptrstr= (((dparm->prop->type == PROP_POINTER) && !(dparm->prop->flag & PROP_RNAPTR)) || (dparm->prop->arraydimension))? "*": "";
- fprintf(f, "\t*((%s%s%s*)_retdata)= %s;\n", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr, func->ret->identifier);
+ fprintf(f, "\t*((%s%s%s*)_retdata)= %s;\n", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr, func->c_ret->identifier);
}
}
@@ -1552,13 +1566,14 @@ static void rna_generate_static_parameter_prototypes(BlenderRNA *brna, StructRNA
PropertyDefRNA *dparm;
StructDefRNA *dsrna;
int first;
+ char *ptrstr;
dsrna= rna_find_struct_def(srna);
func= dfunc->func;
/* return type */
for(dparm= dfunc->cont.properties.first; dparm; dparm= dparm->next) {
- if(dparm->prop==func->ret) {
+ if(dparm->prop==func->c_ret) {
if(dparm->prop->arraydimension)
fprintf(f, "XXX no array return types yet"); /* XXX not supported */
else if(dparm->prop->type == PROP_POINTER && !(dparm->prop->flag & PROP_RNAPTR))
@@ -1600,18 +1615,25 @@ static void rna_generate_static_parameter_prototypes(BlenderRNA *brna, StructRNA
/* defined parameters */
for(dparm= dfunc->cont.properties.first; dparm; dparm= dparm->next) {
- if(dparm->prop==func->ret)
+ if(dparm->prop==func->c_ret)
continue;
if(!first) fprintf(f, ", ");
first= 0;
+ if((dparm->prop->type == PROP_STRING && dparm->prop->flag & PROP_THICK_WRAP))
+ ptrstr= "";
+ else if(dparm->prop->flag & PROP_RETURN)
+ ptrstr= "*";
+ else
+ ptrstr= "";
+
if(dparm->prop->arraydimension)
fprintf(f, "%s%s %s[%d]", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), dparm->prop->identifier, dparm->prop->totarraylength);
else if(dparm->prop->type == PROP_POINTER)
- fprintf(f, "%s%s *%s", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), dparm->prop->identifier);
+ fprintf(f, "%s%s *%s%s", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), (dparm->prop->flag & PROP_RNAPTR) ? "" : ptrstr, dparm->prop->identifier);
else
- fprintf(f, "%s%s %s", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), dparm->prop->identifier);
+ fprintf(f, "%s%s %s%s", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr, dparm->prop->identifier);
}
fprintf(f, ");\n");
@@ -1766,7 +1788,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
fprintf(f, "\t%s%s, %d, %s, %s,\n", (prop->flag & PROP_CONTEXT_UPDATE)? "(UpdateFunc)": "", rna_function_string(prop->update), prop->noteflag, rna_function_string(prop->editable), rna_function_string(prop->itemeditable));
if(prop->flag & PROP_RAW_ACCESS) rna_set_raw_offset(f, srna, prop);
- else fprintf(f, "\t0, 0");
+ else fprintf(f, "\t0, -1");
/* our own type - collections/arrays only */
if(prop->srna) fprintf(f, ", &RNA_%s", (char*)prop->srna);
@@ -1890,8 +1912,8 @@ static void rna_generate_struct(BlenderRNA *brna, StructRNA *srna, FILE *f)
dfunc= rna_find_function_def(func);
if(dfunc->gencall) fprintf(f, "\t%s,\n", dfunc->gencall);
else fprintf(f, "\tNULL,\n");
-
- if(func->ret) fprintf(f, "\t(PropertyRNA*)&rna_%s_%s_%s\n", srna->identifier, func->identifier, func->ret->identifier);
+
+ if(func->c_ret) fprintf(f, "\t(PropertyRNA*)&rna_%s_%s_%s\n", srna->identifier, func->identifier, func->c_ret->identifier);
else fprintf(f, "\tNULL\n");
fprintf(f, "};\n");
@@ -1983,6 +2005,7 @@ RNAProcessItem PROCESS_ITEMS[]= {
{"rna_texture.c", NULL, RNA_def_texture},
{"rna_action.c", "rna_action_api.c", RNA_def_action},
{"rna_animation.c", "rna_animation_api.c", RNA_def_animation},
+ {"rna_animviz.c", NULL, RNA_def_animviz},
{"rna_actuator.c", NULL, RNA_def_actuator},
{"rna_armature.c", "rna_armature_api.c", RNA_def_armature},
{"rna_boid.c", NULL, RNA_def_boid},
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index a250f0a49b4..e931f08c3a3 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -380,6 +380,7 @@ static void rna_def_ID(BlenderRNA *brna)
prop= RNA_def_property(srna, "tag", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", LIB_DOIT);
+ RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
RNA_def_property_ui_text(prop, "Tag", "Tools can use this to tag data, (initial state is undefined).");
prop= RNA_def_property(srna, "library", PROP_POINTER, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 7dcc72e4158..ce06bc8f6c4 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -249,7 +249,7 @@ static int rna_ensure_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
{
if(prop->magic == RNA_MAGIC) {
int arraylen[RNA_MAX_ARRAY_DIMENSION];
- return (prop->getlength)? prop->getlength(ptr, arraylen): prop->totarraylength;
+ return (prop->getlength && ptr->data)? prop->getlength(ptr, arraylen): prop->totarraylength;
}
else {
IDProperty *idprop= (IDProperty*)prop;
@@ -2021,7 +2021,7 @@ int RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
if(key+1 < len) {
/* move element to be removed to the back */
memcpy(&tmp, &array[key], sizeof(IDProperty));
- memmove(array+key, array+key+1, sizeof(IDProperty)*(len-key+1));
+ memmove(array+key, array+key+1, sizeof(IDProperty)*(len-(key+1)));
memcpy(&array[len-1], &tmp, sizeof(IDProperty));
}
@@ -2266,8 +2266,9 @@ static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *pro
/* try to access as raw array */
if(RNA_property_collection_raw_array(ptr, prop, itemprop, &out)) {
- if(in.len != itemlen*out.len) {
- BKE_reportf(reports, RPT_ERROR, "Array length mismatch (expected %d, got %d).", out.len*itemlen, in.len);
+ int arraylen = (itemlen == 0) ? 1 : itemlen;
+ if(in.len != arraylen*out.len) {
+ BKE_reportf(reports, RPT_ERROR, "Array length mismatch (expected %d, got %d).", out.len*arraylen, in.len);
return 0;
}
@@ -2277,8 +2278,7 @@ static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *pro
void *outp= out.array;
int a, size;
- itemlen= (itemlen == 0)? 1: itemlen;
- size= RNA_raw_type_sizeof(out.type) * itemlen;
+ size= RNA_raw_type_sizeof(out.type) * arraylen;
for(a=0; a<out.len; a++) {
if(set) memcpy(outp, inp, size);
@@ -2300,6 +2300,12 @@ static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *pro
void *tmparray= NULL;
int tmplen= 0;
int err= 0, j, a= 0;
+ int needconv = 1;
+
+ if (((itemtype == PROP_BOOLEAN || itemtype == PROP_INT) && in.type == PROP_RAW_INT) ||
+ (itemtype == PROP_FLOAT && in.type == PROP_RAW_FLOAT))
+ /* avoid creating temporary buffer if the data type match */
+ needconv = 0;
/* no item property pointer, can still be id property, or
* property of a type derived from the collection pointer type */
@@ -2387,7 +2393,7 @@ static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *pro
}
a++;
}
- else {
+ else if (needconv == 1) {
/* allocate temporary array if needed */
if(tmparray && tmplen != itemlen) {
MEM_freeN(tmparray);
@@ -2448,6 +2454,50 @@ static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *pro
}
}
}
+ else {
+ if(set) {
+ switch(itemtype) {
+ case PROP_BOOLEAN: {
+ RNA_property_boolean_set_array(&itemptr, iprop, &((int*)in.array)[a]);
+ a += itemlen;
+ break;
+ }
+ case PROP_INT: {
+ RNA_property_int_set_array(&itemptr, iprop, &((int*)in.array)[a]);
+ a += itemlen;
+ break;
+ }
+ case PROP_FLOAT: {
+ RNA_property_float_set_array(&itemptr, iprop, &((float*)in.array)[a]);
+ a += itemlen;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ else {
+ switch(itemtype) {
+ case PROP_BOOLEAN: {
+ RNA_property_boolean_get_array(&itemptr, iprop, &((int*)in.array)[a]);
+ a += itemlen;
+ break;
+ }
+ case PROP_INT: {
+ RNA_property_int_get_array(&itemptr, iprop, &((int*)in.array)[a]);
+ a += itemlen;
+ break;
+ }
+ case PROP_FLOAT: {
+ RNA_property_float_get_array(&itemptr, iprop, &((float*)in.array)[a]);
+ a += itemlen;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
}
}
}
@@ -2462,6 +2512,21 @@ static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *pro
RawPropertyType RNA_property_raw_type(PropertyRNA *prop)
{
+ if (prop->rawtype == PROP_RAW_UNSET) {
+ /* this property has no raw access, yet we try to provide a raw type to help building the array */
+ switch (prop->type) {
+ case PROP_BOOLEAN:
+ return PROP_RAW_INT;
+ case PROP_INT:
+ return PROP_RAW_INT;
+ case PROP_FLOAT:
+ return PROP_RAW_FLOAT;
+ case PROP_ENUM:
+ return PROP_RAW_INT;
+ default:
+ break;
+ }
+ }
return prop->rawtype;
}
@@ -3464,11 +3529,6 @@ const char *RNA_function_identifier(FunctionRNA *func)
return func->identifier;
}
-PropertyRNA *RNA_function_return(FunctionRNA *func)
-{
- return func->ret;
-}
-
const char *RNA_function_ui_description(FunctionRNA *func)
{
return func->description;
@@ -3929,7 +3989,7 @@ int RNA_function_call_direct_va(bContext *C, ReportList *reports, PointerRNA *pt
tid= RNA_struct_identifier(ptr->type);
fid= RNA_function_identifier(func);
- pret= RNA_function_return(func);
+ pret= func->c_ret;
flen= strlen(format);
RNA_parameter_list_create(&parms, ptr, func);
@@ -3937,14 +3997,17 @@ int RNA_function_call_direct_va(bContext *C, ReportList *reports, PointerRNA *pt
for(i= 0, ofs= 0; iter.valid; RNA_parameter_list_next(&iter), i++) {
parm= iter.parm;
+ flag= RNA_property_flag(parm);
if(parm==pret) {
retdata= iter.data;
continue;
}
+ else if (flag & PROP_RETURN) {
+ continue;
+ }
pid= RNA_property_identifier(parm);
- flag= RNA_property_flag(parm);
if (ofs>=flen || format[ofs]=='N') {
if (flag & PROP_REQUIRED) {
diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c
index 00c5b8ce7c4..b9c5661b771 100644
--- a/source/blender/makesrna/intern/rna_action.c
+++ b/source/blender/makesrna/intern/rna_action.c
@@ -88,7 +88,7 @@ static void rna_def_dopesheet(BlenderRNA *brna)
prop= RNA_def_property(srna, "display_summary", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "filterflag", ADS_FILTER_SUMMARY);
- RNA_def_property_ui_text(prop, "Display Summary", "Display an additional 'summary' line.");
+ RNA_def_property_ui_text(prop, "Display Summary", "Display an additional 'summary' line. (DopeSheet Editors only)");
RNA_def_property_ui_icon(prop, ICON_BORDERMOVE, 0);
RNA_def_property_update(prop, NC_ANIMATION|ND_ANIMCHAN_EDIT, NULL);
@@ -172,7 +172,7 @@ static void rna_def_dopesheet(BlenderRNA *brna)
prop= RNA_def_property(srna, "collapse_summary", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ADS_FLAG_SUMMARY_COLLAPSED);
- RNA_def_property_ui_text(prop, "Collapse Summary", "Collapse summary when shown, so all other channels get hidden. (DopeSheet Window Editors Only)");
+ RNA_def_property_ui_text(prop, "Collapse Summary", "Collapse summary when shown, so all other channels get hidden. (DopeSheet Editors Only)");
RNA_def_property_update(prop, NC_ANIMATION|ND_ANIMCHAN_EDIT, NULL);
}
diff --git a/source/blender/makesrna/intern/rna_animviz.c b/source/blender/makesrna/intern/rna_animviz.c
new file mode 100644
index 00000000000..261cfc83b6c
--- /dev/null
+++ b/source/blender/makesrna/intern/rna_animviz.c
@@ -0,0 +1,350 @@
+/**
+ * $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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contributor(s): Blender Foundation (2010), Joshua Leung
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_types.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
+#include "DNA_anim_types.h"
+#include "DNA_action_types.h"
+#include "DNA_scene_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "WM_types.h"
+
+#ifdef RNA_RUNTIME
+
+static PointerRNA rna_AnimViz_onion_skinning_get(PointerRNA *ptr)
+{
+ return rna_pointer_inherit_refine(ptr, &RNA_AnimVizOnionSkinning, ptr->data);
+}
+
+static PointerRNA rna_AnimViz_motion_paths_get(PointerRNA *ptr)
+{
+ return rna_pointer_inherit_refine(ptr, &RNA_AnimVizMotionPaths, ptr->data);
+}
+
+static void rna_AnimViz_ghost_start_frame_set(PointerRNA *ptr, int value)
+{
+ bAnimVizSettings *data= (bAnimVizSettings*)ptr->data;
+
+ CLAMP(value, 1, data->ghost_ef);
+ data->ghost_sf= value;
+}
+
+static void rna_AnimViz_ghost_end_frame_set(PointerRNA *ptr, int value)
+{
+ bAnimVizSettings *data= (bAnimVizSettings*)ptr->data;
+
+ CLAMP(value, data->ghost_sf, (int)(MAXFRAMEF/2));
+ data->ghost_ef= value;
+}
+
+static void rna_AnimViz_path_start_frame_set(PointerRNA *ptr, int value)
+{
+ bAnimVizSettings *data= (bAnimVizSettings*)ptr->data;
+
+ CLAMP(value, 1, data->path_ef);
+ data->path_sf= value;
+}
+
+static void rna_AnimViz_path_end_frame_set(PointerRNA *ptr, int value)
+{
+ bAnimVizSettings *data= (bAnimVizSettings*)ptr->data;
+
+ CLAMP(value, data->path_sf, (int)(MAXFRAMEF/2));
+ data->path_ef= value;
+}
+
+#else
+
+void rna_def_motionpath_common(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ prop= RNA_def_property(srna, "motion_path", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "mpath");
+ RNA_def_property_ui_text(prop, "Motion Path", "Motion Path for this element.");
+}
+
+static void rna_def_animviz_motionpath_vert(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= RNA_def_struct(brna, "MotionPathVert", NULL);
+ RNA_def_struct_sdna(srna, "bMotionPathVert");
+ RNA_def_struct_ui_text(srna, "Motion Path Cache Point", "Cached location on path.");
+
+ prop= RNA_def_property(srna, "co", PROP_FLOAT, PROP_XYZ);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Coordinates", "");
+
+ prop= RNA_def_property(srna, "selected", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", MOTIONPATH_VERT_SEL);
+ RNA_def_property_ui_text(prop, "Selected", "Path point is selected for editing.");
+}
+
+static void rna_def_animviz_motion_path(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= RNA_def_struct(brna, "MotionPath", NULL);
+ RNA_def_struct_sdna(srna, "bMotionPath");
+ RNA_def_struct_ui_text(srna, "Motion Path", "Cache of the worldspace positions of an element over a frame range.");
+
+ /* Collections */
+ prop= RNA_def_property(srna, "points", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "points", "length");
+ RNA_def_property_struct_type(prop, "MotionPathVert");
+ RNA_def_property_ui_text(prop, "Motion Path Points", "Cached positions per frame");
+
+ /* Playback Ranges */
+ prop= RNA_def_property(srna, "start_frame", PROP_INT, PROP_TIME);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Start Frame", "Starting frame of the stored range.");
+
+ prop= RNA_def_property(srna, "end_frame", PROP_INT, PROP_TIME);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "End Frame", "End frame of the stored range.");
+
+ prop= RNA_def_property(srna, "length", PROP_INT, PROP_TIME);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Length", "Number of frames cached.");
+
+ /* Settings */
+ prop= RNA_def_property(srna, "use_bone_head", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", MOTIONPATH_FLAG_BHEAD);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); // xxx
+ RNA_def_property_ui_text(prop, "Use Bone Heads", "For PoseBone paths, use the bone head location when calculating this path.");
+
+ prop= RNA_def_property(srna, "editing", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", MOTIONPATH_FLAG_EDIT);
+ RNA_def_property_ui_text(prop, "Edit Path", "Path is being edited.");
+}
+
+/* --- */
+
+static void rna_def_animviz_ghosts(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static const EnumPropertyItem prop_type_items[] = {
+ {GHOST_TYPE_NONE, "NONE", 0, "No Ghosts", "Don not show any ghosts"},
+ {GHOST_TYPE_ACFRA, "CURRENT_FRAME", 0, "Around Current Frame", "Show ghosts from around the current frame"},
+ {GHOST_TYPE_RANGE, "RANGE", 0, "In Range", "Show ghosts for the specified frame range"},
+ {GHOST_TYPE_KEYS, "KEYS", 0, "On Keyframes", "Show ghosts on keyframes"},
+ {0, NULL, 0, NULL, NULL}};
+
+
+ srna= RNA_def_struct(brna, "AnimVizOnionSkinning", NULL);
+ RNA_def_struct_sdna(srna, "bAnimVizSettings");
+ RNA_def_struct_nested(brna, srna, "AnimViz");
+ RNA_def_struct_ui_text(srna, "Onion Skinning Settings", "Onion Skinning settings for animation visualisation.");
+
+ /* Enums */
+ prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "ghost_type");
+ RNA_def_property_enum_items(prop, prop_type_items);
+ RNA_def_property_ui_text(prop, "Type", "Method used for determining what ghosts get drawn.");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
+
+ /* Settings */
+ prop= RNA_def_property(srna, "only_selected", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "ghost_flag", GHOST_FLAG_ONLYSEL);
+ RNA_def_property_ui_text(prop, "On Selected Bones Only", "For Pose-Mode drawing, only draw ghosts for selected bones.");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
+
+ prop= RNA_def_property(srna, "frame_step", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "ghost_step");
+ RNA_def_property_range(prop, 1, 20);
+ RNA_def_property_ui_text(prop, "Frame Step", "Number of frames between ghosts shown (not for 'On Keyframes' Onion-skining method).");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
+
+ /* Playback Ranges */
+ prop= RNA_def_property(srna, "start_frame", PROP_INT, PROP_TIME);
+ RNA_def_property_int_sdna(prop, NULL, "ghost_sf");
+ RNA_def_property_int_funcs(prop, NULL, "rna_AnimViz_ghost_start_frame_set", NULL);
+ RNA_def_property_ui_text(prop, "Start Frame", "Starting frame of range of Ghosts to display (not for 'Around Current Frame' Onion-skinning method).");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
+
+ prop= RNA_def_property(srna, "end_frame", PROP_INT, PROP_TIME);
+ RNA_def_property_int_sdna(prop, NULL, "ghost_ef");
+ RNA_def_property_int_funcs(prop, NULL, "rna_AnimViz_ghost_end_frame_set", NULL);
+ RNA_def_property_ui_text(prop, "End Frame", "End frame of range of Ghosts to display (not for 'Around Current Frame' Onion-skinning method).");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
+
+ /* Around Current Ranges */
+ prop= RNA_def_property(srna, "before_current", PROP_INT, PROP_TIME);
+ RNA_def_property_int_sdna(prop, NULL, "ghost_bc");
+ RNA_def_property_range(prop, 0, 30);
+ RNA_def_property_ui_text(prop, "Before Current", "Number of frames to show before the current frame (only for 'Around Current Frame' Onion-skinning method).");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
+
+ prop= RNA_def_property(srna, "after_current", PROP_INT, PROP_TIME);
+ RNA_def_property_int_sdna(prop, NULL, "ghost_ac");
+ RNA_def_property_range(prop, 0, 30);
+ RNA_def_property_ui_text(prop, "After Current", "Number of frames to show after the current frame (only for 'Around Current Frame' Onion-skinning method).");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
+}
+
+static void rna_def_animviz_paths(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static const EnumPropertyItem prop_type_items[]= {
+ {MOTIONPATH_TYPE_RANGE, "RANGE", 0, "In Range", "Display Paths of poses within specified range."},
+ {MOTIONPATH_TYPE_ACFRA, "CURRENT_FRAME", 0, "Around Frame", "Display Paths of poses within a fixed number of frames around the current frame."},
+ {0, NULL, 0, NULL, NULL}};
+ static const EnumPropertyItem prop_location_items[]= {
+ {MOTIONPATH_BAKE_HEADS, "HEADS", 0, "Heads", "Calculate bone paths from heads"},
+ {0, "TAILS", 0, "Tails", "Calculate bone paths from tails"},
+ {0, NULL, 0, NULL, NULL}};
+
+ srna= RNA_def_struct(brna, "AnimVizMotionPaths", NULL);
+ RNA_def_struct_sdna(srna, "bAnimVizSettings");
+ RNA_def_struct_nested(brna, srna, "AnimViz");
+ RNA_def_struct_ui_text(srna, "Motion Path Settings", "Motion Path settings for animation visualisation.");
+
+ /* Enums */
+ prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "path_type");
+ RNA_def_property_enum_items(prop, prop_type_items);
+ RNA_def_property_ui_text(prop, "Paths Type", "Type of range to show for Motion Paths");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
+
+ prop= RNA_def_property(srna, "bake_location", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "path_bakeflag");
+ RNA_def_property_enum_items(prop, prop_location_items);
+ RNA_def_property_ui_text(prop, "Bake Location", "When calculating Bone Paths, use Head or Tips");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
+
+ /* Settings */
+ prop= RNA_def_property(srna, "show_frame_numbers", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "path_viewflag", MOTIONPATH_VIEW_FNUMS);
+ RNA_def_property_ui_text(prop, "Show Frame Numbers", "Show frame numbers on Motion Paths");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
+
+ prop= RNA_def_property(srna, "highlight_keyframes", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "path_viewflag", MOTIONPATH_VIEW_KFRAS);
+ RNA_def_property_ui_text(prop, "Highlight Keyframes", "Emphasize position of keyframes on Motion Paths");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
+
+ prop= RNA_def_property(srna, "show_keyframe_numbers", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "path_viewflag", MOTIONPATH_VIEW_KFNOS);
+ RNA_def_property_ui_text(prop, "Show Keyframe Numbers", "Show frame numbers of Keyframes on Motion Paths");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
+
+ prop= RNA_def_property(srna, "frame_step", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "path_step");
+ RNA_def_property_range(prop, 1, 100);
+ RNA_def_property_ui_text(prop, "Frame Step", "Number of frames between paths shown (not for 'On Keyframes' Onion-skining method).");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
+
+
+ /* Playback Ranges */
+ prop= RNA_def_property(srna, "start_frame", PROP_INT, PROP_TIME);
+ RNA_def_property_int_sdna(prop, NULL, "path_sf");
+ RNA_def_property_int_funcs(prop, NULL, "rna_AnimViz_path_start_frame_set", NULL);
+ RNA_def_property_ui_text(prop, "Start Frame", "Starting frame of range of paths to display/calculate (not for 'Around Current Frame' Onion-skinning method).");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
+
+ prop= RNA_def_property(srna, "end_frame", PROP_INT, PROP_TIME);
+ RNA_def_property_int_sdna(prop, NULL, "path_ef");
+ RNA_def_property_int_funcs(prop, NULL, "rna_AnimViz_path_end_frame_set", NULL);
+ RNA_def_property_ui_text(prop, "End Frame", "End frame of range of paths to display/calculate (not for 'Around Current Frame' Onion-skinning method).");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
+
+ /* Around Current Ranges */
+ prop= RNA_def_property(srna, "before_current", PROP_INT, PROP_TIME);
+ RNA_def_property_int_sdna(prop, NULL, "path_bc");
+ RNA_def_property_range(prop, 1, MAXFRAMEF/2);
+ RNA_def_property_ui_text(prop, "Before Current", "Number of frames to show before the current frame (only for 'Around Current Frame' Onion-skinning method).");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
+
+ prop= RNA_def_property(srna, "after_current", PROP_INT, PROP_TIME);
+ RNA_def_property_int_sdna(prop, NULL, "path_ac");
+ RNA_def_property_range(prop, 1, MAXFRAMEF/2);
+ RNA_def_property_ui_text(prop, "After Current", "Number of frames to show after the current frame (only for 'Around Current Frame' Onion-skinning method).");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
+}
+
+/* --- */
+
+void rna_def_animviz_common(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ prop= RNA_def_property(srna, "animation_visualisation", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_pointer_sdna(prop, NULL, "avs");
+ RNA_def_property_ui_text(prop, "Animation Visualisation", "Animation data for this datablock.");
+}
+
+static void rna_def_animviz(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= RNA_def_struct(brna, "AnimViz", NULL);
+ RNA_def_struct_sdna(srna, "bAnimVizSettings");
+ RNA_def_struct_ui_text(srna, "Animation Visualisation", "Settings for the visualisation of motion.");
+
+ /* onion-skinning settings (nested struct) */
+ prop= RNA_def_property(srna, "onion_skinning", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_struct_type(prop, "AnimVizOnionSkinning");
+ RNA_def_property_pointer_funcs(prop, "rna_AnimViz_onion_skinning_get", NULL, NULL);
+ RNA_def_property_ui_text(prop, "Onion Skinning", "Onion Skinning (ghosting) settings for visualisation.");
+
+ /* motion path settings (nested struct) */
+ prop= RNA_def_property(srna, "motion_paths", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_struct_type(prop, "AnimVizMotionPaths");
+ RNA_def_property_pointer_funcs(prop, "rna_AnimViz_motion_paths_get", NULL, NULL);
+ RNA_def_property_ui_text(prop, "Motion Paths", "Motion Path settings for visualisation.");
+}
+
+/* --- */
+
+void RNA_def_animviz(BlenderRNA *brna)
+{
+ rna_def_animviz(brna);
+ rna_def_animviz_ghosts(brna);
+ rna_def_animviz_paths(brna);
+
+ rna_def_animviz_motion_path(brna);
+ rna_def_animviz_motionpath_vert(brna);
+}
+
+#endif
diff --git a/source/blender/makesrna/intern/rna_armature_api.c b/source/blender/makesrna/intern/rna_armature_api.c
index 22bd7313166..f3983a43b4f 100644
--- a/source/blender/makesrna/intern/rna_armature_api.c
+++ b/source/blender/makesrna/intern/rna_armature_api.c
@@ -58,7 +58,7 @@ void RNA_api_armature_edit_bone(StructRNA *srna)
PropertyRNA *parm;
func= RNA_def_function(srna, "align_roll", "rna_EditBone_align_roll");
- RNA_def_function_ui_description(func, "Align the bone to a localspace vector.");
+ RNA_def_function_ui_description(func, "Align the bone to a localspace roll so the Z axis points in the direction of the vector given.");
parm= RNA_def_float_vector(func, "vector", 3, NULL, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
RNA_def_property_flag(parm, PROP_REQUIRED);
}
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index 7f7126c659a..8f8dd4681ab 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -33,6 +33,7 @@
#include "DNA_texture_types.h"
#include "IMB_imbuf.h"
+#include "WM_types.h"
EnumPropertyItem brush_sculpt_tool_items[] = {
{SCULPT_TOOL_DRAW, "DRAW", 0, "Draw", ""},
@@ -52,29 +53,6 @@ EnumPropertyItem brush_sculpt_tool_items[] = {
#include "BKE_texture.h"
#include "WM_api.h"
-#include "WM_types.h"
-
-static void rna_Brush_mtex_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
-{
- Brush *brush= (Brush*)ptr->data;
- rna_iterator_array_begin(iter, (void*)brush->mtex, sizeof(MTex*), MAX_MTEX, 0, NULL);
-}
-
-static PointerRNA rna_Brush_active_texture_get(PointerRNA *ptr)
-{
- Brush *br= (Brush*)ptr->data;
- Tex *tex;
-
- tex= give_current_brush_texture(br);
- return rna_pointer_inherit_refine(ptr, &RNA_Texture, tex);
-}
-
-static void rna_Brush_active_texture_set(PointerRNA *ptr, PointerRNA value)
-{
- Brush *br= (Brush*)ptr->data;
-
- set_current_brush_texture(br, value.data);
-}
static void rna_Brush_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
@@ -291,8 +269,17 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Brush_update");
/* texture */
- rna_def_mtex_common(srna, "rna_Brush_mtex_begin", "rna_Brush_active_texture_get",
- "rna_Brush_active_texture_set", "BrushTextureSlot", "rna_Brush_update");
+ prop= RNA_def_property(srna, "texture_slot", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "BrushTextureSlot");
+ RNA_def_property_pointer_sdna(prop, NULL, "mtex");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Texture Slot", "");
+
+ prop= RNA_def_property(srna, "texture", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "mtex.tex");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Texture", "");
+ RNA_def_property_update(prop, NC_TEXTURE, "rna_Brush_update");
/* clone tool */
prop= RNA_def_property(srna, "clone_image", PROP_POINTER, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index f9405dec531..5ec8d438c42 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -43,6 +43,7 @@ EnumPropertyItem constraint_type_items[] ={
{CONSTRAINT_TYPE_LOCLIKE, "COPY_LOCATION", ICON_CONSTRAINT_DATA, "Copy Location", ""},
{CONSTRAINT_TYPE_ROTLIKE, "COPY_ROTATION", ICON_CONSTRAINT_DATA, "Copy Rotation", ""},
{CONSTRAINT_TYPE_SIZELIKE, "COPY_SCALE", ICON_CONSTRAINT_DATA, "Copy Scale", ""},
+ {CONSTRAINT_TYPE_TRANSLIKE, "COPY_TRANSFORMS", ICON_CONSTRAINT_DATA, "Copy Transforms", ""},
{CONSTRAINT_TYPE_DISTLIMIT, "LIMIT_DISTANCE", ICON_CONSTRAINT_DATA, "Limit Distance", ""},
{CONSTRAINT_TYPE_LOCLIMIT, "LIMIT_LOCATION", ICON_CONSTRAINT_DATA, "Limit Location", ""},
{CONSTRAINT_TYPE_ROTLIMIT, "LIMIT_ROTATION", ICON_CONSTRAINT_DATA, "Limit Rotation", ""},
@@ -151,6 +152,8 @@ static StructRNA *rna_ConstraintType_refine(struct PointerRNA *ptr)
return &RNA_DampedTrackConstraint;
case CONSTRAINT_TYPE_SPLINEIK:
return &RNA_SplineIKConstraint;
+ case CONSTRAINT_TYPE_TRANSLIKE:
+ return &RNA_CopyTransformsConstraint;
default:
return &RNA_UnknownType;
}
@@ -647,6 +650,69 @@ static void rna_def_constraint_track_to(BlenderRNA *brna)
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
}
+static void rna_def_constraint_locate_like(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= RNA_def_struct(brna, "CopyLocationConstraint", "Constraint");
+ RNA_def_struct_ui_text(srna, "Copy Location Constraint", "Copies the location of the target.");
+
+ prop= RNA_def_property(srna, "head_tail", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, "bConstraint", "headtail");
+ RNA_def_property_ui_text(prop, "Head/Tail", "Target along length of bone: Head=0, Tail=1.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+
+ RNA_def_struct_sdna_from(srna, "bLocateLikeConstraint", "data");
+
+ prop= RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "tar");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Target", "Target Object");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
+
+ prop= RNA_def_property(srna, "subtarget", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "subtarget");
+ RNA_def_property_ui_text(prop, "Sub-Target", "");
+ RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
+
+ prop= RNA_def_property(srna, "use_x", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", LOCLIKE_X);
+ RNA_def_property_ui_text(prop, "Copy X", "Copy the target's X location.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop= RNA_def_property(srna, "use_y", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", LOCLIKE_Y);
+ RNA_def_property_ui_text(prop, "Copy Y", "Copy the target's Y location.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop= RNA_def_property(srna, "use_z", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", LOCLIKE_Z);
+ RNA_def_property_ui_text(prop, "Copy Z", "Copy the target's Z location.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop= RNA_def_property(srna, "invert_x", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", LOCLIKE_X_INVERT);
+ RNA_def_property_ui_text(prop, "Invert X", "Invert the X location.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop= RNA_def_property(srna, "invert_y", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", LOCLIKE_Y_INVERT);
+ RNA_def_property_ui_text(prop, "Invert Y", "Invert the Y location.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop= RNA_def_property(srna, "invert_z", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", LOCLIKE_Z_INVERT);
+ RNA_def_property_ui_text(prop, "Invert Z", "Invert the Z location.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop= RNA_def_property(srna, "use_offset", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", LOCLIKE_OFFSET);
+ RNA_def_property_ui_text(prop, "Offset", "Add original location into copied location.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+}
+
static void rna_def_constraint_rotate_like(BlenderRNA *brna)
{
StructRNA *srna;
@@ -703,20 +769,14 @@ static void rna_def_constraint_rotate_like(BlenderRNA *brna)
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
}
-static void rna_def_constraint_locate_like(BlenderRNA *brna)
+static void rna_def_constraint_size_like(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
- srna= RNA_def_struct(brna, "CopyLocationConstraint", "Constraint");
- RNA_def_struct_ui_text(srna, "Copy Location Constraint", "Copies the location of the target.");
-
- prop= RNA_def_property(srna, "head_tail", PROP_FLOAT, PROP_FACTOR);
- RNA_def_property_float_sdna(prop, "bConstraint", "headtail");
- RNA_def_property_ui_text(prop, "Head/Tail", "Target along length of bone: Head=0, Tail=1.");
- RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
-
- RNA_def_struct_sdna_from(srna, "bLocateLikeConstraint", "data");
+ srna= RNA_def_struct(brna, "CopyScaleConstraint", "Constraint");
+ RNA_def_struct_ui_text(srna, "Copy Scale Constraint", "Copies the scale of the target.");
+ RNA_def_struct_sdna_from(srna, "bSizeLikeConstraint", "data");
prop= RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "tar");
@@ -731,39 +791,50 @@ static void rna_def_constraint_locate_like(BlenderRNA *brna)
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
prop= RNA_def_property(srna, "use_x", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", LOCLIKE_X);
- RNA_def_property_ui_text(prop, "Copy X", "Copy the target's X location.");
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SIZELIKE_X);
+ RNA_def_property_ui_text(prop, "Copy X", "Copy the target's X scale.");
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
prop= RNA_def_property(srna, "use_y", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", LOCLIKE_Y);
- RNA_def_property_ui_text(prop, "Copy Y", "Copy the target's Y location.");
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SIZELIKE_Y);
+ RNA_def_property_ui_text(prop, "Copy Y", "Copy the target's Y scale.");
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
prop= RNA_def_property(srna, "use_z", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", LOCLIKE_Z);
- RNA_def_property_ui_text(prop, "Copy Z", "Copy the target's Z location.");
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SIZELIKE_Z);
+ RNA_def_property_ui_text(prop, "Copy Z", "Copy the target's Z scale.");
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
- prop= RNA_def_property(srna, "invert_x", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", LOCLIKE_X_INVERT);
- RNA_def_property_ui_text(prop, "Invert X", "Invert the X location.");
+ prop= RNA_def_property(srna, "use_offset", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SIZELIKE_OFFSET);
+ RNA_def_property_ui_text(prop, "Offset", "Add original scale into copied scale.");
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+}
- prop= RNA_def_property(srna, "invert_y", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", LOCLIKE_Y_INVERT);
- RNA_def_property_ui_text(prop, "Invert Y", "Invert the Y location.");
- RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+static void rna_def_constraint_transform_like(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
- prop= RNA_def_property(srna, "invert_z", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", LOCLIKE_Z_INVERT);
- RNA_def_property_ui_text(prop, "Invert Z", "Invert the Z location.");
+ srna= RNA_def_struct(brna, "CopyTransformsConstraint", "Constraint");
+ RNA_def_struct_ui_text(srna, "Copy Transforms Constraint", "Copies all the transforms of the target.");
+ RNA_def_struct_sdna_from(srna, "bTransLikeConstraint", "data");
+
+ prop= RNA_def_property(srna, "head_tail", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, "bConstraint", "headtail");
+ RNA_def_property_ui_text(prop, "Head/Tail", "Target along length of bone: Head=0, Tail=1.");
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
- prop= RNA_def_property(srna, "use_offset", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", LOCLIKE_OFFSET);
- RNA_def_property_ui_text(prop, "Offset", "Add original location into copied location.");
- RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+ prop= RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "tar");
+ RNA_def_property_ui_text(prop, "Target", "Target Object");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
+
+ prop= RNA_def_property(srna, "subtarget", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "subtarget");
+ RNA_def_property_ui_text(prop, "Sub-Target", "");
+ RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
}
static void rna_def_constraint_minmax(BlenderRNA *brna)
@@ -817,48 +888,6 @@ static void rna_def_constraint_minmax(BlenderRNA *brna)
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
}
-static void rna_def_constraint_size_like(BlenderRNA *brna)
-{
- StructRNA *srna;
- PropertyRNA *prop;
-
- srna= RNA_def_struct(brna, "CopyScaleConstraint", "Constraint");
- RNA_def_struct_ui_text(srna, "Copy Scale Constraint", "Copies the scale of the target.");
- RNA_def_struct_sdna_from(srna, "bSizeLikeConstraint", "data");
-
- prop= RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "tar");
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Target", "Target Object");
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
-
- prop= RNA_def_property(srna, "subtarget", PROP_STRING, PROP_NONE);
- RNA_def_property_string_sdna(prop, NULL, "subtarget");
- RNA_def_property_ui_text(prop, "Sub-Target", "");
- RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
-
- prop= RNA_def_property(srna, "use_x", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", SIZELIKE_X);
- RNA_def_property_ui_text(prop, "Copy X", "Copy the target's X scale.");
- RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
-
- prop= RNA_def_property(srna, "use_y", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", SIZELIKE_Y);
- RNA_def_property_ui_text(prop, "Copy Y", "Copy the target's Y scale.");
- RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
-
- prop= RNA_def_property(srna, "use_z", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", SIZELIKE_Z);
- RNA_def_property_ui_text(prop, "Copy Z", "Copy the target's Z scale.");
- RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
-
- prop= RNA_def_property(srna, "use_offset", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", SIZELIKE_OFFSET);
- RNA_def_property_ui_text(prop, "Offset", "Add original scale into copied scale.");
- RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
-}
-
static void rna_def_constraint_action(BlenderRNA *brna)
{
StructRNA *srna;
@@ -1869,6 +1898,7 @@ void RNA_def_constraint(BlenderRNA *brna)
rna_def_constraint_size_like(brna);
rna_def_constraint_locate_like(brna);
rna_def_constraint_rotate_like(brna);
+ rna_def_constraint_transform_like(brna);
rna_def_constraint_minmax(brna);
rna_def_constraint_track_to(brna);
rna_def_constraint_kinematic(brna);
diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c
index 9bf5afdac48..ed10c0819fd 100644
--- a/source/blender/makesrna/intern/rna_define.c
+++ b/source/blender/makesrna/intern/rna_define.c
@@ -931,6 +931,8 @@ PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier
prop->subtype= subtype;
prop->name= identifier;
prop->description= "";
+ /* a priori not raw editable */
+ prop->rawtype = -1;
if(type != PROP_COLLECTION && type != PROP_POINTER) {
prop->flag= PROP_EDITABLE;
@@ -2417,9 +2419,16 @@ FunctionRNA *RNA_def_function_runtime(StructRNA *srna, const char *identifier, C
return func;
}
+/* C return value only!, multiple rna returns can be done with RNA_def_function_return_mark */
void RNA_def_function_return(FunctionRNA *func, PropertyRNA *ret)
{
- func->ret= ret;
+ func->c_ret= ret;
+
+ RNA_def_function_return_mark(func, ret);
+}
+
+void RNA_def_function_return_mark(FunctionRNA *func, PropertyRNA *ret)
+{
ret->flag|=PROP_RETURN;
}
@@ -2461,7 +2470,12 @@ int rna_parameter_size(PropertyRNA *parm)
case PROP_FLOAT:
return sizeof(float);
case PROP_STRING:
- return sizeof(char *);
+ /* return valyes dont store a pointer to the original */
+ if(parm->flag & PROP_THICK_WRAP) {
+ StringPropertyRNA *sparm= (StringPropertyRNA*)parm;
+ return sizeof(char) * sparm->maxlength;
+ } else
+ return sizeof(char *);
case PROP_POINTER: {
#ifdef RNA_RUNTIME
if(parm->flag & PROP_RNAPTR)
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index 62ee19df352..b6b05eb4896 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -116,10 +116,12 @@ static void rna_DriverTarget_update_data(Main *bmain, Scene *scene, PointerRNA *
AnimData *adt= BKE_animdata_from_id(ptr->id.data);
/* find the driver this belongs to and update it */
- for(fcu=adt->drivers.first; fcu; fcu=fcu->next) {
+ for (fcu=adt->drivers.first; fcu; fcu=fcu->next) {
driver= fcu->driver;
-
- if(driver && BLI_findindex(&driver->targets, ptr->data) != -1) {
+
+ if (driver) {
+ // FIXME: need to be able to search targets for required one...
+ //BLI_findindex(&driver->targets, ptr->data) != -1)
RNA_pointer_create(ptr->id.data, &RNA_Driver, driver, &driverptr);
rna_ChannelDriver_update_data(bmain, scene, &driverptr);
return;
@@ -127,6 +129,15 @@ static void rna_DriverTarget_update_data(Main *bmain, Scene *scene, PointerRNA *
}
}
+static void rna_DriverTarget_update_name(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ ChannelDriver *driver= ptr->data;
+ rna_DriverTarget_update_data(bmain, scene, ptr);
+
+ driver->flag |= DRIVER_FLAG_RENAMEVAR;
+
+}
+
/* ----------- */
static StructRNA *rna_DriverTarget_id_typef(PointerRNA *ptr)
@@ -185,6 +196,14 @@ static void rna_DriverTarget_RnaPath_set(PointerRNA *ptr, const char *value)
dtar->rna_path= NULL;
}
+static void rna_DriverVariable_type_set(PointerRNA *ptr, int value)
+{
+ DriverVar *dvar= (DriverVar *)ptr->data;
+
+ /* call the API function for this */
+ driver_change_variable_type(dvar, value);
+}
+
/* ****************************** */
static void rna_FCurve_RnaPath_get(PointerRNA *ptr, char *value)
@@ -220,15 +239,16 @@ static void rna_FCurve_RnaPath_set(PointerRNA *ptr, const char *value)
fcu->rna_path= NULL;
}
-DriverTarget *rna_Driver_new_target(ChannelDriver *driver)
+DriverVar *rna_Driver_new_variable(ChannelDriver *driver)
{
- return driver_add_new_target(driver);
+ /* call the API function for this */
+ return driver_add_new_variable(driver);
}
-void rna_Driver_remove_target(ChannelDriver *driver, DriverTarget *dtar)
+void rna_Driver_remove_variable(ChannelDriver *driver, DriverVar *dvar)
{
/* call the API function for this */
- driver_free_target(driver, dtar);
+ driver_free_variable(driver, dvar);
}
@@ -676,14 +696,20 @@ static void rna_def_drivertarget(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
- srna= RNA_def_struct(brna, "DriverTarget", NULL);
- RNA_def_struct_ui_text(srna, "Driver Target", "Variable from some source/target for driver relationship.");
+ static EnumPropertyItem prop_trans_chan_items[] = {
+ {DTAR_TRANSCHAN_LOCX, "LOC_X", 0, "X Location", ""},
+ {DTAR_TRANSCHAN_LOCY, "LOC_Y", 0, "Y Location", ""},
+ {DTAR_TRANSCHAN_LOCZ, "LOC_Z", 0, "Z Location", ""},
+ {DTAR_TRANSCHAN_ROTX, "ROT_X", 0, "X Rotation", ""},
+ {DTAR_TRANSCHAN_ROTY, "ROT_Y", 0, "Y Rotation", ""},
+ {DTAR_TRANSCHAN_ROTZ, "ROT_Z", 0, "Z Rotation", ""},
+ {DTAR_TRANSCHAN_SCALEX, "SCALE_X", 0, "X Scale", ""},
+ {DTAR_TRANSCHAN_SCALEY, "SCALE_Y", 0, "Y Scale", ""},
+ {DTAR_TRANSCHAN_SCALEZ, "SCALE_Z", 0, "Z Scale", ""},
+ {0, NULL, 0, NULL, NULL}};
- /* Variable Name */
- prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
- RNA_def_struct_name_property(srna, prop);
- RNA_def_property_ui_text(prop, "Name", "Name to use in scripted expressions/functions. (No spaces or dots are allowed. Also, must not start with a symbol or digit)");
- RNA_def_property_update(prop, 0, "rna_DriverTarget_update_data");
+ srna= RNA_def_struct(brna, "DriverTarget", NULL);
+ RNA_def_struct_ui_text(srna, "Driver Target", "Source of input values for driver variables.");
/* Target Properties - ID-block to Drive */
prop= RNA_def_property(srna, "id", PROP_POINTER, PROP_NONE);
@@ -698,6 +724,7 @@ static void rna_def_drivertarget(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "idtype");
RNA_def_property_enum_items(prop, id_type_items);
RNA_def_property_enum_default(prop, ID_OB);
+ // XXX need to add an 'editable func' for this, in the case where certain flags are set already...
RNA_def_property_enum_funcs(prop, NULL, "rna_DriverTarget_id_type_set", NULL);
RNA_def_property_ui_text(prop, "ID Type", "Type of ID-block that can be used.");
RNA_def_property_update(prop, 0, "rna_DriverTarget_update_data");
@@ -705,44 +732,93 @@ static void rna_def_drivertarget(BlenderRNA *brna)
/* Target Properties - Property to Drive */
prop= RNA_def_property(srna, "data_path", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, "rna_DriverTarget_RnaPath_get", "rna_DriverTarget_RnaPath_length", "rna_DriverTarget_RnaPath_set");
- RNA_def_property_ui_text(prop, "Data Path", "RNA Path (from Object) to property used");
+ RNA_def_property_ui_text(prop, "Data Path", "RNA Path (from ID-block) to property used.");
RNA_def_property_update(prop, 0, "rna_DriverTarget_update_data");
- prop= RNA_def_property(srna, "array_index", PROP_INT, PROP_NONE);
- RNA_def_property_ui_text(prop, "RNA Array Index", "Index to the specific property used (if applicable)");
+ prop= RNA_def_property(srna, "bone_target", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "pchan_name");
+ RNA_def_property_ui_text(prop, "Bone Name", "Name of PoseBone to use as target.");
RNA_def_property_update(prop, 0, "rna_DriverTarget_update_data");
+
+ prop= RNA_def_property(srna, "transform_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "transChan");
+ RNA_def_property_enum_items(prop, prop_trans_chan_items);
+ RNA_def_property_ui_text(prop, "Type", "Driver variable type.");
+ RNA_def_property_update(prop, 0, "rna_DriverTarget_update_data");
+
+ prop= RNA_def_property(srna, "use_local_space_transforms", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", DTAR_FLAG_LOCALSPACE);
+ RNA_def_property_ui_text(prop, "Local Space", "Use transforms in Local Space (as opposed to the worldspace default).");
+ RNA_def_property_update(prop, 0, "rna_DriverTarget_update_data");
+}
+
+static void rna_def_drivervar(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem prop_type_items[] = {
+ {DVAR_TYPE_SINGLE_PROP, "SINGLE_PROP", 0, "Single Property", "Use the value from some RNA property (Default)"},
+ {DVAR_TYPE_TRANSFORM_CHAN, "TRANSFORMS", 0, "Transform Channel", "Final transformation value of object or bone"},
+ {DVAR_TYPE_ROT_DIFF, "ROTATION_DIFF", 0, "Rotational Difference", "Use the angle between two bones"},
+ {DVAR_TYPE_LOC_DIFF, "LOC_DIFF", 0, "Distance", "Distance between two bones or objects"},
+ {0, NULL, 0, NULL, NULL}};
+
+
+ srna= RNA_def_struct(brna, "DriverVariable", NULL);
+ RNA_def_struct_sdna(srna, "DriverVar");
+ RNA_def_struct_ui_text(srna, "Driver Variable", "Variable from some source/target for driver relationship.");
+
+ /* Variable Name */
+ prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
+ RNA_def_struct_name_property(srna, prop);
+ RNA_def_property_ui_text(prop, "Name", "Name to use in scripted expressions/functions. (No spaces or dots are allowed. Also, must not start with a symbol or digit)");
+ RNA_def_property_update(prop, 0, "rna_DriverTarget_update_name"); // XXX
+
+ /* Enums */
+ prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, prop_type_items);
+ RNA_def_property_enum_funcs(prop, NULL, "rna_DriverVariable_type_set", NULL);
+ RNA_def_property_ui_text(prop, "Type", "Driver variable type.");
+ RNA_def_property_update(prop, 0, "rna_ChannelDriver_update_data"); // XXX
+
+ /* Targets */
+ // TODO: for nicer api, only expose the relevant props via subclassing, instead of exposing the collection of targets
+ prop= RNA_def_property(srna, "targets", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "targets", "num_targets");
+ RNA_def_property_struct_type(prop, "DriverTarget");
+ RNA_def_property_ui_text(prop, "Targets", "Sources of input data for evaluating this variable.");
}
-/* channeldriver.targets.* */
-static void rna_def_channeldriver_targets(BlenderRNA *brna, PropertyRNA *cprop)
+/* channeldriver.variables.* */
+static void rna_def_channeldriver_variables(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
// PropertyRNA *prop;
-
+
FunctionRNA *func;
PropertyRNA *parm;
-
- RNA_def_property_srna(cprop, "ChannelDriverTargets");
- srna= RNA_def_struct(brna, "ChannelDriverTargets", NULL);
+
+ RNA_def_property_srna(cprop, "ChannelDriverVariables");
+ srna= RNA_def_struct(brna, "ChannelDriverVariables", NULL);
RNA_def_struct_sdna(srna, "ChannelDriver");
- RNA_def_struct_ui_text(srna, "ChannelDriver Targets", "Collection of channel driver Targets.");
-
-
- /* add target */
- func= RNA_def_function(srna, "new", "rna_Driver_new_target");
- RNA_def_function_ui_description(func, "Add a new target for the driver.");
+ RNA_def_struct_ui_text(srna, "ChannelDriver Variables", "Collection of channel driver Variables.");
+
+
+ /* add variable */
+ func= RNA_def_function(srna, "new", "rna_Driver_new_variable");
+ RNA_def_function_ui_description(func, "Add a new variable for the driver.");
/* return type */
- parm= RNA_def_pointer(func, "target", "DriverTarget", "", "Newly created Driver Target.");
+ parm= RNA_def_pointer(func, "var", "DriverVariable", "", "Newly created Driver Variable.");
RNA_def_function_return(func, parm);
- /* remove target */
- func= RNA_def_function(srna, "remove", "rna_Driver_remove_target");
- RNA_def_function_ui_description(func, "Remove an existing target from the driver.");
- /* target to remove*/
- parm= RNA_def_pointer(func, "target", "DriverTarget", "", "Target to remove from the driver.");
+ /* remove variable */
+ func= RNA_def_function(srna, "remove", "rna_Driver_remove_variable");
+ RNA_def_function_ui_description(func, "Remove an existing variable from the driver.");
+ /* target to remove */
+ parm= RNA_def_pointer(func, "var", "DriverVariable", "", "Variable to remove from the driver.");
RNA_def_property_flag(parm, PROP_REQUIRED);
-
}
static void rna_def_channeldriver(BlenderRNA *brna)
@@ -754,7 +830,8 @@ static void rna_def_channeldriver(BlenderRNA *brna)
{DRIVER_TYPE_AVERAGE, "AVERAGE", 0, "Averaged Value", ""},
{DRIVER_TYPE_SUM, "SUM", 0, "Sum Values", ""},
{DRIVER_TYPE_PYTHON, "SCRIPTED", 0, "Scripted Expression", ""},
- {DRIVER_TYPE_ROTDIFF, "ROTDIFF", 0, "Rotational Difference", ""},
+ {DRIVER_TYPE_MIN, "MIN", 0, "Minimum Value", ""},
+ {DRIVER_TYPE_MAX, "MAX", 0, "Maximum Value", ""},
{0, NULL, 0, NULL, NULL}};
srna= RNA_def_struct(brna, "Driver", NULL);
@@ -764,7 +841,7 @@ static void rna_def_channeldriver(BlenderRNA *brna)
/* Enums */
prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_type_items);
- RNA_def_property_ui_text(prop, "Type", "Driver types.");
+ RNA_def_property_ui_text(prop, "Type", "Driver type.");
RNA_def_property_update(prop, 0, "rna_ChannelDriver_update_data");
/* String values */
@@ -773,11 +850,11 @@ static void rna_def_channeldriver(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_ChannelDriver_update_expr");
/* Collections */
- prop= RNA_def_property(srna, "targets", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_collection_sdna(prop, NULL, "targets", NULL);
- RNA_def_property_struct_type(prop, "DriverTarget");
- RNA_def_property_ui_text(prop, "Target Variables", "Properties acting as targets for this driver.");
- rna_def_channeldriver_targets(brna, prop);
+ prop= RNA_def_property(srna, "variables", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "variables", NULL);
+ RNA_def_property_struct_type(prop, "DriverVariable");
+ RNA_def_property_ui_text(prop, "Variables", "Properties acting as inputs for this driver.");
+ rna_def_channeldriver_variables(brna, prop);
/* Functions */
RNA_api_drivers(srna);
@@ -933,6 +1010,7 @@ void RNA_def_fcurve(BlenderRNA *brna)
rna_def_fpoint(brna);
rna_def_drivertarget(brna);
+ rna_def_drivervar(brna);
rna_def_channeldriver(brna);
rna_def_fmodifier(brna);
diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c
index 129fad4e98c..30591efc481 100644
--- a/source/blender/makesrna/intern/rna_gpencil.c
+++ b/source/blender/makesrna/intern/rna_gpencil.c
@@ -199,6 +199,10 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_LOCKED);
RNA_def_property_ui_text(prop, "Locked", "Layer is protected from further editing and/or frame changes.");
+ prop= RNA_def_property(srna, "frame_lock", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_FRAMELOCK);
+ RNA_def_property_ui_text(prop, "Frame Locked", "Current frame displayed by layer cannot be changed.");
+
prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_ACTIVE);
RNA_def_property_boolean_funcs(prop, NULL, "rna_GPencilLayer_active_set");
@@ -220,6 +224,13 @@ static void rna_def_gpencil_data(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
+ static EnumPropertyItem draw_mode_items[] = {
+ {GP_DATA_VIEWALIGN, "CURSOR", 0, "Cursor", ""},
+ {0, "VIEW", 0, "View", ""}, /* weired, GP_DATA_VIEWALIGN is inverted */
+ {GP_DATA_VIEWALIGN|GP_DATA_DEPTH_VIEW, "SURFACE", 0, "Surface", ""},
+ {GP_DATA_VIEWALIGN|GP_DATA_DEPTH_STROKE, "STROKE", 0, "Stroke", ""},
+ {0, NULL, 0, NULL, NULL}};
+
srna= RNA_def_struct(brna, "GreasePencil", "ID");
RNA_def_struct_sdna(srna, "bGPdata");
RNA_def_struct_ui_text(srna, "Grease Pencil", "Freehand annotation sketchbook.");
@@ -232,9 +243,16 @@ static void rna_def_gpencil_data(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Layers", "Similar to layers in Photoshop.");
/* Flags */
- prop= RNA_def_property(srna, "view_space_draw", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GP_DATA_VIEWALIGN);
- RNA_def_property_ui_text(prop, "Stick to View", "Newly drawn strokes get added in view space (i.e. sketches stick to data when view is manipulated).");
+ prop= RNA_def_property(srna, "draw_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
+ RNA_def_property_enum_items(prop, draw_mode_items);
+ RNA_def_property_ui_text(prop, "Draw Mode", "");
+
+ prop= RNA_def_property(srna, "use_stroke_endpoints", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_DEPTH_STROKE_ENDPOINTS);
+ RNA_def_property_ui_text(prop, "Only Endpoints", "When snapping the stroke to existing lines, only use the first and last parts of the line.");
+
+
}
/* --- */
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index e0d8a6950de..c4d7e772c58 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -153,6 +153,26 @@ static int rna_Image_has_data_get(PointerRNA *ptr)
return 0;
}
+static void rna_Image_size_get(PointerRNA *ptr,int *values)
+{
+ Image *im= (Image*)ptr->data;
+ ImBuf *ibuf;
+ void *lock;
+
+ ibuf = BKE_image_acquire_ibuf(im, NULL , &lock);
+ if (ibuf) {
+ values[0]= ibuf->x;
+ values[1]= ibuf->y;
+ }
+ else {
+ values[0]= 0;
+ values[1]= 0;
+ }
+
+ BKE_image_release_ibuf(im, lock);
+}
+
+
static int rna_Image_depth_get(PointerRNA *ptr)
{
Image *im= (Image*)ptr->data;
@@ -401,6 +421,10 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Depth", "Image bit depth.");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ prop= RNA_def_int_vector(srna, "size" , 2 , NULL , 0, 0, "Size" , "Width and height in pixels, zero when image data cant be loaded." , 0 , 0);
+ RNA_def_property_int_funcs(prop, "rna_Image_size_get" , NULL, NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
RNA_api_image(srna);
}
diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c
index 2bb7905fc03..34e2fc06ad7 100644
--- a/source/blender/makesrna/intern/rna_image_api.c
+++ b/source/blender/makesrna/intern/rna_image_api.c
@@ -63,6 +63,35 @@ static char *rna_Image_get_export_path(Image *image, char *dest_dir, int rel)
return path;
}
+static void rna_Image_save(Image *image, bContext *C, ReportList *reports, char *path, Scene *scene)
+{
+ ImBuf *ibuf;
+
+ if (scene == NULL) {
+ scene = CTX_data_scene(C);
+ }
+
+ if (scene) {
+ ImageUser iuser;
+ void *lock;
+
+ iuser.scene = scene;
+ iuser.ok = 1;
+
+ ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
+
+ if (ibuf == NULL) {
+ BKE_reportf(reports, RPT_ERROR, "Couldn't acquire buffer from image");
+ }
+
+ if (!BKE_write_ibuf(NULL, ibuf, path, scene->r.imtype, scene->r.subimtype, scene->r.quality)) {
+ BKE_reportf(reports, RPT_ERROR, "Couldn't write image: %s", path);
+ }
+ } else {
+ BKE_reportf(reports, RPT_ERROR, "Scene not in context, couldn't get save parameters");
+ }
+}
+
char *rna_Image_get_abs_filename(Image *image, bContext *C)
{
char *filename= MEM_callocN(FILE_MAX, "Image.get_abs_filename()");
@@ -95,6 +124,13 @@ void RNA_api_image(StructRNA *srna)
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.");
+ 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.");
}
#endif
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index 5bb3c82395d..3d18804036a 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -118,6 +118,7 @@ extern BlenderRNA BLENDER_RNA;
void RNA_def_ID(struct BlenderRNA *brna);
void RNA_def_action(struct BlenderRNA *brna);
void RNA_def_animation(struct BlenderRNA *brna);
+void RNA_def_animviz(struct BlenderRNA *brna);
void RNA_def_armature(struct BlenderRNA *brna);
void RNA_def_actuator(struct BlenderRNA *brna);
void RNA_def_boid(struct BlenderRNA *brna);
@@ -175,6 +176,9 @@ void RNA_def_world(struct BlenderRNA *brna);
void rna_def_animdata_common(struct StructRNA *srna);
+void rna_def_animviz_common(struct StructRNA *srna);
+void rna_def_motionpath_common(struct StructRNA *srna);
+
void rna_def_texmat_common(struct StructRNA *srna, const char *texspace_editable);
void rna_def_mtex_common(struct StructRNA *srna, const char *begin, const char *activeget, const char *activeset, const char *structname, const char *update);
void rna_def_render_layer_common(struct StructRNA *srna, int scene);
@@ -211,6 +215,7 @@ void RNA_api_armature_edit_bone(StructRNA *srna);
void RNA_api_drivers(StructRNA *srna);
void RNA_api_image(struct StructRNA *srna);
void RNA_api_operator(struct StructRNA *srna);
+void RNA_api_macro(struct StructRNA *srna);
void RNA_api_keyconfig(struct StructRNA *srna);
void RNA_api_keyingset(struct StructRNA *srna);
void RNA_api_keymap(struct StructRNA *srna);
@@ -220,11 +225,39 @@ void RNA_api_material(StructRNA *srna);
void RNA_api_mesh(struct StructRNA *srna);
void RNA_api_object(struct StructRNA *srna);
void RNA_api_pose_channel(struct StructRNA *srna);
-void RNA_api_scene(struct StructRNA *srna);
+void RNA_api_scene(struct StructRNA *srna);
+void RNA_api_scene_render(struct StructRNA *srna);
void RNA_api_text(struct StructRNA *srna);
void RNA_api_ui_layout(struct StructRNA *srna);
void RNA_api_wm(struct StructRNA *srna);
+/* main collection functions */
+void RNA_def_main_cameras(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_scenes(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_objects(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_materials(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_node_groups(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_meshes(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_lamps(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_libraries(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_screens(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_window_managers(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_images(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_lattices(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_curves(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_metaballs(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_vfonts(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_textures(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_brushes(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_worlds(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_groups(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_texts(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_sounds(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_armatures(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_actions(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_particles(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_gpencil(BlenderRNA *brna, PropertyRNA *cprop);
+
/* ID Properties */
extern StringPropertyRNA rna_IDProperty_string;
diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h
index 4f05e6132f7..bef568bfa7d 100644
--- a/source/blender/makesrna/intern/rna_internal_types.h
+++ b/source/blender/makesrna/intern/rna_internal_types.h
@@ -118,8 +118,9 @@ struct FunctionRNA {
/* callback to execute the function */
CallFunc call;
- /* parameter for the return value */
- PropertyRNA *ret;
+ /* parameter for the return value
+ * note: this is only the C return value, rna functions can have multiple return values */
+ PropertyRNA *c_ret;
};
struct PropertyRNA {
diff --git a/source/blender/makesrna/intern/rna_key.c b/source/blender/makesrna/intern/rna_key.c
index 9e560a50af0..6ff961070b9 100644
--- a/source/blender/makesrna/intern/rna_key.c
+++ b/source/blender/makesrna/intern/rna_key.c
@@ -283,7 +283,13 @@ static PointerRNA rna_ShapeKey_data_get(CollectionPropertyIterator *iter)
static char *rna_ShapeKey_path(PointerRNA *ptr)
{
- return BLI_sprintfN("keys[\"%s\"]", ((KeyBlock*)ptr->data)->name);
+ KeyBlock *kb= (KeyBlock *)ptr->data;
+ ID *id= ptr->id.data;
+
+ if ((id) && (GS(id->name) != ID_KE))
+ return BLI_sprintfN("shape_keys.keys[\"%s\"]", kb->name);
+ else
+ return BLI_sprintfN("keys[\"%s\"]", kb->name);
}
static void rna_Key_update_data(Main *bmain, Scene *scene, PointerRNA *ptr)
diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c
index 82988a06af9..4b5a404b268 100644
--- a/source/blender/makesrna/intern/rna_main.c
+++ b/source/blender/makesrna/intern/rna_main.c
@@ -235,40 +235,44 @@ static PointerRNA rna_Test_test_get(PointerRNA *ptr)
#else
+typedef void (*CollectionDefFunc)(struct BlenderRNA *brna, struct PropertyRNA *cprop);
+
void RNA_def_main(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
+ CollectionDefFunc func;
+
+ const char *lists[][6]= {
+ {"cameras", "Camera", "rna_Main_camera_begin", "Cameras", "Camera datablocks.", (char *)RNA_def_main_cameras},
+ {"scenes", "Scene", "rna_Main_scene_begin", "Scenes", "Scene datablocks.", (char *)RNA_def_main_scenes},
+ {"objects", "Object", "rna_Main_object_begin", "Objects", "Object datablocks.", (char *)RNA_def_main_objects},
+ {"materials", "Material", "rna_Main_mat_begin", "Materials", "Material datablocks.", (char *)RNA_def_main_materials},
+ {"node_groups", "NodeTree", "rna_Main_nodetree_begin", "Node Groups", "Node group datablocks.", (char *)RNA_def_main_node_groups},
+ {"meshes", "Mesh", "rna_Main_mesh_begin", "Meshes", "Mesh datablocks.", (char *)RNA_def_main_meshes},
+ {"lamps", "Lamp", "rna_Main_lamp_begin", "Lamps", "Lamp datablocks.", (char *)RNA_def_main_lamps},
+ {"libraries", "Library", "rna_Main_library_begin", "Libraries", "Library datablocks.", (char *)RNA_def_main_libraries},
+ {"screens", "Screen", "rna_Main_screen_begin", "Screens", "Screen datablocks.", (char *)RNA_def_main_screens},
+ {"window_managers", "WindowManager", "rna_Main_wm_begin", "Window Managers", "Window manager datablocks.", (char *)RNA_def_main_window_managers},
+ {"images", "Image", "rna_Main_image_begin", "Images", "Image datablocks.", (char *)RNA_def_main_images},
+ {"lattices", "Lattice", "rna_Main_latt_begin", "Lattices", "Lattice datablocks.", (char *)RNA_def_main_lattices},
+ {"curves", "Curve", "rna_Main_curve_begin", "Curves", "Curve datablocks.", (char *)RNA_def_main_curves} ,
+ {"metaballs", "MetaBall", "rna_Main_mball_begin", "Metaballs", "Metaball datablocks.", (char *)RNA_def_main_metaballs},
+ {"vfonts", "VectorFont", "rna_Main_vfont_begin", "Vector Fonts", "Vector font datablocks.", (char *)RNA_def_main_vfonts},
+ {"textures", "Texture", "rna_Main_tex_begin", "Textures", "Texture datablocks.", (char *)RNA_def_main_textures},
+ {"brushes", "Brush", "rna_Main_brush_begin", "Brushes", "Brush datablocks.", (char *)RNA_def_main_brushes},
+ {"worlds", "World", "rna_Main_world_begin", "Worlds", "World datablocks.", (char *)RNA_def_main_worlds},
+ {"groups", "Group", "rna_Main_group_begin", "Groups", "Group datablocks.", (char *)RNA_def_main_groups},
+/* {"keys", "Key", "rna_Main_key_begin", "Keys", "Key datablocks.", NULL}, */
+ {"scripts", "ID", "rna_Main_script_begin", "Scripts", "Script datablocks (DEPRECATED).", (char *)NULL},
+ {"texts", "Text", "rna_Main_text_begin", "Texts", "Text datablocks.", (char *)RNA_def_main_texts},
+ {"sounds", "Sound", "rna_Main_sound_begin", "Sounds", "Sound datablocks.", (char *)RNA_def_main_sounds},
+ {"armatures", "Armature", "rna_Main_armature_begin", "Armatures", "Armature datablocks.", (char *)RNA_def_main_armatures},
+ {"actions", "Action", "rna_Main_action_begin", "Actions", "Action datablocks.", (char *)RNA_def_main_actions},
+ {"particles", "ParticleSettings", "rna_Main_particle_begin", "Particles", "Particle datablocks.", (char *)RNA_def_main_particles},
+ {"gpencil", "GreasePencil", "rna_Main_gpencil_begin", "Grease Pencil", "Grease Pencil datablocks.", (char *)RNA_def_main_gpencil},
+ {NULL, NULL, NULL, NULL, NULL, NULL}};
- const char *lists[][5]= {
- {"cameras", "Camera", "rna_Main_camera_begin", "Cameras", "Camera datablocks."},
- {"scenes", "Scene", "rna_Main_scene_begin", "Scenes", "Scene datablocks."},
- {"objects", "Object", "rna_Main_object_begin", "Objects", "Object datablocks."},
- {"materials", "Material", "rna_Main_mat_begin", "Materials", "Material datablocks."},
- {"nodegroups", "NodeTree", "rna_Main_nodetree_begin", "Node Groups", "Node group datablocks."},
- {"meshes", "Mesh", "rna_Main_mesh_begin", "Meshes", "Mesh datablocks."}, // "add_mesh", "remove_mesh"
- {"lamps", "Lamp", "rna_Main_lamp_begin", "Lamps", "Lamp datablocks."},
- {"libraries", "Library", "rna_Main_library_begin", "Libraries", "Library datablocks."},
- {"screens", "Screen", "rna_Main_screen_begin", "Screens", "Screen datablocks."},
- {"windowmanagers", "WindowManager", "rna_Main_wm_begin", "Window Managers", "Window manager datablocks."},
- {"images", "Image", "rna_Main_image_begin", "Images", "Image datablocks."},
- {"lattices", "Lattice", "rna_Main_latt_begin", "Lattices", "Lattice datablocks."},
- {"curves", "Curve", "rna_Main_curve_begin", "Curves", "Curve datablocks."} ,
- {"metaballs", "MetaBall", "rna_Main_mball_begin", "Metaballs", "Metaball datablocks."},
- {"vfonts", "VectorFont", "rna_Main_vfont_begin", "Vector Fonts", "Vector font datablocks."},
- {"textures", "Texture", "rna_Main_tex_begin", "Textures", "Texture datablocks."},
- {"brushes", "Brush", "rna_Main_brush_begin", "Brushes", "Brush datablocks."},
- {"worlds", "World", "rna_Main_world_begin", "Worlds", "World datablocks."},
- {"groups", "Group", "rna_Main_group_begin", "Groups", "Group datablocks."},
-/* {"keys", "Key", "rna_Main_key_begin", "Keys", "Key datablocks."}, */
- {"scripts", "ID", "rna_Main_script_begin", "Scripts", "Script datablocks (DEPRECATED)."},
- {"texts", "Text", "rna_Main_text_begin", "Texts", "Text datablocks."},
- {"sounds", "Sound", "rna_Main_sound_begin", "Sounds", "Sound datablocks."},
- {"armatures", "Armature", "rna_Main_armature_begin", "Armatures", "Armature datablocks."},
- {"actions", "Action", "rna_Main_action_begin", "Actions", "Action datablocks."},
- {"particles", "ParticleSettings", "rna_Main_particle_begin", "Particles", "Particle datablocks."},
- {"gpencil", "GreasePencil", "rna_Main_gpencil_begin", "Grease Pencil", "Grease Pencil datablocks."},
- {NULL, NULL, NULL, NULL, NULL}};
int i;
srna= RNA_def_struct(brna, "Main", NULL);
@@ -287,6 +291,11 @@ void RNA_def_main(BlenderRNA *brna)
RNA_def_property_struct_type(prop, lists[i][1]);
RNA_def_property_collection_funcs(prop, lists[i][2], "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0);
RNA_def_property_ui_text(prop, lists[i][3], lists[i][4]);
+
+ /* collection functions */
+ func= (CollectionDefFunc *)lists[i][5];
+ if(func)
+ func(brna, prop);
}
RNA_api_main(srna);
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index 5069bbd6ae6..ecaf6f813da 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -43,108 +43,143 @@
#include "BKE_material.h"
#include "BKE_image.h"
#include "BKE_texture.h"
+#include "BKE_scene.h"
#include "DNA_armature_types.h"
+#include "DNA_camera_types.h"
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
-static Mesh *rna_Main_add_mesh(Main *bmain, char *name)
+static Tex *rna_Main_add_texture(Main *bmain, char *name)
{
- Mesh *me= add_mesh(name);
- me->id.us--;
- return me;
+ return add_texture(name);
}
-static void rna_Main_remove_mesh(Main *bmain, ReportList *reports, Mesh *me)
+/* TODO: remove texture? */
+
+static Image *rna_Main_add_image(Main *bmain, char *filename)
{
- if(me->id.us == 0)
- free_libblock(&bmain->mesh, me);
- else
- BKE_report(reports, RPT_ERROR, "Mesh must have zero users to be removed.");
-
- /* XXX python now has invalid pointer? */
+ return BKE_add_image_file(filename, 0);
}
-static void rna_Main_remove_armature(Main *bmain, ReportList *reports, bArmature *arm)
+static Camera *rna_Main_cameras_new(bContext *C, char* name)
{
- if(arm->id.us == 0)
- free_libblock(&bmain->armature, arm);
+ return add_camera(name);
+}
+static void rna_Main_cameras_remove(bContext *C, ReportList *reports, struct Camera *camera)
+{
+ Main *bmain= CTX_data_main(C);
+ if(camera->id.us == 0)
+ free_libblock(&bmain->camera, camera);
else
- BKE_report(reports, RPT_ERROR, "Armature must have zero users to be removed.");
+ BKE_reportf(reports, RPT_ERROR, "Camera \"%s\" must have zero users to be removed, found %d.", camera->id.name+2, camera->id.us);
/* XXX python now has invalid pointer? */
}
-static bArmature *rna_Main_add_armature(Main *bmain, char *name)
+static Scene *rna_Main_scenes_new(bContext *C, char* name)
{
- bArmature *arm= add_armature(name);
- arm->id.us--;
- return arm;
-}
-
-static Lamp *rna_Main_add_lamp(Main *bmain, char *name)
-{
- Lamp *la= add_lamp(name);
- la->id.us--;
- return la;
+ return add_scene(name);
}
-
-/*
-static void rna_Main_remove_lamp(Main *bmain, ReportList *reports, Lamp *la)
+static void rna_Main_scenes_remove(bContext *C, ReportList *reports, struct Scene *scene)
{
- if(la->id.us == 0)
- free_libblock(&main->lamp, la);
- else
- BKE_report(reports, RPT_ERROR, "Lamp must have zero users to be removed.");
+ Main *bmain= CTX_data_main(C);
+ free_libblock(&bmain->scene, scene);
}
-*/
-static Object* rna_Main_add_object(Main *bmain, int type, char *name)
+static Object *rna_Main_objects_new(bContext *C, char* name, int type)
{
Object *ob= add_only_object(type, name);
ob->id.us--;
return ob;
}
+static void rna_Main_objects_remove(bContext *C, ReportList *reports, struct Object *object)
+{
+ /*
+ NOTE: the following example shows when this function should _not_ be called
-/*
- NOTE: the following example shows when this function should _not_ be called
+ ob = bpy.data.add_object()
+ scene.add_object(ob)
- ob = bpy.data.add_object()
- scene.add_object(ob)
+ # ob is freed here
+ scene.remove_object(ob)
- # ob is freed here
- scene.remove_object(ob)
+ # don't do this since ob is already freed!
+ bpy.data.remove_object(ob)
+ */
+ Main *bmain= CTX_data_main(C);
+ if(object->id.us == 0)
+ free_libblock(&bmain->object, object);
+ else
+ BKE_reportf(reports, RPT_ERROR, "Object \"%s\" must have zero users to be removed, found %d.", object->id.name+2, object->id.us);
+}
- # don't do this since ob is already freed!
- bpy.data.remove_object(ob)
-*/
-static void rna_Main_remove_object(Main *bmain, ReportList *reports, Object *ob)
+static Material *rna_Main_materials_new(bContext *C, char* name)
{
- if(ob->id.us == 0)
- free_libblock(&bmain->object, ob);
+ return add_material(name);
+}
+static void rna_Main_materials_remove(bContext *C, ReportList *reports, struct Material *material)
+{
+ Main *bmain= CTX_data_main(C);
+ if(material->id.us == 0)
+ free_libblock(&bmain->mat, material);
else
- BKE_report(reports, RPT_ERROR, "Object must have zero users to be removed.");
+ BKE_reportf(reports, RPT_ERROR, "Material \"%s\" must have zero users to be removed, found %d.", material->id.name+2, material->id.us);
+
+ /* XXX python now has invalid pointer? */
}
-static Material *rna_Main_add_material(Main *bmain, char *name)
+static Mesh *rna_Main_meshes_new(bContext *C, char* name)
{
- return add_material(name);
+ Mesh *me= add_mesh(name);
+ me->id.us--;
+ return me;
}
+static void rna_Main_meshes_remove(bContext *C, ReportList *reports, Mesh *mesh)
+{
+ Main *bmain= CTX_data_main(C);
+ if(mesh->id.us == 0)
+ free_libblock(&bmain->mesh, mesh);
+ else
+ BKE_reportf(reports, RPT_ERROR, "Mesh \"%s\" must have zero users to be removed, found %d.", mesh->id.name+2, mesh->id.us);
-/* TODO: remove material? */
+ /* XXX python now has invalid pointer? */
+}
-struct Tex *rna_Main_add_texture(Main *bmain, char *name)
+static Lamp *rna_Main_lamps_new(bContext *C, char* name)
{
- return add_texture(name);
+ Lamp *lamp= add_lamp(name);
+ lamp->id.us--;
+ return lamp;
}
+static void rna_Main_lamps_remove(bContext *C, ReportList *reports, Lamp *lamp)
+{
+ Main *bmain= CTX_data_main(C);
+ if(lamp->id.us == 0)
+ free_libblock(&bmain->lamp, lamp);
+ else
+ BKE_reportf(reports, RPT_ERROR, "Lamp \"%s\" must have zero users to be removed, found %d.", lamp->id.name+2, lamp->id.us);
-/* TODO: remove texture? */
+ /* XXX python now has invalid pointer? */
+}
-struct Image *rna_Main_add_image(Main *bmain, char *filename)
+static bArmature *rna_Main_armatures_new(bContext *C, char* name)
{
- return BKE_add_image_file(filename, 0);
+ bArmature *arm= add_armature(name);
+ arm->id.us--;
+ return arm;
+}
+static void rna_Main_armatures_remove(bContext *C, ReportList *reports, bArmature *arm)
+{
+ Main *bmain= CTX_data_main(C);
+ if(arm->id.us == 0)
+ free_libblock(&bmain->armature, arm);
+ else
+ BKE_reportf(reports, RPT_ERROR, "Armature \"%s\" must have zero users to be removed, found %d.", arm->id.name+2, arm->id.us);
+
+ /* XXX python now has invalid pointer? */
}
#else
@@ -154,73 +189,281 @@ void RNA_api_main(StructRNA *srna)
FunctionRNA *func;
PropertyRNA *parm;
- func= RNA_def_function(srna, "add_object", "rna_Main_add_object");
- RNA_def_function_ui_description(func, "Add a new object.");
- parm= RNA_def_enum(func, "type", object_type_items, 0, "", "Type of Object.");
+ func= RNA_def_function(srna, "add_texture", "rna_Main_add_texture");
+ RNA_def_function_ui_description(func, "Add a new texture.");
+ parm= RNA_def_string(func, "name", "Tex", 0, "", "New name for the datablock."); /* optional */
+ parm= RNA_def_pointer(func, "texture", "Texture", "", "New texture.");
+ RNA_def_function_return(func, parm);
+
+ func= RNA_def_function(srna, "add_image", "rna_Main_add_image");
+ RNA_def_function_ui_description(func, "Add a new image.");
+ parm= RNA_def_string(func, "filename", "", 0, "", "Filename to load image from.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_pointer(func, "image", "Image", "", "New image.");
+ RNA_def_function_return(func, parm);
+
+}
+
+void RNA_def_main_cameras(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ RNA_def_property_srna(cprop, "MainCameras");
+ srna= RNA_def_struct(brna, "MainCameras", NULL);
+ RNA_def_struct_sdna(srna, "Camera");
+ RNA_def_struct_ui_text(srna, "Main Cameras", "Collection of cameras.");
+
+ func= RNA_def_function(srna, "new", "rna_Main_cameras_new");
+ RNA_def_function_flag(func, FUNC_NO_SELF|FUNC_USE_CONTEXT);
+ RNA_def_function_ui_description(func, "Add a new camera to the main database");
+ parm= RNA_def_string(func, "name", "Camera", 0, "", "New name for the datablock.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ /* return type */
+ parm= RNA_def_pointer(func, "camera", "Camera", "", "New camera datablock.");
+ RNA_def_function_return(func, parm);
+
+ func= RNA_def_function(srna, "remove", "rna_Main_cameras_remove");
+ RNA_def_function_flag(func, FUNC_NO_SELF|FUNC_USE_CONTEXT|FUNC_USE_REPORTS);
+ RNA_def_function_ui_description(func, "Remove a camera from the current blendfile.");
+ parm= RNA_def_pointer(func, "camera", "Camera", "", "Camera to remove.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+}
+
+void RNA_def_main_scenes(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ RNA_def_property_srna(cprop, "MainScenes");
+ srna= RNA_def_struct(brna, "MainScenes", NULL);
+ RNA_def_struct_sdna(srna, "Scene");
+ RNA_def_struct_ui_text(srna, "Main Scenes", "Collection of scenes.");
+
+ func= RNA_def_function(srna, "new", "rna_Main_scenes_new");
+ RNA_def_function_flag(func, FUNC_NO_SELF|FUNC_USE_CONTEXT);
+ RNA_def_function_ui_description(func, "Add a new scene to the main database");
+ parm= RNA_def_string(func, "name", "Scene", 0, "", "New name for the datablock.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ /* return type */
+ parm= RNA_def_pointer(func, "scene", "Scene", "", "New scene datablock.");
+ RNA_def_function_return(func, parm);
+
+ func= RNA_def_function(srna, "remove", "rna_Main_scenes_remove");
+ RNA_def_function_flag(func, FUNC_NO_SELF|FUNC_USE_CONTEXT|FUNC_USE_REPORTS);
+ parm= RNA_def_pointer(func, "scene", "Scene", "", "Scene to remove.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_function_ui_description(func, "Remove a scene from the current blendfile.");
RNA_def_property_flag(parm, PROP_REQUIRED);
+}
+
+void RNA_def_main_objects(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ RNA_def_property_srna(cprop, "MainObjects");
+ srna= RNA_def_struct(brna, "MainObjects", NULL);
+ RNA_def_struct_sdna(srna, "Object");
+ 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_NO_SELF|FUNC_USE_CONTEXT);
+ 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_pointer(func, "object", "Object", "", "New object.");
+ parm= RNA_def_enum(func, "type", object_type_items, 0, "", "Type of Object.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+
+ /* return type */
+ parm= RNA_def_pointer(func, "object", "Object", "", "New object datablock.");
RNA_def_function_return(func, parm);
- func= RNA_def_function(srna, "remove_object", "rna_Main_remove_object");
- RNA_def_function_flag(func, FUNC_USE_REPORTS);
- RNA_def_function_ui_description(func, "Remove an object if it has zero users.");
+ func= RNA_def_function(srna, "remove", "rna_Main_objects_remove");
+ RNA_def_function_flag(func, FUNC_NO_SELF|FUNC_USE_CONTEXT|FUNC_USE_REPORTS);
parm= RNA_def_pointer(func, "object", "Object", "", "Object to remove.");
RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_function_ui_description(func, "Remove a object from the current blendfile.");
+}
- func= RNA_def_function(srna, "add_mesh", "rna_Main_add_mesh");
- RNA_def_function_ui_description(func, "Add a new mesh.");
- parm= RNA_def_string(func, "name", "Mesh", 0, "", "New name for the datablock.");
+void RNA_def_main_materials(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ RNA_def_property_srna(cprop, "MainMaterials");
+ srna= RNA_def_struct(brna, "MainMaterials", NULL);
+ RNA_def_struct_sdna(srna, "Material");
+ RNA_def_struct_ui_text(srna, "Main Material", "Collection of materials.");
+
+ func= RNA_def_function(srna, "new", "rna_Main_materials_new");
+ RNA_def_function_flag(func, FUNC_NO_SELF|FUNC_USE_CONTEXT);
+ RNA_def_function_ui_description(func, "Add a new material to the main database");
+ parm= RNA_def_string(func, "name", "Material", 0, "", "New name for the datablock.");
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm= RNA_def_pointer(func, "mesh", "Mesh", "", "New mesh.");
+ /* return type */
+ parm= RNA_def_pointer(func, "material", "Material", "", "New material datablock.");
RNA_def_function_return(func, parm);
- func= RNA_def_function(srna, "remove_mesh", "rna_Main_remove_mesh");
- RNA_def_function_flag(func, FUNC_USE_REPORTS);
- RNA_def_function_ui_description(func, "Remove a mesh if it has zero users.");
- parm= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh to remove.");
+ func= RNA_def_function(srna, "remove", "rna_Main_materials_remove");
+ RNA_def_function_flag(func, FUNC_NO_SELF|FUNC_USE_CONTEXT|FUNC_USE_REPORTS);
+ RNA_def_function_ui_description(func, "Remove a material from the current blendfile.");
+ parm= RNA_def_pointer(func, "material", "Material", "", "Material to remove.");
RNA_def_property_flag(parm, PROP_REQUIRED);
+}
+void RNA_def_main_node_groups(BlenderRNA *brna, PropertyRNA *cprop)
+{
- func= RNA_def_function(srna, "add_armature", "rna_Main_add_armature");
- RNA_def_function_ui_description(func, "Add a new armature.");
- parm= RNA_def_string(func, "name", "Armature", 0, "", "New name for the datablock.");
+}
+void RNA_def_main_meshes(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ RNA_def_property_srna(cprop, "MainMeshes");
+ srna= RNA_def_struct(brna, "MainMeshes", NULL);
+ RNA_def_struct_sdna(srna, "Mesh");
+ RNA_def_struct_ui_text(srna, "Main Meshes", "Collection of meshes.");
+
+ func= RNA_def_function(srna, "new", "rna_Main_meshes_new");
+ RNA_def_function_flag(func, FUNC_NO_SELF|FUNC_USE_CONTEXT);
+ RNA_def_function_ui_description(func, "Add a new mesh to the main database");
+ parm= RNA_def_string(func, "name", "Mesh", 0, "", "New name for the datablock.");
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm= RNA_def_pointer(func, "armature", "Armature", "", "New armature.");
+ /* return type */
+ parm= RNA_def_pointer(func, "mesh", "Mesh", "", "New mesh datablock.");
RNA_def_function_return(func, parm);
- func= RNA_def_function(srna, "remove_armature", "rna_Main_remove_armature");
- RNA_def_function_flag(func, FUNC_USE_REPORTS);
- RNA_def_function_ui_description(func, "Remove an armature if it has zero users.");
- parm= RNA_def_pointer(func, "armature", "Armature", "", "Armature to remove.");
+ func= RNA_def_function(srna, "remove", "rna_Main_meshes_remove");
+ RNA_def_function_flag(func, FUNC_NO_SELF|FUNC_USE_CONTEXT|FUNC_USE_REPORTS);
+ RNA_def_function_ui_description(func, "Remove a mesh from the current blendfile.");
+ parm= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh to remove.");
RNA_def_property_flag(parm, PROP_REQUIRED);
+}
+void RNA_def_main_lamps(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ RNA_def_property_srna(cprop, "MainLamps");
+ srna= RNA_def_struct(brna, "MainLamps", NULL);
+ RNA_def_struct_sdna(srna, "Lamp");
+ RNA_def_struct_ui_text(srna, "Main Lamps", "Collection of lamps.");
- func= RNA_def_function(srna, "add_lamp", "rna_Main_add_lamp");
- RNA_def_function_ui_description(func, "Add a new lamp.");
+ func= RNA_def_function(srna, "new", "rna_Main_lamps_new");
+ RNA_def_function_flag(func, FUNC_NO_SELF|FUNC_USE_CONTEXT);
+ RNA_def_function_ui_description(func, "Add a new lamp to the main database");
parm= RNA_def_string(func, "name", "Lamp", 0, "", "New name for the datablock.");
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm= RNA_def_pointer(func, "mesh", "Lamp", "", "New lamp.");
+ /* return type */
+ parm= RNA_def_pointer(func, "lamp", "Lamp", "", "New lamp datablock.");
RNA_def_function_return(func, parm);
- func= RNA_def_function(srna, "add_material", "rna_Main_add_material");
- RNA_def_function_ui_description(func, "Add a new material.");
- parm= RNA_def_string(func, "name", "Material", 0, "", "New name for the datablock."); /* optional */
- parm= RNA_def_pointer(func, "material", "Material", "", "New material.");
- RNA_def_function_return(func, parm);
+ func= RNA_def_function(srna, "remove", "rna_Main_lamps_remove");
+ RNA_def_function_flag(func, FUNC_NO_SELF|FUNC_USE_CONTEXT|FUNC_USE_REPORTS);
+ RNA_def_function_ui_description(func, "Remove a lamp from the current blendfile.");
+ parm= RNA_def_pointer(func, "lamp", "Lamp", "", "Lamp to remove.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+}
+void RNA_def_main_libraries(BlenderRNA *brna, PropertyRNA *cprop)
+{
- func= RNA_def_function(srna, "add_texture", "rna_Main_add_texture");
- RNA_def_function_ui_description(func, "Add a new texture.");
- parm= RNA_def_string(func, "name", "Tex", 0, "", "New name for the datablock."); /* optional */
- parm= RNA_def_pointer(func, "texture", "Texture", "", "New texture.");
- RNA_def_function_return(func, parm);
+}
+void RNA_def_main_screens(BlenderRNA *brna, PropertyRNA *cprop)
+{
- func= RNA_def_function(srna, "add_image", "rna_Main_add_image");
- RNA_def_function_ui_description(func, "Add a new image.");
- parm= RNA_def_string(func, "filename", "", 0, "", "Filename to load image from.");
+}
+void RNA_def_main_window_managers(BlenderRNA *brna, PropertyRNA *cprop)
+{
+
+}
+void RNA_def_main_images(BlenderRNA *brna, PropertyRNA *cprop)
+{
+
+}
+void RNA_def_main_lattices(BlenderRNA *brna, PropertyRNA *cprop)
+{
+
+}
+void RNA_def_main_curves(BlenderRNA *brna, PropertyRNA *cprop)
+{
+
+}
+void RNA_def_main_metaballs(BlenderRNA *brna, PropertyRNA *cprop)
+{
+
+}
+void RNA_def_main_vfonts(BlenderRNA *brna, PropertyRNA *cprop)
+{
+
+}
+void RNA_def_main_textures(BlenderRNA *brna, PropertyRNA *cprop)
+{
+
+}
+void RNA_def_main_brushes(BlenderRNA *brna, PropertyRNA *cprop)
+{
+
+}
+void RNA_def_main_worlds(BlenderRNA *brna, PropertyRNA *cprop)
+{
+
+}
+void RNA_def_main_groups(BlenderRNA *brna, PropertyRNA *cprop)
+{
+
+}
+void RNA_def_main_texts(BlenderRNA *brna, PropertyRNA *cprop)
+{
+
+}
+void RNA_def_main_sounds(BlenderRNA *brna, PropertyRNA *cprop)
+{
+
+}
+void RNA_def_main_armatures(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ RNA_def_property_srna(cprop, "MainArmatures");
+ srna= RNA_def_struct(brna, "MainArmatures", NULL);
+ RNA_def_struct_sdna(srna, "Armature");
+ RNA_def_struct_ui_text(srna, "Main Armatures", "Collection of armatures.");
+
+ func= RNA_def_function(srna, "new", "rna_Main_armatures_new");
+ RNA_def_function_flag(func, FUNC_NO_SELF|FUNC_USE_CONTEXT);
+ RNA_def_function_ui_description(func, "Add a new armature to the main database");
+ parm= RNA_def_string(func, "name", "Armature", 0, "", "New name for the datablock.");
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm= RNA_def_pointer(func, "image", "Image", "", "New image.");
+ /* return type */
+ parm= RNA_def_pointer(func, "armature", "Armature", "", "New armature datablock.");
RNA_def_function_return(func, parm);
+ func= RNA_def_function(srna, "remove", "rna_Main_armatures_remove");
+ RNA_def_function_flag(func, FUNC_NO_SELF|FUNC_USE_CONTEXT|FUNC_USE_REPORTS);
+ RNA_def_function_ui_description(func, "Remove a armature from the current blendfile.");
+ parm= RNA_def_pointer(func, "armature", "Armature", "", "Armature to remove.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+}
+void RNA_def_main_actions(BlenderRNA *brna, PropertyRNA *cprop)
+{
+
+}
+void RNA_def_main_particles(BlenderRNA *brna, PropertyRNA *cprop)
+{
+
+}
+void RNA_def_main_gpencil(BlenderRNA *brna, PropertyRNA *cprop)
+{
+
}
#endif
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index a5c1d8d5f57..b69e5130c0f 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -1023,10 +1023,11 @@ static void rna_def_material_volume(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Diffusion", "Diffusion factor, the strength of the blurring effect");
RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "ms_spread", PROP_INT, PROP_NONE);
- RNA_def_property_int_sdna(prop, NULL, "ms_steps");
- RNA_def_property_range(prop, 0, 1024);
- RNA_def_property_ui_text(prop, "Spread", "Simulation steps, the effective distance over which the light is diffused");
+ prop= RNA_def_property(srna, "ms_spread", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "ms_spread");
+ RNA_def_property_range(prop, 0, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.0f, 1.0f, 1, 3);
+ RNA_def_property_ui_text(prop, "Spread", "Proportional distance over which the light is diffused");
RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "ms_intensity", PROP_FLOAT, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index 528544d09dd..9f317ec6be1 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -75,10 +75,17 @@ void rna_Mesh_update_draw(Main *bmain, Scene *scene, PointerRNA *ptr)
static void rna_MeshVertex_normal_get(PointerRNA *ptr, float *value)
{
MVert *mvert= (MVert*)ptr->data;
+ normal_short_to_float_v3(value, mvert->no);
+}
+
+static void rna_MeshVertex_normal_set(PointerRNA *ptr, const float *value)
+{
+ MVert *mvert= (MVert*)ptr->data;
+ float no[3];
- value[0]= mvert->no[0]/32767.0f;
- value[1]= mvert->no[1]/32767.0f;
- value[2]= mvert->no[2]/32767.0f;
+ copy_v3_v3(no, value);
+ normalize_v3(no);
+ normal_float_to_short_v3(mvert->no, no);
}
static float rna_MeshVertex_bevel_weight_get(PointerRNA *ptr)
@@ -1027,9 +1034,8 @@ static void rna_def_mvert(BlenderRNA *brna)
prop= RNA_def_property(srna, "normal", PROP_FLOAT, PROP_DIRECTION);
RNA_def_property_float_sdna(prop, NULL, "no");
- RNA_def_property_float_funcs(prop, "rna_MeshVertex_normal_get", NULL, NULL);
+ RNA_def_property_float_funcs(prop, "rna_MeshVertex_normal_get", "rna_MeshVertex_normal_set", NULL);
RNA_def_property_ui_text(prop, "Normal", "Vertex Normal");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop= RNA_def_property(srna, "selected", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SELECT);
@@ -1352,6 +1358,12 @@ static void rna_def_mtface(BlenderRNA *brna)
RNA_def_property_float_funcs(prop, "rna_MeshTextureFace_uv_get", "rna_MeshTextureFace_uv_set", NULL);
RNA_def_property_ui_text(prop, "UV", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+
+ prop= RNA_def_property(srna, "uv_raw", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_multi_array(prop, 2, uv_dim);
+ RNA_def_property_float_sdna(prop, NULL, "uv");
+ RNA_def_property_ui_text(prop, "UV", "Fixed size UV coordinates array");
+
}
static void rna_def_msticky(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c
index 52ff98f66f0..4fba65b4db8 100644
--- a/source/blender/makesrna/intern/rna_mesh_api.c
+++ b/source/blender/makesrna/intern/rna_mesh_api.c
@@ -43,6 +43,11 @@ static void rna_Mesh_uv_texture_add(struct Mesh *me, struct bContext *C)
ED_mesh_uv_texture_add(C, NULL, NULL, me);
}
+static void rna_Mesh_vertex_color_add(struct Mesh *me, struct bContext *C)
+{
+ ED_mesh_color_add(C, NULL, NULL, me);
+}
+
#else
void RNA_api_mesh(StructRNA *srna)
@@ -68,6 +73,10 @@ void RNA_api_mesh(StructRNA *srna)
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
RNA_def_function_ui_description(func, "Add a UV texture layer to Mesh.");
+ func= RNA_def_function(srna, "add_vertex_color", "rna_Mesh_vertex_color_add");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+ RNA_def_function_ui_description(func, "Add a vertex color layer to Mesh.");
+
func= RNA_def_function(srna, "calc_normals", "ED_mesh_calc_normals");
RNA_def_function_ui_description(func, "Calculate vertex normals.");
@@ -79,6 +88,8 @@ void RNA_api_mesh(StructRNA *srna)
RNA_def_function_ui_description(func, "Add a new material to Mesh.");
parm= RNA_def_pointer(func, "material", "Material", "", "Material to add.");
RNA_def_property_flag(parm, PROP_REQUIRED);
+
+
}
#endif
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index d1e73d6add3..9922f099cd5 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -1077,12 +1077,6 @@ static void def_cmp_render_layers(StructRNA *srna)
RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Node_scene_layer_itemf");
RNA_def_property_ui_text(prop, "Layer", "");
RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
-
- /* TODO: comments indicate this might be a hack */
- prop = RNA_def_property(srna, "re_render", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "custom2", 1);
- RNA_def_property_ui_text(prop, "Re-render", "");
- RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
}
static void def_cmp_output_file(StructRNA *srna)
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index a670fb244f6..a1109e01d50 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -930,7 +930,7 @@ static PointerRNA rna_Object_active_shape_key_get(PointerRNA *ptr)
return PointerRNA_NULL;
kb= BLI_findlink(&key->block, ob->shapenr-1);
- RNA_pointer_create(&key->id, &RNA_ShapeKey, kb, &keyptr);
+ RNA_pointer_create((ID *)ob->data, &RNA_ShapeKey, kb, &keyptr);
return keyptr;
}
@@ -1559,7 +1559,7 @@ static void rna_def_object(BlenderRNA *brna)
* having a single one is better for Keyframing and other property-management situations...
*/
prop= RNA_def_property(srna, "rotation_axis_angle", PROP_FLOAT, PROP_AXISANGLE);
- RNA_def_property_array(prop, 4); // TODO: maybe we'll need to define the 'default value' getter too...
+ RNA_def_property_array(prop, 4);
RNA_def_property_float_funcs(prop, "rna_Object_rotation_axis_angle_get", "rna_Object_rotation_axis_angle_set", NULL);
RNA_def_property_editable_array_func(prop, "rna_Object_rotation_4d_editable");
RNA_def_property_float_array_default(prop, default_axisAngle);
@@ -1771,6 +1771,9 @@ static void rna_def_object(BlenderRNA *brna)
/* anim */
rna_def_animdata_common(srna);
+ rna_def_animviz_common(srna);
+ rna_def_motionpath_common(srna);
+
/* duplicates */
prop= RNA_def_property(srna, "track_override_parent", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "transflag", OB_POWERTRACK);
@@ -1788,18 +1791,18 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Dupli Type", "If not None, object duplication method to use.");
RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_dependency_update");
- prop= RNA_def_property(srna, "dupli_frames_no_speed", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "transflag", OB_DUPLINOSPEED);
- RNA_def_property_ui_text(prop, "Dupli Frames No Speed", "Set dupliframes to still, regardless of frame.");
+ prop= RNA_def_property(srna, "use_dupli_frames_speed", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "transflag", OB_DUPLINOSPEED);
+ RNA_def_property_ui_text(prop, "Dupli Frames Speed", "Set dupliframes to use the frame."); // TODO, better descriptio!
RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_update");
- prop= RNA_def_property(srna, "dupli_verts_rotation", PROP_BOOLEAN, PROP_NONE);
+ prop= RNA_def_property(srna, "use_dupli_verts_rotation", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "transflag", OB_DUPLIROT);
RNA_def_property_ui_text(prop, "Dupli Verts Rotation", "Rotate dupli according to vertex normal.");
RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
- prop= RNA_def_property(srna, "dupli_faces_inherit_scale", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "transflag", OB_DUPLIROT);
+ prop= RNA_def_property(srna, "use_dupli_faces_scale", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "transflag", OB_DUPLIFACES_SCALE);
RNA_def_property_ui_text(prop, "Dupli Faces Inherit Scale", "Scale dupli based on face size.");
RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_update");
diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index 481e92d1ac9..8379ae7995d 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -49,6 +49,7 @@
#include "BKE_object.h"
#include "BKE_mesh.h"
#include "BKE_DerivedMesh.h"
+#include "BKE_bvhutils.h"
#include "BKE_customdata.h"
#include "BKE_anim.h"
@@ -309,19 +310,23 @@ static Object *rna_Object_find_armature(Object *ob)
return ob_arm;
}
-static KeyBlock *rna_Object_add_shape_key(Object *ob, bContext *C, ReportList *reports, char *name, int from_mix)
+static PointerRNA rna_Object_add_shape_key(Object *ob, bContext *C, ReportList *reports, char *name, int from_mix)
{
Scene *scene= CTX_data_scene(C);
KeyBlock *kb= NULL;
if((kb=object_insert_shape_key(scene, ob, name, from_mix))) {
+ PointerRNA keyptr;
+
+ RNA_pointer_create((ID *)ob->data, &RNA_ShapeKey, kb, &keyptr);
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+
+ return keyptr;
}
else {
BKE_reportf(reports, RPT_ERROR, "Object \"%s\"does not support shapes.", ob->id.name+2);
+ return PointerRNA_NULL;
}
-
- return kb;
}
int rna_Object_is_visible(Object *ob, bContext *C)
@@ -365,6 +370,45 @@ static void rna_Mesh_assign_verts_to_group(Object *ob, bDeformGroup *group, int
}
*/
+void rna_Object_ray_cast(Object *ob, ReportList *reports, float ray_start[3], float ray_end[3], float r_location[3], float r_normal[3], int *index)
+{
+ BVHTreeFromMesh treeData;
+
+ if(ob->derivedFinal==NULL) {
+ BKE_reportf(reports, RPT_ERROR, "object \"%s\" has no mesh data to be used for ray casting.", ob->id.name+2);
+ return;
+ }
+
+ /* no need to managing allocation or freeing of the BVH data. this is generated and freed as needed */
+ bvhtree_from_mesh_faces(&treeData, ob->derivedFinal, 0.0f, 4, 6);
+
+ if(treeData.tree==NULL) {
+ BKE_reportf(reports, RPT_ERROR, "object \"%s\" could not create internal data for ray casting.", ob->id.name+2);
+ return;
+ }
+ else {
+ BVHTreeRayHit hit;
+ float ray_nor[3], dist;
+ sub_v3_v3v3(ray_nor, ray_end, ray_start);
+
+ dist= hit.dist = normalize_v3(ray_nor);
+ hit.index = -1;
+
+ if(BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_nor, 0.0f, &hit, treeData.raycast_callback, &treeData) != -1) {
+ if(hit.dist<=dist) {
+ copy_v3_v3(r_location, hit.co);
+ copy_v3_v3(r_normal, hit.no);
+ *index= hit.index;
+ return;
+ }
+ }
+ }
+
+ zero_v3(r_location);
+ zero_v3(r_normal);
+ *index= -1;
+}
+
#else
void RNA_api_object(StructRNA *srna)
@@ -436,8 +480,32 @@ void RNA_api_object(StructRNA *srna)
parm= RNA_def_string(func, "name", "Key", 0, "", "Unique name for the new keylock."); /* optional */
parm= RNA_def_boolean(func, "from_mix", 1, "", "Create new shape from existing mix of shapes.");
parm= RNA_def_pointer(func, "key", "ShapeKey", "", "New shape keyblock.");
+ RNA_def_property_flag(parm, PROP_RNAPTR);
RNA_def_function_return(func, parm);
+ /* Ray Cast */
+ func= RNA_def_function(srna, "ray_cast", "rna_Object_ray_cast");
+ RNA_def_function_ui_description(func, "Cast a ray onto in object space.");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+
+ /* ray start and end */
+ parm= RNA_def_float_vector(func, "start", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4);
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_float_vector(func, "end", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4);
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+
+ /* return location and normal */
+ parm= RNA_def_float_vector(func, "location", 3, NULL, -FLT_MAX, FLT_MAX, "Location", "The hit location of this ray cast", -1e4, 1e4);
+ RNA_def_property_flag(parm, PROP_THICK_WRAP);
+ RNA_def_function_return_mark(func, parm);
+ parm= RNA_def_float_vector(func, "normal", 3, NULL, -FLT_MAX, FLT_MAX, "Normal", "The face normal at the ray cast hit location", -1e4, 1e4);
+ RNA_def_property_flag(parm, PROP_THICK_WRAP);
+ RNA_def_function_return_mark(func, parm);
+
+ parm= RNA_def_int(func, "index", 0, 0, 0, "", "The face index, -1 when no intersection is found.", 0, 0);
+ RNA_def_function_return_mark(func, parm);
+
+
/* DAG */
func= RNA_def_function(srna, "make_display_list", "rna_Object_make_display_list");
RNA_def_function_ui_description(func, "Update object's display data."); /* XXX describe better */
diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c
index f4ff066f2b4..0eb4f9b9da0 100644
--- a/source/blender/makesrna/intern/rna_object_force.c
+++ b/source/blender/makesrna/intern/rna_object_force.c
@@ -810,6 +810,12 @@ static void rna_def_collision(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", PDEFLE_KILL_PART);
RNA_def_property_ui_text(prop, "Kill Particles", "Kill collided particles");
RNA_def_property_update(prop, 0, "rna_CollisionSettings_update");
+
+ prop= RNA_def_property(srna, "stickness", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "pdef_stickness");
+ RNA_def_property_range(prop, 0.0f, 10.0f);
+ RNA_def_property_ui_text(prop, "Stickness", "Amount of stickness to surface collision");
+ RNA_def_property_update(prop, 0, "rna_CollisionSettings_update");
/* Soft Body and Cloth Interaction */
diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c
index 07c4445872e..b37442fab6a 100644
--- a/source/blender/makesrna/intern/rna_pose.c
+++ b/source/blender/makesrna/intern/rna_pose.c
@@ -693,6 +693,8 @@ static void rna_def_pose_channel(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Bone Paths Calculation End Frame", "End frame of range of frames to use for Bone Path calculations.");
RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update");
+ rna_def_motionpath_common(srna);
+
/* Relationships to other bones */
prop= RNA_def_property(srna, "bone", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
@@ -912,6 +914,13 @@ static void rna_def_pose_channel(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Custom Object", "Object that defines custom draw type for this bone.");
RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update");
+ prop= RNA_def_property(srna, "custom_shape_transform", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "custom_tx");
+ RNA_def_property_struct_type(prop, "PoseBone");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Custom Shape Transform", "Bone that defines the display transform of this custom shape.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update");
+
/* bone groups */
prop= RNA_def_property(srna, "bone_group_index", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "agrp_index");
@@ -1108,7 +1117,8 @@ static void rna_def_pose(BlenderRNA *brna)
RNA_def_property_int_funcs(prop, "rna_Pose_active_bone_group_index_get", "rna_Pose_active_bone_group_index_set", "rna_Pose_active_bone_group_index_range");
RNA_def_property_ui_text(prop, "Active Bone Group Index", "Active index in bone groups array.");
RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update");
-
+
+ /* ik solvers */
prop= RNA_def_property(srna, "ik_solver", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "iksolver");
RNA_def_property_enum_funcs(prop, NULL, "rna_Pose_ik_solver_set", NULL);
@@ -1121,7 +1131,10 @@ static void rna_def_pose(BlenderRNA *brna)
RNA_def_property_pointer_funcs(prop, "rna_Pose_ikparam_get", NULL, "rna_Pose_ikparam_typef");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "IK Param", "Parameters for IK solver.");
-
+
+ /* animviz */
+ rna_def_animviz_common(srna);
+
/* RNA_api_pose(srna); */
}
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index d5de2fdc464..e35f8437995 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -96,11 +96,13 @@ EnumPropertyItem snap_element_items[] = {
#include "BKE_context.h"
#include "BKE_global.h"
+#include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_node.h"
#include "BKE_pointcache.h"
#include "BKE_scene.h"
#include "BKE_depsgraph.h"
+#include "BKE_image.h"
#include "BKE_mesh.h"
#include "BLI_threads.h"
@@ -124,21 +126,28 @@ static PointerRNA rna_Scene_objects_get(CollectionPropertyIterator *iter)
return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, ((Base*)internal->link)->object);
}
-static void rna_Scene_link_object(Scene *sce, ReportList *reports, Object *ob)
+static void rna_Scene_link_object(Scene *scene, ReportList *reports, Object *ob)
{
- Base *base= object_in_scene(ob, sce);
- if (base) {
- BKE_report(reports, RPT_ERROR, "Object is already in this scene.");
+ Base *base;
+
+ if (ob->type != OB_EMPTY && ob->data==NULL) {
+ BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not an Empty type and has no Object Data set.");
+ return;
+ }
+
+ if (object_in_scene(ob, scene)) {
+ BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is already in scene \"%s\".", ob->id.name+2, scene->id.name+2);
return;
}
- base= scene_add_base(sce, ob);
+
+ base= scene_add_base(scene, ob);
ob->id.us++;
/* this is similar to what object_add_type and add_object do */
- ob->lay= base->lay= sce->lay;
+ ob->lay= base->lay= scene->lay;
ob->recalc |= OB_RECALC;
- DAG_scene_sort(sce);
+ DAG_scene_sort(scene);
}
static void rna_Scene_unlink_object(Scene *sce, ReportList *reports, Object *ob)
@@ -359,6 +368,21 @@ static void rna_SceneRenderData_file_format_set(PointerRNA *ptr, int value)
#endif
}
+static int rna_SceneRender_file_ext_length(PointerRNA *ptr)
+{
+ RenderData *rd= (RenderData*)ptr->data;
+ char ext[8];
+
+ BKE_add_image_extension(ext, rd->imtype);
+ return strlen(ext);
+}
+
+static void rna_SceneRender_file_ext_get(PointerRNA *ptr, char *str)
+{
+ RenderData *rd= (RenderData*)ptr->data;
+ BKE_add_image_extension(str, rd->imtype);
+}
+
void rna_SceneRenderData_jpeg2k_preset_update(RenderData *rd)
{
rd->subimtype &= ~(R_JPEG2K_12BIT|R_JPEG2K_16BIT | R_JPEG2K_CINE_PRESET|R_JPEG2K_CINE_48FPS);
@@ -501,6 +525,12 @@ static int rna_SceneRenderData_engine_get(PointerRNA *ptr)
return 0;
}
+static void rna_SceneRenderData_color_management_update(Main *bmain, Scene *unused, PointerRNA *ptr)
+{
+ /* reset all generated image block buffers to prevent out-of-date conversions */
+ BKE_image_free_image_ibufs();
+}
+
static void rna_SceneRenderLayer_name_set(PointerRNA *ptr, const char *value)
{
Scene *scene= (Scene*)ptr->id.data;
@@ -1280,7 +1310,7 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
prop= RNA_def_property(srna, "eye_separation", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "eyeseparation");
RNA_def_property_range(prop, 0.01, 5.0);
- RNA_def_property_ui_text(prop, "Eye Separation", "Set the distance between the eyes");
+ RNA_def_property_ui_text(prop, "Eye Separation", "Set the distance between the eyes - the camera focal length/30 should be fine");
RNA_def_property_update(prop, NC_SCENE, NULL);
/* Dome */
@@ -1526,7 +1556,13 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
{R_BAKE_SPACE_OBJECT, "OBJECT", 0, "Object", ""},
{R_BAKE_SPACE_TANGENT, "TANGENT", 0, "Tangent", ""},
{0, NULL, 0, NULL, NULL}};
-
+
+ static EnumPropertyItem bake_qyad_split_items[] ={
+ {0, "AUTO", 0, "Automatic", "Split quads to give the least distortion while baking"},
+ {1, "FIXED", 0, "Fixed", "Split quads pradictably (0,1,2) (0,2,3)"},
+ {2, "FIXED_ALT", 0, "Fixed Alternate", "Split quads pradictably (1,2,3) (1,3,0)"},
+ {0, NULL, 0, NULL, NULL}};
+
static EnumPropertyItem bake_aa_items[] ={
{5, "AA_5", 0, "5", ""},
{8, "AA_8", 0, "8", ""},
@@ -2170,9 +2206,9 @@ 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, NULL);
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS|NC_MATERIAL|ND_SHADING, "rna_SceneRenderData_color_management_update");
- prop= RNA_def_property(srna, "file_extensions", PROP_BOOLEAN, PROP_NONE);
+ prop= RNA_def_property(srna, "use_file_extension", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_EXTENSION);
RNA_def_property_ui_text(prop, "File Extensions", "Add the file format extensions to the rendered file name (eg: filename + .jpg)");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
@@ -2183,7 +2219,13 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_enum_funcs(prop, NULL, "rna_SceneRenderData_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);
-
+
+ prop= RNA_def_property(srna, "file_extension", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_funcs(prop, "rna_SceneRender_file_ext_get", "rna_SceneRender_file_ext_length", NULL);
+ RNA_def_property_ui_text(prop, "Extension", "The file extension used for saving renders.");
+ RNA_def_struct_name_property(srna, prop);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
prop= RNA_def_property(srna, "free_image_textures", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_FREE_IMAGE);
RNA_def_property_ui_text(prop, "Free Image Textures", "Free all image texture from memory after render, to save memory before compositing.");
@@ -2226,13 +2268,17 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop= RNA_def_property(srna, "bake_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "bake_mode");
RNA_def_property_enum_items(prop, bake_mode_items);
- RNA_def_property_ui_text(prop, "Bake Mode", "");
+ RNA_def_property_ui_text(prop, "Bake Mode", "Choose shading information to bake into the image");
prop= RNA_def_property(srna, "bake_normal_space", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "bake_normal_space");
RNA_def_property_enum_items(prop, bake_normal_space_items);
RNA_def_property_ui_text(prop, "Normal Space", "Choose normal space for baking");
+ prop= RNA_def_property(srna, "bake_quad_split", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, bake_qyad_split_items);
+ RNA_def_property_ui_text(prop, "Quad Split", "Choose the method used to split a quad into 2 triangles for baking");
+
prop= RNA_def_property(srna, "bake_aa_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "bake_osa");
RNA_def_property_enum_items(prop, bake_aa_items);
@@ -2244,10 +2290,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop= RNA_def_property(srna, "bake_normalized", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bake_flag", R_BAKE_NORMALIZE);
- RNA_def_property_ui_text(prop, "Normalized", "");
- //"Bake ambient occlusion normalized, without taking into acount material settings"
- //"Normalized displacement value to fit the 'Dist' range"
- // XXX: Need 1 tooltip here...
+ RNA_def_property_ui_text(prop, "Normalized", "With displacement normalize to the distance, with ambient occlusion normalize without using material settings.");
prop= RNA_def_property(srna, "bake_clear", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bake_flag", R_BAKE_CLEAR);
@@ -2276,7 +2319,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop= RNA_def_property(srna, "stamp_time", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "stamp", R_STAMP_TIME);
- RNA_def_property_ui_text(prop, "Stamp Time", "Include the current time in image metadata");
+ RNA_def_property_ui_text(prop, "Stamp Time", "Include the render frame as HH:MM:SS.FF in image metadata");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
prop= RNA_def_property(srna, "stamp_date", PROP_BOOLEAN, PROP_NONE);
@@ -2388,6 +2431,9 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_boolean_funcs(prop, "rna_SceneRenderData_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.");
+
+ /* Scene API */
+ RNA_api_scene_render(srna);
}
diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c
index 4efbed167a6..84dc3e6971e 100644
--- a/source/blender/makesrna/intern/rna_scene_api.c
+++ b/source/blender/makesrna/intern/rna_scene_api.c
@@ -36,12 +36,15 @@
#include "DNA_anim_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "BKE_utildefines.h"
#ifdef RNA_RUNTIME
#include "BKE_animsys.h"
#include "BKE_scene.h"
+#include "BKE_image.h"
#include "BKE_depsgraph.h"
+#include "BKE_writeavi.h"
#include "ED_object.h"
#include "ED_anim_api.h"
@@ -84,6 +87,14 @@ static KeyingSet *rna_Scene_add_keying_set(Scene *sce, ReportList *reports,
}
}
+static void rna_SceneRender_get_frame_path(RenderData *rd, int frame, char *name)
+{
+ if(BKE_imtype_is_movie(rd->imtype))
+ BKE_makeanimstring(name, rd);
+ else
+ BKE_makepicstring(name, rd->pic, (frame==INT_MIN) ? rd->cfra : frame, rd->imtype, rd->scemode & R_EXTENSION);
+}
+
#else
void RNA_api_scene(StructRNA *srna)
@@ -113,5 +124,18 @@ void RNA_api_scene(StructRNA *srna)
RNA_def_boolean(func, "insertkey_visual", 0, "Insert Keyframes - Visual", "Insert keyframes based on 'visual transforms'.");
}
+void RNA_api_scene_render(StructRNA *srna)
+{
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ func= RNA_def_function(srna, "frame_path", "rna_SceneRender_get_frame_path");
+ RNA_def_function_ui_description(func, "Set scene frame updating all objects immediately.");
+ parm= RNA_def_int(func, "frame", INT_MIN, INT_MIN, INT_MAX, "", "Frame number to use, if unset the current frame will be used.", MINAFRAME, MAXFRAME);
+ parm= RNA_def_string(func, "name", "", FILE_MAX, "File Name", "the resulting filename from the scenes render settings.");
+ RNA_def_property_flag(parm, PROP_THICK_WRAP); /* needed for string return value */
+ RNA_def_function_return_mark(func, parm);
+}
+
#endif
diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c
index 883c77b3faa..5a29eee5cf2 100644
--- a/source/blender/makesrna/intern/rna_screen.c
+++ b/source/blender/makesrna/intern/rna_screen.c
@@ -23,6 +23,7 @@
*/
#include <stdlib.h>
+#include <stddef.h>
#include "RNA_define.h"
#include "RNA_types.h"
@@ -37,9 +38,10 @@ EnumPropertyItem region_type_items[] = {
{RGN_TYPE_WINDOW, "WINDOW", 0, "Window", ""},
{RGN_TYPE_HEADER, "HEADER", 0, "Header", ""},
{RGN_TYPE_CHANNELS, "CHANNELS", 0, "Channels", ""},
- {RGN_TYPE_TOOLS, "TOOLS", 0, "Tools", ""},
{RGN_TYPE_TEMPORARY, "TEMPORARY", 0, "Temporary", ""},
{RGN_TYPE_UI, "UI", 0, "UI", ""},
+ {RGN_TYPE_TOOLS, "TOOLS", 0, "Tools", ""},
+ {RGN_TYPE_TOOL_PROPS, "TOOL_PROPS", 0, "Tool Properties", ""},
{RGN_TYPE_PREVIEW, "PREVIEW", 0, "Preview", ""},
{0, NULL, 0, NULL, NULL}};
@@ -154,8 +156,9 @@ static void rna_def_region(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Region ID", "Unique ID for this region.");
- prop= RNA_def_property(srna, "type", PROP_INT, PROP_NONE);
- RNA_def_property_int_sdna(prop, NULL, "regiontype");
+ prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "regiontype");
+ RNA_def_property_enum_items(prop, region_type_items);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Region Type", "Type of this region.");
diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c
index 4d17da668b2..99bee9413cd 100644
--- a/source/blender/makesrna/intern/rna_sculpt_paint.c
+++ b/source/blender/makesrna/intern/rna_sculpt_paint.c
@@ -454,10 +454,6 @@ static void rna_def_particle_edit(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Draw Particles", "Draw actual particles.");
RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
- prop= RNA_def_property(srna, "mirror_x", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", PE_X_MIRROR);
- RNA_def_property_ui_text(prop, "X-Axis Mirror", "Mirror operations over the X axis while editing.");
-
prop= RNA_def_property(srna, "add_interpolate", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", PE_INTERPOLATE_ADDED);
RNA_def_property_ui_text(prop, "Interpolate", "Interpolate new particles from the existing ones.");
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 7ab01d5ef99..35c8c7ac345 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -1351,7 +1351,7 @@ static void rna_def_space_graph(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "mode");
RNA_def_property_enum_items(prop, mode_items);
RNA_def_property_ui_text(prop, "Mode", "Editing context being displayed.");
- RNA_def_property_update(prop, NC_SPACE|ND_SPACE_GRAPH, NULL);
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_GRAPH, NULL); // XXX need to be able to flush channel types
/* display */
prop= RNA_def_property(srna, "show_seconds", PROP_BOOLEAN, PROP_NONE);
@@ -1481,37 +1481,37 @@ static void rna_def_space_time(BlenderRNA *brna)
/* Define Anim Playback Areas */
prop= RNA_def_property(srna, "play_top_left", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "redraws", TIME_REGION);
- RNA_def_property_ui_text(prop, "Top-Left 3D Window", "");
+ RNA_def_property_ui_text(prop, "Top-Left 3D Editor", "");
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TIME, "rna_SpaceTime_redraw_update");
prop= RNA_def_property(srna, "play_all_3d", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "redraws", TIME_ALL_3D_WIN);
- RNA_def_property_ui_text(prop, "All 3D Windows", "");
+ RNA_def_property_ui_text(prop, "All 3D View Editors", "");
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TIME, "rna_SpaceTime_redraw_update");
prop= RNA_def_property(srna, "play_anim", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "redraws", TIME_ALL_ANIM_WIN);
- RNA_def_property_ui_text(prop, "Animation Windows", "");
+ RNA_def_property_ui_text(prop, "Animation Editors", "");
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TIME, "rna_SpaceTime_redraw_update");
prop= RNA_def_property(srna, "play_buttons", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "redraws", TIME_ALL_BUTS_WIN);
- RNA_def_property_ui_text(prop, "Properties Windows", "");
+ RNA_def_property_ui_text(prop, "Property Editors", "");
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TIME, "rna_SpaceTime_redraw_update");
prop= RNA_def_property(srna, "play_image", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "redraws", TIME_ALL_IMAGE_WIN);
- RNA_def_property_ui_text(prop, "Image Windows", "");
+ RNA_def_property_ui_text(prop, "Image Editors", "");
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TIME, "rna_SpaceTime_redraw_update");
prop= RNA_def_property(srna, "play_sequencer", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "redraws", TIME_SEQ);
- RNA_def_property_ui_text(prop, "Sequencer Windows", "");
+ RNA_def_property_ui_text(prop, "Sequencer Editors", "");
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TIME, "rna_SpaceTime_redraw_update");
prop= RNA_def_property(srna, "play_nodes", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "redraws", TIME_NODES);
- RNA_def_property_ui_text(prop, "Node Windows", "");
+ RNA_def_property_ui_text(prop, "Node Editors", "");
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TIME, "rna_SpaceTime_redraw_update");
/* Other options */
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index 19d33465ceb..79a75c89a08 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -1598,7 +1598,7 @@ static void rna_def_texture_pointdensity(BlenderRNA *brna)
prop= RNA_def_property(srna, "radius", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "radius");
- RNA_def_property_range(prop, 0.01, FLT_MAX);
+ RNA_def_property_range(prop, 0.001, FLT_MAX);
RNA_def_property_ui_text(prop, "Radius", "Radius from the shaded sample to look for points within");
RNA_def_property_update(prop, 0, "rna_Texture_update");
diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c
index 9c4cc64fbb7..011235c862f 100644
--- a/source/blender/makesrna/intern/rna_ui_api.c
+++ b/source/blender/makesrna/intern/rna_ui_api.c
@@ -269,6 +269,15 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_string(func, "open", "", 0, "", "Operator identifier to open a file for creating a new ID block.");
RNA_def_string(func, "unlink", "", 0, "", "Operator identifier to unlink the ID block.");
+ func= RNA_def_function(srna, "template_ID_preview", "uiTemplateIDPreview");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+ api_ui_item_rna_common(func);
+ RNA_def_string(func, "new", "", 0, "", "Operator identifier to create a new ID block.");
+ RNA_def_string(func, "open", "", 0, "", "Operator identifier to open a file for creating a new ID block.");
+ RNA_def_string(func, "unlink", "", 0, "", "Operator identifier to unlink the ID block.");
+ RNA_def_int(func, "rows", 0, 0, INT_MAX, "Number of thumbnail preview rows to display", "", 0, INT_MAX);
+ RNA_def_int(func, "cols", 0, 0, INT_MAX, "Number of thumbnail preview columns to display", "", 0, INT_MAX);
+
func= RNA_def_function(srna, "template_any_ID", "uiTemplateAnyID");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property.");
@@ -311,6 +320,7 @@ void RNA_api_ui_layout(StructRNA *srna)
api_ui_item_rna_common(func);
RNA_def_enum(func, "type", curve_type_items, 0, "Type", "Type of curves to display.");
RNA_def_boolean(func, "levels", 0, "", "Show black/white levels.");
+ RNA_def_boolean(func, "brush", 0, "", "Show brush options.");
func= RNA_def_function(srna, "template_color_ramp", "uiTemplateColorRamp");
api_ui_item_rna_common(func);
@@ -325,6 +335,10 @@ void RNA_api_ui_layout(StructRNA *srna)
parm= RNA_def_int(func, "active_layer", 0, 0, INT_MAX, "Active Layer", "", 0, INT_MAX);
RNA_def_property_flag(parm, PROP_REQUIRED);
+ func= RNA_def_function(srna, "template_color_wheel", "uiTemplateColorWheel");
+ api_ui_item_rna_common(func);
+ RNA_def_boolean(func, "value_slider", 0, "", "Display the value slider to the right of the color wheel");
+
func= RNA_def_function(srna, "template_triColorSet", "uiTemplateTriColorSet");
api_ui_item_rna_common(func);
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 9b314afeb08..bc0e11bf780 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -1434,7 +1434,7 @@ static void rna_def_userdef_themes(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
- static EnumPropertyItem active_theme_group[] = {
+ static EnumPropertyItem active_theme_area[] = {
{0, "USER_INTERFACE", ICON_UI, "User Interface", ""},
{1, "VIEW_3D", ICON_VIEW3D, "3D View", ""},
{2, "TIMELINE", ICON_TIME, "Timeline", ""},
@@ -1462,10 +1462,10 @@ static void rna_def_userdef_themes(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Name", "Name of the theme.");
RNA_def_struct_name_property(srna, prop);
- prop= RNA_def_property(srna, "active_theme", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "active_theme_group");
- RNA_def_property_enum_items(prop, active_theme_group);
- RNA_def_property_ui_text(prop, "Active Theme", "");
+ prop= RNA_def_property(srna, "theme_area", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "active_theme_area");
+ RNA_def_property_enum_items(prop, active_theme_area);
+ RNA_def_property_ui_text(prop, "Active Theme Area", "");
prop= RNA_def_property(srna, "user_interface", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
@@ -1811,8 +1811,6 @@ static void rna_def_userdef_view(BlenderRNA *brna)
RNA_def_property_range(prop, 4, 10);
RNA_def_property_ui_text(prop, "Object Origin Size", "Diameter in Pixels for Object/Lamp origin display.");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
-
}
static void rna_def_userdef_edit(BlenderRNA *brna)
@@ -1841,7 +1839,6 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
{USER_ADD_VIEWALIGNED, "VIEW", 0, "View", "Align newly added objects to the world coordinates"},
{0, NULL, 0, NULL, NULL}};
-
srna= RNA_def_struct(brna, "UserPreferencesEdit", NULL);
RNA_def_struct_sdna(srna, "UserDef");
RNA_def_struct_nested(brna, srna, "UserPreferences");
@@ -1927,7 +1924,7 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
RNA_def_property_enum_items(prop, new_interpolation_types);
RNA_def_property_enum_sdna(prop, NULL, "ipo_new");
RNA_def_property_ui_text(prop, "New Interpolation Type", "");
-
+
prop= RNA_def_property(srna, "grease_pencil_manhattan_distance", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "gp_manhattendist");
RNA_def_property_range(prop, 0, 100);
@@ -2075,7 +2072,14 @@ static void rna_def_userdef_system(BlenderRNA *brna)
{USER_DRAW_OVERLAP, "OVERLAP", 0, "Overlap", "Redraw all overlapping regions, minimal memory usage but more redraws."},
{USER_DRAW_FULL, "FULL", 0, "Full", "Do a full redraw each time, slow, only use for reference or when all else fails."},
{0, NULL, 0, NULL, NULL}};
-
+
+ static EnumPropertyItem color_picker_types[] = {
+ {USER_CP_CIRCLE, "CIRCLE", 0, "Circle", "A circular Hue/Saturation color wheel, with Value slider"},
+ {USER_CP_SQUARE_SV, "SQUARE_SV", 0, "Square (SV + H)", "A square showing Saturation/Value, with Hue slider"},
+ {USER_CP_SQUARE_HS, "SQUARE_HS", 0, "Square (HS + V)", "A square showing Hue/Saturation, with Value slider"},
+ {USER_CP_SQUARE_HV, "SQUARE_HV", 0, "Square (HV + S)", "A square showing Hue/Value, with Saturation slider"},
+ {0, NULL, 0, NULL, NULL}};
+
/* hardcoded here, could become dynamic somehow */
static EnumPropertyItem language_items[] = {
{0, "ENGLISH", 0, "English", ""},
@@ -2172,6 +2176,11 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Weight Color Range", "Color range used for weight visualization in weight painting mode.");
RNA_def_property_update(prop, 0, "rna_UserDef_weight_color_update");
+ prop= RNA_def_property(srna, "color_picker_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, color_picker_types);
+ RNA_def_property_enum_sdna(prop, NULL, "color_picker_type");
+ RNA_def_property_ui_text(prop, "Color Picker Type", "Different styles of displaying the color picker widget");
+
prop= RNA_def_property(srna, "enable_all_codecs", PROP_BOOLEAN, PROP_NONE);
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).");
@@ -2195,10 +2204,6 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_range(prop, 0, 32727);
RNA_def_property_ui_text(prop, "Frame Server Port", "Frameserver Port for Framserver-Rendering.");
- prop= RNA_def_property(srna, "game_sound", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_negative_sdna(prop, NULL, "gameflags", USER_DISABLE_SOUND);
- RNA_def_property_ui_text(prop, "Game Sound", "Enables sounds to be played in games.");
-
prop= RNA_def_property(srna, "clip_alpha", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "glalphaclip");
RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -2212,6 +2217,10 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_boolean_negative_sdna(prop, NULL, "gameflags", USER_DISABLE_VBO);
RNA_def_property_ui_text(prop, "VBOs", "Use Vertex Buffer Objects (or Vertex Arrays, if unsupported) for viewport rendering.");
+ prop= RNA_def_property(srna, "use_antialiasing", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "gameflags", USER_DISABLE_AA);
+ RNA_def_property_ui_text(prop, "Anti-aliasing", "Use anti-aliasing for the 3D view (may impact redraw performance)");
+
prop= RNA_def_property(srna, "gl_texture_limit", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "glreslimit");
RNA_def_property_enum_items(prop, gl_texture_clamp_items);
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index 7abba3c004a..513f2f8f0ec 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -64,6 +64,7 @@ EnumPropertyItem event_value_items[] = {
{KM_PRESS, "PRESS", 0, "Press", ""},
{KM_RELEASE, "RELEASE", 0, "Release", ""},
{KM_CLICK, "CLICK", 0, "Click", ""},
+ {KM_DBL_CLICK, "DOUBLECLICK", 0, "Double Click", ""},
{0, NULL, 0, NULL, NULL}};
EnumPropertyItem event_tweak_type_items[]= {
@@ -692,6 +693,7 @@ static void operator_draw(bContext *C, wmOperator *op)
}
void operator_wrapper(wmOperatorType *ot, void *userdata);
+void macro_wrapper(wmOperatorType *ot, void *userdata);
static char _operator_idname[OP_MAX_TYPENAME];
static char _operator_name[OP_MAX_TYPENAME];
@@ -763,12 +765,84 @@ static StructRNA *rna_Operator_register(const bContext *C, ReportList *reports,
return dummyot.ext.srna;
}
+
+static StructRNA *rna_MacroOperator_register(const bContext *C, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+{
+ wmOperatorType dummyot = {0};
+ wmOperator dummyop= {0};
+ PointerRNA dummyotr;
+ int have_function[4];
+
+ /* setup dummy operator & operator type to store static properties in */
+ dummyop.type= &dummyot;
+ dummyot.idname= _operator_idname; /* only assigne the pointer, string is NULL'd */
+ dummyot.name= _operator_name; /* only assigne the pointer, string is NULL'd */
+ dummyot.description= _operator_descr; /* only assigne the pointer, string is NULL'd */
+ RNA_pointer_create(NULL, &RNA_Macro, &dummyop, &dummyotr);
+
+ /* validate the python class */
+ if(validate(&dummyotr, data, have_function) != 0)
+ return NULL;
+
+ { /* convert foo.bar to FOO_OT_bar
+ * allocate the description and the idname in 1 go */
+ int idlen = strlen(_operator_idname) + 4;
+ int namelen = strlen(_operator_name) + 1;
+ int desclen = strlen(_operator_descr) + 1;
+ char *ch, *ch_arr;
+ ch_arr= ch= MEM_callocN(sizeof(char) * (idlen + namelen + desclen), "_operator_idname"); /* 2 terminators and 3 to convert a.b -> A_OT_b */
+ WM_operator_bl_idname(ch, _operator_idname); /* convert the idname from python */
+ dummyot.idname= ch;
+ ch += idlen;
+ strcpy(ch, _operator_name);
+ dummyot.name = ch;
+ ch += namelen;
+ strcpy(ch, _operator_descr);
+ dummyot.description = ch;
+ }
+
+ if(strlen(identifier) >= sizeof(dummyop.idname)) {
+ BKE_reportf(reports, RPT_ERROR, "registering operator class: '%s' is too long, maximum length is %d.", identifier, sizeof(dummyop.idname));
+ return NULL;
+ }
+
+ /* check if we have registered this operator type before, and remove it */
+ {
+ wmOperatorType *ot= WM_operatortype_exists(dummyot.idname);
+ if(ot && ot->ext.srna)
+ rna_Operator_unregister(C, ot->ext.srna);
+ }
+
+ /* create a new menu type */
+ dummyot.ext.srna= RNA_def_struct(&BLENDER_RNA, dummyot.idname, "Operator");
+ dummyot.ext.data= data;
+ dummyot.ext.call= call;
+ dummyot.ext.free= free;
+
+ dummyot.pyop_poll= (have_function[0])? operator_poll: NULL;
+ dummyot.ui= (have_function[3])? operator_draw: NULL;
+
+ WM_operatortype_append_macro_ptr(macro_wrapper, (void *)&dummyot);
+
+ /* update while blender is running */
+ if(C)
+ WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL);
+
+ return dummyot.ext.srna;
+}
+
static StructRNA* rna_Operator_refine(PointerRNA *opr)
{
wmOperator *op= (wmOperator*)opr->data;
return (op->type && op->type->ext.srna)? op->type->ext.srna: &RNA_Operator;
}
+static StructRNA* rna_MacroOperator_refine(PointerRNA *opr)
+{
+ wmOperator *op= (wmOperator*)opr->data;
+ return (op->type && op->type->ext.srna)? op->type->ext.srna: &RNA_Macro;
+}
+
#else
static void rna_def_operator(BlenderRNA *brna)
@@ -808,6 +882,11 @@ static void rna_def_operator(BlenderRNA *brna)
RNA_def_property_string_maxlength(prop, 1024); /* else it uses the pointer size! */
RNA_def_property_flag(prop, PROP_REGISTER);
+ prop= RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "type->description");
+ RNA_def_property_string_maxlength(prop, 1024); /* else it uses the pointer size! */
+ RNA_def_property_flag(prop, PROP_REGISTER);
+
prop= RNA_def_property(srna, "bl_register", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "type->flag", OPTYPE_REGISTER);
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
@@ -832,6 +911,8 @@ static void rna_def_macro_operator(BlenderRNA *brna)
srna= RNA_def_struct(brna, "Macro", NULL);
RNA_def_struct_ui_text(srna, "Macro Operator", "Storage of a macro operator being executed, or registered after execution.");
RNA_def_struct_sdna(srna, "wmOperator");
+ RNA_def_struct_refine_func(srna, "rna_MacroOperator_refine");
+ RNA_def_struct_register_funcs(srna, "rna_MacroOperator_register", "rna_Operator_unregister");
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -844,6 +925,32 @@ static void rna_def_macro_operator(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "OperatorProperties");
RNA_def_property_ui_text(prop, "Properties", "");
RNA_def_property_pointer_funcs(prop, "rna_Operator_properties_get", NULL, NULL);
+
+ /* Registration */
+ prop= RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "type->idname");
+ RNA_def_property_string_maxlength(prop, OP_MAX_TYPENAME); /* else it uses the pointer size! */
+ RNA_def_property_flag(prop, PROP_REGISTER);
+
+ prop= RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "type->name");
+ RNA_def_property_string_maxlength(prop, 1024); /* else it uses the pointer size! */
+ RNA_def_property_flag(prop, PROP_REGISTER);
+
+ prop= RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "type->description");
+ RNA_def_property_string_maxlength(prop, 1024); /* else it uses the pointer size! */
+ RNA_def_property_flag(prop, PROP_REGISTER);
+
+ prop= RNA_def_property(srna, "bl_register", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "type->flag", OPTYPE_REGISTER);
+ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+
+ prop= RNA_def_property(srna, "bl_undo", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "type->flag", OPTYPE_UNDO);
+ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+
+ RNA_api_macro(srna);
}
static void rna_def_operator_type_macro(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c
index 1afedf1c6a6..9ed6046ecd0 100644
--- a/source/blender/makesrna/intern/rna_wm_api.c
+++ b/source/blender/makesrna/intern/rna_wm_api.c
@@ -237,6 +237,35 @@ void RNA_api_operator(StructRNA *srna)
RNA_def_pointer(func, "context", "Context", "", "");
}
+void RNA_api_macro(StructRNA *srna)
+{
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ /* utility, not for registering */
+ func= RNA_def_function(srna, "report", "rna_Operator_report");
+ parm= RNA_def_enum(func, "type", wm_report_items, 0, "Type", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED|PROP_ENUM_FLAG);
+ parm= RNA_def_string(func, "message", "", 0, "Report Message", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+
+
+ /* Registration */
+
+ /* poll */
+ func= RNA_def_function(srna, "poll", NULL);
+ RNA_def_function_ui_description(func, "Test if the operator can be called or not.");
+ RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
+ RNA_def_function_return(func, RNA_def_boolean(func, "visible", 1, "", ""));
+ RNA_def_pointer(func, "context", "Context", "", "");
+
+ /* draw */
+ func= RNA_def_function(srna, "draw", NULL);
+ RNA_def_function_ui_description(func, "Draw function for the operator.");
+ RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
+ RNA_def_pointer(func, "context", "Context", "", "");
+}
+
void RNA_api_keyconfig(StructRNA *srna)
{
FunctionRNA *func;
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_image.c b/source/blender/nodes/intern/CMP_nodes/CMP_image.c
index 89a3072ac8d..a204f8df4b2 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_image.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_image.c
@@ -64,27 +64,19 @@ static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *i
ibuf= BKE_image_get_ibuf(ima, iuser);
if(ibuf==NULL)
return NULL;
-
- if (rd->color_mgt_flag & R_COLOR_MANAGEMENT) {
- if (ibuf->profile == IB_PROFILE_NONE) {
- /* if float buffer already exists = already linear */
- /* else ... */
- if (ibuf->rect_float == NULL) {
- imb_freerectfloatImBuf(ibuf);
- ibuf->profile = IB_PROFILE_SRGB;
- IMB_float_from_rect(ibuf);
- } else {
- ibuf->profile = IB_PROFILE_LINEAR_RGB;
- }
- }
- } else {
- if (ibuf->profile == IB_PROFILE_SRGB) {
- if (ibuf->rect_float != NULL) {
- imb_freerectfloatImBuf(ibuf);
- }
- ibuf->profile = IB_PROFILE_NONE;
- IMB_float_from_rect(ibuf);
+
+ if (!(rd->color_mgt_flag & R_COLOR_MANAGEMENT)) {
+ int profile = IB_PROFILE_NONE;
+
+ /* temporarily set profile to none to not disturb actual */
+ SWAP(int, ibuf->profile, profile);
+
+ if (ibuf->rect_float != NULL) {
+ imb_freerectfloatImBuf(ibuf);
}
+ IMB_float_from_rect(ibuf);
+
+ SWAP(int, ibuf->profile, profile);
}
if (ibuf->rect_float == NULL) {
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_outputFile.c b/source/blender/nodes/intern/CMP_nodes/CMP_outputFile.c
index e63e5802507..ebb7c1e8478 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_outputFile.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_outputFile.c
@@ -62,7 +62,7 @@ static void node_composit_exec_output_file(void *data, bNode *node, bNodeStack *
}
}
- BKE_makepicstring((Scene *)node->id, string, nif->name, rd->cfra, nif->imtype);
+ BKE_makepicstring(string, nif->name, rd->cfra, nif->imtype, ((Scene *)node->id)->r.scemode & R_EXTENSION);
if(0 == BKE_write_ibuf((Scene *)node->id, ibuf, string, nif->imtype, nif->subimtype, nif->imtype==R_OPENEXR?nif->codec:nif->quality))
printf("Cannot save Node File Output to %s\n", string);
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_rgb.c b/source/blender/nodes/intern/CMP_nodes/CMP_rgb.c
index ae2678dc5f0..496e432bebf 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_rgb.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_rgb.c
@@ -47,7 +47,7 @@ bNodeType cmp_node_rgb= {
/* *next,*prev */ NULL, NULL,
/* type code */ CMP_NODE_RGB,
/* name */ "RGB",
- /* width+range */ 100, 60, 140,
+ /* width+range */ 140, 80, 140,
/* class+opts */ NODE_CLASS_INPUT, NODE_OPTIONS,
/* input sock */ NULL,
/* output sock */ cmp_node_rgb_out,
diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_rgb.c b/source/blender/nodes/intern/SHD_nodes/SHD_rgb.c
index 1aa1a2ffc33..1c18e006a74 100644
--- a/source/blender/nodes/intern/SHD_nodes/SHD_rgb.c
+++ b/source/blender/nodes/intern/SHD_nodes/SHD_rgb.c
@@ -54,7 +54,7 @@ bNodeType sh_node_rgb= {
/* *next,*prev */ NULL, NULL,
/* type code */ SH_NODE_RGB,
/* name */ "RGB",
- /* width+range */ 100, 60, 140,
+ /* width+range */ 140, 80, 140,
/* class+opts */ NODE_CLASS_INPUT, NODE_OPTIONS,
/* input sock */ NULL,
/* output sock */ sh_node_rgb_out,
diff --git a/source/blender/python/generic/euler.c b/source/blender/python/generic/euler.c
index f6f2e337211..ae7a6783358 100644
--- a/source/blender/python/generic/euler.c
+++ b/source/blender/python/generic/euler.c
@@ -541,7 +541,7 @@ static PyGetSetDef Euler_getseters[] = {
{"z", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler Z axis", (void *)2},
{"wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, "True when this wraps blenders internal data", NULL},
- {"__owner__", (getter)BaseMathObject_getOwner, (setter)NULL, "Read only owner for vectors that depend on another object", NULL},
+ {"_owner", (getter)BaseMathObject_getOwner, (setter)NULL, "Read only owner for vectors that depend on another object", NULL},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
};
diff --git a/source/blender/python/generic/matrix.c b/source/blender/python/generic/matrix.c
index dcd1057f881..074a397b6d9 100644
--- a/source/blender/python/generic/matrix.c
+++ b/source/blender/python/generic/matrix.c
@@ -1129,12 +1129,33 @@ static PyObject *Matrix_getColSize( MatrixObject * self, void *type )
return PyLong_FromLong((long) self->colSize);
}
+static PyObject *Matrix_getMedianScale( MatrixObject * self, void *type )
+{
+ float mat[3][3];
+
+ if(!BaseMath_ReadCallback(self))
+ return NULL;
+
+ /*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);
+ else if(self->colSize == 3 && self->rowSize == 3)
+ copy_m3_m3(mat, (float (*)[3])*self->matrix);
+ else {
+ PyErr_SetString(PyExc_AttributeError, "Matrix.median_scale: inappropriate matrix size - expects 3x3 or 4x4 matrix\n");
+ return NULL;
+ }
+
+ return PyFloat_FromDouble(mat3_to_scale(mat));
+}
+
/*****************************************************************************/
/* Python attributes get/set structure: */
/*****************************************************************************/
static PyGetSetDef Matrix_getseters[] = {
- {"rowSize", (getter)Matrix_getRowSize, (setter)NULL, "", NULL},
- {"colSize", (getter)Matrix_getColSize, (setter)NULL, "", NULL},
+ {"row_size", (getter)Matrix_getRowSize, (setter)NULL, "", NULL},
+ {"col_size", (getter)Matrix_getColSize, (setter)NULL, "", NULL},
+ {"median_scale", (getter)Matrix_getMedianScale, (setter)NULL, "", NULL},
{"wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, "", NULL},
{"_owner",(getter)BaseMathObject_getOwner, (setter)NULL, "",
NULL},
diff --git a/source/blender/python/generic/quat.c b/source/blender/python/generic/quat.c
index 2ee78235224..e739e1a5036 100644
--- a/source/blender/python/generic/quat.c
+++ b/source/blender/python/generic/quat.c
@@ -739,7 +739,7 @@ static PyGetSetDef Quaternion_getseters[] = {
(getter)BaseMathObject_getWrapped, (setter)NULL,
"True when this wraps blenders internal data",
NULL},
- {"__owner__",
+ {"_owner",
(getter)BaseMathObject_getOwner, (setter)NULL,
"Read only owner for vectors that depend on another object",
NULL},
diff --git a/source/blender/python/generic/vector.c b/source/blender/python/generic/vector.c
index ae2c96fa86a..0713d60c6c2 100644
--- a/source/blender/python/generic/vector.c
+++ b/source/blender/python/generic/vector.c
@@ -1421,7 +1421,7 @@ static PyGetSetDef Vector_getseters[] = {
(getter)BaseMathObject_getWrapped, (setter)NULL,
"True when this wraps blenders internal data",
NULL},
- {"__owner__",
+ {"_owner",
(getter)BaseMathObject_getOwner, (setter)NULL,
"Read only owner for vectors that depend on another object",
NULL},
diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c
index 76df28494ac..f80d79d9a2a 100644
--- a/source/blender/python/intern/bpy_driver.c
+++ b/source/blender/python/intern/bpy_driver.c
@@ -26,6 +26,8 @@
#include "DNA_anim_types.h"
+#include "BLI_listbase.h"
+
#include "BPY_extern.h"
#include "BKE_fcurve.h"
@@ -145,12 +147,15 @@ float BPY_pydriver_eval (ChannelDriver *driver)
{
PyObject *driver_vars=NULL;
PyObject *retval= NULL;
+ PyObject *expr_vars; /* speed up by pre-hashing string & avoids re-converting unicode strings for every execution */
+ PyObject *expr_code;
PyGILState_STATE gilstate;
- DriverTarget *dtar;
+ DriverVar *dvar;
float result = 0.0f; /* default return */
char *expr = NULL;
short targets_ok= 1;
+ int i;
/* sanity checks - should driver be executed? */
if ((driver == NULL) /*|| (G.f & G_DOSCRIPTLINKS)==0*/)
@@ -172,43 +177,75 @@ float BPY_pydriver_eval (ChannelDriver *driver)
}
}
+ if(driver->expr_comp==NULL)
+ driver->flag |= DRIVER_FLAG_RECOMPILE;
+
+ /* compile the expression first if it hasn't been compiled or needs to be rebuilt */
+ if(driver->flag & DRIVER_FLAG_RECOMPILE) {
+ Py_XDECREF(driver->expr_comp);
+ driver->expr_comp= PyTuple_New(2);
+
+ expr_code= Py_CompileString(expr, "<bpy driver>", Py_eval_input);
+ PyTuple_SET_ITEM(((PyObject *)driver->expr_comp), 0, expr_code);
+
+ driver->flag &= ~DRIVER_FLAG_RECOMPILE;
+ driver->flag |= DRIVER_FLAG_RENAMEVAR; /* maybe this can be removed but for now best keep until were sure */
+ }
+ else {
+ expr_code= PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 0);
+ }
+
+ if(driver->flag & DRIVER_FLAG_RENAMEVAR) {
+ /* may not be set */
+ expr_vars= PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 1);
+ Py_XDECREF(expr_vars);
+
+ /* intern the arg names so creating the namespace for every run is faster */
+ expr_vars= PyTuple_New(BLI_countlist(&driver->variables));
+ PyTuple_SET_ITEM(((PyObject *)driver->expr_comp), 1, expr_vars);
+
+ for (dvar= driver->variables.first, i=0; dvar; dvar= dvar->next) {
+ PyTuple_SET_ITEM(expr_vars, i++, PyUnicode_InternFromString(dvar->name));
+ }
+ }
+ else {
+ expr_vars= PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 1);
+ }
+
/* add target values to a dict that will be used as '__locals__' dict */
driver_vars = PyDict_New(); // XXX do we need to decref this?
- for (dtar= driver->targets.first; dtar; dtar= dtar->next) {
+ for (dvar= driver->variables.first, i=0; dvar; dvar= dvar->next) {
PyObject *driver_arg = NULL;
float tval = 0.0f;
-
+
/* try to get variable value */
- tval= driver_get_target_value(driver, dtar);
+ tval= driver_get_variable_value(driver, dvar);
driver_arg= PyFloat_FromDouble((double)tval);
-
+
/* try to add to dictionary */
- if (PyDict_SetItemString(driver_vars, dtar->name, driver_arg)) {
+ /* if (PyDict_SetItemString(driver_vars, dvar->name, driver_arg)) { */
+ if (PyDict_SetItem(driver_vars, PyTuple_GET_ITEM(expr_vars, i++), driver_arg)) { /* use string interning for faster namespace creation */
/* this target failed - bad name */
if (targets_ok) {
/* first one - print some extra info for easier identification */
fprintf(stderr, "\nBPY_pydriver_eval() - Error while evaluating PyDriver:\n");
targets_ok= 0;
}
-
- fprintf(stderr, "\tBPY_pydriver_eval() - couldn't add variable '%s' to namespace \n", dtar->name);
+
+ fprintf(stderr, "\tBPY_pydriver_eval() - couldn't add variable '%s' to namespace \n", dvar->name);
// BPy_errors_to_report(NULL); // TODO - reports
PyErr_Print();
PyErr_Clear();
}
}
-#if 0 // slow
+#if 0 // slow, with this can avoid all Py_CompileString above.
/* execute expression to get a value */
retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars);
#else
- if(driver->flag & DRIVER_FLAG_RECOMPILE || driver->expr_comp==NULL) {
- Py_XDECREF(driver->expr_comp);
- driver->expr_comp= Py_CompileString(expr, "<bpy driver>", Py_eval_input);
- driver->flag &= ~DRIVER_FLAG_RECOMPILE;
- }
- if(driver->expr_comp)
- retval= PyEval_EvalCode(driver->expr_comp, bpy_pydriver_Dict, driver_vars);
+ /* evaluate the compiled expression */
+ if (expr_code)
+ retval= PyEval_EvalCode((PyCodeObject *)expr_code, bpy_pydriver_Dict, driver_vars);
#endif
/* decref the driver vars first... */
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index 82d1c0f262a..c0f296b5233 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -226,12 +226,15 @@ static void bpy_init_modules( void )
/* blender info that wont change at runtime, add into _bpy */
{
+ extern char bprogname[]; /* argv[0] from creator.c */
+
PyObject *mod_dict= PyModule_GetDict(mod);
char tmpstr[256];
PyModule_AddStringConstant(mod, "_HOME", BLI_gethome());
PyDict_SetItemString(mod_dict, "_VERSION", Py_BuildValue("(iii)", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION));
sprintf(tmpstr, "%d.%02d (sub %d)", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION);
PyModule_AddStringConstant(mod, "_VERSION_STR", tmpstr);
+ PyModule_AddStringConstant(mod, "_BINPATH", bprogname);
}
/* add our own modules dir, this is a python package */
diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c
index 101f3619da4..d5f4b2f6d08 100644
--- a/source/blender/python/intern/bpy_operator.c
+++ b/source/blender/python/intern/bpy_operator.c
@@ -244,10 +244,7 @@ PyObject *BPY_operator_module( void )
static PyMethodDef pyop_as_string_meth ={"as_string", (PyCFunction) pyop_as_string, METH_VARARGS, NULL};
static PyMethodDef pyop_dir_meth = {"dir", (PyCFunction) pyop_dir, METH_NOARGS, NULL};
static PyMethodDef pyop_getrna_meth = {"get_rna", (PyCFunction) pyop_getrna, METH_O, NULL};
-// static PyMethodDef pyop_add_meth = {"add", (PyCFunction) PYOP_wrap_add, METH_O, NULL};
- static PyMethodDef pyop_add_macro_meth ={"add_macro", (PyCFunction) PYOP_wrap_add_macro, METH_O, NULL};
static PyMethodDef pyop_macro_def_meth ={"macro_define", (PyCFunction) PYOP_wrap_macro_define, METH_VARARGS, NULL};
- static PyMethodDef pyop_remove_meth = {"remove", (PyCFunction) PYOP_wrap_remove, METH_O, NULL};
PyObject *submodule = PyModule_New("_bpy.ops");
PyDict_SetItemString(PySys_GetObject("modules"), "_bpy.ops", submodule);
@@ -256,10 +253,7 @@ PyObject *BPY_operator_module( void )
PyModule_AddObject( submodule, "as_string",PyCFunction_New(&pyop_as_string_meth,NULL) );
PyModule_AddObject( submodule, "dir", PyCFunction_New(&pyop_dir_meth, NULL) );
PyModule_AddObject( submodule, "get_rna", PyCFunction_New(&pyop_getrna_meth, NULL) );
-// PyModule_AddObject( submodule, "add", PyCFunction_New(&pyop_add_meth, NULL) );
- PyModule_AddObject( submodule, "add_macro", PyCFunction_New(&pyop_add_macro_meth, NULL) );
PyModule_AddObject( submodule, "macro_define",PyCFunction_New(&pyop_macro_def_meth, NULL) );
- PyModule_AddObject( submodule, "remove", PyCFunction_New(&pyop_remove_meth, NULL) );
return submodule;
}
diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c
index 3bd18d98563..11f36d5f8ec 100644
--- a/source/blender/python/intern/bpy_operator_wrap.c
+++ b/source/blender/python/intern/bpy_operator_wrap.c
@@ -42,226 +42,6 @@
#include "../generic/bpy_internal_import.h" // our own imports
-#define PYOP_ATTR_UINAME "bl_label"
-#define PYOP_ATTR_IDNAME "bl_idname" /* the name given by python */
-#define PYOP_ATTR_IDNAME_BL "_bl_idname" /* our own name converted into blender syntax, users wont see this */
-#define PYOP_ATTR_DESCRIPTION "__doc__" /* use pythons docstring */
-#define PYOP_ATTR_REGISTER "bl_register" /* True/False. if this python operator should be registered */
-#define PYOP_ATTR_UNDO "bl_undo" /* True/False. if this python operator should be undone */
-
-static struct BPY_flag_def pyop_ret_flags[] = {
- {"RUNNING_MODAL", OPERATOR_RUNNING_MODAL},
- {"CANCELLED", OPERATOR_CANCELLED},
- {"FINISHED", OPERATOR_FINISHED},
- {"PASS_THROUGH", OPERATOR_PASS_THROUGH},
- {NULL, 0}
-};
-
-/* This invoke function can take events and
- *
- * It is up to the pyot->py_invoke() python func to run pyot->py_exec()
- * the invoke function gets the keyword props as a dict, but can parse them
- * to py_exec like this...
- *
- * def op_exec(x=-1, y=-1, text=""):
- * ...
- *
- * def op_invoke(event, prop_defs):
- * prop_defs['x'] = event['x']
- * ...
- * op_exec(**prop_defs)
- *
- * when there is no invoke function, C calls exec and sets the props.
- * python class instance is stored in op->customdata so exec() can access
- */
-
-
-#define PYOP_EXEC 1
-#define PYOP_INVOKE 2
-#define PYOP_POLL 3
-#define PYOP_DRAW 4
-
-extern void BPY_update_modules( void ); //XXX temp solution
-
-static int PYTHON_OT_generic(int mode, bContext *C, wmOperatorType *ot, wmOperator *op, wmEvent *event, uiLayout *layout)
-{
- PyObject *py_class = ot->pyop_data;
- PyObject *args;
- PyObject *ret= NULL, *py_class_instance, *item= NULL;
- int ret_flag= (mode==PYOP_POLL ? 0:OPERATOR_CANCELLED);
- PointerRNA ptr_context;
- PointerRNA ptr_operator;
-
- PyGILState_STATE gilstate;
-
- bpy_context_set(C, &gilstate);
-
- args = PyTuple_New(1);
-
- /* poll has no 'op', should be ok still */
- /* use an rna instance as the first arg */
- RNA_pointer_create(NULL, &RNA_Operator, op, &ptr_operator);
- PyTuple_SET_ITEM(args, 0, pyrna_struct_CreatePyObject(&ptr_operator));
-
- py_class_instance = PyObject_Call(py_class, args, NULL);
- Py_DECREF(args);
-
- if (py_class_instance==NULL) { /* Initializing the class worked, now run its invoke function */
- PyErr_Print();
- PyErr_Clear();
- }
- else {
- RNA_pointer_create(NULL, &RNA_Context, C, &ptr_context);
-
- if (mode==PYOP_INVOKE) {
- PointerRNA ptr_event;
- item= PyObject_GetAttrString(py_class, "invoke");
- args = PyTuple_New(3);
-
- RNA_pointer_create(NULL, &RNA_Event, event, &ptr_event);
-
- // PyTuple_SET_ITEM "steals" object reference, it is
- // an object passed shouldn't be DECREF'ed
- PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context));
- PyTuple_SET_ITEM(args, 2, pyrna_struct_CreatePyObject(&ptr_event));
- }
- else if (mode==PYOP_EXEC) {
- item= PyObject_GetAttrString(py_class, "execute");
- args = PyTuple_New(2);
-
- PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context));
- }
- else if (mode==PYOP_POLL) {
- item= PyObject_GetAttrString(py_class, "poll");
- args = PyTuple_New(2);
- PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context));
- }
- else if (mode==PYOP_DRAW) {
- PointerRNA ptr_layout;
- item= PyObject_GetAttrString(py_class, "draw");
- args = PyTuple_New(2);
-
- RNA_pointer_create(NULL, &RNA_UILayout, layout, &ptr_layout);
-
- // PyTuple_SET_ITEM "steals" object reference, it is
- // an object passed shouldn't be DECREF'ed
- PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context));
-#if 0
- PyTuple_SET_ITEM(args, 2, pyrna_struct_CreatePyObject(&ptr_layout));
-#else
- {
- /* mimic panels */
- PyObject *py_layout= pyrna_struct_CreatePyObject(&ptr_layout);
- PyObject *pyname= PyUnicode_FromString("layout");
-
- if(PyObject_GenericSetAttr(py_class_instance, pyname, py_layout)) {
- PyErr_Print();
- PyErr_Clear();
- }
- else {
- Py_DECREF(py_layout);
- }
-
- Py_DECREF(pyname);
- }
-#endif
- }
- PyTuple_SET_ITEM(args, 0, py_class_instance);
-
- ret = PyObject_Call(item, args, NULL);
-
- Py_DECREF(args);
- Py_DECREF(item);
- }
-
- if (ret == NULL) { /* covers py_class_instance failing too */
- if(op)
- BPy_errors_to_report(op->reports);
- }
- else {
- if (mode==PYOP_POLL) {
- if (PyBool_Check(ret) == 0) {
- PyErr_Format(PyExc_ValueError, "Python operator '%s.poll', did not return a bool value", ot->idname);
- BPy_errors_to_report(op ? op->reports:NULL); /* prints and clears if NULL given */
- }
- else {
- ret_flag= ret==Py_True ? 1:0;
- }
- } else if(mode==PYOP_DRAW) {
- /* pass */
- } else if (BPY_flag_from_seq(pyop_ret_flags, ret, &ret_flag) == -1) {
- /* the returned value could not be converted into a flag */
- PyErr_Format(PyExc_ValueError, "Python operator, error using return value from \"%s\"\n", ot->idname);
- BPy_errors_to_report(op ? op->reports:NULL);
- ret_flag = OPERATOR_CANCELLED;
- }
- /* there is no need to copy the py keyword dict modified by
- * pyot->py_invoke(), back to the operator props since they are just
- * thrown away anyway
- *
- * If we ever want to do this and use the props again,
- * it can be done with - pyrna_pydict_to_props(op->ptr, kw, "")
- */
-
- Py_DECREF(ret);
- }
-
-#if 0 /* only for testing */
-
- /* print operator return value */
- if (mode != PYOP_POLL) {
- char flag_str[100];
- char class_name[100];
- BPY_flag_def *flag_def = pyop_ret_flags;
-
- strcpy(flag_str, "");
-
- while(flag_def->name) {
- if (ret_flag & flag_def->flag) {
- if(flag_str[1])
- sprintf(flag_str, "%s | %s", flag_str, flag_def->name);
- else
- strcpy(flag_str, flag_def->name);
- }
- flag_def++;
- }
-
- /* get class name */
- item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME);
- strcpy(class_name, _PyUnicode_AsString(item));
- Py_DECREF(item);
-
- fprintf(stderr, "%s's %s returned %s\n", class_name, mode == PYOP_EXEC ? "execute" : "invoke", flag_str);
- }
-#endif
-
- bpy_context_clear(C, &gilstate);
-
- return ret_flag;
-}
-
-static int PYTHON_OT_invoke(bContext *C, wmOperator *op, wmEvent *event)
-{
- return PYTHON_OT_generic(PYOP_INVOKE, C, op->type, op, event, NULL);
-}
-
-static int PYTHON_OT_execute(bContext *C, wmOperator *op)
-{
- return PYTHON_OT_generic(PYOP_EXEC, C, op->type, op, NULL, NULL);
-}
-
-static int PYTHON_OT_poll(bContext *C, wmOperatorType *ot)
-{
- return PYTHON_OT_generic(PYOP_POLL, C, ot, NULL, NULL, NULL);
-}
-
-static void PYTHON_OT_draw(bContext *C, wmOperator *op, uiLayout *layout)
-{
- PYTHON_OT_generic(PYOP_DRAW, C, op->type, op, NULL, layout);
-}
-
-
-
void operator_wrapper(wmOperatorType *ot, void *userdata)
{
/* take care not to overwrite anything set in
@@ -299,288 +79,46 @@ void operator_wrapper(wmOperatorType *ot, void *userdata)
}
}
-
-
-
-
-void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
+void macro_wrapper(wmOperatorType *ot, void *userdata)
{
- PyObject *py_class = (PyObject *)userdata;
- PyObject *item;
+ wmOperatorType *data = (wmOperatorType *)userdata;
- /* identifiers */
- item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME_BL);
- ot->idname= _PyUnicode_AsString(item);
- Py_DECREF(item);
-
- item= PyObject_GetAttrString(py_class, PYOP_ATTR_UINAME);
- if (item) {
- ot->name= _PyUnicode_AsString(item);
- Py_DECREF(item);
- }
- else {
- ot->name= ot->idname;
- PyErr_Clear();
- }
-
- item= PyObject_GetAttrString(py_class, PYOP_ATTR_DESCRIPTION);
- ot->description= (item && PyUnicode_Check(item)) ? _PyUnicode_AsString(item):"undocumented python operator";
- Py_XDECREF(item);
-
- /* api callbacks, detailed checks dont on adding */
- if (PyObject_HasAttrString(py_class, "invoke"))
- ot->invoke= PYTHON_OT_invoke;
- //else
- // ot->invoke= WM_operator_props_popup; /* could have an option for standard invokes */
+ /* only copy a couple of things, the rest is set by the macro registration */
+ ot->name = data->name;
+ ot->idname = data->idname;
+ ot->description = data->description;
+ ot->flag |= data->flag; /* append flags to the one set by registration */
+ ot->pyop_poll = data->pyop_poll;
+ ot->ui = data->ui;
+ ot->ext = data->ext;
- if (PyObject_HasAttrString(py_class, "execute"))
- ot->exec= PYTHON_OT_execute;
- if (PyObject_HasAttrString(py_class, "poll"))
- ot->pyop_poll= PYTHON_OT_poll;
- if (PyObject_HasAttrString(py_class, "draw"))
- ot->ui= PYTHON_OT_draw;
-
- ot->pyop_data= userdata;
+ RNA_struct_blender_type_set(ot->ext.srna, ot);
- /* flags */
- ot->flag= 0;
-
- item= PyObject_GetAttrString(py_class, PYOP_ATTR_REGISTER);
- if (item) {
- ot->flag |= PyObject_IsTrue(item)!=0 ? OPTYPE_REGISTER:0;
- Py_DECREF(item);
- }
- else {
- PyErr_Clear();
- }
- item= PyObject_GetAttrString(py_class, PYOP_ATTR_UNDO);
- if (item) {
- ot->flag |= PyObject_IsTrue(item)!=0 ? OPTYPE_UNDO:0;
- Py_DECREF(item);
- }
- else {
- PyErr_Clear();
- }
/* Can't use this because it returns a dict proxy
*
* item= PyObject_GetAttrString(py_class, "__dict__");
*/
- item= ((PyTypeObject*)py_class)->tp_dict;
- if(item) {
- /* only call this so pyrna_deferred_register_props gives a useful error
- * WM_operatortype_append_ptr will call RNA_def_struct_identifier
- * later */
- RNA_def_struct_identifier(ot->srna, ot->idname);
+ {
+ PyObject *py_class = ot->ext.data;
+ PyObject *item= ((PyTypeObject*)py_class)->tp_dict;
+ if(item) {
+ /* only call this so pyrna_deferred_register_props gives a useful error
+ * WM_operatortype_append_ptr will call RNA_def_struct_identifier
+ * later */
+ RNA_def_struct_identifier(ot->srna, ot->idname);
- if(pyrna_deferred_register_props(ot->srna, item)!=0) {
- /* failed to register operator props */
- PyErr_Print();
- PyErr_Clear();
+ if(pyrna_deferred_register_props(ot->srna, item)!=0) {
+ /* failed to register operator props */
+ PyErr_Print();
+ PyErr_Clear();
+ }
}
- }
- else {
- PyErr_Clear();
- }
-}
-
-void PYTHON_OT_MACRO_wrapper(wmOperatorType *ot, void *userdata)
-{
- PyObject *py_class = (PyObject *)userdata;
- PyObject *item;
-
- /* identifiers */
- item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME_BL);
- ot->idname= _PyUnicode_AsString(item);
- Py_DECREF(item);
-
- item= PyObject_GetAttrString(py_class, PYOP_ATTR_UINAME);
- if (item) {
- ot->name= _PyUnicode_AsString(item);
- Py_DECREF(item);
- }
- else {
- ot->name= ot->idname;
- PyErr_Clear();
- }
-
- item= PyObject_GetAttrString(py_class, PYOP_ATTR_DESCRIPTION);
- ot->description= (item && PyUnicode_Check(item)) ? _PyUnicode_AsString(item):"undocumented python operator";
- Py_XDECREF(item);
-
- if (PyObject_HasAttrString(py_class, "poll"))
- ot->pyop_poll= PYTHON_OT_poll;
- if (PyObject_HasAttrString(py_class, "draw"))
- ot->ui= PYTHON_OT_draw;
-
- ot->pyop_data= userdata;
-
- /* flags */
- ot->flag= OPTYPE_MACRO; /* macro at least */
-
- item= PyObject_GetAttrString(py_class, PYOP_ATTR_REGISTER);
- if (item) {
- ot->flag |= PyObject_IsTrue(item)!=0 ? OPTYPE_REGISTER:0;
- Py_DECREF(item);
- }
- else {
- PyErr_Clear();
- }
- item= PyObject_GetAttrString(py_class, PYOP_ATTR_UNDO);
- if (item) {
- ot->flag |= PyObject_IsTrue(item)!=0 ? OPTYPE_UNDO:0;
- Py_DECREF(item);
- }
- else {
- PyErr_Clear();
- }
-
- /* Can't use this because it returns a dict proxy
- *
- * item= PyObject_GetAttrString(py_class, "__dict__");
- */
- item= ((PyTypeObject*)py_class)->tp_dict;
- if(item) {
- /* only call this so pyrna_deferred_register_props gives a useful error
- * WM_operatortype_append_macro_ptr will call RNA_def_struct_identifier
- * later */
- RNA_def_struct_identifier(ot->srna, ot->idname);
-
- if(pyrna_deferred_register_props(ot->srna, item)!=0) {
- /* failed to register operator props */
- PyErr_Print();
+ else {
PyErr_Clear();
-
}
}
- else {
- PyErr_Clear();
- }
-}
-
-
-/* pyOperators - Operators defined IN Python */
-PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class)
-{
- PyObject *base_class, *item;
- wmOperatorType *ot;
-
-
- char *idname= NULL;
- char idname_bl[OP_MAX_TYPENAME]; /* converted to blender syntax */
-
- static struct BPY_class_attr_check pyop_class_attr_values[]= {
- {PYOP_ATTR_IDNAME, 's', -1, OP_MAX_TYPENAME-3, 0}, /* -3 because a.b -> A_OT_b */
- {PYOP_ATTR_UINAME, 's', -1,-1, BPY_CLASS_ATTR_OPTIONAL},
- {PYOP_ATTR_DESCRIPTION, 's', -1,-1, BPY_CLASS_ATTR_NONE_OK},
- {"execute", 'f', 2, -1, BPY_CLASS_ATTR_OPTIONAL},
- {"invoke", 'f', 3, -1, BPY_CLASS_ATTR_OPTIONAL},
- {"poll", 'f', 2, -1, BPY_CLASS_ATTR_OPTIONAL},
- {"draw", 'f', 2, -1, BPY_CLASS_ATTR_OPTIONAL},
- {NULL, 0, 0, 0}
- };
-
- // in python would be...
- //PyObject *optype = PyObject_GetAttrString(PyObject_GetAttrString(PyDict_GetItemString(PyEval_GetGlobals(), "bpy"), "types"), "Operator");
-
- //PyObject bpy_mod= PyDict_GetItemString(PyEval_GetGlobals(), "bpy");
- PyObject *bpy_mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
- base_class = PyObject_GetAttrStringArgs(bpy_mod, 2, "types", "Operator");
- Py_DECREF(bpy_mod);
-
- if(BPY_class_validate("Operator", py_class, base_class, pyop_class_attr_values, NULL) < 0) {
- return NULL; /* BPY_class_validate sets the error */
- }
- Py_DECREF(base_class);
-
- /* class name is used for operator ID - this can be changed later if we want */
- item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME);
- idname = _PyUnicode_AsString(item);
-
-
- /* annoying conversion! */
- WM_operator_bl_idname(idname_bl, idname);
- Py_DECREF(item);
-
- item= PyUnicode_FromString(idname_bl);
- PyObject_SetAttrString(py_class, PYOP_ATTR_IDNAME_BL, item);
- idname = _PyUnicode_AsString(item);
- Py_DECREF(item);
- /* end annoying conversion! */
-
-
- /* remove if it already exists */
- if ((ot=WM_operatortype_exists(idname))) {
- if(ot->pyop_data) {
- Py_XDECREF((PyObject*)ot->pyop_data);
- }
- WM_operatortype_remove(idname);
- }
-
- Py_INCREF(py_class);
- WM_operatortype_append_ptr(PYTHON_OT_wrapper, py_class);
-
- Py_RETURN_NONE;
-}
-
-/* pyOperators - Macro Operators defined IN Python */
-PyObject *PYOP_wrap_add_macro(PyObject *self, PyObject *py_class)
-{
- PyObject *base_class, *item;
- wmOperatorType *ot;
-
-
- char *idname= NULL;
- char idname_bl[OP_MAX_TYPENAME]; /* converted to blender syntax */
-
- static struct BPY_class_attr_check pyop_class_attr_values[]= {
- {PYOP_ATTR_IDNAME, 's', -1, OP_MAX_TYPENAME-3, 0}, /* -3 because a.b -> A_OT_b */
- {PYOP_ATTR_UINAME, 's', -1,-1, BPY_CLASS_ATTR_OPTIONAL},
- {PYOP_ATTR_DESCRIPTION, 's', -1,-1, BPY_CLASS_ATTR_NONE_OK},
- {"poll", 'f', 2, -1, BPY_CLASS_ATTR_OPTIONAL},
- {"draw", 'f', 2, -1, BPY_CLASS_ATTR_OPTIONAL},
- {NULL, 0, 0, 0}
- };
-
- //PyObject bpy_mod= PyDict_GetItemString(PyEval_GetGlobals(), "bpy");
- PyObject *bpy_mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
- base_class = PyObject_GetAttrStringArgs(bpy_mod, 2, "types", "Macro");
- Py_DECREF(bpy_mod);
-
- if(BPY_class_validate("Macro", py_class, base_class, pyop_class_attr_values, NULL) < 0) {
- return NULL; /* BPY_class_validate sets the error */
- }
- Py_DECREF(base_class);
-
- /* class name is used for operator ID - this can be changed later if we want */
- item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME);
- idname = _PyUnicode_AsString(item);
-
-
- /* annoying conversion! */
- WM_operator_bl_idname(idname_bl, idname);
- Py_DECREF(item);
-
- item= PyUnicode_FromString(idname_bl);
- PyObject_SetAttrString(py_class, PYOP_ATTR_IDNAME_BL, item);
- idname = _PyUnicode_AsString(item);
- Py_DECREF(item);
- /* end annoying conversion! */
-
-
- /* remove if it already exists */
- if ((ot=WM_operatortype_exists(idname))) {
- if(ot->pyop_data) {
- Py_XDECREF((PyObject*)ot->pyop_data);
- }
- WM_operatortype_remove(idname);
- }
-
- Py_INCREF(py_class);
- WM_operatortype_append_macro_ptr(PYTHON_OT_MACRO_wrapper, py_class);
-
- Py_RETURN_NONE;
}
PyObject *PYOP_wrap_macro_define(PyObject *self, PyObject *args)
@@ -588,11 +126,11 @@ PyObject *PYOP_wrap_macro_define(PyObject *self, PyObject *args)
wmOperatorType *ot;
wmOperatorTypeMacro *otmacro;
PyObject *macro;
- PyObject *item;
PointerRNA ptr_otmacro;
+ StructRNA *srna;
char *opname;
- char *macroname;
+ const char *macroname;
if (!PyArg_ParseTuple(args, "Os:_bpy.ops.macro_define", &macro, &opname))
return NULL;
@@ -603,21 +141,8 @@ PyObject *PYOP_wrap_macro_define(PyObject *self, PyObject *args)
}
/* identifiers */
- item= PyObject_GetAttrString(macro, PYOP_ATTR_IDNAME_BL);
-
- if (!item) {
- item= PyObject_GetAttrString(macro, PYOP_ATTR_IDNAME);
-
- if (!item) {
- PyErr_Format(PyExc_ValueError, "Macro Define: not a valid Macro class");
- } else {
- macroname= _PyUnicode_AsString(item);
- PyErr_Format(PyExc_ValueError, "Macro Define: '%s' hasn't been registered yet", macroname);
- }
- return NULL;
- }
-
- macroname= _PyUnicode_AsString(item);
+ srna= srna_from_self(macro);
+ macroname = RNA_struct_identifier(srna);
ot = WM_operatortype_exists(macroname);
@@ -633,40 +158,3 @@ PyObject *PYOP_wrap_macro_define(PyObject *self, PyObject *args)
return pyrna_struct_CreatePyObject(&ptr_otmacro);
}
-
-PyObject *PYOP_wrap_remove(PyObject *self, PyObject *value)
-{
- PyObject *py_class;
- char *idname= NULL;
- wmOperatorType *ot;
-
-
- if (PyUnicode_Check(value))
- idname = _PyUnicode_AsString(value);
- else if (PyCFunction_Check(value)) {
- PyObject *cfunc_self = PyCFunction_GetSelf(value);
- if (cfunc_self)
- idname = _PyUnicode_AsString(cfunc_self);
- }
-
- if (idname==NULL) {
- PyErr_SetString( PyExc_ValueError, "Expected the operator name as a string or the operator function");
- return NULL;
- }
-
- if (!(ot= WM_operatortype_exists(idname))) {
- PyErr_Format( PyExc_AttributeError, "Operator \"%s\" does not exists, cant remove", idname);
- return NULL;
- }
-
- if (!(py_class= (PyObject *)ot->pyop_data)) {
- PyErr_Format( PyExc_AttributeError, "Operator \"%s\" was not created by python", idname);
- return NULL;
- }
-
- Py_XDECREF(py_class);
-
- WM_operatortype_remove(idname);
-
- Py_RETURN_NONE;
-}
diff --git a/source/blender/python/intern/bpy_operator_wrap.h b/source/blender/python/intern/bpy_operator_wrap.h
index 939fedd1f2b..b55dd674dbf 100644
--- a/source/blender/python/intern/bpy_operator_wrap.h
+++ b/source/blender/python/intern/bpy_operator_wrap.h
@@ -28,9 +28,5 @@
#include <Python.h>
/* these are used for operator methods, used by bpy_operator.c */
-PyObject *PYOP_wrap_add(PyObject *self, PyObject *args);
-PyObject *PYOP_wrap_add_macro(PyObject *self, PyObject *args);
PyObject *PYOP_wrap_macro_define(PyObject *self, PyObject *args);
-PyObject *PYOP_wrap_remove(PyObject *self, PyObject *args);
-
#endif
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 7c4e49e93e3..ace638914dc 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -1,3 +1,4 @@
+
/**
* $Id$
*
@@ -53,6 +54,8 @@
#include "../generic/Mathutils.h" /* so we can have mathutils callbacks */
#include "../generic/IDProp.h" /* for IDprop lookups */
+static PyObject *prop_subscript_array_slice(PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length);
+
/* bpyrna vector/euler/quat callbacks */
static int mathutils_rna_array_cb_index= -1; /* index for our callbacks */
@@ -138,6 +141,8 @@ Mathutils_Callback mathutils_rna_matrix_cb = {
(BaseMathSetIndexFunc) NULL
};
+#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)
{
PyObject *ret= NULL;
@@ -146,28 +151,24 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
int subtype, totdim;
int len;
int is_thick;
+ int flag= RNA_property_flag(prop);
/* disallow dynamic sized arrays to be wrapped since the size could change
* to a size mathutils does not support */
- if ((RNA_property_type(prop) != PROP_FLOAT) || (RNA_property_flag(prop) & PROP_DYNAMIC))
+ if ((RNA_property_type(prop) != PROP_FLOAT) || (flag & PROP_DYNAMIC))
return NULL;
len= RNA_property_array_length(ptr, prop);
subtype= RNA_property_subtype(prop);
totdim= RNA_property_array_dimension(ptr, prop, NULL);
- is_thick = (RNA_property_flag(prop) & PROP_THICK_WRAP);
+ is_thick = (flag & PROP_THICK_WRAP);
if (totdim == 1 || (totdim == 2 && subtype == PROP_MATRIX)) {
if(!is_thick)
ret = pyrna_prop_CreatePyObject(ptr, prop); /* owned by the Mathutils PyObject */
switch(RNA_property_subtype(prop)) {
- case PROP_TRANSLATION:
- case PROP_DIRECTION:
- case PROP_VELOCITY:
- case PROP_ACCELERATION:
- case PROP_XYZ:
- case PROP_XYZ|PROP_UNIT_LENGTH:
+ case PROP_ALL_VECTOR_SUBTYPES:
if(len>=2 && len <= 4) {
if(is_thick) {
ret= newVectorObject(NULL, len, Py_NEW, NULL);
@@ -234,8 +235,15 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
}
}
- if(ret==NULL)
- ret = pyrna_prop_CreatePyObject(ptr, prop); /* TODO, convert to a python list */
+ if(ret==NULL) {
+ if(is_thick) {
+ /* this is an array we cant reference (since its not thin wrappable)
+ * and cannot be coerced into a mathutils type, so return as a list */
+ ret = prop_subscript_array_slice(ptr, prop, 0, len, len);
+ } else {
+ ret = pyrna_prop_CreatePyObject(ptr, prop); /* owned by the Mathutils PyObject */
+ }
+ }
#endif
@@ -244,8 +252,6 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
#endif
-static StructRNA *pyrna_struct_as_srna(PyObject *self);
-
static int pyrna_struct_compare( BPy_StructRNA * a, BPy_StructRNA * b )
{
return (a->ptr.data==b->ptr.data) ? 0 : -1;
@@ -1001,7 +1007,7 @@ static PyObject *prop_subscript_collection_str(BPy_PropertyRNA *self, char *keyn
}
/* static PyObject *prop_subscript_array_str(BPy_PropertyRNA *self, char *keyname) */
-static PyObject *prop_subscript_collection_slice(BPy_PropertyRNA *self, int start, int stop)
+static PyObject *prop_subscript_collection_slice(PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length)
{
PointerRNA newptr;
PyObject *list = PyList_New(stop - start);
@@ -1010,8 +1016,8 @@ static PyObject *prop_subscript_collection_slice(BPy_PropertyRNA *self, int star
start = MIN2(start,stop); /* values are clamped from */
for(count = start; count < stop; count++) {
- if(RNA_property_collection_lookup_int(&self->ptr, self->prop, count - start, &newptr)) {
- PyList_SetItem(list, count - start, pyrna_struct_CreatePyObject(&newptr));
+ if(RNA_property_collection_lookup_int(ptr, prop, count - start, &newptr)) {
+ PyList_SET_ITEM(list, count - start, pyrna_struct_CreatePyObject(&newptr));
}
else {
Py_DECREF(list);
@@ -1023,16 +1029,72 @@ static PyObject *prop_subscript_collection_slice(BPy_PropertyRNA *self, int star
return list;
}
-static PyObject *prop_subscript_array_slice(BPy_PropertyRNA *self, int start, int stop)
+
+/* TODO - dimensions
+ * note: could also use pyrna_prop_to_py_index(self, count) in a loop but its a lot slower
+ * since at the moment it reads (and even allocates) the entire array for each index.
+ */
+#define PYRNA_STACK_ARRAY 32
+static PyObject *prop_subscript_array_slice(PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length)
{
PyObject *list = PyList_New(stop - start);
int count;
- start = MIN2(start,stop); /* values are clamped from PySlice_GetIndicesEx */
+ switch (RNA_property_type(prop)) {
+ case PROP_FLOAT:
+ {
+ float values_stack[PYRNA_STACK_ARRAY];
+ float *values;
+ if(length > PYRNA_STACK_ARRAY) { values= PyMem_MALLOC(sizeof(float) * length); }
+ else { values= values_stack; }
+ RNA_property_float_get_array(ptr, prop, values);
+
+ for(count=start; count<stop; count++)
+ PyList_SET_ITEM(list, count-start, PyFloat_FromDouble(values[count]));
- for(count = start; count < stop; count++)
- PyList_SetItem(list, count - start, pyrna_prop_to_py_index(self, count));
+ if(values != values_stack) {
+ PyMem_FREE(values);
+ }
+ break;
+ }
+ case PROP_BOOLEAN:
+ {
+ int values_stack[PYRNA_STACK_ARRAY];
+ int *values;
+ if(length > PYRNA_STACK_ARRAY) { values= PyMem_MALLOC(sizeof(int) * length); }
+ else { values= values_stack; }
+ RNA_property_boolean_get_array(ptr, prop, values);
+ for(count=start; count<stop; count++)
+ PyList_SET_ITEM(list, count-start, PyBool_FromLong(values[count]));
+
+ if(values != values_stack) {
+ PyMem_FREE(values);
+ }
+ break;
+ }
+ case PROP_INT:
+ {
+ int values_stack[PYRNA_STACK_ARRAY];
+ int *values;
+ if(length > PYRNA_STACK_ARRAY) { values= PyMem_MALLOC(sizeof(int) * length); }
+ else { values= values_stack; }
+
+ RNA_property_int_get_array(ptr, prop, values);
+ for(count=start; count<stop; count++)
+ PyList_SET_ITEM(list, count-start, PyLong_FromSsize_t(values[count]));
+
+ if(values != values_stack) {
+ PyMem_FREE(values);
+ }
+ break;
+ }
+ default:
+ /* probably will never happen */
+ PyErr_SetString(PyExc_TypeError, "not an array type");
+ Py_DECREF(list);
+ list= NULL;
+ }
return list;
}
@@ -1059,7 +1121,7 @@ static PyObject *prop_subscript_collection(BPy_PropertyRNA *self, PyObject *key)
return PyList_New(0);
}
else if (step == 1) {
- return prop_subscript_collection_slice(self, start, stop);
+ return prop_subscript_collection_slice(&self->ptr, self->prop, start, stop, len);
}
else {
PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna");
@@ -1094,7 +1156,7 @@ static PyObject *prop_subscript_array(BPy_PropertyRNA *self, PyObject *key)
return PyList_New(0);
}
else if (step == 1) {
- return prop_subscript_array_slice(self, start, stop);
+ return prop_subscript_array_slice(&self->ptr, self->prop, start, stop, len);
}
else {
PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna");
@@ -1119,21 +1181,93 @@ static PyObject *pyrna_prop_subscript( BPy_PropertyRNA *self, PyObject *key )
return NULL;
}
-static int prop_subscript_ass_array_slice(BPy_PropertyRNA *self, int begin, int end, PyObject *value)
+/* could call (pyrna_py_to_prop_index(self, i, value) in a loop but it is slow */
+static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length, PyObject *value_orig)
{
+ PyObject *value;
int count;
+ void *values_alloc= NULL;
+ int ret= 0;
- /* values are clamped from */
- begin = MIN2(begin,end);
+ if(value_orig == NULL) {
+ PyErr_SetString(PyExc_TypeError, "invalid slice assignment, deleting with list types is not supported by StructRNA.");
+ return -1;
+ }
- for(count = begin; count < end; count++) {
- if(pyrna_py_to_prop_index(self, count - begin, value) == -1) {
- /* TODO - this is wrong since some values have been assigned... will need to fix that */
- return -1; /* pyrna_struct_CreatePyObject should set the error */
+ if(!(value=PySequence_Fast(value_orig, "invalid slice assignment, 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.");
+ return -1;
+ }
+
+ switch (RNA_property_type(prop)) {
+ case PROP_FLOAT:
+ {
+ float values_stack[PYRNA_STACK_ARRAY];
+ float *values;
+ if(length > PYRNA_STACK_ARRAY) { values= values_alloc= PyMem_MALLOC(sizeof(float) * length); }
+ else { values= values_stack; }
+ if(start != 0 || stop != length) /* partial assignment? - need to get the array */
+ RNA_property_float_get_array(ptr, prop, values);
+
+ for(count=start; count<stop; count++)
+ values[count] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, count-start));
+
+ if(PyErr_Occurred()) ret= -1;
+ else RNA_property_float_set_array(ptr, prop, values);
+ break;
+ }
+ case PROP_BOOLEAN:
+ {
+ int values_stack[PYRNA_STACK_ARRAY];
+ int *values;
+ if(length > PYRNA_STACK_ARRAY) { values= values_alloc= PyMem_MALLOC(sizeof(int) * length); }
+ else { values= values_stack; }
+
+ if(start != 0 || stop != length) /* partial assignment? - need to get the array */
+ RNA_property_boolean_get_array(ptr, prop, values);
+
+ for(count=start; count<stop; count++)
+ values[count] = PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, count-start));
+
+ if(PyErr_Occurred()) ret= -1;
+ else RNA_property_boolean_set_array(ptr, prop, values);
+ break;
}
+ case PROP_INT:
+ {
+ int values_stack[PYRNA_STACK_ARRAY];
+ int *values;
+ if(length > PYRNA_STACK_ARRAY) { values= values_alloc= PyMem_MALLOC(sizeof(int) * length); }
+ else { values= values_stack; }
+
+ if(start != 0 || stop != length) /* partial assignment? - need to get the array */
+ RNA_property_int_get_array(ptr, prop, values);
+
+ for(count=start; count<stop; count++)
+ values[count] = PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, count-start));
+
+ if(PyErr_Occurred()) ret= -1;
+ else RNA_property_int_set_array(ptr, prop, values);
+ break;
+ }
+ default:
+ PyErr_SetString(PyExc_TypeError, "not an array type");
+ ret= -1;
}
- return 0;
+ Py_DECREF(value);
+
+ if(values_alloc) {
+ PyMem_FREE(values_alloc);
+ }
+
+ return ret;
+
}
static int prop_subscript_ass_array_int(BPy_PropertyRNA *self, int keynum, PyObject *value)
@@ -1182,7 +1316,7 @@ static int pyrna_prop_ass_subscript( BPy_PropertyRNA *self, PyObject *key, PyObj
return 0;
}
else if (step == 1) {
- return prop_subscript_ass_array_slice(self, start, stop, value);
+ return prop_subscript_ass_array_slice(&self->ptr, self->prop, start, stop, len, value);
}
else {
PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna");
@@ -1872,6 +2006,16 @@ static PyObject *pyrna_prop_getattro( BPy_PropertyRNA *self, PyObject *pyname )
}
}
}
+ else {
+ /* annoying exception, maybe we need to have different types for this... */
+ if((strcmp(name, "__getitem__")==0 || strcmp(name, "__setitem__")==0) &&
+ (RNA_property_type(self->prop) != PROP_COLLECTION) &&
+ RNA_property_array_check(&self->ptr, self->prop)==0
+ ) {
+ PyErr_SetString(PyExc_AttributeError, "PropertyRNA - no __getitem__ support for this type");
+ return NULL;
+ }
+ }
/* The error raised here will be displayed */
return PyObject_GenericGetAttr((PyObject *)self, pyname);
@@ -2104,10 +2248,11 @@ static void foreach_attr_type( BPy_PropertyRNA *self, char *attr,
RawPropertyType *raw_type, int *attr_tot, int *attr_signed )
{
PropertyRNA *prop;
- *raw_type= -1;
+ *raw_type= PROP_RAW_UNSET;
*attr_tot= 0;
*attr_signed= FALSE;
+ /* note: this is fail with zero length lists, so dont let this get caled in that case */
RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
prop = RNA_struct_find_property(&itemptr, attr);
*raw_type= RNA_property_raw_type(prop);
@@ -2130,7 +2275,8 @@ static int foreach_parse_args(
int target_tot;
#endif
- *size= *raw_type= *attr_tot= *attr_signed= FALSE;
+ *size= *attr_tot= *attr_signed= FALSE;
+ *raw_type= PROP_RAW_UNSET;
if(!PyArg_ParseTuple(args, "sO", attr, seq) || (!PySequence_Check(*seq) && PyObject_CheckBuffer(*seq))) {
PyErr_SetString( PyExc_TypeError, "foreach_get(attr, sequence) expects a string and a sequence" );
@@ -2163,6 +2309,12 @@ static int foreach_parse_args(
#endif
}
+ /* check 'attr_tot' otherwise we dont know if any values were set
+ * this isnt ideal because it means running on an empty list may fail silently when its not compatible. */
+ if (*size == 0 && *attr_tot != 0) {
+ PyErr_SetString( PyExc_AttributeError, "attribute does not support foreach method" );
+ return -1;
+ }
return 0;
}
@@ -2184,6 +2336,8 @@ static int foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, cons
return (f=='f') ? 1:0;
case PROP_RAW_DOUBLE:
return (f=='d') ? 1:0;
+ case PROP_RAW_UNSET:
+ return 0;
}
return 0;
@@ -2248,6 +2402,9 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
case PROP_RAW_DOUBLE:
((double *)array)[i]= (double)PyFloat_AsDouble(item);
break;
+ case PROP_RAW_UNSET:
+ /* should never happen */
+ break;
}
Py_DECREF(item);
@@ -2299,6 +2456,9 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
case PROP_RAW_DOUBLE:
item= PyFloat_FromDouble( (double) ((double *)array)[i] );
break;
+ case PROP_RAW_UNSET:
+ /* should never happen */
+ break;
}
PySequence_SetItem(seq, i, item);
@@ -2343,14 +2503,8 @@ PyObject *pyrna_prop_iter(BPy_PropertyRNA *self)
PyObject *iter;
if(RNA_property_array_check(&self->ptr, self->prop)) {
- int len = pyrna_prop_array_length(self);
- int i;
- PyErr_Clear();
- ret = PyList_New(len);
-
- for (i=0; i < len; i++) {
- PyList_SET_ITEM(ret, i, pyrna_prop_to_py_index(self, i));
- }
+ int len= pyrna_prop_array_length(self);
+ ret = prop_subscript_array_slice(&self->ptr, self->prop, 0, len, len);
}
else if ((ret = pyrna_prop_values(self))) {
/* do nothing */
@@ -2449,29 +2603,48 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
{
PyObject *ret;
int type = RNA_property_type(prop);
-
+ int flag = RNA_property_flag(prop);
int a;
if(RNA_property_array_check(ptr, prop)) {
int len = RNA_property_array_length(ptr, prop);
/* resolve the array from a new pytype */
- ret = PyTuple_New(len);
/* kazanbas: TODO make multidim sequences here */
switch (type) {
case PROP_BOOLEAN:
+ ret = PyTuple_New(len);
for(a=0; a<len; a++)
PyTuple_SET_ITEM(ret, a, PyBool_FromLong( ((int*)data)[a] ));
break;
case PROP_INT:
+ ret = PyTuple_New(len);
for(a=0; a<len; a++)
PyTuple_SET_ITEM(ret, a, PyLong_FromSsize_t( (Py_ssize_t)((int*)data)[a] ));
break;
case PROP_FLOAT:
- for(a=0; a<len; a++)
- PyTuple_SET_ITEM(ret, a, PyFloat_FromDouble( ((float*)data)[a] ));
+ switch(RNA_property_subtype(prop)) {
+ case PROP_ALL_VECTOR_SUBTYPES:
+ ret= newVectorObject(data, len, Py_NEW, NULL);
+ break;
+ case PROP_MATRIX:
+ if(len==16) {
+ ret= newMatrixObject(data, 4, 4, Py_NEW, NULL);
+ break;
+ }
+ else if (len==9) {
+ ret= newMatrixObject(data, 3, 3, Py_NEW, NULL);
+ break;
+ }
+ /* pass through */
+ default:
+ ret = PyTuple_New(len);
+ for(a=0; a<len; a++)
+ PyTuple_SET_ITEM(ret, a, PyFloat_FromDouble( ((float*)data)[a] ));
+
+ }
break;
default:
PyErr_Format(PyExc_TypeError, "RNA Error: unknown array type \"%d\" (pyrna_param_to_py)", type);
@@ -2493,7 +2666,10 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
break;
case PROP_STRING:
{
- ret = PyUnicode_FromString( *(char**)data );
+ if(flag & PROP_THICK_WRAP)
+ ret = PyUnicode_FromString( (char*)data );
+ else
+ ret = PyUnicode_FromString( *(char**)data );
break;
}
case PROP_ENUM:
@@ -2505,7 +2681,6 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
{
PointerRNA newptr;
StructRNA *type= RNA_property_pointer_type(ptr, prop);
- int flag = RNA_property_flag(prop);
if(flag & PROP_RNAPTR) {
/* in this case we get the full ptr */
@@ -2566,11 +2741,13 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
PointerRNA funcptr;
ParameterList parms;
ParameterIterator iter;
- PropertyRNA *pret, *parm;
+ PropertyRNA *parm;
PyObject *ret, *item;
- int i, args_len, parms_len, flag, err= 0, kw_tot= 0, kw_arg;
+ int i, args_len, parms_len, ret_len, flag, err= 0, kw_tot= 0, kw_arg;
const char *parm_id;
- void *retdata= NULL;
+
+ PropertyRNA *pret_single= NULL;
+ void *retdata_single= NULL;
/* Should never happen but it does in rare cases */
if(self_ptr==NULL) {
@@ -2588,14 +2765,15 @@ 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);
- pret= RNA_function_return(self_func);
args_len= PyTuple_GET_SIZE(args);
RNA_parameter_list_create(&parms, self_ptr, self_func);
RNA_parameter_list_begin(&parms, &iter);
- parms_len = RNA_parameter_list_size(&parms);
+ parms_len= RNA_parameter_list_size(&parms);
+ ret_len= 0;
if(args_len + (kw ? PyDict_Size(kw):0) > 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);
err= -1;
}
@@ -2603,14 +2781,20 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
/* parse function parameters */
for (i= 0; iter.valid && err==0; RNA_parameter_list_next(&iter)) {
parm= iter.parm;
+ flag= RNA_property_flag(parm);
+
+ /* only useful for single argument returns, we'll need another list loop for multiple */
+ if (flag & PROP_RETURN) {
+ ret_len++;
+ if (pret_single==NULL) {
+ pret_single= parm;
+ retdata_single= iter.data;
+ }
- if (parm==pret) {
- retdata= iter.data;
continue;
}
parm_id= RNA_property_identifier(parm);
- flag= RNA_property_flag(parm);
item= NULL;
if ((i < args_len) && (flag & PROP_REQUIRED)) {
@@ -2655,6 +2839,8 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
break;
}
}
+
+ RNA_parameter_list_end(&iter);
/* Check if we gave args that dont exist in the function
@@ -2742,8 +2928,25 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
/* return value */
if(err==0) {
- if(pret) {
- ret= pyrna_param_to_py(&funcptr, pret, retdata);
+ if (ret_len > 0) {
+ if (ret_len > 1) {
+ ret= PyTuple_New(ret_len);
+ i= 0; /* arg index */
+
+ RNA_parameter_list_begin(&parms, &iter);
+
+ for(; iter.valid; RNA_parameter_list_next(&iter)) {
+ parm= iter.parm;
+ flag= RNA_property_flag(parm);
+
+ if (flag & PROP_RETURN)
+ PyTuple_SET_ITEM(ret, i++, pyrna_param_to_py(&funcptr, parm, iter.data));
+ }
+
+ RNA_parameter_list_end(&iter);
+ }
+ else
+ ret= pyrna_param_to_py(&funcptr, pret_single, retdata_single);
/* possible there is an error in conversion */
if(ret==NULL)
@@ -3354,7 +3557,7 @@ PyObject *BPY_rna_props( void )
return submodule;
}
-static StructRNA *pyrna_struct_as_srna(PyObject *self)
+StructRNA *pyrna_struct_as_srna(PyObject *self)
{
BPy_StructRNA *py_srna = NULL;
StructRNA *srna;
@@ -3395,7 +3598,7 @@ static StructRNA *pyrna_struct_as_srna(PyObject *self)
/* Orphan functions, not sure where they should go */
/* get the srna for methods attached to types */
/* */
-static StructRNA *srna_from_self(PyObject *self)
+StructRNA *srna_from_self(PyObject *self)
{
/* a bit sloppy but would cause a very confusing bug if
* an error happened to be set here */
@@ -3937,31 +4140,26 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
item = PyObject_GetAttrString(py_class, identifier);
if (item==NULL) {
-
/* Sneaky workaround to use the class name as the bl_idname */
- if(strcmp(identifier, "bl_idname") == 0) {
- item= PyObject_GetAttrString(py_class, "__name__");
- if(item) {
- Py_DECREF(item); /* no need to keep a ref, the class owns it */
+#define BPY_REPLACEMENT_STRING(rna_attr, py_attr) \
+ if(strcmp(identifier, rna_attr) == 0) { \
+ item= PyObject_GetAttrString(py_class, py_attr); \
+ if(item && item != Py_None) { \
+ if(pyrna_py_to_prop(dummyptr, prop, NULL, item, "validating class error:") != 0) { \
+ Py_DECREF(item); \
+ return -1; \
+ } \
+ } \
+ Py_XDECREF(item); \
+ } \
- if(pyrna_py_to_prop(dummyptr, prop, NULL, item, "validating class error:") != 0)
- return -1;
- }
- }
-#if 0
- if(strcmp(identifier, "bl_label") == 0) {
- item= PyObject_GetAttrString(py_class, "__doc__");
+ BPY_REPLACEMENT_STRING("bl_idname", "__name__");
+ BPY_REPLACEMENT_STRING("bl_description", "__doc__");
- if(item) {
- Py_DECREF(item); /* no need to keep a ref, the class owns it */
+#undef BPY_REPLACEMENT_STRING
- if(pyrna_py_to_prop(dummyptr, prop, NULL, item, "validating class error:") != 0)
- return -1;
- }
- }
-#endif
if (item == NULL && (((flag & PROP_REGISTER_OPTIONAL) != PROP_REGISTER_OPTIONAL))) {
PyErr_Format( PyExc_AttributeError, "expected %.200s, %.200s class to have an \"%.200s\" attribute", class_type, py_class_name, identifier);
return -1;
@@ -3982,15 +4180,18 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
extern void BPY_update_modules( void ); //XXX temp solution
+/* TODO - multiple return values like with rna functions */
static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *parms)
{
PyObject *args;
PyObject *ret= NULL, *py_class, *py_class_instance, *item, *parmitem;
- PropertyRNA *pret= NULL, *parm;
+ PropertyRNA *parm;
ParameterIterator iter;
PointerRNA funcptr;
- void *retdata= NULL;
- int err= 0, i, flag;
+ int err= 0, i, flag, ret_len=0;
+
+ PropertyRNA *pret_single= NULL;
+ void *retdata_single= NULL;
PyGILState_STATE gilstate;
@@ -4016,10 +4217,9 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par
if (py_class_instance) { /* Initializing the class worked, now run its invoke function */
item= PyObject_GetAttrString(py_class, RNA_function_identifier(func));
- flag= RNA_function_flag(func);
+// flag= RNA_function_flag(func);
if(item) {
- pret= RNA_function_return(func);
RNA_pointer_create(NULL, &RNA_Function, func, &funcptr);
args = PyTuple_New(rna_function_arg_count(func)); /* first arg is included in 'item' */
@@ -4030,9 +4230,16 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par
/* parse function parameters */
for (i= 1; iter.valid; RNA_parameter_list_next(&iter)) {
parm= iter.parm;
+ flag= RNA_property_flag(parm);
+
+ /* only useful for single argument returns, we'll need another list loop for multiple */
+ if (flag & PROP_RETURN) {
+ ret_len++;
+ if (pret_single==NULL) {
+ pret_single= parm;
+ retdata_single= iter.data;
+ }
- if (parm==pret) {
- retdata= iter.data;
continue;
}
@@ -4043,6 +4250,7 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par
ret = PyObject_Call(item, args, NULL);
+ RNA_parameter_list_end(&iter);
Py_DECREF(item);
Py_DECREF(args);
}
@@ -4062,8 +4270,39 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par
err= -1;
}
else {
- if(retdata)
- err= pyrna_py_to_prop(&funcptr, pret, retdata, ret, "calling class function:");
+ if(ret_len==1) {
+ err= pyrna_py_to_prop(&funcptr, pret_single, retdata_single, ret, "calling class function:");
+ }
+ else if (ret_len > 1) {
+
+ if(PyTuple_Check(ret)==0) {
+ PyErr_Format(PyExc_RuntimeError, "expected class %.200s, function %.200s to return a tuple of size %d.", RNA_struct_identifier(ptr->type), RNA_function_identifier(func), ret_len);
+ err= -1;
+ }
+ else if (PyTuple_GET_SIZE(ret) != ret_len) {
+ PyErr_Format(PyExc_RuntimeError, "class %.200s, function %.200s to returned %d items, expected %d.", RNA_struct_identifier(ptr->type), RNA_function_identifier(func), PyTuple_GET_SIZE(ret), ret_len);
+ err= -1;
+ }
+ else {
+
+ RNA_parameter_list_begin(parms, &iter);
+
+ /* parse function parameters */
+ for (i= 0; iter.valid; RNA_parameter_list_next(&iter)) {
+ parm= iter.parm;
+ flag= RNA_property_flag(parm);
+
+ /* only useful for single argument returns, we'll need another list loop for multiple */
+ if (flag & PROP_RETURN) {
+ err= pyrna_py_to_prop(&funcptr, parm, iter.data, PyTuple_GET_ITEM(ret, i++), "calling class function:");
+ if(err)
+ break;
+ }
+ }
+
+ RNA_parameter_list_end(&iter);
+ }
+ }
Py_DECREF(ret);
}
diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h
index 37f6af36726..74a16b43dc1 100644
--- a/source/blender/python/intern/bpy_rna.h
+++ b/source/blender/python/intern/bpy_rna.h
@@ -62,6 +62,9 @@ typedef struct {
/* cheap trick */
#define BPy_BaseTypeRNA BPy_PropertyRNA
+StructRNA *srna_from_self(PyObject *self);
+StructRNA *pyrna_struct_as_srna(PyObject *self);
+
void BPY_rna_init( void );
PyObject *BPY_rna_module( void );
void BPY_update_rna_module( void );
diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c
index db3798146d3..2cd1337fba7 100644
--- a/source/blender/python/intern/bpy_util.c
+++ b/source/blender/python/intern/bpy_util.c
@@ -35,95 +35,6 @@ bContext* __py_context = NULL;
bContext* BPy_GetContext(void) { return __py_context; };
void BPy_SetContext(bContext *C) { __py_context= C; };
-
-PyObject *BPY_flag_to_list(struct BPY_flag_def *flagdef, int flag)
-{
- PyObject *list = PyList_New(0);
-
- PyObject *item;
- BPY_flag_def *fd;
-
- fd= flagdef;
- while(fd->name) {
- if (fd->flag & flag) {
- item = PyUnicode_FromString(fd->name);
- PyList_Append(list, item);
- Py_DECREF(item);
- }
- fd++;
- }
-
- return list;
-
-}
-
-static char *bpy_flag_error_str(BPY_flag_def *flagdef)
-{
- BPY_flag_def *fd= flagdef;
- DynStr *dynstr= BLI_dynstr_new();
- char *cstring;
-
- BLI_dynstr_append(dynstr, "Error converting a sequence of strings into a flag.\n\tExpected only these strings...\n\t");
-
- while(fd->name) {
- BLI_dynstr_appendf(dynstr, fd!=flagdef?", '%s'":"'%s'", fd->name);
- fd++;
- }
-
- cstring = BLI_dynstr_get_cstring(dynstr);
- BLI_dynstr_free(dynstr);
- return cstring;
-}
-
-int BPY_flag_from_seq(BPY_flag_def *flagdef, PyObject *seq, int *flag)
-{
- int i, error_val= 0;
- char *cstring;
- PyObject *item;
- BPY_flag_def *fd;
- *flag = 0;
-
- if (PySequence_Check(seq)) {
- i= PySequence_Length(seq);
-
- while(i--) {
- item = PySequence_ITEM(seq, i);
- cstring= _PyUnicode_AsString(item);
- if(cstring) {
- fd= flagdef;
- while(fd->name) {
- if (strcmp(cstring, fd->name) == 0) {
- (*flag) |= fd->flag;
- break;
- }
- fd++;
- }
- if (fd->name==NULL) { /* could not find a match */
- error_val= 1;
- }
- } else {
- error_val= 1;
- }
- Py_DECREF(item);
- }
- }
- else {
- error_val= 1;
- }
-
- if (*flag == 0)
- error_val = 1;
-
- if (error_val) {
- char *buf = bpy_flag_error_str(flagdef);
- PyErr_SetString(PyExc_AttributeError, buf);
- MEM_freeN(buf);
- return -1; /* error value */
- }
-
- return 0; /* ok */
-}
-
/* for debugging */
void PyObSpit(char *name, PyObject *var) {
fprintf(stderr, "<%s> : ", name);
diff --git a/source/blender/python/intern/bpy_util.h b/source/blender/python/intern/bpy_util.h
index 83fa7a5b7c4..dcf957969e8 100644
--- a/source/blender/python/intern/bpy_util.h
+++ b/source/blender/python/intern/bpy_util.h
@@ -36,16 +36,6 @@
struct EnumPropertyItem;
struct ReportList;
-/* for internal use only, so python can interchange a sequence of strings with flags */
-typedef struct BPY_flag_def {
- const char *name;
- int flag;
-} BPY_flag_def;
-
-
-PyObject *BPY_flag_to_list(BPY_flag_def *flagdef, int flag);
-int BPY_flag_from_seq(BPY_flag_def *flagdef, PyObject *seq, int *flag);
-
void PyObSpit(char *name, PyObject *var);
void PyLineSpit(void);
void BPY_getFileAndNum(char **filename, int *lineno);
diff --git a/source/blender/python/sphinx_doc_gen.py b/source/blender/python/sphinx_doc_gen.py
index c8e283ac447..afa117ea60f 100644
--- a/source/blender/python/sphinx_doc_gen.py
+++ b/source/blender/python/sphinx_doc_gen.py
@@ -23,10 +23,10 @@ Usage,
run this script from blenders root path once you have compiled blender
./blender.bin -b -P /b/source/blender/python/sphinx_doc_gen.py
-This will generate python files in "./source/blender/python/doc/bpy/sphinx-in"
+This will generate python files in "./source/blender/python/doc/sphinx-in"
Generate html docs by running...
- sphinx-build source/blender/python/doc/bpy/sphinx-in source/blender/python/doc/bpy/sphinx-out
+ sphinx-build source/blender/python/doc/sphinx-in source/blender/python/doc/sphinx-out
'''
# if you dont have graphvis installed ommit the --graph arg.
@@ -115,7 +115,7 @@ def rna2sphinx(BASEPATH):
#if not struct.identifier.startswith("Sc") and not struct.identifier.startswith("I"):
# return
- #if not struct.identifier.startswith("Bone"):
+ #if not struct.identifier == "Object":
# return
filepath = os.path.join(BASEPATH, "bpy.types.%s.rst" % struct.identifier)
@@ -182,8 +182,17 @@ def rna2sphinx(BASEPATH):
for prop in func.args:
write_param(" ", fw, prop)
- if func.return_value:
- write_param(" ", fw, func.return_value, is_return=True)
+ if len(func.return_values) == 1:
+ write_param(" ", fw, func.return_values[0], is_return=True)
+ else: # multiple return values
+ fw(" :return (%s):\n" % ", ".join([prop.identifier for prop in func.return_values]))
+ for prop in func.return_values:
+ type_descr = prop.get_type_description(as_arg=True, class_fmt=":class:`%s`")
+ descr = prop.description
+ if not descr:
+ descr = prop.name
+ fw(" `%s`, %s, %s\n\n" % (prop.identifier, descr, type_descr))
+
fw("\n")
@@ -265,9 +274,9 @@ if __name__ == '__main__':
print("\nError, this script must run from inside blender2.5")
print(script_help_msg)
else:
- # os.system("rm source/blender/python/doc/bpy/sphinx-in/*.rst")
- # os.system("rm -rf source/blender/python/doc/bpy/sphinx-out/*")
- rna2sphinx('source/blender/python/doc/bpy/sphinx-in')
+ # os.system("rm source/blender/python/doc/sphinx-in/*.rst")
+ # os.system("rm -rf source/blender/python/doc/sphinx-out/*")
+ rna2sphinx('source/blender/python/doc/sphinx-in')
import sys
sys.exit()
diff --git a/source/blender/quicktime/apple/Makefile b/source/blender/quicktime/apple/Makefile
index 19f87ed31e3..70f3f05c5f0 100644
--- a/source/blender/quicktime/apple/Makefile
+++ b/source/blender/quicktime/apple/Makefile
@@ -31,6 +31,12 @@
LIBNAME = blenderqt
DIR = $(OCGDIR)/blender/$(LIBNAME)
+ifeq ($(OS), $(findstring $(OS), "darwin"))
+ ifeq ($(USE_QTKIT),true)
+ OCSRCS += $(wildcard *.m)
+ endif
+endif
+
include nan_compile.mk
CFLAGS += $(LEVEL1_C_WARNINGS)
diff --git a/source/blender/quicktime/apple/qtkit_export.m b/source/blender/quicktime/apple/qtkit_export.m
index 1466d3a3a09..8a537617348 100644
--- a/source/blender/quicktime/apple/qtkit_export.m
+++ b/source/blender/quicktime/apple/qtkit_export.m
@@ -153,6 +153,23 @@ void makeqtstring (RenderData *rd, char *string) {
}
}
+void filepath_qt(char *string, RenderData *rd) {
+ char txt[64];
+
+ if (string==0) return;
+
+ strcpy(string, rd->pic);
+ BLI_convertstringcode(string, G.sce);
+
+ BLI_make_existing_file(string);
+
+ if (BLI_strcasecmp(string + strlen(string) - 4, ".mov")) {
+ sprintf(txt, "%04d_%04d.mov", (rd->sfra) , (rd->efra) );
+ strcat(string, txt);
+ }
+}
+
+
#pragma mark export functions
int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, ReportList *reports)
diff --git a/source/blender/quicktime/apple/quicktime_export.c b/source/blender/quicktime/apple/quicktime_export.c
index abce6c08395..bd1705db13a 100644
--- a/source/blender/quicktime/apple/quicktime_export.c
+++ b/source/blender/quicktime/apple/quicktime_export.c
@@ -30,6 +30,7 @@
#ifdef WITH_QUICKTIME
#if defined(_WIN32) || defined(__APPLE__)
+#ifndef USE_QTKIT
#include "DNA_scene_types.h"
#include "DNA_windowmanager_types.h"
@@ -487,7 +488,7 @@ static void QT_EndAddVideoSamplesToMedia (void)
}
-void makeqtstring (RenderData *rd, char *string) {
+void filepath_qt(char *string, RenderData *rd) {
char txt[64];
if (string==0) return;
@@ -538,7 +539,7 @@ int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, R
sframe = (rd->sfra);
- makeqtstring(rd, name);
+ filepath_qt(name, rd);
#ifdef __APPLE__
EnterMoviesOnThread(0);
@@ -886,6 +887,7 @@ void SCENE_OT_render_data_set_quicktime_codec(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
+#endif /* USE_QTKIT */
#endif /* _WIN32 || __APPLE__ */
#endif /* WITH_QUICKTIME */
diff --git a/source/blender/quicktime/apple/quicktime_import.c b/source/blender/quicktime/apple/quicktime_import.c
index 571da92a292..6fd72131b00 100644
--- a/source/blender/quicktime/apple/quicktime_import.c
+++ b/source/blender/quicktime/apple/quicktime_import.c
@@ -30,6 +30,7 @@
#ifdef WITH_QUICKTIME
#if defined(_WIN32) || defined(__APPLE__)
+#ifndef USE_QTKIT
#include "IMB_anim.h"
#include "BLO_sys_types.h"
@@ -771,6 +772,7 @@ bail:
return ibuf;
}
+#endif /* USE_QTKIT */
#endif /* _WIN32 || __APPLE__ */
#endif /* WITH_QUICKTIME */
diff --git a/source/blender/quicktime/quicktime_export.h b/source/blender/quicktime/quicktime_export.h
index 2ccda8eb526..33c9a85910f 100644
--- a/source/blender/quicktime/quicktime_export.h
+++ b/source/blender/quicktime/quicktime_export.h
@@ -50,6 +50,7 @@ struct ReportList;
int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports); //for movie handle (BKE writeavi.c now)
int append_qt(struct RenderData *rd, int frame, int *pixels, int rectx, int recty, struct ReportList *reports);
void end_qt(void);
+void filepath_qt(char *string, struct RenderData *rd);
/*RNA helper functions */
void quicktime_verify_image_type(struct RenderData *rd); //used by RNA for defaults values init, if needed
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index 76e3e002513..a90220b9c1b 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -46,6 +46,7 @@ struct RenderEngineType;
struct RenderResult;
struct ReportList;
struct Scene;
+struct SceneRenderLayer;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* this include is what is exposed of render to outside world */
@@ -169,7 +170,7 @@ struct RenderLayer *RE_GetRenderLayer(struct RenderResult *rr, const char *name)
float *RE_RenderLayerGetPass(struct RenderLayer *rl, int passtype);
/* obligatory initialize call, disprect is optional */
-void RE_InitState (struct Render *re, struct Render *source, struct RenderData *rd, int winx, int winy, rcti *disprect);
+void RE_InitState (struct Render *re, struct Render *source, struct RenderData *rd, struct SceneRenderLayer *srl, int winx, int winy, rcti *disprect);
/* use this to change disprect of active render */
void RE_SetDispRect (struct Render *re, rcti *disprect);
@@ -200,7 +201,7 @@ void RE_init_threadcount(Render *re);
void RE_TileProcessor(struct Render *re, int firsttile, int threaded);
/* only RE_NewRender() needed, main Blender render calls */
-void RE_BlenderFrame(struct Render *re, struct Scene *scene, int frame);
+void RE_BlenderFrame(struct Render *re, struct Scene *scene, struct SceneRenderLayer *srl, int frame);
void RE_BlenderAnim(struct Render *re, struct Scene *scene, int sfra, int efra, int tfra, struct ReportList *reports);
void RE_ReadRenderResult(struct Scene *scene, struct Scene *scenode);
diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h
index 2615be1440a..28d88e1f8b4 100644
--- a/source/blender/render/extern/include/RE_shader_ext.h
+++ b/source/blender/render/extern/include/RE_shader_ext.h
@@ -197,7 +197,7 @@ struct Image;
struct Object;
void RE_shade_external(struct Render *re, struct ShadeInput *shi, struct ShadeResult *shr);
-int RE_bake_shade_all_selected(struct Render *re, int type, struct Object *actob);
+int RE_bake_shade_all_selected(struct Render *re, int type, struct Object *actob, short *do_update);
struct Image *RE_bake_shade_get_image(void);
#endif /* RE_SHADER_EXT_H */
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 05153113a55..63782223c33 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -2284,6 +2284,14 @@ static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float
shi.mat= vlr->mat; /* current input material */
shi.thread= 0;
+ /* TODO, assign these, displacement with new bumpmap is skipped without - campbell */
+#if 0
+ /* order is not known ? */
+ shi.v1= vlr->v1;
+ shi.v2= vlr->v2;
+ shi.v3= vlr->v3;
+#endif
+
/* Displace the verts, flag is set when done */
if (!vlr->v1->flag)
displace_render_vert(re, obr, &shi, vlr->v1,0, scale, mat, imat);
@@ -3622,7 +3630,7 @@ static GroupObject *add_render_lamp(Render *re, Object *ob)
}
/* set flag for spothalo en initvars */
- if(la->type==LA_SPOT && (la->mode & LA_HALO)) {
+ if(la->type==LA_SPOT && (la->mode & LA_HALO) && (la->buftype != LA_SHADBUF_DEEP)) {
if(la->haint>0.0) {
re->flag |= R_LAMPHALO;
@@ -5597,7 +5605,7 @@ void RE_make_sticky(Scene *scene, View3D *v3d)
}
re= RE_NewRender("_make sticky_");
- RE_InitState(re, NULL, &scene->r, scene->r.xsch, scene->r.ysch, NULL);
+ RE_InitState(re, NULL, &scene->r, NULL, scene->r.xsch, scene->r.ysch, NULL);
/* use renderdata and camera to set viewplane */
RE_SetCamera(re, scene->camera);
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index 323eb6a9500..7ba860955b3 100644
--- a/source/blender/render/intern/source/envmap.c
+++ b/source/blender/render/intern/source/envmap.c
@@ -127,7 +127,7 @@ static Render *envmap_render_copy(Render *re, EnvMap *env)
envre->r.size= 100;
envre->r.yasp= envre->r.xasp= 1;
- RE_InitState(envre, NULL, &envre->r, cuberes, cuberes, NULL);
+ RE_InitState(envre, NULL, &envre->r, NULL, cuberes, cuberes, NULL);
envre->scene= re->scene; /* unsure about this... */
/* view stuff in env render */
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 1d8ef12cd4d..30282c5ad2b 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -133,8 +133,8 @@ static void result_nothing(void *unused, RenderResult *rr) {}
static void result_rcti_nothing(void *unused, RenderResult *rr, volatile struct rcti *rect) {}
static void stats_nothing(void *unused, RenderStats *rs) {}
static void int_nothing(void *unused, int val) {}
-static int void_nothing(void *unused) {return 0;}
static void print_error(void *unused, char *str) {printf("ERROR: %s\n", str);}
+static int default_break(void *unused) {return G.afbreek == 1;}
int RE_RenderInProgress(Render *re)
{
@@ -1118,19 +1118,12 @@ Render *RE_NewRender(const char *name)
BLI_rw_mutex_init(&re->resultmutex);
}
- /* prevent UI to draw old results */
- BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
- RE_FreeRenderResult(re->result);
- re->result= NULL;
- re->result_ok= 0;
- BLI_rw_mutex_unlock(&re->resultmutex);
-
/* set default empty callbacks */
re->display_init= result_nothing;
re->display_clear= result_nothing;
re->display_draw= result_rcti_nothing;
re->timecursor= int_nothing;
- re->test_break= void_nothing;
+ re->test_break= default_break;
re->error= print_error;
if(G.background)
re->stats_draw= stats_background;
@@ -1173,7 +1166,7 @@ void RE_FreeAllRender(void)
/* what doesn't change during entire render sequence */
/* disprect is optional, if NULL it assumes full window render */
-void RE_InitState(Render *re, Render *source, RenderData *rd, int winx, int winy, rcti *disprect)
+void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer *srl, int winx, int winy, rcti *disprect)
{
re->ok= TRUE; /* maybe flag */
@@ -1199,62 +1192,70 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, int winx, int winy
(re->rectx < 16 || re->recty < 16) )) {
re->error(re->erh, "Image too small");
re->ok= 0;
+ return;
}
- else {
+
#ifdef WITH_OPENEXR
- if(re->r.scemode & R_FULL_SAMPLE)
- re->r.scemode |= R_EXR_TILE_FILE; /* enable automatic */
+ if(re->r.scemode & R_FULL_SAMPLE)
+ re->r.scemode |= R_EXR_TILE_FILE; /* enable automatic */
#else
- /* can't do this without openexr support */
- re->r.scemode &= ~(R_EXR_TILE_FILE|R_FULL_SAMPLE);
+ /* can't do this without openexr support */
+ re->r.scemode &= ~(R_EXR_TILE_FILE|R_FULL_SAMPLE);
#endif
-
- /* fullsample wants uniform osa levels */
- if(source && (re->r.scemode & R_FULL_SAMPLE)) {
- /* but, if source has no full sample we disable it */
- if((source->r.scemode & R_FULL_SAMPLE)==0)
- re->r.scemode &= ~R_FULL_SAMPLE;
- else
- re->r.osa= re->osa= source->osa;
+
+ /* fullsample wants uniform osa levels */
+ if(source && (re->r.scemode & R_FULL_SAMPLE)) {
+ /* but, if source has no full sample we disable it */
+ if((source->r.scemode & R_FULL_SAMPLE)==0)
+ re->r.scemode &= ~R_FULL_SAMPLE;
+ else
+ re->r.osa= re->osa= source->osa;
+ }
+ else {
+ /* check state variables, osa? */
+ if(re->r.mode & (R_OSA)) {
+ re->osa= re->r.osa;
+ if(re->osa>16) re->osa= 16;
}
- else {
- /* check state variables, osa? */
- if(re->r.mode & (R_OSA)) {
- re->osa= re->r.osa;
- if(re->osa>16) re->osa= 16;
- }
- else re->osa= 0;
+ else re->osa= 0;
+ }
+
+ if (srl) {
+ int index = BLI_findindex(&re->r.layers, srl);
+ if (index != -1) {
+ re->r.actlay = index;
+ re->r.scemode |= (R_SINGLE_LAYER|R_COMP_RERENDER);
}
-
- /* always call, checks for gamma, gamma tables and jitter too */
- make_sample_tables(re);
+ }
- /* if preview render, we try to keep old result */
- BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+ /* always call, checks for gamma, gamma tables and jitter too */
+ make_sample_tables(re);
+
+ /* if preview render, we try to keep old result */
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
- if(re->r.scemode & R_PREVIEWBUTS) {
- if(re->result && re->result->rectx==re->rectx && re->result->recty==re->recty);
- else {
- RE_FreeRenderResult(re->result);
- re->result= NULL;
- }
- }
+ if(re->r.scemode & R_PREVIEWBUTS) {
+ if(re->result && re->result->rectx==re->rectx && re->result->recty==re->recty);
else {
-
- /* make empty render result, so display callbacks can initialize */
RE_FreeRenderResult(re->result);
- re->result= MEM_callocN(sizeof(RenderResult), "new render result");
- re->result->rectx= re->rectx;
- re->result->recty= re->recty;
+ re->result= NULL;
}
-
- BLI_rw_mutex_unlock(&re->resultmutex);
-
- /* we clip faces with a minimum of 2 pixel boundary outside of image border. see zbuf.c */
- re->clipcrop= 1.0f + 2.0f/(float)(re->winx>re->winy?re->winy:re->winx);
+ }
+ else {
- RE_init_threadcount(re);
+ /* make empty render result, so display callbacks can initialize */
+ RE_FreeRenderResult(re->result);
+ re->result= MEM_callocN(sizeof(RenderResult), "new render result");
+ re->result->rectx= re->rectx;
+ re->result->recty= re->recty;
}
+
+ BLI_rw_mutex_unlock(&re->resultmutex);
+
+ /* we clip faces with a minimum of 2 pixel boundary outside of image border. see zbuf.c */
+ re->clipcrop= 1.0f + 2.0f/(float)(re->winx>re->winy?re->winy:re->winx);
+
+ RE_init_threadcount(re);
}
/* part of external api, not called for regular render pipeline */
@@ -2164,7 +2165,7 @@ static void render_scene(Render *re, Scene *sce, int cfra)
}
/* initial setup */
- RE_InitState(resc, re, &sce->r, winx, winy, &re->disprect);
+ RE_InitState(resc, re, &sce->r, NULL, winx, winy, &re->disprect);
/* still unsure entity this... */
resc->scene= sce;
@@ -2676,7 +2677,7 @@ static void update_physics_cache(Render *re, Scene *scene, int anim_init)
BKE_ptcache_make_cache(&baker);
}
/* evaluating scene options for general Blender render */
-static int render_initialize_from_scene(Render *re, Scene *scene, int anim, int anim_init)
+static int render_initialize_from_scene(Render *re, Scene *scene, SceneRenderLayer *srl, int anim, int anim_init)
{
int winx, winy;
rcti disprect;
@@ -2723,10 +2724,10 @@ static int render_initialize_from_scene(Render *re, Scene *scene, int anim, int
update_physics_cache(re, scene, anim_init);
}
- if(scene->r.scemode & R_SINGLE_LAYER)
+ if(srl || scene->r.scemode & R_SINGLE_LAYER)
push_render_result(re);
- RE_InitState(re, NULL, &scene->r, winx, winy, &disprect);
+ RE_InitState(re, NULL, &scene->r, srl, winx, winy, &disprect);
if(!re->ok) /* if an error was printed, abort */
return 0;
@@ -2743,7 +2744,7 @@ static int render_initialize_from_scene(Render *re, Scene *scene, int anim, int
}
/* general Blender frame render call */
-void RE_BlenderFrame(Render *re, Scene *scene, int frame)
+void RE_BlenderFrame(Render *re, Scene *scene, SceneRenderLayer *srl, int frame)
{
/* ugly global still... is to prevent preview events and signal subsurfs etc to make full resol */
G.rendering= 1;
@@ -2751,7 +2752,7 @@ void RE_BlenderFrame(Render *re, Scene *scene, int frame)
scene->r.cfra= frame;
- if(render_initialize_from_scene(re, scene, 0, 0)) {
+ if(render_initialize_from_scene(re, scene, srl, 0, 0)) {
do_render_all_options(re);
}
@@ -2784,7 +2785,7 @@ static int do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh, R
printf("Append frame %d", scene->r.cfra);
}
else {
- BKE_makepicstring(scene, name, scene->r.pic, scene->r.cfra, scene->r.imtype);
+ BKE_makepicstring(name, scene->r.pic, scene->r.cfra, scene->r.imtype, scene->r.scemode & R_EXTENSION);
if(re->r.imtype==R_MULTILAYER) {
if(re->result) {
@@ -2817,7 +2818,7 @@ static int do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh, R
if(ok && scene->r.imtype==R_OPENEXR && (scene->r.subimtype & R_PREVIEW_JPG)) {
if(BLI_testextensie(name, ".exr"))
name[strlen(name)-4]= 0;
- BKE_add_image_extension(scene, name, R_JPEG90);
+ BKE_add_image_extension(name, R_JPEG90);
ibuf->depth= 24;
BKE_write_ibuf(scene, ibuf, name, R_JPEG90, scene->r.subimtype, scene->r.quality);
printf("\nSaved: %s", name);
@@ -2846,7 +2847,7 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra, Repo
int nfra;
/* do not fully call for each frame, it initializes & pops output window */
- if(!render_initialize_from_scene(re, scene, 0, 1))
+ if(!render_initialize_from_scene(re, scene, NULL, 0, 1))
return;
/* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */
@@ -2880,7 +2881,7 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra, Repo
char name[FILE_MAX];
/* only border now, todo: camera lens. (ton) */
- render_initialize_from_scene(re, scene, 1, 0);
+ render_initialize_from_scene(re, scene, NULL, 1, 0);
if(nfra!=scene->r.cfra) {
/*
@@ -2902,7 +2903,7 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra, Repo
/* Touch/NoOverwrite options are only valid for image's */
if(BKE_imtype_is_movie(scene->r.imtype) == 0) {
if(scene->r.mode & (R_NO_OVERWRITE | R_TOUCH))
- BKE_makepicstring(scene, name, scene->r.pic, scene->r.cfra, scene->r.imtype);
+ BKE_makepicstring(name, scene->r.pic, scene->r.cfra, scene->r.imtype, scene->r.scemode & R_EXTENSION);
if(scene->r.mode & R_NO_OVERWRITE && BLI_exist(name)) {
printf("skipping existing frame \"%s\"\n", name);
@@ -2984,7 +2985,7 @@ void RE_ReadRenderResult(Scene *scene, Scene *scenode)
re= RE_GetRender(scene->id.name);
if(re==NULL)
re= RE_NewRender(scene->id.name);
- RE_InitState(re, NULL, &scene->r, winx, winy, &disprect);
+ RE_InitState(re, NULL, &scene->r, NULL, winx, winy, &disprect);
re->scene= scene;
read_render_result(re, 0);
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index 85442480a9c..9fa23c73ec6 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -192,9 +192,10 @@ void freeraytree(Render *re)
static int is_raytraceable_vlr(Render *re, VlakRen *vlr)
{
- if((re->flag & R_BAKE_TRACE) || (vlr->mat->mode & MA_TRACEBLE))
- if(vlr->mat->material_type != MA_TYPE_WIRE)
- return 1;
+ /* note: volumetric must be tracable, wire must not */
+ if((re->flag & R_BAKE_TRACE) || (vlr->mat->mode & MA_TRACEBLE) || (vlr->mat->material_type == MA_TYPE_VOLUME))
+ if(vlr->mat->material_type != MA_TYPE_WIRE)
+ return 1;
return 0;
}
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index cae6c640f8b..23875b536c9 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -1988,6 +1988,8 @@ typedef struct BakeShade {
char *rect_mask; /* bake pixel mask */
float dxco[3], dyco[3];
+
+ short *do_update;
} BakeShade;
/* bake uses a char mask to know what has been baked */
@@ -2252,9 +2254,7 @@ static int bake_check_intersect(Isect *is, int ob, RayFace *face)
static int bake_intersect_tree(RayObject* raytree, Isect* isect, float *start, float *dir, float sign, float *hitco, float *dist)
{
- //TODO
- assert( 0 );
-#if 0
+ //TODO, validate against blender 2.4x, results may have changed.
float maxdist;
int hit;
@@ -2264,15 +2264,20 @@ static int bake_intersect_tree(RayObject* raytree, Isect* isect, float *start, f
else
maxdist= FLT_MAX + R.r.bake_biasdist;
- //TODO normalized direction?
- VECADDFAC(isect->start, start, dir, -R.r.bake_biasdist);
- isect->dir[0] = dir[0]*sign;
- isect->dir[1] = dir[1]*sign;
- isect->dir[2] = dir[2]*sign;
+ /* 'dir' is always normalized */
+ VECADDFAC(isect->start, start, dir, -R.r.bake_biasdist);
+
+ isect->vec[0] = dir[0]*maxdist*sign;
+ isect->vec[1] = dir[1]*maxdist*sign;
+ isect->vec[2] = dir[2]*maxdist*sign;
+
isect->labda = maxdist;
+ /* TODO, 2.4x had this...
+ hit = RE_ray_tree_intersect_check(R.raytree, isect, bake_check_intersect);
+ ...the active object may NOT be ignored in some cases.
+ */
hit = RE_rayobject_raycast(raytree, isect);
- //TODO bake_check_intersect
if(hit) {
hitco[0] = isect->start[0] + isect->labda*isect->vec[0];
hitco[1] = isect->start[1] + isect->labda*isect->vec[1];
@@ -2282,8 +2287,6 @@ static int bake_intersect_tree(RayObject* raytree, Isect* isect, float *start, f
}
return hit;
-#endif
- return 0;
}
static void bake_set_vlr_dxyco(BakeShade *bs, float *uv1, float *uv2, float *uv3)
@@ -2587,6 +2590,11 @@ static void *do_bake_thread(void *bs_v)
/* fast threadsafe break test */
if(R.test_break(R.tbh))
break;
+
+ /* access is not threadsafe but since its just true/false probably ok
+ * only used for interactive baking */
+ if(bs->do_update)
+ *bs->do_update= TRUE;
}
bs->ready= 1;
@@ -2596,7 +2604,7 @@ static void *do_bake_thread(void *bs_v)
/* using object selection tags, the faces with UV maps get baked */
/* render should have been setup */
/* returns 0 if nothing was handled */
-int RE_bake_shade_all_selected(Render *re, int type, Object *actob)
+int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_update)
{
BakeShade handles[BLENDER_MAX_THREADS];
ListBase threads;
@@ -2645,6 +2653,8 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob)
handles[a].zspan= MEM_callocN(sizeof(ZSpan), "zspan for bake");
handles[a].usemask = usemask;
+
+ handles[a].do_update = do_update; /* use to tell the view to update */
BLI_insert_thread(&threads, &handles[a]);
}
diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c
index 958a2e34215..e9386bb0d94 100644
--- a/source/blender/render/intern/source/shadeoutput.c
+++ b/source/blender/render/intern/source/shadeoutput.c
@@ -354,7 +354,7 @@ void renderspothalo(ShadeInput *shi, float *col, float alpha)
lar= go->lampren;
if(lar==NULL) continue;
- if(lar->type==LA_SPOT && (lar->mode & LA_HALO) && lar->haint>0) {
+ if(lar->type==LA_SPOT && (lar->mode & LA_HALO) && (lar->buftype != LA_SHADBUF_DEEP) && lar->haint>0) {
if(lar->mode & LA_LAYER)
if(shi->vlr && (lar->lay & shi->obi->lay)==0)
diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c
index 9d03889a747..7bf349705cb 100644
--- a/source/blender/render/intern/source/texture.c
+++ b/source/blender/render/intern/source/texture.c
@@ -1737,7 +1737,8 @@ void do_material_tex(ShadeInput *shi)
// (should not be here, dudnu, dudnv, dvdnu & dvdnv should probably be part of ShadeInputUV struct,
// nu/nv in ShadeInput and this calculation should then move to shadeinput.c, shade_input_set_shade_texco() func.)
// NOTE: test for shi->obr->ob here, since vlr/obr/obi can be 'fake' when called from fastshade(), another reason to move it..
- if ((mtex->texflag & MTEX_NEW_BUMP) && shi->obr && shi->obr->ob) {
+ // NOTE: shi->v1 is NULL when called from displace_render_vert, assigning verts in this case is not trivial because the shi quad face side is not know.
+ if ((mtex->texflag & MTEX_NEW_BUMP) && shi->obr && shi->obr->ob && shi->v1) {
if(mtex->mapto & (MAP_NORM|MAP_DISPLACE|MAP_WARP)) {
MTFace* tf = RE_vlakren_get_tface(shi->obr, shi->vlr, i, NULL, 0);
int j1 = shi->i1, j2 = shi->i2, j3 = shi->i3;
diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c
index e9162b7367f..80a6dd9d6a0 100644
--- a/source/blender/render/intern/source/volume_precache.c
+++ b/source/blender/render/intern/source/volume_precache.c
@@ -21,7 +21,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): Matt Ebb.
+ * Contributor(s): Matt Ebb, Ra˙l Fern·ndez Hern·ndez (Farsthary).
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -134,9 +134,10 @@ static float get_avg_surrounds(float *cache, int *res, int xx, int yy, int zz)
for (x=-1; x <= 1; x++) {
x_ = xx+x;
if (x_ >= 0 && x_ <= res[0]-1) {
-
- if (cache[ V_I(x_, y_, z_, res) ] > 0.0f) {
- tot += cache[ V_I(x_, y_, z_, res) ];
+ const int i= V_I(x_, y_, z_, res);
+
+ if (cache[i] > 0.0f) {
+ tot += cache[i];
added++;
}
@@ -164,12 +165,14 @@ static void lightcache_filter(VolumePrecache *vp)
for (y=0; y < vp->res[1]; y++) {
for (x=0; x < vp->res[0]; x++) {
/* trigger for outside mesh */
- if (vp->data_r[ V_I(x, y, z, vp->res) ] < -0.f)
- vp->data_r[ V_I(x, y, z, vp->res) ] = get_avg_surrounds(vp->data_r, vp->res, x, y, z);
- if (vp->data_g[ V_I(x, y, z, vp->res) ] < -0.f)
- vp->data_g[ V_I(x, y, z, vp->res) ] = get_avg_surrounds(vp->data_g, vp->res, x, y, z);
- if (vp->data_b[ V_I(x, y, z, vp->res) ] < -0.f)
- vp->data_b[ V_I(x, y, z, vp->res) ] = get_avg_surrounds(vp->data_b, vp->res, x, y, z);
+ const int i= V_I(x, y, z, vp->res);
+
+ if (vp->data_r[i] < -0.f)
+ vp->data_r[i] = get_avg_surrounds(vp->data_r, vp->res, x, y, z);
+ if (vp->data_g[i] < -0.f)
+ vp->data_g[i] = get_avg_surrounds(vp->data_g, vp->res, x, y, z);
+ if (vp->data_b[i] < -0.f)
+ vp->data_b[i] = get_avg_surrounds(vp->data_b, vp->res, x, y, z);
}
}
}
@@ -194,12 +197,13 @@ static void lightcache_filter2(VolumePrecache *vp)
for (y=0; y < vp->res[1]; y++) {
for (x=0; x < vp->res[0]; x++) {
/* trigger for outside mesh */
- if (vp->data_r[ V_I(x, y, z, vp->res) ] < -0.f)
- new_r[ V_I(x, y, z, vp->res) ] = get_avg_surrounds(vp->data_r, vp->res, x, y, z);
- if (vp->data_g[ V_I(x, y, z, vp->res) ] < -0.f)
- new_g[ V_I(x, y, z, vp->res) ] = get_avg_surrounds(vp->data_g, vp->res, x, y, z);
- if (vp->data_b[ V_I(x, y, z, vp->res) ] < -0.f)
- new_b[ V_I(x, y, z, vp->res) ] = get_avg_surrounds(vp->data_b, vp->res, x, y, z);
+ const int i= V_I(x, y, z, vp->res);
+ if (vp->data_r[i] < -0.f)
+ new_r[i] = get_avg_surrounds(vp->data_r, vp->res, x, y, z);
+ if (vp->data_g[i] < -0.f)
+ new_g[i] = get_avg_surrounds(vp->data_g, vp->res, x, y, z);
+ if (vp->data_b[i] < -0.f)
+ new_b[i] = get_avg_surrounds(vp->data_b, vp->res, x, y, z);
}
}
}
@@ -216,9 +220,21 @@ static void lightcache_filter2(VolumePrecache *vp)
static inline int ms_I(int x, int y, int z, int *n) //has a pad of 1 voxel surrounding the core for boundary simulation
{
- return z*(n[1]+2)*(n[0]+2) + y*(n[0]+2) + x;
+ /* different ordering to light cache */
+ return x*(n[1]+2)*(n[2]+2) + y*(n[2]+2) + z;
+}
+
+static inline int v_I_pad(int x, int y, int z, int *n) //has a pad of 1 voxel surrounding the core for boundary simulation
+{
+ /* same ordering to light cache, with padding */
+ return z*(n[1]+2)*(n[0]+2) + y*(n[0]+2) + x;
}
+static inline int lc_to_ms_I(int x, int y, int z, int *n)
+{
+ /* converting light cache index to multiple scattering index */
+ return (x-1)*(n[1]*n[2]) + (y-1)*(n[2]) + z-1;
+}
/* *** multiple scattering approximation *** */
@@ -232,9 +248,11 @@ static float total_ss_energy(VolumePrecache *vp)
for (z=0; z < res[2]; z++) {
for (y=0; y < res[1]; y++) {
for (x=0; x < res[0]; x++) {
- if (vp->data_r[ V_I(x, y, z, res) ] > 0.f) energy += vp->data_r[ V_I(x, y, z, res) ];
- if (vp->data_g[ V_I(x, y, z, res) ] > 0.f) energy += vp->data_g[ V_I(x, y, z, res) ];
- if (vp->data_b[ V_I(x, y, z, res) ] > 0.f) energy += vp->data_b[ V_I(x, y, z, res) ];
+ const int i=V_I(x, y, z, res);
+
+ if (vp->data_r[i] > 0.f) energy += vp->data_r[i];
+ if (vp->data_g[i] > 0.f) energy += vp->data_g[i];
+ if (vp->data_b[i] > 0.f) energy += vp->data_b[i];
}
}
}
@@ -244,14 +262,14 @@ static float total_ss_energy(VolumePrecache *vp)
static float total_ms_energy(float *sr, float *sg, float *sb, int *res)
{
- int x, y, z, i;
+ int x, y, z;
float energy=0.f;
for (z=1;z<=res[2];z++) {
for (y=1;y<=res[1];y++) {
for (x=1;x<=res[0];x++) {
-
- i = ms_I(x,y,z,res);
+ const int i = ms_I(x,y,z,res);
+
if (sr[i] > 0.f) energy += sr[i];
if (sg[i] > 0.f) energy += sg[i];
if (sb[i] > 0.f) energy += sb[i];
@@ -262,7 +280,7 @@ static float total_ms_energy(float *sr, float *sg, float *sb, int *res)
return energy;
}
-static void ms_diffuse(int b, float* x0, float* x, float diff, int *n)
+static void ms_diffuse(float *x0, float *x, float diff, int *n) //n is the unpadded resolution
{
int i, j, k, l;
const float dt = VOL_MS_TIMESTEP;
@@ -276,10 +294,9 @@ static void ms_diffuse(int b, float* x0, float* x, float diff, int *n)
{
for (i=1; i<=n[0]; i++)
{
- x[ms_I(i,j,k,n)] = (x0[ms_I(i,j,k,n)] + a*(
- x[ms_I(i-1,j,k,n)]+x[ms_I(i+1,j,k,n)]+
- x[ms_I(i,j-1,k,n)]+x[ms_I(i,j+1,k,n)]+
- x[ms_I(i,j,k-1,n)]+x[ms_I(i,j,k+1,n)]))/(1+6*a);
+ x[v_I_pad(i,j,k,n)] = (x0[v_I_pad(i,j,k,n)]) + a*( x0[v_I_pad(i-1,j,k,n)]+ x0[v_I_pad(i+1,j,k,n)]+ x0[v_I_pad(i,j-1,k,n)]+
+ x0[v_I_pad(i,j+1,k,n)]+ x0[v_I_pad(i,j,k-1,n)]+x0[v_I_pad(i,j,k+1,n)]
+ ) / (1+6*a);
}
}
}
@@ -289,7 +306,7 @@ static void ms_diffuse(int b, float* x0, float* x, float diff, int *n)
void multiple_scattering_diffusion(Render *re, VolumePrecache *vp, Material *ma)
{
const float diff = ma->vol.ms_diff * 0.001f; /* compensate for scaling for a nicer UI range */
- const float simframes = ma->vol.ms_steps;
+ const int simframes = (int)(ma->vol.ms_spread * (float)MAX3(vp->res[0], vp->res[1], vp->res[2]));
const int shade_type = ma->vol.shade_type;
float fac = ma->vol.ms_intensity;
@@ -299,7 +316,6 @@ void multiple_scattering_diffusion(Render *re, VolumePrecache *vp, Material *ma)
double time, lasttime= PIL_check_seconds_timer();
float total;
float c=1.0f;
- int i;
float origf; /* factor for blending in original light cache */
float energy_ss, energy_ms;
@@ -324,22 +340,22 @@ void multiple_scattering_diffusion(Render *re, VolumePrecache *vp, Material *ma)
{
for (x=1; x<=n[0]; x++)
{
- i = V_I((x-1), (y-1), (z-1), n);
+ const int i = lc_to_ms_I(x, y ,z, n); //lc index
+ const int j = ms_I(x, y, z, n); //ms index
+
time= PIL_check_seconds_timer();
- c++;
-
- if (vp->data_r[i] > 0.f)
- sr[ms_I(x,y,z,n)] += vp->data_r[i];
- if (vp->data_g[i] > 0.f)
- sg[ms_I(x,y,z,n)] += vp->data_g[i];
- if (vp->data_b[i] > 0.f)
- sb[ms_I(x,y,z,n)] += vp->data_b[i];
+ c++;
+ if (vp->data_r[i] > 0.0f)
+ sr[j] += vp->data_r[i];
+ if (vp->data_g[i] > 0.0f)
+ sg[j] += vp->data_g[i];
+ if (vp->data_b[i] > 0.0f)
+ sb[j] += vp->data_b[i];
/* Displays progress every second */
if(time-lasttime>1.0f) {
char str[64];
- sprintf(str, "Simulating multiple scattering: %d%%", (int)
- (100.0f * (c / total)));
+ sprintf(str, "Simulating multiple scattering: %d%%", (int)(100.0f * (c / total)));
re->i.infostr= str;
re->stats_draw(re->sdh, &re->i);
re->i.infostr= NULL;
@@ -348,14 +364,14 @@ void multiple_scattering_diffusion(Render *re, VolumePrecache *vp, Material *ma)
}
}
}
- SWAP(float *, sr, sr0);
- SWAP(float *, sg, sg0);
- SWAP(float *, sb, sb0);
-
+ SWAP(float *,sr,sr0);
+ SWAP(float *,sg,sg0);
+ SWAP(float *,sb,sb0);
+
/* main diffusion simulation */
- ms_diffuse(0, sr0, sr, diff, n);
- ms_diffuse(0, sg0, sg, diff, n);
- ms_diffuse(0, sb0, sb, diff, n);
+ ms_diffuse(sr0, sr, diff, n);
+ ms_diffuse(sg0, sg, diff, n);
+ ms_diffuse(sb0, sb, diff, n);
if (re->test_break(re->tbh)) break;
}
@@ -379,10 +395,12 @@ void multiple_scattering_diffusion(Render *re, VolumePrecache *vp, Material *ma)
{
for (x=1;x<=n[0];x++)
{
- int index=(x-1)*n[1]*n[2] + (y-1)*n[2] + z-1;
- vp->data_r[index] = origf * vp->data_r[index] + fac * sr[ms_I(x,y,z,n)];
- vp->data_g[index] = origf * vp->data_g[index] + fac * sg[ms_I(x,y,z,n)];
- vp->data_b[index] = origf * vp->data_b[index] + fac * sb[ms_I(x,y,z,n)];
+ const int i = lc_to_ms_I(x, y ,z, n); //lc index
+ const int j = ms_I(x, y, z, n); //ms index
+
+ vp->data_r[i] = origf * vp->data_r[i] + fac * sr[j];
+ vp->data_g[i] = origf * vp->data_g[i] + fac * sg[j];
+ vp->data_b[i] = origf * vp->data_b[i] + fac * sb[j];
}
}
}
@@ -426,7 +444,7 @@ static void *vol_precache_part(void *data)
ShadeInput *shi = pa->shi;
float scatter_col[3] = {0.f, 0.f, 0.f};
float co[3];
- int x, y, z;
+ int x, y, z, i;
const int res[3]= {pa->res[0], pa->res[1], pa->res[2]};
for (z= pa->minz; z < pa->maxz; z++) {
@@ -437,12 +455,14 @@ static void *vol_precache_part(void *data)
for (x=pa->minx; x < pa->maxx; x++) {
co[0] = pa->bbmin[0] + (pa->voxel[0] * (x + 0.5f));
+
+ i= V_I(x, y, z, res);
// don't bother if the point is not inside the volume mesh
if (!point_inside_obi(tree, obi, co)) {
- obi->volume_precache->data_r[ V_I(x, y, z, res) ] = -1.0f;
- obi->volume_precache->data_g[ V_I(x, y, z, res) ] = -1.0f;
- obi->volume_precache->data_b[ V_I(x, y, z, res) ] = -1.0f;
+ obi->volume_precache->data_r[i] = -1.0f;
+ obi->volume_precache->data_g[i] = -1.0f;
+ obi->volume_precache->data_b[i] = -1.0f;
continue;
}
@@ -450,9 +470,9 @@ static void *vol_precache_part(void *data)
normalize_v3(shi->view);
vol_get_scattering(shi, scatter_col, co);
- obi->volume_precache->data_r[ V_I(x, y, z, res) ] = scatter_col[0];
- obi->volume_precache->data_g[ V_I(x, y, z, res) ] = scatter_col[1];
- obi->volume_precache->data_b[ V_I(x, y, z, res) ] = scatter_col[2];
+ obi->volume_precache->data_r[i] = scatter_col[0];
+ obi->volume_precache->data_g[i] = scatter_col[1];
+ obi->volume_precache->data_b[i] = scatter_col[2];
}
}
}
@@ -684,12 +704,13 @@ void vol_precache_objectinstance_threads(Render *re, ObjectInstanceRen *obi, Mat
//tree= NULL;
}
- lightcache_filter(obi->volume_precache);
-
if (ELEM(ma->vol.shade_type, MA_VOL_SHADE_MULTIPLE, MA_VOL_SHADE_SHADEDPLUSMULTIPLE))
{
- multiple_scattering_diffusion(re, vp, ma);
+ /* this should be before the filtering */
+ multiple_scattering_diffusion(re, obi->volume_precache, ma);
}
+
+ lightcache_filter(obi->volume_precache);
}
static int using_lightcache(Material *ma)
@@ -741,7 +762,7 @@ int point_inside_volume_objectinstance(Render *re, ObjectInstanceRen *obi, float
RayObject *tree;
int inside=0;
- tree = makeraytree_object(re, obi); //create_raytree_obi(obi, obi->obr->boundbox[0], obi->obr->boundbox[1]);
+ tree = makeraytree_object(re, obi);
if (!tree) return 0;
inside = point_inside_obi(tree, obi, co);
diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c
index 32ab2980316..e44064de606 100644
--- a/source/blender/render/intern/source/volumetric.c
+++ b/source/blender/render/intern/source/volumetric.c
@@ -493,7 +493,7 @@ void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float *
if (shi->mat->vol.shade_type == MA_VOL_SHADE_SHADOWED) {
mul_v3_fl(lacol, vol_get_shadow(shi, lar, co));
}
- else if (shi->mat->vol.shade_type == MA_VOL_SHADE_SHADED)
+ else if (ELEM3(shi->mat->vol.shade_type, MA_VOL_SHADE_SHADED, MA_VOL_SHADE_MULTIPLE, MA_VOL_SHADE_SHADEDPLUSMULTIPLE))
{
Isect is;
diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt
index e93b9906dac..9f57fd5efec 100644
--- a/source/blender/windowmanager/CMakeLists.txt
+++ b/source/blender/windowmanager/CMakeLists.txt
@@ -81,9 +81,8 @@ IF(WITH_COCOA)
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/wm_apple.c")
ENDIF(WITH_COCOA)
-# TODO buildinfo
-IF(BF_BUILDINFO)
+IF(WITH_BUILDINFO)
ADD_DEFINITIONS(-DNAN_BUILDINFO)
-ENDIF(BF_BUILDINFO)
+ENDIF(WITH_BUILDINFO)
BLENDERLIB_NOLIST(bf_windowmanager "${SRC}" "${INC}")
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 78125954816..9f52cde27e1 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -213,11 +213,12 @@ typedef struct wmNotifier {
#define ND_NLA_SELECT (75<<16)
#define ND_NLA_EDIT (76<<16)
#define ND_NLA_ACTCHANGE (77<<16)
+#define ND_FCURVES_ORDER (78<<16)
/* NC_GEOM Geometry */
/* Mesh, Curve, MetaBall, Armature, .. */
-#define ND_SELECT (80<<16)
-#define ND_DATA (81<<16)
+#define ND_SELECT (90<<16)
+#define ND_DATA (91<<16)
/* NC_NODE Nodes */
#define ND_NODE_SELECT (1<<16)
diff --git a/source/blender/windowmanager/intern/Makefile b/source/blender/windowmanager/intern/Makefile
index f4d65975d43..e472c87fe54 100644
--- a/source/blender/windowmanager/intern/Makefile
+++ b/source/blender/windowmanager/intern/Makefile
@@ -74,6 +74,10 @@ ifeq ($(WITH_QUICKTIME),true)
CPPFLAGS += -DWITH_QUICKTIME
endif
+ifeq ($(WITH_OPENCOLLADA), true)
+ CPPFLAGS += -DWITH_COLLADA
+endif
+
ifeq ($(OS),linux)
ifeq ($(CPU),alpha)
CPPFLAGS += -I$(NAN_MESA)/include
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 825d8cbcf8c..aff843dc1cb 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -391,6 +391,8 @@ static wmOperator *wm_operator_create(wmWindowManager *wm, wmOperatorType *ot, P
wmOperatorType *otm= WM_operatortype_find(otmacro->idname, 0);
wmOperator *opm= wm_operator_create(wm, otm, otmacro->ptr, NULL);
+ IDP_ReplaceGroupInGroup(opm->properties, motherop->properties);
+
BLI_addtail(&motherop->macro, opm);
opm->opm= motherop; /* pointer to mom, for modal() */
}
diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c
index b95d171c1b0..a57421560a6 100644
--- a/source/blender/windowmanager/intern/wm_gesture.c
+++ b/source/blender/windowmanager/intern/wm_gesture.c
@@ -37,6 +37,8 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
+#include "BLI_editVert.h" /* lasso tessellation */
+#include "BLI_scanfill.h" /* lasso tessellation */
#include "BKE_context.h"
#include "BKE_utildefines.h"
@@ -149,8 +151,18 @@ static void wm_gesture_draw_rect(wmWindow *win, wmGesture *gt)
{
rcti *rect= (rcti *)gt->customdata;
+ glEnable(GL_BLEND);
+ glColor4f(1.0, 1.0, 1.0, 0.05);
+ glBegin(GL_QUADS);
+ glVertex2s(rect->xmax, rect->ymin);
+ glVertex2s(rect->xmax, rect->ymax);
+ glVertex2s(rect->xmin, rect->ymax);
+ glVertex2s(rect->xmin, rect->ymin);
+ glEnd();
+ glDisable(GL_BLEND);
+
glEnable(GL_LINE_STIPPLE);
- glColor3ub(0, 0, 0);
+ glColor3ub(96, 96, 96);
glLineStipple(1, 0xCCCC);
sdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
glColor3ub(255, 255, 255);
@@ -164,7 +176,7 @@ static void wm_gesture_draw_line(wmWindow *win, wmGesture *gt)
rcti *rect= (rcti *)gt->customdata;
glEnable(GL_LINE_STIPPLE);
- glColor3ub(0, 0, 0);
+ glColor3ub(96, 96, 96);
glLineStipple(1, 0xAAAA);
sdrawline(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
glColor3ub(255, 255, 255);
@@ -181,8 +193,13 @@ static void wm_gesture_draw_circle(wmWindow *win, wmGesture *gt)
glTranslatef((float)rect->xmin, (float)rect->ymin, 0.0f);
+ glEnable(GL_BLEND);
+ glColor4f(1.0, 1.0, 1.0, 0.05);
+ glutil_draw_filled_arc(0.0, M_PI*2.0, rect->xmax, 40);
+ glDisable(GL_BLEND);
+
glEnable(GL_LINE_STIPPLE);
- glColor3ub(0, 0, 0);
+ glColor3ub(96, 96, 96);
glLineStipple(1, 0xAAAA);
glutil_draw_lined_arc(0.0, M_PI*2.0, rect->xmax, 40);
glColor3ub(255, 255, 255);
@@ -194,15 +211,53 @@ static void wm_gesture_draw_circle(wmWindow *win, wmGesture *gt)
}
+static void draw_filled_lasso(wmGesture *gt)
+{
+ EditVert *v, *lastv=NULL, *firstv=NULL;
+ EditEdge *e;
+ EditFace *efa;
+ short *lasso= (short *)gt->customdata;
+ int i;
+
+ for (i=0; i<gt->points; i++, lasso+=2) {
+ float co[3] = {(float)lasso[0], (float)lasso[1], 0.f};
+
+ v = BLI_addfillvert(co);
+ if (lastv)
+ e = BLI_addfilledge(lastv, v);
+ lastv = v;
+ if (firstv==NULL) firstv = v;
+ }
+
+ BLI_addfilledge(firstv, v);
+ BLI_edgefill(0, 0);
+
+ glEnable(GL_BLEND);
+ glColor4f(1.0, 1.0, 1.0, 0.05);
+ glBegin(GL_TRIANGLES);
+ for (efa = fillfacebase.first; efa; efa=efa->next) {
+ glVertex2f(efa->v1->co[0], efa->v1->co[1]);
+ glVertex2f(efa->v2->co[0], efa->v2->co[1]);
+ glVertex2f(efa->v3->co[0], efa->v3->co[1]);
+ }
+ glEnd();
+ glDisable(GL_BLEND);
+
+ BLI_end_edgefill();
+}
+
static void wm_gesture_draw_lasso(wmWindow *win, wmGesture *gt)
{
short *lasso= (short *)gt->customdata;
int i;
+
+ draw_filled_lasso(gt);
glEnable(GL_LINE_STIPPLE);
- glColor3ub(0, 0, 0);
+ glColor3ub(96, 96, 96);
glLineStipple(1, 0xAAAA);
glBegin(GL_LINE_STRIP);
+ lasso= (short *)gt->customdata;
for(i=0; i<gt->points; i++, lasso+=2)
glVertex2sv(lasso);
if(gt->type==WM_GESTURE_LASSO)
@@ -228,7 +283,7 @@ static void wm_gesture_draw_cross(wmWindow *win, wmGesture *gt)
rcti *rect= (rcti *)gt->customdata;
glEnable(GL_LINE_STIPPLE);
- glColor3ub(0, 0, 0);
+ glColor3ub(96, 96, 96);
glLineStipple(1, 0xCCCC);
sdrawline(rect->xmin - win->sizex, rect->ymin, rect->xmin + win->sizex, rect->ymin);
sdrawline(rect->xmin, rect->ymin - win->sizey, rect->xmin, rect->ymin + win->sizey);
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index f7054af9443..1d4e4eb2d39 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -42,6 +42,8 @@
#include "MEM_guardedalloc.h"
+#include "BLF_api.h"
+
#include "PIL_time.h"
#include "BLI_blenlib.h"
@@ -193,6 +195,7 @@ static int wm_macro_end(wmOperator *op, int retval)
if (retval & (OPERATOR_FINISHED|OPERATOR_CANCELLED)) {
if (op->customdata) {
MEM_freeN(op->customdata);
+ op->customdata = NULL;
}
}
@@ -360,6 +363,7 @@ void WM_operatortype_append_macro_ptr(void (*opfunc)(wmOperatorType*, void*), vo
ot= MEM_callocN(sizeof(wmOperatorType), "operatortype");
ot->srna= RNA_def_struct(&BLENDER_RNA, "", "OperatorProperties");
+ ot->flag= OPTYPE_MACRO;
ot->exec= wm_macro_exec;
ot->invoke= wm_macro_invoke;
ot->modal= wm_macro_modal;
@@ -930,14 +934,48 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *arg_unuse
uiLayout *layout, *split, *col;
uiStyle *style= U.uistyles.first;
struct RecentFile *recent;
- int i;
+ int i, ver_width, rev_width;
+ char *version_str = NULL;
+ char *revision_str = NULL;
+
+#ifdef NAN_BUILDINFO
+ char version_buf[128];
+ char revision_buf[128];
+ extern char * build_rev;
+ char *cp;
+
+ version_str = &version_buf[0];
+ revision_str = &revision_buf[0];
+ sprintf(version_str, "%d.%02d.%d", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION);
+ sprintf(revision_str, "r%s", build_rev);
+
+ /* here on my system I get ugly double quotes around the revision number.
+ * if so, clip it off: */
+ cp = strchr(revision_str, '"');
+ if (cp) {
+ memmove(cp, cp+1, strlen(cp+1));
+ cp = strchr(revision_str, '"');
+ if (cp)
+ *cp = 0;
+ }
+
+ ver_width = BLF_width(version_str);
+ rev_width = BLF_width(revision_str);
+#endif NAN_BUILDINFO
+
block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN|UI_BLOCK_RET_1);
but= uiDefBut(block, BUT_IMAGE, 0, "", 0, 10, 501, 282, NULL, 0.0, 0.0, 0, 0, "");
uiButSetFunc(but, wm_block_splash_close, block, NULL);
+#ifdef NAN_BUILDINFO
+ uiDefBut(block, LABEL, 0, version_str, 500-ver_width, 282-24, ver_width, 20, NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, LABEL, 0, revision_str, 500-rev_width, 282-36, rev_width, 20, NULL, 0, 0, 0, 0, NULL);
+#endif NAN_BUILDINFO
+
+
uiBlockSetEmboss(block, UI_EMBOSSP);
layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 10, 10, 480, 110, style);
@@ -956,8 +994,12 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *arg_unuse
col = uiLayoutColumn(split, 0);
uiItemL(col, "Recent", 0);
- for(recent = G.recent_files.first, i=0; (i<6) && (recent); recent = recent->next, i++)
- uiItemStringO(col, BLI_last_slash(recent->filename)+1, ICON_FILE_BLEND, "WM_OT_open_mainfile", "path", recent->filename);
+ for(recent = G.recent_files.first, i=0; (i<6) && (recent); recent = recent->next, i++) {
+ char *display_name= BLI_last_slash(recent->filename);
+ if(display_name) display_name++; /* skip the slash */
+ else display_name= recent->filename;
+ uiItemStringO(col, display_name, ICON_FILE_BLEND, "WM_OT_open_mainfile", "path", recent->filename);
+ }
uiItemS(col);
@@ -1032,7 +1074,7 @@ static uiBlock *wm_block_search_menu(bContext *C, ARegion *ar, void *arg_op)
block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_RET_1|UI_BLOCK_MOVEMOUSE_QUIT);
- but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 10, 180, 19, "");
+ but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 10, 180, 19, 0, 0, "");
uiButSetSearchFunc(but, operator_search_cb, NULL, operator_call_cb, NULL);
/* fake button, it holds space for search items */
@@ -1218,7 +1260,7 @@ static short wm_link_append_flag(wmOperator *op)
if(RNA_boolean_get(op->ptr, "active_layer")) flag |= FILE_ACTIVELAY;
if(RNA_boolean_get(op->ptr, "relative_paths")) flag |= FILE_STRINGCODE;
if(RNA_boolean_get(op->ptr, "link")) flag |= FILE_LINK;
-
+ if(RNA_boolean_get(op->ptr, "instance_groups")) flag |= FILE_GROUP_INSTANCE;
return flag;
}
@@ -1234,9 +1276,6 @@ static void wm_link_make_library_local(Main *main, const char *libname)
/* make local */
if(lib) {
all_local(lib, 1);
- /* important we unset, otherwise these object wont
- * link into other scenes from this blend file */
- flag_all_listbases_ids(LIB_APPEND_TAG, 0);
}
}
@@ -1294,9 +1333,11 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
flag = wm_link_append_flag(op);
- /* tag everything, all untagged data can be made local */
- if((flag & FILE_LINK)==0)
- flag_all_listbases_ids(LIB_APPEND_TAG, 1);
+ /* tag everything, all untagged data can be made local
+ * its also generally useful to know what is new
+ *
+ * take extra care flag_all_listbases_ids(LIB_LINK_TAG, 0) is called after! */
+ flag_all_listbases_ids(LIB_PRE_EXISTING, 1);
/* here appending/linking starts */
mainl = BLO_library_append_begin(C, &bh, libname);
@@ -1319,6 +1360,10 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
if((flag & FILE_LINK)==0)
wm_link_make_library_local(bmain, libname);
+ /* important we unset, otherwise these object wont
+ * link into other scenes from this blend file */
+ flag_all_listbases_ids(LIB_PRE_EXISTING, 0);
+
/* recreate dependency graph to include new objects */
DAG_scene_sort(scene);
DAG_ids_flush_update(0);
@@ -1350,6 +1395,7 @@ static void WM_OT_link_append(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "link", 1, "Link", "Link the objects or datablocks rather than appending.");
RNA_def_boolean(ot->srna, "autoselect", 1, "Select", "Select the linked objects.");
RNA_def_boolean(ot->srna, "active_layer", 1, "Active Layer", "Put the linked objects on the active layer.");
+ RNA_def_boolean(ot->srna, "instance_groups", 1, "Instance Groups", "Create instances for each group as a DupliGroup.");
RNA_def_boolean(ot->srna, "relative_paths", 1, "Relative Paths", "Store the library path as a relative path to current .blend file.");
RNA_def_collection_runtime(ot->srna, "files", &RNA_OperatorFileListElement, "Files", "");
@@ -1489,10 +1535,10 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op)
fileflags= G.fileflags;
/* set compression flag */
- if(RNA_boolean_get(op->ptr, "compress"))
- fileflags |= G_FILE_COMPRESS;
- else
- fileflags &= ~G_FILE_COMPRESS;
+ if(RNA_boolean_get(op->ptr, "compress")) fileflags |= G_FILE_COMPRESS;
+ else fileflags &= ~G_FILE_COMPRESS;
+ if(RNA_boolean_get(op->ptr, "relative_remap")) fileflags |= G_FILE_RELATIVE_REMAP;
+ else fileflags &= ~G_FILE_RELATIVE_REMAP;
WM_write_file(C, path, fileflags, op->reports);
@@ -1513,6 +1559,7 @@ static void WM_OT_save_as_mainfile(wmOperatorType *ot)
WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER);
RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file.");
+ RNA_def_boolean(ot->srna, "relative_remap", 0, "Remap Relative", "Remap relative paths when saving in a different directory.");
}
/* *************** save file directly ******** */
@@ -1551,6 +1598,7 @@ static void WM_OT_save_mainfile(wmOperatorType *ot)
WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER);
RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file.");
+ RNA_def_boolean(ot->srna, "relative_remap", 0, "Remap Relative", "Remap relative paths when saving in a different directory.");
}
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 54f6d58ced4..94248fb392c 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -307,12 +307,14 @@ static void wm_window_add_ghostwindow(wmWindowManager *wm, char *title, wmWindow
inital_state += macPrefState;
}
#endif
-
+ /* Disable AA for now, as GL_SELECT (used for border, lasso, ... select)
+ doesn't work well when AA is initialized, even if not used. */
ghostwin= GHOST_CreateWindow(g_system, title,
win->posx, posy, win->sizex, win->sizey,
inital_state,
GHOST_kDrawingContextTypeOpenGL,
- 0 /* no stereo */);
+ 0 /* no stereo */,
+ 0 /* no AA */);
if (ghostwin) {
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index ede1b865970..eddd85c6444 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -83,6 +83,7 @@ void WM_autosave_init(struct bContext *C){}
void WM_jobs_stop_all(struct wmWindowManager *wm){}
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){}
void ED_armature_edit_bone_remove(struct bArmature *arm, struct EditBone *exBone){}
void object_test_constraints (struct Object *owner){}
@@ -110,10 +111,14 @@ struct wmKeyMap *WM_keymap_active(struct wmWindowManager *wm, struct wmKeyMap *k
struct wmKeyMap *WM_keymap_find(struct wmKeyConfig *keyconf, char *idname, int spaceid, int regionid){return (struct wmKeyMap *) NULL;}
struct wmKeyMap *WM_keymap_add_item(struct wmKeyMap *keymap, char *idname, int type, int val, int modifier, int keymodifier){return (struct wmKeyMap *) NULL;}
struct wmKeyMap *WM_keymap_copy_to_user(struct wmKeyMap *kemap){return (struct wmKeyMap *) NULL;}
+struct wmKeyMap *WM_keymap_list_find(struct ListBase *lb, char *idname, int spaceid, int regionid){return (struct wmKeyMap *) NULL;}
struct wmKeyConfig *WM_keyconfig_add(struct wmWindowManager *wm, char *idname){return (struct wmKeyConfig *) NULL;}
void WM_keymap_remove_item(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi){}
void WM_keymap_restore_to_default(struct wmKeyMap *keymap){}
+void WM_keymap_restore_item_to_default(struct bContext *C, struct wmKeyMap *keymap, struct wmKeyMapItem *kmi){}
+void WM_keymap_properties_reset(struct wmKeyMapItem *kmi){}
int WM_keymap_user_init(struct wmWindowManager *wm, struct wmKeyMap *keymap) {return 0;}
+int WM_keymap_item_compare(struct wmKeyMapItem *k1, struct wmKeyMapItem *k2){return 0;}
/* rna editors */
@@ -127,6 +132,7 @@ void WM_event_add_fileselect(struct bContext *C, struct wmOperator *op){}
void ED_node_texture_default(struct Tex *tx){}
void ED_node_changed_update(struct bContext *C, struct bNode *node){}
void ED_view3d_scene_layers_update(struct Main *bmain, struct Scene *scene){}
+int ED_view3d_scene_layer_set(int lay, const int *values){return 0;}
int text_file_modified(struct Text *text){return 0;}
void ED_node_shader_default(struct Material *ma){}
void ED_screen_animation_timer_update(struct bContext *C, int redraws){}
@@ -153,12 +159,19 @@ void ED_mesh_geometry_add(struct Mesh *mesh, struct ReportList *reports, int ver
void ED_mesh_material_add(struct Mesh *me, struct Material *ma){}
void ED_mesh_transform(struct Mesh *me, float *mat){}
void ED_mesh_update(struct Mesh *mesh, struct bContext *C){}
+int ED_mesh_color_add(struct bContext *C, struct Scene *scene, struct Object *ob, struct Mesh *me){return 0;}
int ED_mesh_uv_texture_add(struct bContext *C, struct Scene *scene, struct Object *ob, struct Mesh *me){return 0;}
void ED_object_apply_obmat(struct Object *ob){}
void ED_object_constraint_dependency_update(struct Scene *scene, struct Object *ob){}
void ED_object_constraint_update(struct Object *ob){}
struct bDeformGroup *ED_vgroup_add_name(struct Object *ob, char *name){return (struct bDeformGroup *) NULL;}
void ED_vgroup_vert_add(struct Object *ob, struct bDeformGroup *dg, int vertnum, float weight, int assignmode){}
+void ED_sequencer_update_view(struct bContext *C, int view){}
+float ED_rollBoneToVector(struct EditBone *bone, float new_up_axis[3]){return 0.0f;}
+
+void EM_selectmode_set(struct EditMesh *em){}
+void make_editMesh(struct Scene *scene, struct Object *ob){}
+void load_editMesh(struct Scene *scene, struct Object *ob){}
void uiItemR(struct uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, int flag){}
@@ -184,6 +197,7 @@ void uiItemM(struct uiLayout *layout, struct bContext *C, char *name, int icon,
void uiItemS(struct uiLayout *layout){}
void uiItemFullR(struct uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, int value, int flag){}
void uiLayoutSetContextPointer(struct uiLayout *layout, char *name, struct PointerRNA *ptr){}
+char *uiLayoutIntrospect(struct uiLayout *layout){return (char *)NULL;}
/* rna template */
void uiTemplateAnyID(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, char *text){}
@@ -193,6 +207,7 @@ void uiTemplateID(struct uiLayout *layout, struct bContext *C, struct PointerRNA
struct uiLayout *uiTemplateModifier(struct uiLayout *layout, struct PointerRNA *ptr){return (struct uiLayout *) NULL;}
struct uiLayout *uiTemplateConstraint(struct uiLayout *layout, struct PointerRNA *ptr){return (struct uiLayout *) NULL;}
void uiTemplatePreview(struct uiLayout *layout, struct ID *id, struct ID *parent, struct MTex *slot){}
+void uiTemplateIDPreview(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop, int rows, int cols){}
void uiTemplateCurveMapping(struct uiLayout *layout, struct CurveMapping *cumap, int type, int compact){}
void uiTemplateColorRamp(struct uiLayout *layout, struct ColorBand *coba, int expand){}
void uiTemplateLayers(struct uiLayout *layout, struct PointerRNA *ptr, char *propname){}
@@ -204,6 +219,7 @@ void uiTemplateOperatorSearch(struct uiLayout *layout){}
void uiTemplateHeader3D(struct uiLayout *layout, struct bContext *C){}
void uiTemplateTextureImage(struct uiLayout *layout, struct bContext *C, struct Tex *tex){}
void uiTemplateImage(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, struct PointerRNA *userptr, int compact){}
+void uiTemplateDopeSheetFilter(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr){}
/* rna render */
struct RenderResult *RE_engine_begin_result(struct RenderEngine *engine, int x, int y, int w, int h){return (struct RenderResult *) NULL;}
@@ -224,6 +240,7 @@ int RE_engine_test_break(struct RenderEngine *engine){return 0;}
struct wmOperatorType *WM_operatortype_find(const char *idname, int quiet){return (struct wmOperatorType *) NULL;}
struct wmOperatorType *WM_operatortype_first(){return (struct wmOperatorType *) NULL;}
struct wmOperatorType *WM_operatortype_exists(const char *idname){return (struct wmOperatorType *) NULL;}
+struct wmOperatorTypeMacro *WM_operatortype_macro_define(struct wmOperatorType *ot, const char *idname){return (struct wmOperatorTypeMacro *) NULL;}
int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, int context, struct PointerRNA *properties, struct ReportList *reports){return 0;}
int WM_operatortype_remove(const char *idname){return 0;}
int WM_operator_poll(struct bContext *C, struct wmOperatorType *ot){return 0;}
@@ -235,6 +252,7 @@ void WM_operatortype_append_ptr(void (*opfunc)(struct wmOperatorType*, void*), v
void WM_operatortype_append_macro_ptr(void (*opfunc)(struct wmOperatorType*, void*), void *userdata){}
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;}
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;}
diff --git a/source/darwin/Makefile b/source/darwin/Makefile
index 1431ab817ff..6007ff4d91c 100644
--- a/source/darwin/Makefile
+++ b/source/darwin/Makefile
@@ -31,7 +31,9 @@ include nan_definitions.mk
DIR = $(OCGDIR)/$(DEBUG_DIR)
-all::
+PYARCHIVE = python_$(MACOSX_ARCHITECTURE).zip
+
+all::
@# set up directory structure for the OSX aplication bundle
@echo "---> creating directory structure for $(APPLICATION)"
@rm -rf $(DIR)/bin/$(APPLICATION).app
@@ -51,7 +53,7 @@ ifeq ($(APPLICATION), blender)
@cp -R $(NANBLENDERHOME)/release/scripts $(DIR)/bin/$(APPLICATION).app/Contents/MacOS/.blender/
@echo "---> copying python modules"
@mkdir $(DIR)/bin/$(APPLICATION).app/Contents/MacOS/.blender/python
- @unzip -q $(LCGDIR)/release/python.zip -d $(DIR)/bin/$(APPLICATION).app/Contents/MacOS/.blender/python/
+ @unzip -q $(LCGDIR)/release/$(PYARCHIVE) -d $(DIR)/bin/$(APPLICATION).app/Contents/MacOS/.blender/python/
endif
@echo "---> removing SVN directories and Mac hidden files from distribution"
@find $(DIR)/bin/$(APPLICATION).app -name CVS -prune -exec rm -rf {} \;
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index a7f8b5c5fdf..a54c229593f 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -1633,11 +1633,16 @@ static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int l
lightobj.m_nodiffuse = (la->mode & LA_NO_DIFF) != 0;
lightobj.m_nospecular = (la->mode & LA_NO_SPEC) != 0;
- if (la->mode & LA_NEG)
- {
- lightobj.m_red = -lightobj.m_red;
- lightobj.m_green = -lightobj.m_green;
- lightobj.m_blue = -lightobj.m_blue;
+ bool glslmat = converter->GetGLSLMaterials();
+
+ // in GLSL NEGATIVE LAMP is handled inside the lamp update function
+ if(glslmat==0) {
+ if (la->mode & LA_NEG)
+ {
+ lightobj.m_red = -lightobj.m_red;
+ lightobj.m_green = -lightobj.m_green;
+ lightobj.m_blue = -lightobj.m_blue;
+ }
}
if (la->type==LA_SUN) {
@@ -1649,7 +1654,7 @@ static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int l
}
gamelight = new KX_LightObject(kxscene, KX_Scene::m_callbacks, rendertools,
- lightobj, converter->GetGLSLMaterials());
+ lightobj, glslmat);
BL_ConvertLampIpos(la, gamelight, converter);
diff --git a/source/gameengine/GamePlayer/common/CMakeLists.txt b/source/gameengine/GamePlayer/common/CMakeLists.txt
index c865cf5ce25..2898d07e63d 100644
--- a/source/gameengine/GamePlayer/common/CMakeLists.txt
+++ b/source/gameengine/GamePlayer/common/CMakeLists.txt
@@ -71,5 +71,7 @@ SET(INC
${ZLIB_INC}
)
+ADD_DEFINITIONS(-DGLEW_STATIC)
+
BLENDERLIB_NOLIST(gp_common "${SRC}" "${INC}")
#env.BlenderLib (libname='gp_common', sources=source_files, includes=incs, defines = [], libtype='player', priority=5, compileflags=cflags)
diff --git a/source/gameengine/GamePlayer/common/SConscript b/source/gameengine/GamePlayer/common/SConscript
index 51fc2fc7334..b66d644f9f5 100644
--- a/source/gameengine/GamePlayer/common/SConscript
+++ b/source/gameengine/GamePlayer/common/SConscript
@@ -58,7 +58,7 @@ incs = ['.',
# 'unix/GPU_System.cpp']
# gp_common_env.Append ( CPPPATH = ['unix'])
-defs = []
+defs = [ 'GLEW_STATIC' ]
if env['WITH_BF_PYTHON']:
incs += Split(env['BF_PYTHON_INC'])
diff --git a/source/gameengine/GamePlayer/ghost/CMakeLists.txt b/source/gameengine/GamePlayer/ghost/CMakeLists.txt
index d50784cb967..8d73a6f248b 100644
--- a/source/gameengine/GamePlayer/ghost/CMakeLists.txt
+++ b/source/gameengine/GamePlayer/ghost/CMakeLists.txt
@@ -66,6 +66,8 @@ SET(INC
${PYTHON_INC}
)
+ADD_DEFINITIONS(-DGLEW_STATIC)
+
IF(WITH_FFMPEG)
ADD_DEFINITIONS(-DWITH_FFMPEG)
ENDIF(WITH_FFMPEG)
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
index e771d12988c..c6952a68a58 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
@@ -565,7 +565,10 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode)
else
m_rasterizer = new RAS_OpenGLRasterizer(m_canvas);
+ /* Stereo parameters - Eye Separation from the UI - stereomode from the command-line/UI */
m_rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) stereoMode);
+ m_rasterizer->SetEyeSeparation(m_startScene->gm.eyeseparation);
+
if (!m_rasterizer)
goto initFailed;
diff --git a/source/gameengine/GamePlayer/ghost/SConscript b/source/gameengine/GamePlayer/ghost/SConscript
index 93769e60401..2269b6400e3 100644
--- a/source/gameengine/GamePlayer/ghost/SConscript
+++ b/source/gameengine/GamePlayer/ghost/SConscript
@@ -40,7 +40,7 @@ incs = ['.',
'#source/blender/gpu',
'#extern/glew/include']
-defs = []
+defs = [ 'GLEW_STATIC' ]
if env['WITH_BF_PYTHON']:
incs += Split(env['BF_PYTHON_INC'])
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index e64e0914b87..6865f9f04a2 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -2605,6 +2605,23 @@ static PyObject *none_tuple_4()
return ret;
}
+static PyObject *none_tuple_5()
+{
+ PyObject *ret= PyTuple_New(5);
+ PyTuple_SET_ITEM(ret, 0, Py_None);
+ PyTuple_SET_ITEM(ret, 1, Py_None);
+ PyTuple_SET_ITEM(ret, 2, Py_None);
+ PyTuple_SET_ITEM(ret, 3, Py_None);
+ PyTuple_SET_ITEM(ret, 4, Py_None);
+
+ Py_INCREF(Py_None);
+ Py_INCREF(Py_None);
+ Py_INCREF(Py_None);
+ Py_INCREF(Py_None);
+ Py_INCREF(Py_None);
+ return ret;
+}
+
KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
"rayCast(to,from,dist,prop,face,xray,poly): cast a ray and return 3-tuple (object,hit,normal) or 4-tuple (object,hit,normal,polygon) or 4-tuple (object,hit,normal,polygon,hituv) of contact point with object within dist that matches prop.\n"
" If no hit, return (None,None,None) or (None,None,None,None) or (None,None,None,None,None).\n"
@@ -2742,11 +2759,11 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
return returnValue;
}
// no hit
- if (poly)
- //return Py_BuildValue("OOOO", Py_None, Py_None, Py_None, Py_None);
+ if (poly == 2)
+ return none_tuple_5();
+ else if (poly)
return none_tuple_4();
else
- //return Py_BuildValue("OOO", Py_None, Py_None, Py_None);
return none_tuple_3();
}
diff --git a/source/gameengine/PyDoc/Rasterizer.py b/source/gameengine/PyDoc/Rasterizer.py
index bafcfece473..8fd4d506bde 100644
--- a/source/gameengine/PyDoc/Rasterizer.py
+++ b/source/gameengine/PyDoc/Rasterizer.py
@@ -136,7 +136,7 @@ def disableMist():
def setEyeSeparation(eyesep):
"""
- Sets the eye separation for stereo mode.
+ Sets the eye separation for stereo mode. Usually Focal Length/30 provides a confortable value.
@param eyesep: The distance between the left and right eye.
@type eyesep: float
@@ -151,7 +151,7 @@ def getEyeSeparation():
def setFocalLength(focallength):
"""
- Sets the focal length for stereo mode.
+ Sets the focal length for stereo mode. It uses the current camera focal length as initial value.
@param focallength: The focal length.
@type focallength: float
diff --git a/source/nan_compile.mk b/source/nan_compile.mk
index 03f5a0d1cd6..3255f102ab7 100644
--- a/source/nan_compile.mk
+++ b/source/nan_compile.mk
@@ -24,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): GSR
+# Contributor(s): GSR, Stefan Gartner
#
# ***** END GPL LICENSE BLOCK *****
#
@@ -70,21 +70,48 @@ DBG_CCFLAGS += -g
# OS dependent parts ---------------------------------------------------
ifeq ($(OS),darwin)
- CC ?= gcc
+ CC ?= gcc
CCC ?= g++
- ifeq ($(CPU),powerpc)
- CFLAGS += -pipe -fPIC -ffast-math -mcpu=7450 -mtune=G5 -funsigned-char -fno-strict-aliasing -Wno-long-double
- CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing -Wno-long-double
+ ifeq ($(MACOSX_DEPLOYMENT_TARGET), 10.4)
+ CC = gcc-4.0
+ CCC = g++-4.0
else
- CFLAGS += -pipe -fPIC -ffast-math -march=pentium-m -funsigned-char -fno-strict-aliasing
+ ifeq ($(MACOSX_DEPLOYMENT_TARGET), 10.5)
+ CC = gcc-4.2
+ CCC = g++-4.2
+ endif
+ endif
+ ifeq ($(CPU),powerpc)
+ CFLAGS += -pipe -fPIC -ffast-math -mcpu=7450 -mtune=G5 -funsigned-char -fno-strict-aliasing
CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing
+ else
+ CFLAGS += -pipe -fPIC -ffast-math -funsigned-char
+ CCFLAGS += -pipe -fPIC -funsigned-char
endif
-# REL_CFLAGS += -O
-# REL_CCFLAGS += -O2
- CPPFLAGS += -D_THREAD_SAFE
+
+
+ CFLAGS += -arch $(MACOSX_ARCHITECTURE) #-isysroot $(MACOSX_SDK) -mmacosx-version-min=$(MACOSX_MIN_VERS)
+ CCFLAGS += -arch $(MACOSX_ARCHITECTURE) #-isysroot $(MACOSX_SDK) -mmacosx-version-min=$(MACOSX_MIN_VERS)
+
+ ifeq ($(MACOSX_ARCHITECTURE), $(findstring $(MACOSX_ARCHITECTURE), "i386 x86_64"))
+ REL_CFLAGS += -O2 -ftree-vectorize -msse -msse2 -msse3
+ REL_CCFLAGS += -O2 -ftree-vectorize -msse -msse2 -msse3
+ endif
+
+ ifeq ($(MACOSX_ARCHITECTURE), x86_64)
+ REL_CFLAGS += -mssse3
+ REL_CCFLAGS += -mssse3
+ endif
+
+ CPPFLAGS += -D_THREAD_SAFE -fpascal-strings
+
ifeq ($(WITH_COCOA), true)
CPPFLAGS += -DGHOST_COCOA
endif
+ ifeq ($(USE_QTKIT), true)
+ CPPFLAGS += -DUSE_QTKIT
+ endif
+
NAN_DEPEND = true
OPENGL_HEADERS = /System/Library/Frameworks/OpenGL.framework
AR = ar
@@ -324,6 +351,21 @@ $(DIR)/$(DEBUG_DIR)%.o: %.mm
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
endif
+$(DIR)/$(DEBUG_DIR)%.o: %.m
+ ifdef NAN_DEPEND
+ @set -e; $(CC) -M $(CPPFLAGS) $< 2>/dev/null \
+ | sed 's@\($*\)\.o[ :]*@$(DIR)/$(DEBUG_DIR)\1.o : @g' \
+ > $(DIR)/$(DEBUG_DIR)$*.d; \
+ [ -s $(DIR)/$(DEBUG_DIR)$*.d ] || $(RM) $(DIR)/$(DEBUG_DIR)$*.d
+ endif
+ ifdef NAN_QUIET
+ @echo " -- $< -- "
+ @$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
+ else
+ $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
+ endif
+
+
$(DIR)/$(DEBUG_DIR)%.res: %.rc
ifeq ($(FREE_WINDOWS),true)
windres $< -O coff -o $@
@@ -349,18 +391,20 @@ CCSRCS ?= $(wildcard *.cpp)
JSRCS ?= $(wildcard *.java)
ifdef NAN_DEPEND
--include $(CSRCS:%.c=$(DIR)/$(DEBUG_DIR)%.d) $(CCSRCS:%.cpp=$(DIR)/$(DEBUG_DIR)%.d) $(OCSRCS:$.mm=$(DIR)/$(DEBUG_DIR)%.d)
+-include $(CSRCS:%.c=$(DIR)/$(DEBUG_DIR)%.d) $(CCSRCS:%.cpp=$(DIR)/$(DEBUG_DIR)%.d) $(OCCSRCS:$.mm=$(DIR)/$(DEBUG_DIR)%.d) $(OCSRCS:$.m=$(DIR)/$(DEBUG_DIR)%.d)
endif
OBJS_AR := $(OBJS)
OBJS_AR += $(CSRCS:%.c=%.o)
OBJS_AR += $(CCSRCS:%.cpp=%.o)
-OBJS_AR += $(OCSRCS:%.mm=%.o)
+OBJS_AR += $(OCCSRCS:%.mm=%.o)
+OBJS_AR += $(OCSRCS:%.m=%.o)
OBJS_AR += $(WINRC:%.rc=%.res)
OBJS += $(CSRCS:%.c=$(DIR)/$(DEBUG_DIR)%.o)
OBJS += $(CCSRCS:%.cpp=$(DIR)/$(DEBUG_DIR)%.o)
-OBJS += $(OCSRCS:%.mm=$(DIR)/$(DEBUG_DIR)%.o)
+OBJS += $(OCCSRCS:%.mm=$(DIR)/$(DEBUG_DIR)%.o)
+OBJS += $(OCSRCS:%.m=$(DIR)/$(DEBUG_DIR)%.o)
OBJS += $(WINRC:%.rc=$(DIR)/$(DEBUG_DIR)%.res)
JCLASS += $(JSRCS:%.java=$(DIR)/$(DEBUG_DIR)%.class)
diff --git a/source/nan_definitions.mk b/source/nan_definitions.mk
index 50df0e777cc..24fe489a26c 100644
--- a/source/nan_definitions.mk
+++ b/source/nan_definitions.mk
@@ -24,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): GSR
+# Contributor(s): GSR, Stefan Gartner
#
# ***** END GPL LICENSE BLOCK *****
#
@@ -108,7 +108,11 @@ ifndef CONFIG_GUESS
export NAN_FFMPEGLIBS ?= $(NAN_FFMPEG)/lib/libavformat.a $(NAN_FFMPEG)/lib/libavutil.a $(NAN_FFMPEG)/lib/libavcodec.a $(NAN_FFMPEG)/lib/libavdevice.a
else
export NAN_FFMPEG ?= $(LCGDIR)/ffmpeg
- 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
+ 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
+ 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
endif
export NAN_FFMPEGCFLAGS ?= -I$(NAN_FFMPEG)/include -I$(NANBLENDERHOME)/extern/ffmpeg
@@ -146,8 +150,17 @@ ifndef CONFIG_GUESS
export NAN_FFMPEGCFLAGS = $(shell pkg-config --cflags libavcodec libavdevice libavformat libswscale libavutil)
endif
- # Compare recreated .mo files with committed ones
- export BF_VERIFY_MO_FILES ?= true
+ ifeq ($(WITH_OPENCOLLADA), true)
+ export BF_OPENCOLLADA ?= $(LCGDIR)/opencollada
+ export BF_OPENCOLLADA_INC ?= $(BF_OPENCOLLADA)/include
+ export BF_OPENCOLLADA_LIBS ?= $(BF_OPENCOLLADA)/lib/libOpenCOLLADASaxFrameworkLoader.a $(BF_OPENCOLLADA)/lib/libOpenCOLLADAFramework.a $(BF_OPENCOLLADA)/lib/libOpenCOLLADABaseUtils.a $(BF_OPENCOLLADA)/lib/libOpenCOLLADAStreamWriter.a $(BF_OPENCOLLADA)/lib/libMathMLSolver.a $(BF_OPENCOLLADA)/lib/libGeneratedSaxParser.a $(BF_OPENCOLLADA)/lib/libUTF.a -lxml2
+ export BF_PCRE ?= $(LCGDIR)/pcre
+ export BF_PCRE_LIBS ?= $(NAN_PCRE)/lib/libpcre.a
+ endif
+
+
+ # Compare recreated .mo files with committed ones
+ export BF_VERIFY_MO_FILES ?= true
# Platform Dependent settings go below:
ifeq ($(OS),darwin)
@@ -155,6 +168,36 @@ ifndef CONFIG_GUESS
export ID = $(shell whoami)
export HOST = $(shell hostname -s)
+ # set target arch & os version
+ # architecture defaults to host arch, can be ppc, ppc64, i386, x86_64
+ ifeq ($(CPU),powerpc)
+ export MACOSX_ARCHITECTURE ?= ppc
+ else
+ export MACOSX_ARCHITECTURE ?= i386
+ endif
+ # target os version defaults to 10.4 for ppc & i386 (32 bit), 10.5 for ppc64, x86_64
+ ifeq (64,$(findstring 64, $(MACOSX_ARCHITECTURE)))
+ export MACOSX_MIN_VERS ?= 10.5
+ export MACOSX_DEPLOYMENT_TARGET ?= 10.5
+ export MACOSX_SDK ?= /Developer/SDKs/MacOSX10.5.sdk
+ else
+ export MACOSX_MIN_VERS ?= 10.4
+ export MACOSX_DEPLOYMENT_TARGET ?= 10.4
+ export MACOSX_SDK ?= /Developer/SDKs/MacOSX10.4u.sdk
+ endif
+
+ # useful for crosscompiling
+ ifeq ($(MACOSX_ARCHITECTURE),$(findstring $(MACOSX_ARCHITECTURE), "ppc ppc64"))
+ export CPU = powerpc
+ export LCGDIR = $(NAN_LIBDIR)/$(OS)-$(OS_VERSION)-$(CPU)
+ export OCGDIR = $(NAN_OBJDIR)/$(OS)-$(OS_VERSION)-$(CPU)
+ endif
+ ifeq ($(MACOSX_ARCHITECTURE),$(findstring $(MACOSX_ARCHITECTURE),"i386 x86_64"))
+ export CPU = i386
+ export LCGDIR = $(NAN_LIBDIR)/$(OS)-$(OS_VERSION)-$(CPU)
+ export OCGDIR = $(NAN_OBJDIR)/$(OS)-$(OS_VERSION)-$(CPU)
+ endif
+
export NAN_PYTHON_VERSION = 3.1
ifeq ($(NAN_PYTHON_VERSION),3.1)
@@ -199,9 +242,9 @@ ifndef CONFIG_GUESS
export NAN_NO_KETSJI=false
- ifeq ($(CPU), i386)
- export WITH_OPENAL=false
- endif
+ #ifeq ($(CPU), i386)
+ # export WITH_OPENAL=false
+ #endif
# Location of MOZILLA/Netscape header files...
export NAN_MOZILLA_INC ?= $(LCGDIR)/mozilla/include
@@ -222,6 +265,17 @@ ifndef CONFIG_GUESS
export NAN_SAMPLERATE ?= $(LCGDIR)/samplerate
export NAN_SAMPLERATE_LIBS ?= $(NAN_SAMPLERATE)/lib/libsamplerate.a
+ # enable building with Cocoa
+ export WITH_COCOA ?= true
+ export USE_QTKIT ?= false
+ # use cocoa and qtkit for 64bit builds
+ ifeq (64, $(findstring 64, $(MACOSX_ARCHITECTURE)))
+ export WITH_COCOA = true
+ export USE_QTKIT = true
+ endif
+
+ export NAN_PCRE = $(LCGDIR)/opencollada
+
else
ifeq ($(OS),freebsd)
diff --git a/source/nan_link.mk b/source/nan_link.mk
index 0524ee7592d..54021ab016f 100644
--- a/source/nan_link.mk
+++ b/source/nan_link.mk
@@ -59,9 +59,19 @@ ifeq ($(OS),darwin)
LLIBS += -framework Cocoa
endif
LLIBS += -framework Carbon -framework AGL -framework OpenGL
- LLIBS += -framework QuickTime -framework CoreAudio
- LLIBS += -framework AudioUnit -framework AudioToolbox
+ ifeq ($(WITH_QUICKTIME), true)
+ ifeq ($(USE_QTKIT), true)
+ LLIBS += -framework QTKit
+ else
+ LLIBS += -framework QuickTime
+ endif
+ endif
+ LLIBS += -framework CoreAudio
+ LLIBS += -framework AudioUnit -framework AudioToolbox
LDFLAGS += -L/System/Library/Frameworks/OpenGL.framework/Libraries
+ # useful for crosscompiling
+ LDFLAGS += -arch $(MACOSX_ARCHITECTURE) #-isysroot $(MACOSX_SDK) -mmacosx-version-min=$(MACOSX_MIN_VERS)
+
DBG_LDFLAGS += -L/System/Library/Frameworks/OpenGL.framework/Libraries
endif
@@ -177,4 +187,8 @@ ifeq ($(WITH_FFTW3),true)
LLIBS += $(BF_FFTW3_LIBS)
endif
+ifeq ($(WITH_OPENCOLLADA),true)
+ LLIBS += $(BF_OPENCOLLADA_LIBS)
+endif
+
LLIBS += $(NAN_PYTHON_LIB)
diff --git a/tools/btools.py b/tools/btools.py
index 556cb9b901a..b3a97f96417 100644
--- a/tools/btools.py
+++ b/tools/btools.py
@@ -77,7 +77,8 @@ def validate_arguments(args, bc):
'BF_VERSION',
'BF_GHOST_DEBUG',
'WITH_BF_RAYOPTIMIZATION',
- 'BF_RAYOPTIMIZATION_SSE_FLAGS'
+ 'BF_RAYOPTIMIZATION_SSE_FLAGS',
+ 'BF_NO_ELBEEM'
]
# Have options here that scons expects to be lists